From 68d15a84b72d7215995c225fc60f3b20990aca77 Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Fri, 5 Dec 2014 18:13:42 +0000 Subject: [PATCH 1/9] get_all_users passes --- lib/library_plus.rb | 7 ++++++- lib/library_plus/book_repo.rb | 10 ++++++++++ lib/library_plus/user_repo.rb | 3 +++ spec/repos/user_repo_spec.rb | 14 ++++++++++++-- spec/spec_helper.rb | 2 +- 5 files changed, 32 insertions(+), 4 deletions(-) diff --git a/lib/library_plus.rb b/lib/library_plus.rb index 9148018a..c125517d 100644 --- a/lib/library_plus.rb +++ b/lib/library_plus.rb @@ -1,13 +1,18 @@ require 'pg' module Library + + def self.create_db(dbname) + success = system("createdb #{dbname}") + end + def self.create_db_connection(dbname) PG.connect(host: 'localhost', dbname: dbname) end def self.clear_db(db) db.exec <<-SQL - DELETE FROM users; + DROP TABLE IF EXISTS users; /* TODO: Clear rest of the tables (books, etc.) */ SQL end diff --git a/lib/library_plus/book_repo.rb b/lib/library_plus/book_repo.rb index 46409041..19f5e6aa 100644 --- a/lib/library_plus/book_repo.rb +++ b/lib/library_plus/book_repo.rb @@ -1 +1,11 @@ # TODO +# module Library +# class BookRepo +# def self.all +# end +# +# def self.check_cout(db, book_id) +# +# end +# end +# end diff --git a/lib/library_plus/user_repo.rb b/lib/library_plus/user_repo.rb index ef6ee87c..6acb9ef6 100644 --- a/lib/library_plus/user_repo.rb +++ b/lib/library_plus/user_repo.rb @@ -1,3 +1,6 @@ +# Library::UserRepo.all(db) +# Library::BookRepo.all(db) + module Library class UserRepo diff --git a/spec/repos/user_repo_spec.rb b/spec/repos/user_repo_spec.rb index 94028dde..f497aead 100644 --- a/spec/repos/user_repo_spec.rb +++ b/spec/repos/user_repo_spec.rb @@ -1,4 +1,5 @@ require 'spec_helper' +require 'pg' describe Library::UserRepo do @@ -6,10 +7,19 @@ def user_count(db) db.exec("SELECT COUNT(*) FROM users")[0]["count"].to_i end - let(:db) { Library.create_db_connection('library_test') } + # A let(:db) define means you can use db in an it statement below + # Also, the code in {} does not run until it sees a 'db' statement in an 'it' block + # Therefore, the code will run for each 'it' block + let(:db) { + Library.create_db('library_test') + Library.create_db_connection('library_test') + } + # Before each 'it' block we are clearing the data base + # That way when we crete users we know exactly how many should be in the db before(:each) do Library.clear_db(db) + Library.create_tables(db) end it "gets all users" do @@ -24,7 +34,7 @@ def user_count(db) expect(names).to include "Alice", "Bob" end - it "creates users" do + xit "creates users" do expect(user_count(db)).to eq 0 user = Library::UserRepo.save(db, :name => "Alice") diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 962938ee..6a4c4d17 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,4 +1,4 @@ -require 'library_plus' +require 'library_plus.rb' RSpec.configure do |config| config.treat_symbols_as_metadata_keys_with_true_values = true From 9b582e79c78a094f8ef466c076df4f048250de76 Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Fri, 5 Dec 2014 20:48:11 +0000 Subject: [PATCH 2/9] All "creates users" tests pass --- lib/library_plus.rb | 1 + lib/library_plus/user_repo.rb | 15 +++++++++++++-- spec/repos/user_repo_spec.rb | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/lib/library_plus.rb b/lib/library_plus.rb index c125517d..8c67d0da 100644 --- a/lib/library_plus.rb +++ b/lib/library_plus.rb @@ -1,4 +1,5 @@ require 'pg' +require 'pry-byebug' module Library diff --git a/lib/library_plus/user_repo.rb b/lib/library_plus/user_repo.rb index af4c27f6..a42a6f81 100644 --- a/lib/library_plus/user_repo.rb +++ b/lib/library_plus/user_repo.rb @@ -16,15 +16,26 @@ def self.find(db, user_id) def self.save(db, user_data) if user_data['id'] - # TODO: Update SQL statement + # Update Name + db.exec("UPDATE users SET name = '#{user_data['name']}' WHERE id = #{user_data['id']}") else - # TODO: Insert SQL statement + # Enter Name and Unique ID gets assigned automatically + db.exec("INSERT INTO users (name) VALUES ('#{user_data['name']}')") end + get_user(db, user_data).last end def self.destroy(db, user_id) # TODO: Delete SQL statement end + def self.get_user(db, user_data) + if user_data['id'] + db.exec("SELECT * FROM users WHERE id = #{user_data['id']}").entries + else + db.exec("SELECT * FROM users WHERE name = '#{user_data['name']}'").entries + end + end + end end diff --git a/spec/repos/user_repo_spec.rb b/spec/repos/user_repo_spec.rb index 2036553d..4e6868a9 100644 --- a/spec/repos/user_repo_spec.rb +++ b/spec/repos/user_repo_spec.rb @@ -34,7 +34,7 @@ def user_count(db) expect(names).to include "Alice", "Bob" end - xit "creates users" do + it "creates users" do expect(user_count(db)).to eq 0 user = Library::UserRepo.save(db, { 'name' => "Alice" }) From ef10b83fd8906d7ca8383961e89d57ee020fabc1 Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Fri, 5 Dec 2014 21:01:34 +0000 Subject: [PATCH 3/9] All 5/5 Tests Pass --- lib/library_plus/user_repo.rb | 8 ++++---- spec/repos/user_repo_spec.rb | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/library_plus/user_repo.rb b/lib/library_plus/user_repo.rb index a42a6f81..4230f43b 100644 --- a/lib/library_plus/user_repo.rb +++ b/lib/library_plus/user_repo.rb @@ -11,7 +11,7 @@ def self.all(db) end def self.find(db, user_id) - # TODO: Insert SQL statement + db.exec("SELECT * FROM users WHERE id = #{user_id}").entries.last end def self.save(db, user_data) @@ -22,14 +22,14 @@ def self.save(db, user_data) # Enter Name and Unique ID gets assigned automatically db.exec("INSERT INTO users (name) VALUES ('#{user_data['name']}')") end - get_user(db, user_data).last + get_users(db, user_data).last end def self.destroy(db, user_id) - # TODO: Delete SQL statement + db.exec("DELETE FROM users WHERE id = #{user_id}") end - def self.get_user(db, user_data) + def self.get_users(db, user_data) if user_data['id'] db.exec("SELECT * FROM users WHERE id = #{user_data['id']}").entries else diff --git a/spec/repos/user_repo_spec.rb b/spec/repos/user_repo_spec.rb index 4e6868a9..afbd870f 100644 --- a/spec/repos/user_repo_spec.rb +++ b/spec/repos/user_repo_spec.rb @@ -48,13 +48,13 @@ def user_count(db) expect(user['name']).to eq "Alice" end - xit "finds users" do + 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 + 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']) @@ -65,7 +65,7 @@ def user_count(db) expect(user3['name']).to eq "Alicia" end - xit "destroys users" do + it "destroys users" do user = Library::UserRepo.save(db, { 'name' => "Alice" }) expect(user_count(db)).to eq 1 From 763af7d6755d12042425ce39dd9138472c5986d4 Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Sat, 6 Dec 2014 21:23:16 +0000 Subject: [PATCH 4/9] Add functionality to 'Manage Users' from '/' and Register new users Print users alphabetically by name in users/index --- lib/library_plus.rb | 2 +- server.rb | 20 +++++++++++++++++++- views/index.erb | 2 ++ views/users/index.erb | 22 ++++++++++++++++++++++ 4 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 views/users/index.erb diff --git a/lib/library_plus.rb b/lib/library_plus.rb index 8c67d0da..25d0292a 100644 --- a/lib/library_plus.rb +++ b/lib/library_plus.rb @@ -20,7 +20,7 @@ def self.clear_db(db) def self.create_tables(db) db.exec <<-SQL - CREATE TABLE users( + CREATE TABLE IF NOT EXISTS users( id SERIAL PRIMARY KEY, name VARCHAR ); diff --git a/server.rb b/server.rb index 91a87bcd..180d4812 100644 --- a/server.rb +++ b/server.rb @@ -1,8 +1,26 @@ require 'sinatra' require './lib/library_plus' +require 'pry-byebug' -# set :bind, '0.0.0.0' # This is needed for Vagrant +set :bind, '0.0.0.0' # This is needed for Vagrant get '/' do erb :index end + +get '/users' do + Library.create_db('library_dev') + db = Library.create_db_connection('library_dev') + Library.create_tables(db) + @users = Library::UserRepo.all(db) + erb :"users/index" +end + +post '/users' do + # puts params + username = params[:user_name] + db = Library.create_db_connection('library_dev') + Library::UserRepo.save(db, { 'name' => username }) + @users = Library::UserRepo.all(db) + erb :"users/index" +end diff --git a/views/index.erb b/views/index.erb index aba3235d..f8d5392e 100644 --- a/views/index.erb +++ b/views/index.erb @@ -1,3 +1,5 @@

The Library Plus System

Welcome to your freedom!

+ +
  • Manage Users
  • \ No newline at end of file diff --git a/views/users/index.erb b/views/users/index.erb new file mode 100644 index 00000000..671fb52e --- /dev/null +++ b/views/users/index.erb @@ -0,0 +1,22 @@ + + + + User Index + + +

    All Users

    +
    +

    Register New User

    + + + + +
    +
      + <% @users.sort_by!{ |u| u['name'].downcase } %> + <% @users.each do |user| %> +
    • '><%= user['name'] %>
    • + <% end %> +
    + + \ No newline at end of file From 41934656daa3fcdec1dfb08db32cde097f656cd5 Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Sat, 6 Dec 2014 21:52:08 +0000 Subject: [PATCH 5/9] Initial BookRepo Functions (untested but compiles) --- lib/library_plus.rb | 11 ++++-- lib/library_plus/book_repo.rb | 74 +++++++++++++++++++++++++++++------ 2 files changed, 71 insertions(+), 14 deletions(-) diff --git a/lib/library_plus.rb b/lib/library_plus.rb index 25d0292a..f67f06d0 100644 --- a/lib/library_plus.rb +++ b/lib/library_plus.rb @@ -14,7 +14,7 @@ def self.create_db_connection(dbname) def self.clear_db(db) db.exec <<-SQL DROP TABLE IF EXISTS users; - /* TODO: Clear rest of the tables (books, etc.) */ + DROP TABLE IF EXISTS books; SQL end @@ -24,14 +24,19 @@ def self.create_tables(db) id SERIAL PRIMARY KEY, name VARCHAR ); - /* TODO: Create rest of the tables (books, etc.) */ + CREATE TABLE IF NOT EXISTS books( + id SERIAL PRIMARY KEY, + title VARCHAR, + author VARCHAR, + user_id INTEGER + ); SQL end def self.drop_tables(db) db.exec <<-SQL DROP TABLE users; - /* TODO: Drop rest of the tables (books, etc.) */ + DROP TABLE books; SQL end end diff --git a/lib/library_plus/book_repo.rb b/lib/library_plus/book_repo.rb index 19f5e6aa..6a7cd807 100644 --- a/lib/library_plus/book_repo.rb +++ b/lib/library_plus/book_repo.rb @@ -1,11 +1,63 @@ -# TODO -# module Library -# class BookRepo -# def self.all -# end -# -# def self.check_cout(db, book_id) -# -# end -# end -# end +module Library + class BookRepo + def self.all + db.exec("SELECT * FROM books").to_a + end + + def self.find(db, book_id) + db.exec("SELECT * FROM books WHERE id = #{book_id}").entries.last + end + + def self.check_out(db, book_id, user_id) + book = db.exec("SELECT * FROM books WHERE id = #{book_id}").entries.last + if book['status'] == 'available' + # Update Status to 'checked-out' + db.exec("UPDATE books SET status = 'checked_out' WHERE id = #{book_id}") + db.exec("UPDATE books SET user_id = '#{user_id}' WHERE id = #{book_id}") + end + find(db, book_id) + end + + def self.check_in(db, book_id) + book = db.exec("SELECT * FROM books WHERE id = #{book_id}").entries.last + if book['status'] == 'checked_out' + # Update Status to 'available' + db.exec("UPDATE books SET status = 'available' WHERE id = #{book_id}") + db.exec("UPDATE books SET user_id = 'nil' WHERE id = #{book_id}") + end + find(db, book_id) + end + + def self.save(db, book_data) + if book_data['id'] + # Update Name + db.exec("UPDATE books SET title = '#{book_data['title']}', author = '#{book_data['author']}' WHERE id = #{book_data['id']}") + else + # Enter Name and Unique ID gets assigned automatically + db.exec("INSERT INTO books (title, author) VALUES ('#{book_data['name']}', '#{book_data['author']}')") + end + get_books(db, book_data).last + end + + def self.destroy(db, book_id) + db.exec("DELETE FROM books WHERE id = #{book_id}") + end + + def self.get_books(db, book_data) + if book_data['id'] + db.exec("SELECT * FROM books WHERE id = #{book_data['id']}").entries + elsif book_data['title'] && book_data['author'] + db.exec("SELECT * FROM books WHERE title = '#{book_data['title']}', author = '#{book_data['author']}'").entries + elsif book_data['title'] + db.exec("SELECT * FROM books WHERE title = '#{book_data['title']}'").entries + elsif book_data['author'] + db.exec("SELECT * FROM books WHERE title = '#{book_data['author']}'").entries + end + end + + def self.get_status(db, book_id) + db.exec("SELECT * FROM books WHERE id = #{book_data['id']}").entries.last['status'] + end + + end +end From fee6966885f9ec1a50950737bee4d5b96de54966 Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Sun, 7 Dec 2014 00:38:44 +0000 Subject: [PATCH 6/9] Add tests for book_repo (Note: All tests are currently disabled for book_repo) --- lib/library_plus.rb | 14 +++- lib/library_plus/book_repo.rb | 34 ++++++++-- spec/repos/book_repo_spec.rb | 117 ++++++++++++++++++++++++++++++++++ spec/repos/user_repo_spec.rb | 1 + 4 files changed, 156 insertions(+), 10 deletions(-) create mode 100644 spec/repos/book_repo_spec.rb diff --git a/lib/library_plus.rb b/lib/library_plus.rb index f67f06d0..54f3f592 100644 --- a/lib/library_plus.rb +++ b/lib/library_plus.rb @@ -13,6 +13,7 @@ def self.create_db_connection(dbname) def self.clear_db(db) db.exec <<-SQL + DROP TABLE IF EXISTS checkouts; DROP TABLE IF EXISTS users; DROP TABLE IF EXISTS books; SQL @@ -28,15 +29,22 @@ def self.create_tables(db) id SERIAL PRIMARY KEY, title VARCHAR, author VARCHAR, - user_id INTEGER + status VARCHAR + ); + CREATE TABLE IF NOT EXISTS checkouts( + book_id INTEGER references books(id), + user_id INTEGER references users(id), + status VARCHAR, + checkout_date VARCHAR ); SQL end def self.drop_tables(db) db.exec <<-SQL - DROP TABLE users; - DROP TABLE books; + DROP TABLE IF EXISTS checkouts; # Drop Dependent Tables First + DROP TABLE IF EXISTS users; + DROP TABLE IF EXISTS books; SQL end end diff --git a/lib/library_plus/book_repo.rb b/lib/library_plus/book_repo.rb index 6a7cd807..11dcaa79 100644 --- a/lib/library_plus/book_repo.rb +++ b/lib/library_plus/book_repo.rb @@ -13,7 +13,9 @@ def self.check_out(db, book_id, user_id) if book['status'] == 'available' # Update Status to 'checked-out' db.exec("UPDATE books SET status = 'checked_out' WHERE id = #{book_id}") - db.exec("UPDATE books SET user_id = '#{user_id}' WHERE id = #{book_id}") + + # Add book to checkout history table + db.exec("INSERT INTO checkouts (book_id, user_id, status, checkout_date) VALUES (#{book_id}, #{user_id}), 'checked_out', '#{Time.now}'") end find(db, book_id) end @@ -21,9 +23,12 @@ def self.check_out(db, book_id, user_id) def self.check_in(db, book_id) book = db.exec("SELECT * FROM books WHERE id = #{book_id}").entries.last if book['status'] == 'checked_out' - # Update Status to 'available' + + # Update books table to 'available' db.exec("UPDATE books SET status = 'available' WHERE id = #{book_id}") - db.exec("UPDATE books SET user_id = 'nil' WHERE id = #{book_id}") + + # Update checkout table to 'returned' + db.exec("UPDATE checkout SET status = 'returned' WHERE book_id = #{book_id}, status = 'checked_out'") end find(db, book_id) end @@ -31,16 +36,23 @@ def self.check_in(db, book_id) def self.save(db, book_data) if book_data['id'] # Update Name - db.exec("UPDATE books SET title = '#{book_data['title']}', author = '#{book_data['author']}' WHERE id = #{book_data['id']}") + if book_data['title'] + db.exec("UPDATE books SET title = '#{book_data['title']}' WHERE id = #{book_data['id']}") + end + if book_data['author'] + db.exec("UPDATE books SET author = '#{book_data['author']}' WHERE id = #{book_data['id']}") + end else # Enter Name and Unique ID gets assigned automatically - db.exec("INSERT INTO books (title, author) VALUES ('#{book_data['name']}', '#{book_data['author']}')") + db.exec("INSERT INTO books (title, author, status) VALUES ('#{book_data['name']}', '#{book_data['author']}', 'available')") end get_books(db, book_data).last end - def self.destroy(db, book_id) - db.exec("DELETE FROM books WHERE id = #{book_id}") + def self.lose(db, book_id) + # Update books table to 'available' + db.exec("UPDATE books SET status = 'lost' WHERE id = #{book_id}") + db.exec("UPDATE checkout SET status = 'lost' WHERE book_id = #{book_id}, status = 'checked_out'") end def self.get_books(db, book_data) @@ -59,5 +71,13 @@ def self.get_status(db, book_id) db.exec("SELECT * FROM books WHERE id = #{book_data['id']}").entries.last['status'] end + def self.get_history(db, id) + if id['book_id'] + db.exec("SELECT * FROM checkouts WHERE book_id = #{book_id}").entries + elsif id['user_id'] + db.exec("SELECT * FROM checkouts WHERE user_id = #{user_id}").entries + end + end + end end diff --git a/spec/repos/book_repo_spec.rb b/spec/repos/book_repo_spec.rb new file mode 100644 index 00000000..359802a7 --- /dev/null +++ b/spec/repos/book_repo_spec.rb @@ -0,0 +1,117 @@ +require 'spec_helper' +require 'pg' + +describe Library::BookRepo do + + def book_count(db) + db.exec("SELECT COUNT(*) FROM books")[0]["count"].to_i + end + + def checkout_count(db) + db.exec("SELECT COUNT(*) FROM checkouts")[0]["count"].to_i + end + + # A let(:db) define means you can use db in an it statement below + # Also, the code in {} does not run until it sees a 'db' statement in an 'it' block + # Therefore, the code will run for each 'it' block + let(:db) { + Library.create_db('library_test') + Library.create_db_connection('library_test') + } + + # Before each 'it' block we are clearing the data base + # That way when we crete users we know exactly how many should be in the db + before(:each) do + Library.clear_db(db) + Library.create_tables(db) + end + + it "gets all books" do + db.exec("INSERT INTO books (title, author) VALUES ($1, $2)", ["Alice's Adventures in Wonderland", "Lewis Carrol"]) + db.exec("INSERT INTO books (title, author) VALUES ($1, $2)", ["The Prophet", "Kahlil Gibran"]) + + books = Library::BookRepo.all(db) + expect(books).to be_a Array + expect(books.count).to eq 2 + + titles = books.map {|u| u['title'] } + expect(titles).to include "Alice's Adventures in Wonderland", "The Prophet" + end + + xit "creates books" do + expect(book_count(db)).to eq 0 + expect(checkout_count(db)).to eq 0 + + book = Library::UserRepo.save(db, { 'title' => "Alice's Adventures in Wonderland", 'author' => "Lewis Carrol" }) + expect(book['id']).to_not be_nil + expect(book['title']).to eq "Alice's Adventures in Wonderland" + expect(book['author']).to eq "Lewis Carol" + expect(book['status']).to eq "available" + + # Check for persistence + expect(book_count(db)).to eq 1 + expect(checkout_count(db)).to eq 1 + + book = db.exec("SELECT * FROM users")[0] + expect(book['title']).to eq "Alice's Adventures in Wonderland" + end + + xit "finds books" do + book = Library::BookRepo.save(db, { 'title' => "Alice's Adventures in Wonderland", 'author' => "Lewis Carrol" }) + retrieved_book = Library::BookRepo.find(db, book['id']) + expect(retrieved_book['title']).to eq "Alice's Adventures in Wonderland" + end + + xit "updates books" do + book1 = Library::BookRepo.save(db, { 'title' => "Alice's Adventures in Wonderland", 'author' => "Lewis Carrol" }) + book2 = Library::BookRepo.save(db, { 'id' => user1['id'], 'name' => "Alicia's Adventures in Wonderland", 'author' => "Louis CK" }) + expect(book2['id']).to eq(book1['id']) + expect(book2['title']).to include "Alicia" + + # Check for persistence + user3 = Library::BookRepo.find(db, book1['id']) + expect(user3['title']).to include "Alicia" + end + + xit "check-out books" do + book = Library::BookRepo.save(db, { 'title' => "Alice's Adventures in Wonderland", 'author' => "Lewis Carrol" }) + user = Library::UserRepo.save(db, { 'name' => "Alice" }) + + # Checkout Book and Check Book Status + book = book.checkout(db, book['id'], user['id']) + expect(book['status'].to eq('checked_out')) + + # Check Checkouts Table Status from book_id + checkout = Library::BookRepo.get_history(db, { 'book_id' => book['id'] })[0] + expect(checkout['status'].to eq('checked_out')) + + # Check Checkouts Table Status from user_id + checkout_log = Library::BookRepo.get_history(db, { 'user_id' => user['id'] })[0] + expect(checkout_log['status'].to eq('checked_out')) + expect(checkout_log['book_id'].to eq(book['id'])) + expect(checkout_log['user_id'].to eq(user['id'])) + end + + xit "check-in books" do + book = Library::BookRepo.save(db, { 'title' => "Alice's Adventures in Wonderland", 'author' => "Lewis Carrol" }) + user = Library::UserRepo.save(db, { 'name' => "Alice" }) + + # Check-out Book and Check-In Book + book = book.checkout(db, book['id'], user['id']) + book = book.checkin(db, book['id']) + + checkout = Library::BookRepo.get_history(db, { 'user_id' => user['id'] })[0] + expect(checkout_log['status'].to eq('returned')) + expect(checkout_log['book_id'].to eq(book['id'])) + expect(checkout_log['user_id'].to eq(user['id'])) + + end + + xit "lose books" do + book = Library::BookRepo.save(db, { 'title' => "Alice's Adventures in Wonderland", 'author' => "Lewis Carrol" }) + expect(book_count(db)).to eq 1 + + Library::BookRepo.lose(db, book['id']) + expect(book_count(db)).to eq 0 + end +end diff --git a/spec/repos/user_repo_spec.rb b/spec/repos/user_repo_spec.rb index afbd870f..e46bbadd 100644 --- a/spec/repos/user_repo_spec.rb +++ b/spec/repos/user_repo_spec.rb @@ -72,4 +72,5 @@ def user_count(db) Library::UserRepo.destroy(db, user['id']) expect(user_count(db)).to eq 0 end + end From 72447ba4eece42ee9badda6b5b7e22666f27f997 Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Sun, 7 Dec 2014 02:21:13 +0000 Subject: [PATCH 7/9] Pass all book repo tests --- lib/library_plus/book_repo.rb | 27 +++++++----- lib/library_plus/user_repo.rb | 3 +- spec/repos/book_repo_spec.rb | 82 ++++++++++++++++++++--------------- 3 files changed, 62 insertions(+), 50 deletions(-) diff --git a/lib/library_plus/book_repo.rb b/lib/library_plus/book_repo.rb index 11dcaa79..ab6e7c45 100644 --- a/lib/library_plus/book_repo.rb +++ b/lib/library_plus/book_repo.rb @@ -1,6 +1,8 @@ +require 'pry-byebug' + module Library class BookRepo - def self.all + def self.all(db) db.exec("SELECT * FROM books").to_a end @@ -8,19 +10,19 @@ def self.find(db, book_id) db.exec("SELECT * FROM books WHERE id = #{book_id}").entries.last end - def self.check_out(db, book_id, user_id) + def self.checkout(db, book_id, user_id) book = db.exec("SELECT * FROM books WHERE id = #{book_id}").entries.last if book['status'] == 'available' # Update Status to 'checked-out' db.exec("UPDATE books SET status = 'checked_out' WHERE id = #{book_id}") # Add book to checkout history table - db.exec("INSERT INTO checkouts (book_id, user_id, status, checkout_date) VALUES (#{book_id}, #{user_id}), 'checked_out', '#{Time.now}'") + db.exec("INSERT INTO checkouts (book_id, user_id, status, checkout_date) VALUES (#{book_id}, #{user_id}, 'checked_out', '#{Time.now}')") end find(db, book_id) end - def self.check_in(db, book_id) + def self.checkin(db, book_id) book = db.exec("SELECT * FROM books WHERE id = #{book_id}").entries.last if book['status'] == 'checked_out' @@ -28,14 +30,14 @@ def self.check_in(db, book_id) db.exec("UPDATE books SET status = 'available' WHERE id = #{book_id}") # Update checkout table to 'returned' - db.exec("UPDATE checkout SET status = 'returned' WHERE book_id = #{book_id}, status = 'checked_out'") + db.exec("UPDATE checkouts SET status = 'returned' WHERE book_id = #{book_id} AND status = 'checked_out'") end find(db, book_id) end def self.save(db, book_data) if book_data['id'] - # Update Name + # Update Title if book_data['title'] db.exec("UPDATE books SET title = '#{book_data['title']}' WHERE id = #{book_data['id']}") end @@ -43,23 +45,24 @@ def self.save(db, book_data) db.exec("UPDATE books SET author = '#{book_data['author']}' WHERE id = #{book_data['id']}") end else - # Enter Name and Unique ID gets assigned automatically - db.exec("INSERT INTO books (title, author, status) VALUES ('#{book_data['name']}', '#{book_data['author']}', 'available')") + # Enter Title and Unique ID gets assigned automatically + db.exec("INSERT INTO books (title, author, status) VALUES ('#{book_data['title']}', '#{book_data['author']}', 'available')") end + # puts get_users(db, user_data) get_books(db, book_data).last end def self.lose(db, book_id) # Update books table to 'available' + db.exec("UPDATE checkouts SET status = 'lost' WHERE book_id = #{book_id} AND status = 'checked_out'") db.exec("UPDATE books SET status = 'lost' WHERE id = #{book_id}") - db.exec("UPDATE checkout SET status = 'lost' WHERE book_id = #{book_id}, status = 'checked_out'") end def self.get_books(db, book_data) if book_data['id'] db.exec("SELECT * FROM books WHERE id = #{book_data['id']}").entries elsif book_data['title'] && book_data['author'] - db.exec("SELECT * FROM books WHERE title = '#{book_data['title']}', author = '#{book_data['author']}'").entries + db.exec("SELECT * FROM books WHERE title = '#{book_data['title']}' AND author = '#{book_data['author']}'").entries elsif book_data['title'] db.exec("SELECT * FROM books WHERE title = '#{book_data['title']}'").entries elsif book_data['author'] @@ -73,9 +76,9 @@ def self.get_status(db, book_id) def self.get_history(db, id) if id['book_id'] - db.exec("SELECT * FROM checkouts WHERE book_id = #{book_id}").entries + db.exec("SELECT * FROM checkouts WHERE book_id = #{id['book_id']}").entries elsif id['user_id'] - db.exec("SELECT * FROM checkouts WHERE user_id = #{user_id}").entries + db.exec("SELECT * FROM checkouts WHERE user_id = #{id['user_id']}").entries end end diff --git a/lib/library_plus/user_repo.rb b/lib/library_plus/user_repo.rb index 4230f43b..8dcf6db7 100644 --- a/lib/library_plus/user_repo.rb +++ b/lib/library_plus/user_repo.rb @@ -1,5 +1,4 @@ -# Library::UserRepo.all(db) -# Library::BookRepo.all(db) +require 'pry-byebug' module Library class UserRepo diff --git a/spec/repos/book_repo_spec.rb b/spec/repos/book_repo_spec.rb index 359802a7..19f16cb1 100644 --- a/spec/repos/book_repo_spec.rb +++ b/spec/repos/book_repo_spec.rb @@ -27,7 +27,7 @@ def checkout_count(db) end it "gets all books" do - db.exec("INSERT INTO books (title, author) VALUES ($1, $2)", ["Alice's Adventures in Wonderland", "Lewis Carrol"]) + db.exec("INSERT INTO books (title, author) VALUES ($1, $2)", ["Alices Adventures in Wonderland", "Lewis Carrol"]) db.exec("INSERT INTO books (title, author) VALUES ($1, $2)", ["The Prophet", "Kahlil Gibran"]) books = Library::BookRepo.all(db) @@ -35,83 +35,93 @@ def checkout_count(db) expect(books.count).to eq 2 titles = books.map {|u| u['title'] } - expect(titles).to include "Alice's Adventures in Wonderland", "The Prophet" + expect(titles).to include "Alices Adventures in Wonderland", "The Prophet" end - xit "creates books" do + it "creates books" do expect(book_count(db)).to eq 0 expect(checkout_count(db)).to eq 0 - book = Library::UserRepo.save(db, { 'title' => "Alice's Adventures in Wonderland", 'author' => "Lewis Carrol" }) + book = Library::BookRepo.save(db, { 'title' => "Alices Adventures in Wonderland", 'author' => "Lewis Carrol" }) expect(book['id']).to_not be_nil - expect(book['title']).to eq "Alice's Adventures in Wonderland" - expect(book['author']).to eq "Lewis Carol" + expect(book['title']).to eq "Alices Adventures in Wonderland" + expect(book['author']).to eq "Lewis Carrol" expect(book['status']).to eq "available" # Check for persistence expect(book_count(db)).to eq 1 - expect(checkout_count(db)).to eq 1 + expect(checkout_count(db)).to eq 0 - book = db.exec("SELECT * FROM users")[0] - expect(book['title']).to eq "Alice's Adventures in Wonderland" + book = db.exec("SELECT * FROM books")[0] + expect(book['title']).to eq "Alices Adventures in Wonderland" end - xit "finds books" do - book = Library::BookRepo.save(db, { 'title' => "Alice's Adventures in Wonderland", 'author' => "Lewis Carrol" }) + it "finds books" do + book = Library::BookRepo.save(db, { 'title' => "Alices Adventures in Wonderland", 'author' => "Lewis Carrol" }) retrieved_book = Library::BookRepo.find(db, book['id']) - expect(retrieved_book['title']).to eq "Alice's Adventures in Wonderland" + expect(retrieved_book['title']).to eq "Alices Adventures in Wonderland" end - xit "updates books" do - book1 = Library::BookRepo.save(db, { 'title' => "Alice's Adventures in Wonderland", 'author' => "Lewis Carrol" }) - book2 = Library::BookRepo.save(db, { 'id' => user1['id'], 'name' => "Alicia's Adventures in Wonderland", 'author' => "Louis CK" }) + it "updates books" do + book1 = Library::BookRepo.save(db, { 'title' => "Alices Adventures in Wonderland", 'author' => "Lewis Carrol" }) + book2 = Library::BookRepo.save(db, { 'id' => book1['id'], 'title' => "Alicias Adventures in Wonderland", 'author' => "Louis CK" }) expect(book2['id']).to eq(book1['id']) expect(book2['title']).to include "Alicia" + expect(book2['author']).to eq "Louis CK" # Check for persistence - user3 = Library::BookRepo.find(db, book1['id']) - expect(user3['title']).to include "Alicia" + book3 = Library::BookRepo.find(db, book1['id']) + expect(book3['title']).to include "Alicia" end - xit "check-out books" do - book = Library::BookRepo.save(db, { 'title' => "Alice's Adventures in Wonderland", 'author' => "Lewis Carrol" }) + it "check-out books" do + book = Library::BookRepo.save(db, { 'title' => "Alices Adventures in Wonderland", 'author' => "Lewis Carrol" }) user = Library::UserRepo.save(db, { 'name' => "Alice" }) # Checkout Book and Check Book Status - book = book.checkout(db, book['id'], user['id']) - expect(book['status'].to eq('checked_out')) + book = Library::BookRepo.checkout(db, book['id'], user['id']) + expect(book['status']).to eq('checked_out') # Check Checkouts Table Status from book_id checkout = Library::BookRepo.get_history(db, { 'book_id' => book['id'] })[0] - expect(checkout['status'].to eq('checked_out')) + expect(checkout['status']).to eq('checked_out') # Check Checkouts Table Status from user_id checkout_log = Library::BookRepo.get_history(db, { 'user_id' => user['id'] })[0] - expect(checkout_log['status'].to eq('checked_out')) - expect(checkout_log['book_id'].to eq(book['id'])) - expect(checkout_log['user_id'].to eq(user['id'])) + expect(checkout_log['status']).to eq('checked_out') + expect(checkout_log['book_id']).to eq(book['id']) + + checkout_log = Library::BookRepo.get_history(db, { 'book_id' => book['id'] })[0] + expect(checkout_log['status']).to eq('checked_out') + expect(checkout_log['user_id']).to eq(user['id']) end - xit "check-in books" do - book = Library::BookRepo.save(db, { 'title' => "Alice's Adventures in Wonderland", 'author' => "Lewis Carrol" }) + it "check-in books" do + book = Library::BookRepo.save(db, { 'title' => "Alices Adventures in Wonderland", 'author' => "Lewis Carrol" }) user = Library::UserRepo.save(db, { 'name' => "Alice" }) # Check-out Book and Check-In Book - book = book.checkout(db, book['id'], user['id']) - book = book.checkin(db, book['id']) + book = Library::BookRepo.checkout(db, book['id'], user['id']) + book = Library::BookRepo.checkin(db, book['id']) + + checkout_log = Library::BookRepo.get_history(db, { 'user_id' => user['id'] })[0] + expect(checkout_log['status']).to eq('returned') + expect(checkout_log['book_id']).to eq(book['id']) + expect(checkout_log['user_id']).to eq(user['id']) - checkout = Library::BookRepo.get_history(db, { 'user_id' => user['id'] })[0] - expect(checkout_log['status'].to eq('returned')) - expect(checkout_log['book_id'].to eq(book['id'])) - expect(checkout_log['user_id'].to eq(user['id'])) + checkout = Library::BookRepo.get_history(db, { 'book_id' => book['id'] })[0] + expect(checkout_log['status']).to eq('returned') + expect(checkout_log['book_id']).to eq(book['id']) + expect(checkout_log['user_id']).to eq(user['id']) end - xit "lose books" do - book = Library::BookRepo.save(db, { 'title' => "Alice's Adventures in Wonderland", 'author' => "Lewis Carrol" }) + it "lose books" do + book = Library::BookRepo.save(db, { 'title' => "Alices Adventures in Wonderland", 'author' => "Lewis Carrol" }) expect(book_count(db)).to eq 1 Library::BookRepo.lose(db, book['id']) - expect(book_count(db)).to eq 0 + lost_book = Library::BookRepo.find(db, book['id']) + expect(lost_book['status']).to eq "lost" end end From 16d0bd450b05c7cece12211198e75c06ab3a2663 Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Sun, 7 Dec 2014 22:38:34 +0000 Subject: [PATCH 8/9] Add Extensions: CheckOut Hitory and Currently hecked Out Books for a User --- lib/library_plus/book_repo.rb | 8 +++-- spec/repos/book_repo_spec.rb | 61 +++++++++++++++++++++++++++++++++-- 2 files changed, 64 insertions(+), 5 deletions(-) diff --git a/lib/library_plus/book_repo.rb b/lib/library_plus/book_repo.rb index ab6e7c45..3fc203ad 100644 --- a/lib/library_plus/book_repo.rb +++ b/lib/library_plus/book_repo.rb @@ -45,7 +45,7 @@ def self.save(db, book_data) db.exec("UPDATE books SET author = '#{book_data['author']}' WHERE id = #{book_data['id']}") end else - # Enter Title and Unique ID gets assigned automatically + # Enter book_data['title'], book_data['author'] and Status / Unique ID gets assigned automatically db.exec("INSERT INTO books (title, author, status) VALUES ('#{book_data['title']}', '#{book_data['author']}', 'available')") end # puts get_users(db, user_data) @@ -71,7 +71,7 @@ def self.get_books(db, book_data) end def self.get_status(db, book_id) - db.exec("SELECT * FROM books WHERE id = #{book_data['id']}").entries.last['status'] + find(db, book_id)['status'] end def self.get_history(db, id) @@ -82,5 +82,9 @@ def self.get_history(db, id) end end + def self.get_checkedOutBooks(db, user_id) + get_history(db, user_id).select{ |entry| entry['status'] == 'checked_out'} + end + end end diff --git a/spec/repos/book_repo_spec.rb b/spec/repos/book_repo_spec.rb index 19f16cb1..8e959ca8 100644 --- a/spec/repos/book_repo_spec.rb +++ b/spec/repos/book_repo_spec.rb @@ -7,7 +7,7 @@ def book_count(db) db.exec("SELECT COUNT(*) FROM books")[0]["count"].to_i end - def checkout_count(db) + def checkout_history_count(db) db.exec("SELECT COUNT(*) FROM checkouts")[0]["count"].to_i end @@ -40,7 +40,7 @@ def checkout_count(db) it "creates books" do expect(book_count(db)).to eq 0 - expect(checkout_count(db)).to eq 0 + expect(checkout_history_count(db)).to eq 0 book = Library::BookRepo.save(db, { 'title' => "Alices Adventures in Wonderland", 'author' => "Lewis Carrol" }) expect(book['id']).to_not be_nil @@ -50,7 +50,7 @@ def checkout_count(db) # Check for persistence expect(book_count(db)).to eq 1 - expect(checkout_count(db)).to eq 0 + expect(checkout_history_count(db)).to eq 0 book = db.exec("SELECT * FROM books")[0] expect(book['title']).to eq "Alices Adventures in Wonderland" @@ -124,4 +124,59 @@ def checkout_count(db) lost_book = Library::BookRepo.find(db, book['id']) expect(lost_book['status']).to eq "lost" end + + it "list of checked-out books" do + book1 = Library::BookRepo.save(db, { 'title' => "Alices Adventures in Wonderland", 'author' => "Lewis Carrol" }) + book2 = Library::BookRepo.save(db, { 'title' => "The Prophet", 'author' => "Kahlil Gibran" }) + user = Library::UserRepo.save(db, { 'name' => "Alice" }) + + # Checkout Book and Check Book Status + Library::BookRepo.checkout(db, book1['id'], user['id']) + Library::BookRepo.checkout(db, book2['id'], user['id']) + + # Check Checkouts Table Status from user_id + user_checkout_log = Library::BookRepo.get_checkedOutBooks(db, { 'user_id' => user['id'] }) + expect(user_checkout_log.count).to eq 2 + user_checkout_log.each do |entry| + expect(entry['status']).to eq('checked_out') + end + + # Check book1 Back In + Library::BookRepo.checkin(db, book1['id']) + + user_checkout_log = Library::BookRepo.get_checkedOutBooks(db, { 'user_id' => user['id'] }) + expect(user_checkout_log.count).to eq 1 + user_checkout_log.each do |entry| + expect(entry['status']).to eq('checked_out') + end + + end + + it "history of checked-out books" do + book1 = Library::BookRepo.save(db, { 'title' => "Alices Adventures in Wonderland", 'author' => "Lewis Carrol" }) + book2 = Library::BookRepo.save(db, { 'title' => "The Prophet", 'author' => "Kahlil Gibran" }) + user = Library::UserRepo.save(db, { 'name' => "Alice" }) + + # Checkout Book and Check Book Status + Library::BookRepo.checkout(db, book1['id'], user['id']) + Library::BookRepo.checkout(db, book2['id'], user['id']) + + # Check Checkouts Table Status from user_id + checkout_log = Library::BookRepo.get_history(db, { 'user_id' => user['id'] }) + expect(checkout_history_count(db)).to eq 2 + + checkout_log.each do |entry| + expect(entry['status']).to eq('checked_out') + end + + # Check Books Back In + Library::BookRepo.checkin(db, book1['id']) + Library::BookRepo.checkin(db, book2['id']) + + checkout_log = Library::BookRepo.get_history(db, { 'user_id' => user['id'] }) + expect(checkout_history_count(db)).to eq 2 + checkout_log.each do |entry| + expect(entry['status']).to eq('returned') + end + end end From ee8b9803acb40838f74a44992fc08745e4a56ce6 Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Mon, 8 Dec 2014 19:19:05 +0000 Subject: [PATCH 9/9] Checkout Currently Works --- server.rb | 71 +++++++++++++++++++++++++++++++++- views/books/checkout/index.erb | 17 ++++++++ views/books/index.erb | 31 +++++++++++++++ views/books/summary.erb | 15 +++++++ views/index.erb | 3 +- views/users/checkout/index.erb | 17 ++++++++ views/users/summary.erb | 21 ++++++++++ 7 files changed, 172 insertions(+), 3 deletions(-) create mode 100644 views/books/checkout/index.erb create mode 100644 views/books/index.erb create mode 100644 views/books/summary.erb create mode 100644 views/users/checkout/index.erb create mode 100644 views/users/summary.erb diff --git a/server.rb b/server.rb index 180d4812..4075ee74 100644 --- a/server.rb +++ b/server.rb @@ -4,14 +4,17 @@ set :bind, '0.0.0.0' # This is needed for Vagrant +Library.create_db('library_dev') +db = Library.create_db_connection('library_dev') +Library.create_tables(db) + get '/' do erb :index end +# User Index get '/users' do - Library.create_db('library_dev') db = Library.create_db_connection('library_dev') - Library.create_tables(db) @users = Library::UserRepo.all(db) erb :"users/index" end @@ -24,3 +27,67 @@ @users = Library::UserRepo.all(db) erb :"users/index" end + +get '/users/*' do + user_id = params[:splat][0] + db = Library.create_db_connection('library_dev') + @checked_out_books = Library::BookRepo.get_checkedOutBooks(db, { 'user_id' => user_id }) + erb :"users/summary" +end + +# Book Index +get '/books' do + db = Library.create_db_connection('library_dev') + @books = Library::BookRepo.all(db) + erb :"books/index" +end + +post '/books' do + # puts params + title = params[:title] + author = params[:author] + db = Library.create_db_connection('library_dev') + Library::BookRepo.save(db, { 'title' => title, 'author' => author }) + @books = Library::BookRepo.all(db) + erb :"books/index" +end + +get '/books/:book_id' do + # We need to choose a User that will checkout the book + book_id = params[:book_id] + db = Library.create_db_connection('library_dev') + @book_history = Library::BookRepo.get_history(db, book_id) + erb :"books/summary" +end + +get '/books/:book_id/checkout' do + # We need to choose a User that will checkout the book + @book_id = params[:book_id] + db = Library.create_db_connection('library_dev') + @users = Library::UserRepo.all(db) + erb :"books/checkout/index" +end + +post '/books/:book_id/checkout/:user_id' do + # We need to choose a User that will checkout the book + book_id = params[:book_id] + user_id = params[:user_id] + db = Library.create_db_connection('library_dev') + Library::BookRepo.checkout(db, book_id, user_id) + checkout_log = Library::BookRepo.get_checkedOutBooks(db, { 'user_id' => user_id }) + books = Library::BookRepo.all(db) + @checked_out_books = [] + checkout_log.each do |log| + book = Library::BookRepo.find(db, log['book_id']) + @checked_out_books.push(book) + end + binding.pry + erb :"users/summary" +end + +post '/books/*/return' do + book_id = params[:splat][0] + db = Library.create_db_connection('library_dev') + Library::BookRepo.checkin(db, book_id) + erb :"books/index" +end diff --git a/views/books/checkout/index.erb b/views/books/checkout/index.erb new file mode 100644 index 00000000..534fdeb2 --- /dev/null +++ b/views/books/checkout/index.erb @@ -0,0 +1,17 @@ + + + + Checkout Index + + +

    All Users

    +
      + <% @users.sort_by!{ |u| u['name'].downcase } %> + <% @users.each do |user| %> +
      '> + +
      + <% end %> +
    + + \ No newline at end of file diff --git a/views/books/index.erb b/views/books/index.erb new file mode 100644 index 00000000..8312fe20 --- /dev/null +++ b/views/books/index.erb @@ -0,0 +1,31 @@ + + + + Book Index + + +

    All Books

    +
    +

    Register New Book

    + + + + + + +
    +
      + <% @books.sort_by!{ |b| b['author'].downcase } %> + <% @books.each do |book| %> +
      /checkout'> +
    • + '><%= book['title'] %> - <%= book['author'] %> + <% if book['status'] == "available" %> +
      + <% end %> +
    • +
      + <% end %> +
    + + \ No newline at end of file diff --git a/views/books/summary.erb b/views/books/summary.erb new file mode 100644 index 00000000..00973ad5 --- /dev/null +++ b/views/books/summary.erb @@ -0,0 +1,15 @@ + + + + User Index + + +

    History for Book

    +
      + <% @book_history.sort_by!{ |b| b['data'] } %> + <% @book_history.each do |entry| %> +
    • TODO - Display History
    • + <% end %> +
    + + \ No newline at end of file diff --git a/views/index.erb b/views/index.erb index f8d5392e..b7d34fb8 100644 --- a/views/index.erb +++ b/views/index.erb @@ -2,4 +2,5 @@

    Welcome to your freedom!

    -
  • Manage Users
  • \ No newline at end of file +
  • Manage Users
  • +
  • Manage Books
  • \ No newline at end of file diff --git a/views/users/checkout/index.erb b/views/users/checkout/index.erb new file mode 100644 index 00000000..534fdeb2 --- /dev/null +++ b/views/users/checkout/index.erb @@ -0,0 +1,17 @@ + + + + Checkout Index + + +

    All Users

    +
      + <% @users.sort_by!{ |u| u['name'].downcase } %> + <% @users.each do |user| %> +
      '> + +
      + <% end %> +
    + + \ No newline at end of file diff --git a/views/users/summary.erb b/views/users/summary.erb new file mode 100644 index 00000000..35e29f7a --- /dev/null +++ b/views/users/summary.erb @@ -0,0 +1,21 @@ + + + + User Index + + +

    Summary of Checked- Books For User

    + + + \ No newline at end of file