diff --git a/Gemfile b/Gemfile index 66526d43..1446f3d9 100644 --- a/Gemfile +++ b/Gemfile @@ -5,6 +5,7 @@ gem 'rspec', '~> 2.14.1' gem 'sinatra', '~> 1.4.5' gem 'sinatra-contrib', '~> 1.4.2' gem 'rest-client' +gem 'pg' # Testing gem 'pry-byebug' diff --git a/Gemfile.lock b/Gemfile.lock index bbeebb1e..1bf7ce17 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,19 +1,20 @@ GEM remote: https://rubygems.org/ specs: - backports (3.6.3) + backports (3.6.4) byebug (3.5.1) columnize (~> 0.8) debugger-linecache (~> 1.2) slop (~> 3.6) coderay (1.1.0) - columnize (0.8.9) + columnize (0.9.0) debugger-linecache (1.2.0) diff-lcs (1.2.5) method_source (0.8.2) - mime-types (1.25.1) + mime-types (2.4.3) multi_json (1.10.1) - netrc (0.8.0) + netrc (0.10.0) + pg (0.17.1) pry (0.10.1) coderay (~> 1.1.0) method_source (~> 0.8.1) @@ -33,10 +34,10 @@ GEM rspec-core (~> 2.14.0) rspec-expectations (~> 2.14.0) rspec-mocks (~> 2.14.0) - rspec-core (2.14.7) + rspec-core (2.14.8) rspec-expectations (2.14.5) diff-lcs (>= 1.1.3, < 2.0) - rspec-mocks (2.14.5) + rspec-mocks (2.14.6) sinatra (1.4.5) rack (~> 1.4) rack-protection (~> 1.4) @@ -55,6 +56,7 @@ PLATFORMS ruby DEPENDENCIES + pg pry-byebug rest-client rspec (~> 2.14.1) diff --git a/lib/PetDatabaseRepo.rb b/lib/PetDatabaseRepo.rb new file mode 100644 index 00000000..2e23fffc --- /dev/null +++ b/lib/PetDatabaseRepo.rb @@ -0,0 +1,199 @@ +require 'pg' +require 'rest-client' +require 'json' + +# Table "public.shops" +# Column | Type | Modifiers +# --------+-------------------+----------- +# id | numeric | +# name | character varying | + + +# Table "public.dogs" +# Column | Type | Modifiers +# -----------------+-------------------+----------- +# shop_id | integer | +# dog_id | integer | +# name | character varying | +# imageurl | character varying | +# happiness | integer | +# adoption_status | boolean | + + +# Table "public.cats" +# Column | Type | Modifiers +# -----------------+-------------------+----------- +# shop_id | integer | +# cat_id | integer | +# name | character varying | +# imageurl | character varying | +# adoption_status | boolean | + +module PetShop +class Database + def self.dbconnect + PG.connect(host: 'localhost', dbname:'petshop_db') + end + + def addData + url = 'pet-shop.api.mks.io/shops/' + tempshops = RestClient.get(url) + shops = JSON.parse(tempshops) #this is our hash of shop names and id's! + shops.each { |shop| + shopname = shop["name"] + shopid = shop["id"] + sql = %q[ + INSERT INTO shops (name, id) + VALUES ($1, $2) + ] + @db.exec_params(sql, [shopname, shopid]) #enter shop info to shops table + + url = "pet-shop.api.mks.io/shops/" + shopid.to_s + "/dogs/" + tempdogs = RestClient.get(url) + dogs = JSON.parse(tempdogs) + dogs.each { |dog| #each dogs + shop = dog["shopId"] + name = dog["name"] + happiness = dog["happiness"] + image = dog["imageUrl"] + id = dog["id"] + adopt = dog["adopted"] + sql = %q[ + INSERT INTO dogs (shop_id, dog_id, name, imageurl, happiness, adoption_status) + VALUES ($1, $2, $3, $4, $5, $6) + ] + @db.exec(sql, [shop, id, name, image, happiness, adopt]) + }#end each dog + + url = "pet-shop.api.mks.io/shops/" + shopid.to_s + "/cats/" + tempcats = RestClient.get(url) + cats = JSON.parse(tempcats) + cats.each { |cat| #each cat + shop = cat["shopId"] + name = cat["name"] + image = cat["imageUrl"] + id = cat["id"] + adopt = cat["adopted"] + sql = %q[ + INSERT INTO cats (shop_id, cat_id, name, imageurl, adoption_status) + VALUES ($1, $2, $3, $4, $5) + ] + @db.exec_params(sql, [shop, id, name, image, adopt]) + }#end each cat + }#end each shop + end + + + + +##################################################### + + def print_shops + sql = %q[ + SELECT * FROM shops] + success = @db.exec(sql) + shops = success.entries #hashes of shop info + puts "ID | Name" + puts "-----------------------------" + shops.each { |shop| + if shop["id"].to_i < 10 + puts "#{shop["id"].to_i} | #{shop["name"]}" + else + puts "#{shop["id"].to_i} | #{shop["name"]}" + end + } + end + + + def print_store_dogs(store_id) + sql1 = %q[ + SELECT name FROM shops WHERE id = $1 + ] + success1 = @db.exec_params(sql1, [store_id]) + name = success1.entries[0]["name"] + + sql2 = %q[ + SELECT * FROM dogs WHERE shop_id = $1 + ] + success = @db.exec_params(sql2, [store_id]) + dogs = success.entries #hashes of dog info + puts "Dogs in store #{name}:" + puts "------------------" + dogs.each {|dog| + puts "Name: #{dog["name"]}" + puts "Happiness: #{dog["happiness"]}" + if dog["adopted"] + puts "Adopted: Yes!" + else + puts "Adopted: No" + end + puts "------------------" + } + end + + def print_store_dogs(store_id) + sql1 = %q[ + SELECT name FROM shops WHERE id = $1 + ] + success1 = @db.exec_params(sql1, [store_id]) + name = success1.entries[0]["name"] + + sql2 = %q[ + SELECT * FROM dogs WHERE shop_id = $1 + ] + success = @db.exec_params(sql2, [store_id]) + dogs = success.entries #hashes of dog info + puts "Dogs in store #{name}:" + puts "------------------" + dogs.each {|dog| + puts "Name: #{dog["name"]}" + puts "Happiness: #{dog["happiness"]}" + if dog["adopted"] + puts "Adopted: Yes!" + else + puts "Adopted: No" + end + puts "------------------" + } + end + + def happiestdogs + sql = %q[ + SELECT name, happiness FROM dogs ORDER BY happiness + ] + alldogs = @db.exec(sql) + happiest = alldogs.entries[-5..-1] + puts "Happiest Dogs:" + happiest.each{|dog| + puts "#{dog["name"]}: #{dog["happiness"]}" + } + end + + def allpets + sqldogs = %q[ + SELECT dogs.name AS name, dogs.happiness AS happiness, shops.name AS shop + FROM dogs + JOIN shops + ON dogs.shop_id = shops.id + ] + tempdogs = @db.exec(sqldogs) + dogs = tempdogs.entries + puts "All Pets:" + dogs.each {|dog| + puts "#{dog["name"]}, #{dog["happiness"]}, @ #{dog["shop"]}" + } + sqlcats = %q[ + SELECT cats.name AS name, shops.name AS shop + FROM cats + JOIN shops + ON cats.shop_id = shops.id + ] + tempcats = @db.exec(sqlcats) + cats = tempcats.entries + cats.each {|cat| + puts "#{cat["name"]} @ #{cat["shop"]}" + } +end + +end #end of class +end #end of module diff --git a/lib/repos/DB.rb b/lib/repos/DB.rb new file mode 100644 index 00000000..25a54105 --- /dev/null +++ b/lib/repos/DB.rb @@ -0,0 +1,122 @@ +module PetShop +class DB + + def self.get_shops(db) + db.exec("SELECT * FROM shops").entries + end + + def self.get_cats(db, shop_id) + mappings = {"shop_id" => "shopId", "cat_id" => "id", "name" => "name", "imageurl" => "imageUrl", "adoption_status" => "adopted"} + response = db.exec("SELECT * FROM cats WHERE shop_id = $1", [shop_id]).entries + cats = [] + response.each do |cat| + if cat['adoption_status'] == "t" + cat['adoption_status'] = true + else + cat['adoption_status'] = false + end + cats << Hash[cat.map {|k, v| [mappings[k], v] }] + end + cats + end + + def self.get_dogs(db, shop_id) + mappings = {"shop_id" => "shopId", "dog_id" => "id", "name" => "name", "imageurl" => "imageUrl", "adoption_status" => "adopted"} + response = db.exec("SELECT * FROM dogs WHERE shop_id = $1", [shop_id]).entries + dogs = [] + response.each do |dog| + if dog['adoption_status'] == "t" + dog['adoption_status'] = true + else + dog['adoption_status'] = false + end + dogs << Hash[dog.map {|k, v| [mappings[k], v] }] + end + dogs + end + + def self.adopt_cat(db, cat_id, user_id) + db.exec("UPDATE cats set adoption_status = 'true' where cat_id = $1", [cat_id]) + db.exec("INSERT INTO adoptions (user_id, cat_id) VALUES ($1, $2)", [user_id, cat_id]) + end + + def self.adopt_dog(db, dog_id, user_id) + db.exec("UPDATE dogs set adoption_status = 'true' where dog_id = $1", [dog_id]) + db.exec("INSERT INTO adoptions (user_id, dog_id) VALUES ($1, $2)", [user_id, dog_id]) + end + + def self.find db, user_id + sql = %q[SELECT * FROM users WHERE id = $1] + result = db.exec(sql, [user_id]).first + + dog_sql = %q[select dogs.shop_id, dogs.dog_id, dogs.name, dogs.imageurl, dogs.happiness, dogs.adoption_status + from dogs + INNER JOIN adoptions on dogs.dog_id=adoptions.dog_id where user_id = $1; + ] + cat_sql = %q[select cats.shop_id, cats.cat_id, cats.name, cats.imageurl, cats.adoption_status + from cats + INNER JOIN adoptions on cats.cat_id=adoptions.cat_id where user_id = $1; + ] + + dogs = db.exec(dog_sql, [user_id]) + dogs = dogs.entries + result['dogs'] = map_dogs(dogs) + + + cats = db.exec(cat_sql, [user_id]) + cats = cats.entries + result['cats'] = map_cats(cats) + + result + end + # find user by username. Intended to be used when + # someone tries to sign in. + def self.find_by_name db, username + sql = %q[SELECT * FROM users WHERE username = $1] + result = db.exec(sql, [username]) + result.first + + end + + def self.map_cats(cats) + mappings = {"shop_id" => "shopId", "cat_id" => "id", "name" => "name", "imageurl" => "imageUrl", "adoption_status" => "adopted"} + mapped_cats = [] + cats.each do |cat| + if cat['adoption_status'] == "t" + cat['adoption_status'] = true + else + cat['adoption_status'] = false + end + mapped_cats << Hash[cat.map {|k, v| [mappings[k], v] }] + end + mapped_cats + end + + def self.map_dogs(dogs) + mappings = {"shop_id" => "shopId", "dog_id" => "id", "name" => "name", "imageurl" => "imageUrl", "adoption_status" => "adopted"} + mapped_dogs = [] + dogs.each do |dog| + if dog['adoption_status'] == "t" + dog['adoption_status'] = true + else + dog['adoption_status'] = false + end + mapped_dogs << Hash[dog.map {|k, v| [mappings[k], v] }] + end + mapped_dogs + end + +end #end DB +end#end module + +# {"shop_id":"3", +# "cat_id":"5", +# "name":"karthurian", +# "imageurl":"http://cucinatestarossa.blogs.com/weblog/images/cat.jpg", +# "adoption_status":"t"} +# {"shopId":1, +# "name":"Scaredy Cat", +# "imageUrl":"http://i.imgur.com/TOEskNX.jpg", +# "adopted":true, +# "id":1} + diff --git a/server.rb b/server.rb index 07df95f4..70f9bc8f 100644 --- a/server.rb +++ b/server.rb @@ -2,24 +2,49 @@ require 'sinatra/reloader' require 'rest-client' require 'json' +require 'pry-byebug' +require_relative 'lib/PetDatabaseRepo.rb' +require_relative 'lib/repos/DB.rb' +set :bind, '0.0.0.0' # # # This is our only html view... -# + +configure do + enable :sessions + end + + before do + if session['user_id'] + user_id = session['user_id'] + db = PetShop::Database.dbconnect + @current_user = PetShop::DB.find db, user_id + end + end + get '/' do - if session[:user_id] + if session['user_id'] # TODO: Grab user from database - @current_user = $sample_user + db = PetShop::Database.dbconnect + @current_user = PetShop::DB.find(db, session[:user_id]) end erb :index end +get '/logout' do + session.delete('user_id') + redirect to '/' +end # # # ...the rest are JSON endpoints # get '/shops' do headers['Content-Type'] = 'application/json' - RestClient.get("http://pet-shop.api.mks.io/shops") + # RestClient.get("http://pet-shop.api.mks.io/shops") + db = PetShop::Database.dbconnect + shops = PetShop::DB.get_shops(db) + shops.to_json + end post '/signin' do @@ -29,13 +54,20 @@ password = params['password'] # TODO: Grab user by username from database and check password - user = { 'username' => 'alice', 'password' => '123' } + # user = { 'username' => 'alice', 'password' => '123' } + db = PetShop::Database.dbconnect + usersearch = PetShop::DB.find_by_name(db, username) - if password == user['password'] + if password == usersearch['password'] + headers['Content-Type'] = 'application/json' + # TODO: Return all pets adopted by this user # TODO: Set session[:user_id] so the server will remember this user has logged in - $sample_user.to_json + # $sample_user.to_json + session[:user_id] = usersearch['id'] + user = PetShop::DB.find(db, session[:user_id]) + user.to_json else status 401 end @@ -48,16 +80,22 @@ headers['Content-Type'] = 'application/json' id = params[:id] # TODO: Grab from database instead - RestClient.get("http://pet-shop.api.mks.io/shops/#{id}/cats") + # RestClient.get("http://pet-shop.api.mks.io/shops/#{id}/cats") + db = PetShop::Database.dbconnect + cats = PetShop::DB.get_cats(db, id) + cats.to_json end put '/shops/:shop_id/cats/:id/adopt' do headers['Content-Type'] = 'application/json' shop_id = params[:shop_id] id = params[:id] + user_id = session[:user_id] # TODO: Grab from database instead - RestClient.put("http://pet-shop.api.mks.io/shops/#{shop_id}/cats/#{id}", - { adopted: true }, :content_type => 'application/json') + # RestClient.put("http://pet-shop.api.mks.io/shops/#{shop_id}/cats/#{id}", + # { adopted: true }, :content_type => 'application/json') + db = PetShop::Database.dbconnect + PetShop::DB.adopt_cat(db, id, user_id) # TODO (after you create users table): Attach new cat to logged in user end @@ -68,17 +106,20 @@ get '/shops/:id/dogs' do headers['Content-Type'] = 'application/json' id = params[:id] + db = PetShop::Database.dbconnect + dogs = PetShop::DB.get_dogs(db, id) + dogs.to_json # TODO: Update database instead - RestClient.get("http://pet-shop.api.mks.io/shops/#{id}/dogs") + # RestClient.get("http://pet-shop.api.mks.io/shops/#{id}/dogs") end put '/shops/:shop_id/dogs/:id/adopt' do headers['Content-Type'] = 'application/json' shop_id = params[:shop_id] id = params[:id] - # TODO: Update database instead - RestClient.put("http://pet-shop.api.mks.io/shops/#{shop_id}/dogs/#{id}", - { adopted: true }, :content_type => 'application/json') + user_id = session[:user_id] + db = PetShop::Database.dbconnect + PetShop::DB.adopt_dog(db, id, user_id) # TODO (after you create users table): Attach new dog to logged in user end