Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@ ruby '2.0.0'

gem 'rspec', '~> 2.14.1'
gem 'pry-byebug'
gem 'pg'
gem 'sinatra'
gem 'rake'
gem 'sinatra-reloader'
27 changes: 27 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
GEM
remote: https://rubygems.org/
specs:
backports (3.6.4)
byebug (3.5.1)
columnize (~> 0.8)
debugger-linecache (~> 1.2)
Expand All @@ -10,13 +11,21 @@ GEM
debugger-linecache (1.2.0)
diff-lcs (1.2.5)
method_source (0.8.2)
multi_json (1.10.1)
pg (0.17.1)
pry (0.10.1)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
pry-byebug (2.0.0)
byebug (~> 3.4)
pry (~> 0.10)
rack (1.5.2)
rack-protection (1.5.3)
rack
rack-test (0.6.2)
rack (>= 1.0)
rake (10.3.2)
rspec (2.14.1)
rspec-core (~> 2.14.0)
rspec-expectations (~> 2.14.0)
Expand All @@ -25,11 +34,29 @@ GEM
rspec-expectations (2.14.5)
diff-lcs (>= 1.1.3, < 2.0)
rspec-mocks (2.14.5)
sinatra (1.4.5)
rack (~> 1.4)
rack-protection (~> 1.4)
tilt (~> 1.3, >= 1.3.4)
sinatra-contrib (1.4.2)
backports (>= 2.0)
multi_json
rack-protection
rack-test
sinatra (~> 1.4.0)
tilt (~> 1.3)
sinatra-reloader (1.0)
sinatra-contrib
slop (3.6.0)
tilt (1.4.1)

PLATFORMS
ruby

DEPENDENCIES
pg
pry-byebug
rake
rspec (~> 2.14.1)
sinatra
sinatra-reloader
50 changes: 50 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@

task :environment do
require './lib/songify.rb'
end

task :console => :environment do
require 'irb'
ARGV.clear
IRB.start
end


namespace :db do

task :create do
`createdb songify_test`
`createdb songify_dev`
puts "Created."
end

task :drop do
`dropdb songify_test`
`dropdb songify_dev`
puts "Dropped."
end

task :create_tables => :environment do
db1 = Songify.create_db_connection('songify_test')
db2 = Songify.create_db_connection('songify_dev')
Songify.create_tables(db1)
Songify.create_tables(db2)
puts "Created tables."
end

task :drop_tables => :environment do
db1 = Songify.create_db_connection('songify_test')
db2 = Songify.create_db_connection('songify_dev')
Songify.drop_tables(db1)
Songify.drop_tables(db2)
puts "Dropped tables."
end

task :clear => :environment do
# The test db clears all the time, so there's no point in doing it here.
db = Songify.create_db_connection('songify_dev')
Songify.drop_tables(db)
puts "Cleared tables."
end

end
55 changes: 55 additions & 0 deletions lib/songify.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
require 'pg'

module Songify
def self.create_db_connection(dbname)
PG.connect(host: 'localhost', dbname: dbname)
end

def self.clear_db(db)
db.exec <<-SQL
DELETE FROM song_genres;
DELETE FROM songs;
DELETE FROM albums;
DELETE FROM genres;
/* TODO: Clear rest of the tables (books, etc.) */
SQL
end

def self.create_tables(db)
db.exec <<-SQL
CREATE TABLE albums(
id SERIAL PRIMARY KEY,
title VARCHAR
);
CREATE TABLE songs(
id SERIAL PRIMARY KEY,
album_id integer REFERENCES albums (id),
title VARCHAR
);
CREATE TABLE genres(
id SERIAL PRIMARY KEY,
name VARCHAR
);
/* TODO: Create song_genres table */
CREATE TABLE song_genres(
id SERIAL PRIMARY KEY,
album_id INTEGER REFERENCES albums (id),
genre INTEGER REFERENCES genres (id)
);
SQL
end

def self.drop_tables(db)
db.exec <<-SQL
DROP TABLE songs;
DROP TABLE albums;
DROP TABLE genres;
/* TODO: Drop song_genres table */
DROP TABLE song_genres;
SQL
end
end

require_relative 'songify/album_repo'
require_relative 'songify/genre_repo'
require_relative 'songify/song_repo'
54 changes: 54 additions & 0 deletions lib/songify/album_repo.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
module Songify
class AlbumRepo

def self.all(db)
# Other code should not have to deal with the PG:Result.
# Therefore, convert the results into a plain array.
db.exec("SELECT * FROM albums").to_a
end

def self.find(db, album_id)
result = db.exec("SELECT * FROM albums WHERE id=$1;", [album_id]).first
if result
genres = db.exec("Select genres.name, genres.id from song_genres Join genres on (song_genres.genre = genres.id) WHERE album_id = $1;", [album_id]).to_a
genres_array = []
genres.each do |genre|
genres_array << genre
end
result['genres'] = genres_array
end
result
end

def self.save(db, album_data)
if album_data['id']
result = db.exec("UPDATE albums SET title = $2 WHERE id = $1", [album_data['id'], album_data['title']])
self.find(db, album_data['id'])
else
raise "title is required." if album_data['title'].nil? || album_data['title'] == ''
result = db.exec("INSERT INTO albums (title) VALUES ($1) RETURNING id", [album_data['title']])
album_data['id'] = result.entries.first['id']
album_data
end
if album_data['genre_ids']
album_data['genre_ids'].each do |genre|
db.exec("INSERT INTO song_genres (album_id, genre) VALUES ($1, $2) RETURNING genre;", [album_data['id'], genre])
end
genres = db.exec("Select genres.name from song_genres Join genres on (song_genres.genre = genres.id) WHERE album_id = $1;", [album_data['id']]).to_a
genres_array = []
genres.each do |genre|
genres_array << genre['name']
end
album_data['genres'] = genres_array
end
album_data
end

def self.destroy(db, album_id)
# TODO: Delete SQL statement
# ALSO DELETE SONGS
# ALSO DELETE JOIN TABLE ENTRIES BETWEEN THIS ALBUM AND ITS GENRES
end

end
end
33 changes: 33 additions & 0 deletions lib/songify/genre_repo.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module Songify
class GenreRepo

def self.all(db)
# Other code should not have to deal with the PG:Result.
# Therefore, convert the results into a plain array.
db.exec("SELECT * FROM genres").to_a
end

def self.find(db, genre_id)
db.exec("SELECT * FROM genres WHERE id=$1", [genre_id]).first
end

def self.save(db, genre_data)
if genre_data['id']
result = db.exec("UPDATE genres SET name = $2 WHERE id = $1", [genre_data['id'], genre_data['name']])
self.find(db, genre_data['id'])
else
raise "name is required." if genre_data['name'].nil? || genre_data['name'] == ''

result = db.exec("INSERT INTO genres (name) VALUES ($1) RETURNING id", [genre_data['name']])
genre_data['id'] = result.entries.first['id']
genre_data
end
end

def self.destroy(db, genre_id)
# TODO: Delete SQL statement
# ALSO DELETE JOIN TABLE ENTRIES BETWEEN THIS GENRE AND ITS ALBUMS
end

end
end
32 changes: 32 additions & 0 deletions lib/songify/song_repo.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
module Songify
class SongRepo

def self.all(db)
# Other code should not have to deal with the PG:Result.
# Therefore, convert the results into a plain array.
db.exec("SELECT * FROM songs").to_a
end

def self.find(db, song_id)
db.exec("SELECT * FROM songs WHERE id=$1", [song_id]).first
end

def self.save(db, song_data)
if song_data['id']
result = db.exec("UPDATE songs SET title = $2 WHERE id = $1", [song_data['id'], song_data['title']])
self.find(db, song_data['id'])
else
raise "title is required." if song_data['title'].nil? || song_data['title'] == ''

# Ensure album exists
album = AlbumRepo.find(db, song_data['album_id'])
raise "A valid album_id is required." if album.nil?

result = db.exec("INSERT INTO songs (album_id, title) VALUES ($1, $2) RETURNING id", [song_data['album'], song_data['title']])
song_data['id'] = result.entries.first['id']
song_data
end
end

end
end
56 changes: 56 additions & 0 deletions server.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
require 'sinatra'
require './lib/songify.rb'
require 'sinatra/reloader'

set :bind, '0.0.0.0' # This is needed for Vagrant

get '/' do
erb :index
end

get '/albums' do
db = Songify.create_db_connection('songify_dev')
@albums = Songify::AlbumRepo.all(db)
@genres = Songify::GenreRepo.all(db)
erb :"albums/index"
end

post '/albums' do
db = Songify.create_db_connection('songify_dev')
album = Songify::AlbumRepo.save(db, {
'title' => params[:title], 'genre_ids' => params[:genre_ids]
})
redirect to '/albums'
end


get '/songs' do
db = Songify.create_db_connection('songify_dev')
@songs = Songify::SongRepo.all(db)
db = Songify.create_db_connection('songify_dev')
@albums = Songify::AlbumRepo.all(db)
erb :"songs/index"
end

post '/songs' do
song_data = {'title' => params['name'], 'album_id' => params['album-select']}
db = Songify.create_db_connection('songify_dev')
song = Songify::SongRepo.save(db, song_data)
redirect to '/songs'
end



get '/genres' do
db = Songify.create_db_connection('songify_dev')
@genres = Songify::GenreRepo.all(db)
erb :"genres/index"
end

post '/genres' do
db = Songify.create_db_connection('songify_dev')
album = Songify::GenreRepo.save(db, {
'name' => params[:name]
})
redirect to '/genres'
end
Empty file removed spec/.gitkeep
Empty file.
Loading