From de9dd78aa851431ef552c2f226d29812ff6f6a7c Mon Sep 17 00:00:00 2001 From: greg Date: Thu, 4 Dec 2014 14:26:38 -0600 Subject: [PATCH 1/5] Create database. use methods in irb to create tables. pass tests for create a user --- lib/library_plus.rb | 8 +++++++- lib/library_plus/user_repo.rb | 13 ++++++++++--- spec/repos/user_repo_spec.rb | 1 + 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/library_plus.rb b/lib/library_plus.rb index 9148018a..8e39ffe9 100644 --- a/lib/library_plus.rb +++ b/lib/library_plus.rb @@ -2,7 +2,13 @@ module Library def self.create_db_connection(dbname) - PG.connect(host: 'localhost', dbname: dbname) + cstring = { + host: "localhost", + dbname: dbname, + user: "ruby", + password: "rubyRailsJS" +} + PG.connect(cstring) end def self.clear_db(db) diff --git a/lib/library_plus/user_repo.rb b/lib/library_plus/user_repo.rb index ef6ee87c..a866f9c9 100644 --- a/lib/library_plus/user_repo.rb +++ b/lib/library_plus/user_repo.rb @@ -15,13 +15,20 @@ def self.save(db, user_data) if user_data['id'] # TODO: Update SQL statement else - # TODO: Insert SQL statement + userID = ((user_data[:name].hash)/10000000000).abs + r = db.exec("INSERT INTO users (id, name) VALUES (#{userID}, '#{user_data[:name]}')") + return db.exec("SELECT * FROM users WHERE id = #{userID}").to_a[0] + end end def self.destroy(db, user_data) - # TODO: Delete SQL statement - end + if(user_data['id']) + db.exec("DELETE FROM users WHERE id = #{user_data['id']}") + else + db.exec("DELETE FROM users WHERE name = #{user_data['name']}") + end + end end end diff --git a/spec/repos/user_repo_spec.rb b/spec/repos/user_repo_spec.rb index 94028dde..029d78ca 100644 --- a/spec/repos/user_repo_spec.rb +++ b/spec/repos/user_repo_spec.rb @@ -28,6 +28,7 @@ def user_count(db) expect(user_count(db)).to eq 0 user = Library::UserRepo.save(db, :name => "Alice") + p user expect(user['id']).to_not be_nil expect(user['name']).to eq "Alice" From 30b68fc8bc68068a9e177bb3b1573c18f69d8a45 Mon Sep 17 00:00:00 2001 From: greg Date: Fri, 5 Dec 2014 10:49:21 -0600 Subject: [PATCH 2/5] creates methods for Library::BookRepo --- lib/library_plus.rb | 15 +++++++++++++++ lib/library_plus/book_repo.rb | 34 ++++++++++++++++++++++++++++++++++ lib/library_plus/user_repo.rb | 12 ++++++------ server.rb | 25 +++++++++++++++++++++++++ spec/repos/user_repo_spec.rb | 1 - 5 files changed, 80 insertions(+), 7 deletions(-) diff --git a/lib/library_plus.rb b/lib/library_plus.rb index 8e39ffe9..b12af580 100644 --- a/lib/library_plus.rb +++ b/lib/library_plus.rb @@ -16,6 +16,10 @@ def self.clear_db(db) DELETE FROM users; /* TODO: Clear rest of the tables (books, etc.) */ SQL + db.exec <<-SQL + DELETE FROM books; + /* TODO: Clear rest of the tables (books, etc.) */ + SQL end def self.create_tables(db) @@ -26,6 +30,13 @@ def self.create_tables(db) ); /* TODO: Create rest of the tables (books, etc.) */ SQL + db.exec <<-SQL + CREATE TABLE books( + id SERIAL PRIMARY KEY, + title VARCHAR, + author VARCHAR + ); + SQL end def self.drop_tables(db) @@ -33,6 +44,10 @@ def self.drop_tables(db) DROP TABLE users; /* TODO: Drop rest of the tables (books, etc.) */ SQL + db.exec <<-SQL + DROP TABLE books; + /* TODO: Drop rest of the tables (books, etc.) */ + SQL end end diff --git a/lib/library_plus/book_repo.rb b/lib/library_plus/book_repo.rb index 46409041..a0351b5b 100644 --- a/lib/library_plus/book_repo.rb +++ b/lib/library_plus/book_repo.rb @@ -1 +1,35 @@ +module Library + class BookRepo + + 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 books").to_a + end + + def self.find(db, book_data) + # TODO: Insert SQL statement + end + + def self.save(db, book_data) + if book_data[:id] + # TODO: Update SQL statement + else + title = book_data[:title] + author = book_data[:author] + db.exec("INSERT INTO books (title, author) VALUES ('#{title}', '#{author}')") + r = db.exec("SELECT id, title FROM books ORDER BY id DESC LIMIT 1").to_a + return r[0] + end + end + + def self.destroy(db, book_data) + if(book_data[:id]) + db.exec("DELETE FROM books WHERE id = #{book_data[:id]}") + else + db.exec("DELETE FROM books WHERE title = #{book_data[:title]}") + end + end + end +end # TODO diff --git a/lib/library_plus/user_repo.rb b/lib/library_plus/user_repo.rb index a866f9c9..0a88db42 100644 --- a/lib/library_plus/user_repo.rb +++ b/lib/library_plus/user_repo.rb @@ -15,18 +15,18 @@ def self.save(db, user_data) if user_data['id'] # TODO: Update SQL statement else - userID = ((user_data[:name].hash)/10000000000).abs - r = db.exec("INSERT INTO users (id, name) VALUES (#{userID}, '#{user_data[:name]}')") - return db.exec("SELECT * FROM users WHERE id = #{userID}").to_a[0] - + name = user_data[:name] + db.exec("INSERT INTO users (name) VALUES ('#{name}')") + r = db.exec("SELECT id, name FROM users ORDER BY id DESC LIMIT 1").to_a + return r[0] end end def self.destroy(db, user_data) if(user_data['id']) - db.exec("DELETE FROM users WHERE id = #{user_data['id']}") + db.exec("DELETE FROM users WHERE id = #{user_data[:id]}") else - db.exec("DELETE FROM users WHERE name = #{user_data['name']}") + db.exec("DELETE FROM users WHERE name = #{user_data[:name]}") end end diff --git a/server.rb b/server.rb index 91a87bcd..50e2857e 100644 --- a/server.rb +++ b/server.rb @@ -1,8 +1,33 @@ require 'sinatra' require './lib/library_plus' +require 'sinatra/reloader' # set :bind, '0.0.0.0' # This is needed for Vagrant get '/' do erb :index end + +get '/users' do + db = Library.create_db_connection('library_dev') + @users = Library::UserRepo.all(db) + erb :"users/index" +end + +post '/users' do + db = Library.create_db_connection('library_dev') + @u = Library::UserRepo.save(db, :name => params["user_name"]) + erb :"users/create" +end + +get '/books' do + db = Library.create_db_connection('library_dev') + @books = Library::BookRepo.all(db) + erb :"books/index" +end + +post '/books' do + db = Library.create_db_connection('library_dev') + @b = Library::BookRepo.save(db, {title: params["book_title"], author: params["book_author"]}) + erb :"books/create" +end \ No newline at end of file diff --git a/spec/repos/user_repo_spec.rb b/spec/repos/user_repo_spec.rb index 029d78ca..94028dde 100644 --- a/spec/repos/user_repo_spec.rb +++ b/spec/repos/user_repo_spec.rb @@ -28,7 +28,6 @@ def user_count(db) expect(user_count(db)).to eq 0 user = Library::UserRepo.save(db, :name => "Alice") - p user expect(user['id']).to_not be_nil expect(user['name']).to eq "Alice" From dcf8776f9ca2729994d685a089f497d8ac452743 Mon Sep 17 00:00:00 2001 From: greg Date: Fri, 5 Dec 2014 14:16:40 -0600 Subject: [PATCH 3/5] implements and satisfies all tests for Library::BookRepo --- lib/library_plus/book_repo.rb | 31 +++++++++++++++++-------------- lib/library_plus/user_repo.rb | 16 +++++----------- server.rb | 26 ++++++++++++++++++++++++-- spec/repos/user_repo_spec.rb | 21 +++++++++++---------- views/index.erb | 3 +++ 5 files changed, 60 insertions(+), 37 deletions(-) diff --git a/lib/library_plus/book_repo.rb b/lib/library_plus/book_repo.rb index a0351b5b..db0d1057 100644 --- a/lib/library_plus/book_repo.rb +++ b/lib/library_plus/book_repo.rb @@ -8,28 +8,31 @@ def self.all(db) end def self.find(db, book_data) - # TODO: Insert SQL statement + db.exec("SELECT * FROM books WHERE id = #{book_data}").to_a[0] end def self.save(db, book_data) - if book_data[:id] - # TODO: Update SQL statement + if book_data["id"] + s = "" + if(book_data["title"]) + s+="title = '"+book_data["title"]+"'" + end + if(book_data["title"] && book_data["author"]) + s+="," + end + if(book_data["author"]) + s+="author = '"+book_data["author"]+"'" + end + db.exec("UPDATE books SET #{s} WHERE id = #{book_data['id']} returning *").to_a[0] else - title = book_data[:title] - author = book_data[:author] - db.exec("INSERT INTO books (title, author) VALUES ('#{title}', '#{author}')") - r = db.exec("SELECT id, title FROM books ORDER BY id DESC LIMIT 1").to_a - return r[0] - end + db.exec("INSERT INTO books (title, author) VALUES ('#{book_data["title"]}', '#{book_data["author"]}') returning *").to_a[0] + end end def self.destroy(db, book_data) - if(book_data[:id]) - db.exec("DELETE FROM books WHERE id = #{book_data[:id]}") - else - db.exec("DELETE FROM books WHERE title = #{book_data[:title]}") + r = db.exec("DELETE FROM books WHERE id = #{book_data}") + return r.cmd_status() end - end end end # TODO diff --git a/lib/library_plus/user_repo.rb b/lib/library_plus/user_repo.rb index 0a88db42..5a25c1f1 100644 --- a/lib/library_plus/user_repo.rb +++ b/lib/library_plus/user_repo.rb @@ -8,26 +8,20 @@ def self.all(db) end def self.find(db, user_data) - # TODO: Insert SQL statement + db.exec("SELECT * FROM users WHERE id = #{user_data}").to_a[0] end def self.save(db, user_data) if user_data['id'] - # TODO: Update SQL statement + db.exec("UPDATE users SET name = '#{user_data['name']}' WHERE id = #{user_data['id']} returning *").to_a[0] else - name = user_data[:name] - db.exec("INSERT INTO users (name) VALUES ('#{name}')") - r = db.exec("SELECT id, name FROM users ORDER BY id DESC LIMIT 1").to_a - return r[0] + db.exec("INSERT INTO users (name) VALUES ('#{user_data['name']}') returning *").to_a[0] end end def self.destroy(db, user_data) - if(user_data['id']) - db.exec("DELETE FROM users WHERE id = #{user_data[:id]}") - else - db.exec("DELETE FROM users WHERE name = #{user_data[:name]}") - end + r = db.exec("DELETE FROM users WHERE id = #{user_data}") + return r.cmd_status() end end diff --git a/server.rb b/server.rb index 50e2857e..23ce10f3 100644 --- a/server.rb +++ b/server.rb @@ -16,10 +16,21 @@ post '/users' do db = Library.create_db_connection('library_dev') - @u = Library::UserRepo.save(db, :name => params["user_name"]) + @u = Library::UserRepo.save(db, "name" => params["user_name"]) erb :"users/create" end +get '/users/:id/delete' do + db = Library.create_db_connection('library_dev') + r = Library::UserRepo.destroy(db, params["id"]) + if(r.split().last == "1") + @u = "User ##{params["id"]} has been deleted successfully!" + else + @u = "Error deleting user ##{params["id"]}." + end + erb :"users/delete" +end + get '/books' do db = Library.create_db_connection('library_dev') @books = Library::BookRepo.all(db) @@ -28,6 +39,17 @@ post '/books' do db = Library.create_db_connection('library_dev') - @b = Library::BookRepo.save(db, {title: params["book_title"], author: params["book_author"]}) + @b = Library::BookRepo.save(db, {"title" => params["book_title"], "author" => params["book_author"]}) erb :"books/create" +end + +get '/books/:id/delete' do + db = Library.create_db_connection('library_dev') + r = Library::BookRepo.destroy(db, params["id"]) + if(r.split().last == "1") + @u = "Book ##{params["id"]} has been deleted successfully!" + else + @u = "Error deleting book ##{params["id"]}." + end + erb :"books/delete" end \ No newline at end of file diff --git a/spec/repos/user_repo_spec.rb b/spec/repos/user_repo_spec.rb index 94028dde..e98cdb37 100644 --- a/spec/repos/user_repo_spec.rb +++ b/spec/repos/user_repo_spec.rb @@ -27,10 +27,11 @@ def user_count(db) it "creates users" do expect(user_count(db)).to eq 0 - user = Library::UserRepo.save(db, :name => "Alice") + user = Library::UserRepo.save(db, { 'name' => "Alice" }) expect(user['id']).to_not be_nil expect(user['name']).to eq "Alice" + # Check for persistence expect(user_count(db)).to eq 1 @@ -38,28 +39,28 @@ def user_count(db) expect(user['name']).to eq "Alice" end - xit "finds users" do - user = Library::UserRepo.save(db, :name => "Alice") + it "finds users" do + user = Library::UserRepo.save(db, { 'name' => "Alice" }) retrieved_user = Library::UserRepo.find(db, user['id']) expect(retrieved_user['name']).to eq "Alice" end - xit "updates users" do - user1 = Library::UserRepo.save(db, :name => "Alice") - user2 = Library::UserRepo.save(db, :name => "Alicia") + it "updates users" do + user1 = Library::UserRepo.save(db, { 'name' => "Alice" }) + user2 = Library::UserRepo.save(db, { 'id' => user1['id'], 'name' => "Alicia" }) expect(user2['id']).to eq(user1['id']) expect(user2['name']).to eq "Alicia" # Check for persistence - user3 = Library::UserRepo.find(user1['id']) + user3 = Library::UserRepo.find(db, user1['id']) expect(user3['name']).to eq "Alicia" end - xit "destroys users" do - user = Library::UserRepo.save(db, :name => "Alice") + it "destroys users" do + user = Library::UserRepo.save(db, { 'name' => "Alice" }) expect(user_count(db)).to eq 1 Library::UserRepo.destroy(db, user['id']) expect(user_count(db)).to eq 0 end -end +end \ No newline at end of file diff --git a/views/index.erb b/views/index.erb index aba3235d..b0e5aaa9 100644 --- a/views/index.erb +++ b/views/index.erb @@ -1,3 +1,6 @@

The Library Plus System

Welcome to your freedom!

+ +Manage Users
+Manage Books \ No newline at end of file From a8587695971c1f5cb7c3ebbf45fca0101b9f08b4 Mon Sep 17 00:00:00 2001 From: greg Date: Sat, 6 Dec 2014 09:16:42 -0600 Subject: [PATCH 4/5] adds some helper methods to the repositories. creates tests for helper methods --- lib/library_plus.rb | 15 +++++++++++++++ lib/library_plus/book_repo.rb | 21 +++++++++++++++++++-- server.rb | 22 ++++++++++++++++++++-- 3 files changed, 54 insertions(+), 4 deletions(-) diff --git a/lib/library_plus.rb b/lib/library_plus.rb index b12af580..f73f18be 100644 --- a/lib/library_plus.rb +++ b/lib/library_plus.rb @@ -20,6 +20,10 @@ def self.clear_db(db) DELETE FROM books; /* TODO: Clear rest of the tables (books, etc.) */ SQL + db.exec <<-SQL + DELETE FROM checkouts; + /* TODO: Clear rest of the tables (books, etc.) */ + SQL end def self.create_tables(db) @@ -37,6 +41,16 @@ def self.create_tables(db) author VARCHAR ); SQL + db.exec <<-SQL + CREATE TABLE checkouts( + id SERIAL PRIMARY KEY, + book_id INTEGER, + user_id INTEGER, + checkout_date date, + due_date date, + return_date date + ); + SQL end def self.drop_tables(db) @@ -53,3 +67,4 @@ def self.drop_tables(db) require_relative 'library_plus/book_repo' require_relative 'library_plus/user_repo' +require_relative 'library_plus/checkout_repo' diff --git a/lib/library_plus/book_repo.rb b/lib/library_plus/book_repo.rb index db0d1057..4455083c 100644 --- a/lib/library_plus/book_repo.rb +++ b/lib/library_plus/book_repo.rb @@ -4,11 +4,28 @@ class BookRepo 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 books").to_a + b = db.exec("SELECT * FROM books").to_a + checkouts = Library::CheckoutRepo.all_by_book(db) + b.each do |book| + book['available'] = true + id = book['id'] + if (checkouts[id]) + book['checkouts'] = checkouts[id] + book['checkouts'].each do |checkout| + book['available'] = false if !checkout['return_date'] + end + end + end + return b end def self.find(db, book_data) - db.exec("SELECT * FROM books WHERE id = #{book_data}").to_a[0] + book = db.exec("SELECT * FROM books WHERE id = #{book_data}").to_a[0] + checkouts = Library::CheckoutRepo.find(db, 'book_id' => book['id']) # should return array + if (checkouts) + book['checkouts'] = checkouts + end + return book end def self.save(db, book_data) diff --git a/server.rb b/server.rb index 23ce10f3..95f5230f 100644 --- a/server.rb +++ b/server.rb @@ -17,7 +17,7 @@ post '/users' do db = Library.create_db_connection('library_dev') @u = Library::UserRepo.save(db, "name" => params["user_name"]) - erb :"users/create" + redirect to("/users") end get '/users/:id/delete' do @@ -40,7 +40,13 @@ post '/books' do db = Library.create_db_connection('library_dev') @b = Library::BookRepo.save(db, {"title" => params["book_title"], "author" => params["book_author"]}) - erb :"books/create" + redirect to("/books") +end + +get '/books/:id' do + db = Library.create_db_connection('library_dev') + @book = Library::BookRepo.find(db, params['id']) + erb :"books/info" end get '/books/:id/delete' do @@ -52,4 +58,16 @@ @u = "Error deleting book ##{params["id"]}." end erb :"books/delete" +end + +get '/books/:id/checkout' do + db = Library.create_db_connection('library_dev') + @users = Library::UserRepo.all(db) + @book = Library::BookRepo.find(db, params['id']) + erb :"books/checkout" +end + +post '/books/:id/checkout/to/' do + @s = "Checking out #{params['id']} to #{params['user_id']} " + erb :"books/checkout_to" end \ No newline at end of file From 1431a5858e56cb543b6865c97238f6cee0581412 Mon Sep 17 00:00:00 2001 From: greg Date: Mon, 8 Dec 2014 13:35:20 -0600 Subject: [PATCH 5/5] One final commit for all final changes --- lib/library_plus/book_repo.rb | 8 ++++++- lib/library_plus/user_repo.rb | 41 ++++++++++++++++++++++++++++++++++- server.rb | 17 ++++++++++----- 3 files changed, 59 insertions(+), 7 deletions(-) diff --git a/lib/library_plus/book_repo.rb b/lib/library_plus/book_repo.rb index 4455083c..7998465d 100644 --- a/lib/library_plus/book_repo.rb +++ b/lib/library_plus/book_repo.rb @@ -21,10 +21,16 @@ def self.all(db) def self.find(db, book_data) book = db.exec("SELECT * FROM books WHERE id = #{book_data}").to_a[0] - checkouts = Library::CheckoutRepo.find(db, 'book_id' => book['id']) # should return array + checkouts = Library::CheckoutRepo.find_with_user(db, 'book_id' => book['id']) # should return array + book['available'] = true + if (checkouts) book['checkouts'] = checkouts + book['checkouts'].each do |checkout| + book['available'] = false if !checkout['return_date'] + end end + return book end diff --git a/lib/library_plus/user_repo.rb b/lib/library_plus/user_repo.rb index 5a25c1f1..fcf9c213 100644 --- a/lib/library_plus/user_repo.rb +++ b/lib/library_plus/user_repo.rb @@ -6,11 +6,50 @@ def self.all(db) # Therefore, convert the results into a plain array. db.exec("SELECT * FROM users").to_a end + def self.all_with_checkouts(db) + # Other code should not have to deal with the PG:Result. + # Therefore, convert the results into a plain array. + u = db.exec("SELECT * FROM users").to_a + checkouts = Library::CheckoutRepo.all_by_user(db) + u.each do |user| + id = user['id'] + user['checkouts.outstanding'] = [] + if (checkouts[id]) + user['checkouts'] = checkouts[id] + checkouts[id].each do |checkout| + unless(checkout['return_date']) + user['checkouts.outstanding'].push(checkout) + end + end + end + end + return u + end + + def self.find_with_checkouts(db, user_data) + user = db.exec("SELECT * FROM users WHERE id = #{user_data}").to_a[0] + + + checkouts = Library::CheckoutRepo.all_by_user(db) + id = user['id'] + user['checkouts.outstanding'] = [] + if (checkouts[id]) + user['checkouts'] = checkouts[id] + + checkouts[id].each do |checkout| + unless(checkout['return_date']) + user['checkouts.outstanding'].push(checkout) + end + end + end + return user + end def self.find(db, user_data) db.exec("SELECT * FROM users WHERE id = #{user_data}").to_a[0] - end + + end def self.save(db, user_data) if user_data['id'] db.exec("UPDATE users SET name = '#{user_data['name']}' WHERE id = #{user_data['id']} returning *").to_a[0] diff --git a/server.rb b/server.rb index 95f5230f..03870dbb 100644 --- a/server.rb +++ b/server.rb @@ -1,6 +1,7 @@ require 'sinatra' require './lib/library_plus' require 'sinatra/reloader' +require 'json' # set :bind, '0.0.0.0' # This is needed for Vagrant @@ -10,10 +11,14 @@ get '/users' do db = Library.create_db_connection('library_dev') - @users = Library::UserRepo.all(db) + @users = Library::UserRepo.all_with_checkouts(db) erb :"users/index" end - +get '/users/:id' do + db = Library.create_db_connection('library_dev') + @user = Library::UserRepo.find_with_checkouts(db, params[:id]) + erb :"users/info" +end post '/users' do db = Library.create_db_connection('library_dev') @u = Library::UserRepo.save(db, "name" => params["user_name"]) @@ -34,6 +39,7 @@ get '/books' do db = Library.create_db_connection('library_dev') @books = Library::BookRepo.all(db) + @users = JSON.generate(Library::UserRepo.all(db)) # Querying this to populate checkout list. erb :"books/index" end @@ -67,7 +73,8 @@ erb :"books/checkout" end -post '/books/:id/checkout/to/' do - @s = "Checking out #{params['id']} to #{params['user_id']} " - erb :"books/checkout_to" +post '/books/:id/checkout' do + db = Library.create_db_connection('library_dev') + Library.CheckoutRepo.save(db, checkout_data) + redirect to("/books") end \ No newline at end of file