From e24f9a656378a2e156400943760d8d4ebc6f4710 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Thu, 17 Sep 2015 13:30:52 -0700 Subject: [PATCH 01/93] Adds node_modules to .gitignore. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index e43b0f9..9daa824 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .DS_Store +node_modules From d01802f4c17d2e0dc3109d5880d3c6b436272928 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Thu, 17 Sep 2015 13:31:06 -0700 Subject: [PATCH 02/93] Sets up node app. --- app.js | 60 ++++++++++++++++++++++++ bin/www | 90 ++++++++++++++++++++++++++++++++++++ package.json | 17 +++++++ public/stylesheets/style.css | 8 ++++ routes/index.js | 9 ++++ routes/users.js | 9 ++++ views/error.jade | 6 +++ views/index.jade | 5 ++ views/layout.jade | 7 +++ 9 files changed, 211 insertions(+) create mode 100644 app.js create mode 100755 bin/www create mode 100644 package.json create mode 100644 public/stylesheets/style.css create mode 100644 routes/index.js create mode 100644 routes/users.js create mode 100644 views/error.jade create mode 100644 views/index.jade create mode 100644 views/layout.jade diff --git a/app.js b/app.js new file mode 100644 index 0000000..80a3c36 --- /dev/null +++ b/app.js @@ -0,0 +1,60 @@ +var express = require('express'); +var path = require('path'); +var favicon = require('serve-favicon'); +var logger = require('morgan'); +var cookieParser = require('cookie-parser'); +var bodyParser = require('body-parser'); + +var routes = require('./routes/index'); +var users = require('./routes/users'); + +var app = express(); + +// view engine setup +app.set('views', path.join(__dirname, 'views')); +app.set('view engine', 'jade'); + +// uncomment after placing your favicon in /public +//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); +app.use(logger('dev')); +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: false })); +app.use(cookieParser()); +app.use(express.static(path.join(__dirname, 'public'))); + +app.use('/', routes); +app.use('/users', users); + +// catch 404 and forward to error handler +app.use(function(req, res, next) { + var err = new Error('Not Found'); + err.status = 404; + next(err); +}); + +// error handlers + +// development error handler +// will print stacktrace +if (app.get('env') === 'development') { + app.use(function(err, req, res, next) { + res.status(err.status || 500); + res.render('error', { + message: err.message, + error: err + }); + }); +} + +// production error handler +// no stacktraces leaked to user +app.use(function(err, req, res, next) { + res.status(err.status || 500); + res.render('error', { + message: err.message, + error: {} + }); +}); + + +module.exports = app; diff --git a/bin/www b/bin/www new file mode 100755 index 0000000..cc43085 --- /dev/null +++ b/bin/www @@ -0,0 +1,90 @@ +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var app = require('../app'); +var debug = require('debug')('C3Projects--VideoStoreAPI:server'); +var http = require('http'); + +/** + * Get port from environment and store in Express. + */ + +var port = normalizePort(process.env.PORT || '3000'); +app.set('port', port); + +/** + * Create HTTP server. + */ + +var server = http.createServer(app); + +/** + * Listen on provided port, on all network interfaces. + */ + +server.listen(port); +server.on('error', onError); +server.on('listening', onListening); + +/** + * Normalize a port into a number, string, or false. + */ + +function normalizePort(val) { + var port = parseInt(val, 10); + + if (isNaN(port)) { + // named pipe + return val; + } + + if (port >= 0) { + // port number + return port; + } + + return false; +} + +/** + * Event listener for HTTP server "error" event. + */ + +function onError(error) { + if (error.syscall !== 'listen') { + throw error; + } + + var bind = typeof port === 'string' + ? 'Pipe ' + port + : 'Port ' + port; + + // handle specific listen errors with friendly messages + switch (error.code) { + case 'EACCES': + console.error(bind + ' requires elevated privileges'); + process.exit(1); + break; + case 'EADDRINUSE': + console.error(bind + ' is already in use'); + process.exit(1); + break; + default: + throw error; + } +} + +/** + * Event listener for HTTP server "listening" event. + */ + +function onListening() { + var addr = server.address(); + var bind = typeof addr === 'string' + ? 'pipe ' + addr + : 'port ' + addr.port; + debug('Listening on ' + bind); +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..0ab806b --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "name": "C3Projects--VideoStoreAPI", + "version": "0.0.0", + "private": true, + "scripts": { + "start": "node ./bin/www" + }, + "dependencies": { + "body-parser": "~1.13.2", + "cookie-parser": "~1.3.5", + "debug": "~2.2.0", + "express": "~4.13.1", + "jade": "~1.11.0", + "morgan": "~1.6.1", + "serve-favicon": "~2.3.0" + } +} \ No newline at end of file diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css new file mode 100644 index 0000000..9453385 --- /dev/null +++ b/public/stylesheets/style.css @@ -0,0 +1,8 @@ +body { + padding: 50px; + font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; +} + +a { + color: #00B7FF; +} diff --git a/routes/index.js b/routes/index.js new file mode 100644 index 0000000..ecca96a --- /dev/null +++ b/routes/index.js @@ -0,0 +1,9 @@ +var express = require('express'); +var router = express.Router(); + +/* GET home page. */ +router.get('/', function(req, res, next) { + res.render('index', { title: 'Express' }); +}); + +module.exports = router; diff --git a/routes/users.js b/routes/users.js new file mode 100644 index 0000000..623e430 --- /dev/null +++ b/routes/users.js @@ -0,0 +1,9 @@ +var express = require('express'); +var router = express.Router(); + +/* GET users listing. */ +router.get('/', function(req, res, next) { + res.send('respond with a resource'); +}); + +module.exports = router; diff --git a/views/error.jade b/views/error.jade new file mode 100644 index 0000000..51ec12c --- /dev/null +++ b/views/error.jade @@ -0,0 +1,6 @@ +extends layout + +block content + h1= message + h2= error.status + pre #{error.stack} diff --git a/views/index.jade b/views/index.jade new file mode 100644 index 0000000..3d63b9a --- /dev/null +++ b/views/index.jade @@ -0,0 +1,5 @@ +extends layout + +block content + h1= title + p Welcome to #{title} diff --git a/views/layout.jade b/views/layout.jade new file mode 100644 index 0000000..15af079 --- /dev/null +++ b/views/layout.jade @@ -0,0 +1,7 @@ +doctype html +html + head + title= title + link(rel='stylesheet', href='/stylesheets/style.css') + body + block content From 7dee606340a9210947b2580a8b543d461012c7ce Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Thu, 17 Sep 2015 13:56:27 -0700 Subject: [PATCH 03/93] Adds schema file to set up our database tables. --- database.js | 6 ++ db/development.db | Bin 0 -> 4096 bytes package.json | 5 +- customers.json => utils/customers.json | 0 movies.json => utils/movies.json | 0 utils/schema.js | 75 +++++++++++++++++++++++++ 6 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 database.js create mode 100644 db/development.db rename customers.json => utils/customers.json (100%) rename movies.json => utils/movies.json (100%) create mode 100644 utils/schema.js diff --git a/database.js b/database.js new file mode 100644 index 0000000..e237832 --- /dev/null +++ b/database.js @@ -0,0 +1,6 @@ +// "use-strict"; +// var sqlite3 = require('sqlite3').verbose(); +// +// var Database +// // We want to export the Database into the overall node structure +// module.exports = Database; diff --git a/db/development.db b/db/development.db new file mode 100644 index 0000000000000000000000000000000000000000..6e67275d655098a51a815cd5a248e424fc64bd58 GIT binary patch literal 4096 zcmeHG%}xR_5N=r#4u&g)aG>f%67a$ch-NiJ{6j9p!=~&G(70?(TTl`&@JhUs&taGS z5lkS2Bk3mH&U~G=^L;aYeQ7fVWWdFkD$+n%gfY4z1R+$=BdbU9{r7RQuwyQu`p-$; zIztv-qRcm5T2DKo&C)&!%x^QfVx@u?Z;JMPa3@mnF$kF&)=kH5c5TvaUbk(M!sLQ^ zr1jXf@9YkF?zA47ogTTjdo>c!F%Sh`szwA1nN%Rab96sM81*~>QpTRk)GRioqPlmY zpbxG+-*LH@A|oCoHg#P-36$gNgP9@&pHo$xpW|GyRKknX6_GKYGLX?fvq2%kw&$;y z@{^nR6ofwKGfqo@4^)EV{bkC6DFlj(8DW8fA&8nbV#uLW%KT8)WU;DCQZJYBaFwIb zJEviw^ClatLf#r8eaxVH7w>0rUP3lFe)~3LJ$3zh3Rq A<^TWy literal 0 HcmV?d00001 diff --git a/package.json b/package.json index 0ab806b..87e6a93 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "express": "~4.13.1", "jade": "~1.11.0", "morgan": "~1.6.1", - "serve-favicon": "~2.3.0" + "serve-favicon": "~2.3.0", + "sqlite3": "^3.1.0" } -} \ No newline at end of file +} diff --git a/customers.json b/utils/customers.json similarity index 100% rename from customers.json rename to utils/customers.json diff --git a/movies.json b/utils/movies.json similarity index 100% rename from movies.json rename to utils/movies.json diff --git a/utils/schema.js b/utils/schema.js new file mode 100644 index 0000000..1644359 --- /dev/null +++ b/utils/schema.js @@ -0,0 +1,75 @@ +"use-strict"; + +var sqlite3 = require('sqlite3').verbose(), + db_env = process.env.DB || 'development', + db = new sqlite3.Database('db/' + db_env + '.db'); + +var movie_fields = [ + ['title', 'text'], + ['overview', 'text'], + ['release_date', 'text'], + ['inventory', 'integer'], + ['inventory_available', 'integer'] +] + +var customer_fields = [ + ['name', 'text'], + ['registered_at', 'text'], + ['address', 'text'], + ['city', 'text'], + ['state', 'text'], + ['postal_code', 'text'], + ['phone', 'text'], + ['account_credit', 'float'] +] + +var rental_fields = [ + ['check_out', 'text'], + ['check_in', 'text'], + ['due_date', 'text'], + ['overdue', 'boolean'], + ['customer_id', 'integer'], + ['movie_id', 'integer'] +] + +// I want these to work somewhat how rake db:reset works, so I need to do three things: +// db.serialize will make sure that these things happen in order (otherwise +// they would execute asynchronously) +db.serialize(function() { + // 1. drop existing tables (run means, do this right now!) + db.run("DROP TABLE IF EXISTS movies;"); + db.run("DROP TABLE IF EXISTS customers;"); + db.run("DROP TABLE IF EXISTS rentals;"); + + // 2. create fresh versions of those tables + db.run("CREATE TABLE movies (id INTEGER PRIMARY KEY);"); + db.run("CREATE TABLE customers (id INTEGER PRIMARY KEY);"); + db.run("CREATE TABLE rentals (id INTEGER PRIMARY KEY);"); + + // 3. add the columns to those tables + // CREATE MOVIES TABLE COLUMNS + for(var i = 0; i < movie_fields.length; i++) { + var name = movie_fields[i][0], + type = movie_fields[i][1]; + + db.run("ALTER TABLE movies ADD COLUMN " + name + " " + type + ";"); + } + + // CREATE CUSTOMERS TABLE COLUMNS + for(var i = 0; i < customer_fields.length; i++) { + var name = customer_fields[i][0], + type = customer_fields[i][1]; + + db.run("ALTER TABLE customers ADD COLUMN " + name + " " + type + ";"); + } + + // CREATE RENTALS TABLE COLUMNS + for(var i = 0; i < rental_fields.length; i++) { + var name = rental_fields[i][0], + type = rental_fields[i][1]; + + db.run("ALTER TABLE rentals ADD COLUMN " + name + " " + type + ";"); + } +}); + +db.close(); From 76635ccff42022bf44665f3a4c4be3d560203027 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Thu, 17 Sep 2015 14:14:28 -0700 Subject: [PATCH 04/93] Seeds the db. --- db/development.db | Bin 4096 -> 144384 bytes utils/seed.js | 55 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 utils/seed.js diff --git a/db/development.db b/db/development.db index 6e67275d655098a51a815cd5a248e424fc64bd58..9f206157c31a3c31f75751c6b09437a7dabda29e 100644 GIT binary patch literal 144384 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

UBE7bWsyx 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 cosUmrj+T~-Xl9_~RtkHk2m!FV?D7Bq52mJ&!T Date: Thu, 17 Sep 2015 14:44:46 -0700 Subject: [PATCH 05/93] WIP - initial routes (zomg) --- app.js | 10 ++++++++++ controllers/customers.js | 0 controllers/movies.js | 8 ++++++++ controllers/rentals.js | 0 npm-debug.log | 36 ++++++++++++++++++++++++++++++++++++ routes/customers.js | 0 routes/movies.js | 9 +++++++++ routes/rentals.js | 0 8 files changed, 63 insertions(+) create mode 100644 controllers/customers.js create mode 100644 controllers/movies.js create mode 100644 controllers/rentals.js create mode 100644 npm-debug.log create mode 100644 routes/customers.js create mode 100644 routes/movies.js create mode 100644 routes/rentals.js diff --git a/app.js b/app.js index 80a3c36..19ac3bb 100644 --- a/app.js +++ b/app.js @@ -5,8 +5,13 @@ var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); +// establish our routes based on route files var routes = require('./routes/index'); var users = require('./routes/users'); +var movies = require('./routes/movies'); +var customers = require('./routes/customers'); +var rentals = require('./routes/rentals'); + var app = express(); @@ -22,8 +27,13 @@ app.use(bodyParser.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); +// Establishes our routes app.use('/', routes); app.use('/users', users); +app.use('/movies', movies); +app.use('/customers', customers); +app.use('/rentals', rentals); + // catch 404 and forward to error handler app.use(function(req, res, next) { diff --git a/controllers/customers.js b/controllers/customers.js new file mode 100644 index 0000000..e69de29 diff --git a/controllers/movies.js b/controllers/movies.js new file mode 100644 index 0000000..48f7195 --- /dev/null +++ b/controllers/movies.js @@ -0,0 +1,8 @@ +"use strict"; + +exports.moviesController = { + movies: function movies(req, res) { + + return res.status(200).json("it works!"); + } +} diff --git a/controllers/rentals.js b/controllers/rentals.js new file mode 100644 index 0000000..e69de29 diff --git a/npm-debug.log b/npm-debug.log new file mode 100644 index 0000000..bd2156b --- /dev/null +++ b/npm-debug.log @@ -0,0 +1,36 @@ +0 info it worked if it ends with ok +1 verbose cli [ 'node', '/usr/local/bin/npm', 'start' ] +2 info using npm@2.7.5 +3 info using node@v0.12.2 +4 verbose node symlink /usr/local/bin/node +5 verbose run-script [ 'prestart', 'start', 'poststart' ] +6 info prestart C3Projects--VideoStoreAPI@0.0.0 +7 info start C3Projects--VideoStoreAPI@0.0.0 +8 verbose unsafe-perm in lifecycle true +9 info C3Projects--VideoStoreAPI@0.0.0 Failed to exec start script +10 verbose stack Error: C3Projects--VideoStoreAPI@0.0.0 start: `node ./bin/www` +10 verbose stack Exit status 1 +10 verbose stack at EventEmitter. (/usr/local/lib/node_modules/npm/lib/utils/lifecycle.js:213:16) +10 verbose stack at EventEmitter.emit (events.js:110:17) +10 verbose stack at ChildProcess. (/usr/local/lib/node_modules/npm/lib/utils/spawn.js:14:12) +10 verbose stack at ChildProcess.emit (events.js:110:17) +10 verbose stack at maybeClose (child_process.js:1015:16) +10 verbose stack at Process.ChildProcess._handle.onexit (child_process.js:1087:5) +11 verbose pkgid C3Projects--VideoStoreAPI@0.0.0 +12 verbose cwd /Users/brennaleker/Documents/Projects/project-forks/C3Projects--VideoStoreAPI +13 error Darwin 14.3.0 +14 error argv "node" "/usr/local/bin/npm" "start" +15 error node v0.12.2 +16 error npm v2.7.5 +17 error code ELIFECYCLE +18 error C3Projects--VideoStoreAPI@0.0.0 start: `node ./bin/www` +18 error Exit status 1 +19 error Failed at the C3Projects--VideoStoreAPI@0.0.0 start script 'node ./bin/www'. +19 error This is most likely a problem with the C3Projects--VideoStoreAPI package, +19 error not with npm itself. +19 error Tell the author that this fails on your system: +19 error node ./bin/www +19 error You can get their info via: +19 error npm owner ls C3Projects--VideoStoreAPI +19 error There is likely additional logging output above. +20 verbose exit [ 1, true ] diff --git a/routes/customers.js b/routes/customers.js new file mode 100644 index 0000000..e69de29 diff --git a/routes/movies.js b/routes/movies.js new file mode 100644 index 0000000..7c56887 --- /dev/null +++ b/routes/movies.js @@ -0,0 +1,9 @@ +var express = require('express'); +var router = express.Router(); +var movie_exports = require('../controllers/movies'); + +router.get('/zomg', function(req, res, next) { + return movie_exports.moviesController.movies(req, res); +}); + +module.exports = router; diff --git a/routes/rentals.js b/routes/rentals.js new file mode 100644 index 0000000..e69de29 From c7d87a16e517eb24aa743290f331dc567b42fa43 Mon Sep 17 00:00:00 2001 From: Brenna Date: Thu, 17 Sep 2015 14:48:16 -0700 Subject: [PATCH 06/93] movies/zomg is working --- app.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app.js b/app.js index 19ac3bb..bd058ff 100644 --- a/app.js +++ b/app.js @@ -9,8 +9,8 @@ var bodyParser = require('body-parser'); var routes = require('./routes/index'); var users = require('./routes/users'); var movies = require('./routes/movies'); -var customers = require('./routes/customers'); -var rentals = require('./routes/rentals'); +// var customers = require('./routes/customers'); +// var rentals = require('./routes/rentals'); var app = express(); @@ -31,8 +31,8 @@ app.use(express.static(path.join(__dirname, 'public'))); app.use('/', routes); app.use('/users', users); app.use('/movies', movies); -app.use('/customers', customers); -app.use('/rentals', rentals); +// app.use('/customers', customers); +// app.use('/rentals', rentals); // catch 404 and forward to error handler From 32bf680e2121110e222bf384f0f7725f06430e7f Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Thu, 17 Sep 2015 16:13:41 -0700 Subject: [PATCH 07/93] WIP trying to return json data of all movies. --- controllers/movies.js | 9 +++++++++ database.js | 37 +++++++++++++++++++++++++++++++------ movies.js | 22 ++++++++++++++++++++++ npm-debug.log | 4 ++-- routes/movies.js | 4 ++++ 5 files changed, 68 insertions(+), 8 deletions(-) create mode 100644 movies.js diff --git a/controllers/movies.js b/controllers/movies.js index 48f7195..ce9e0b2 100644 --- a/controllers/movies.js +++ b/controllers/movies.js @@ -1,8 +1,17 @@ "use strict"; +var Movie = require('../movies'); +var movie = new Movie(); + exports.moviesController = { movies: function movies(req, res) { return res.status(200).json("it works!"); + }, + + all: function all(req, res) { + var movies = movie.all; + + return res.status(200).json(movies); } } diff --git a/database.js b/database.js index e237832..0e66668 100644 --- a/database.js +++ b/database.js @@ -1,6 +1,31 @@ -// "use-strict"; -// var sqlite3 = require('sqlite3').verbose(); -// -// var Database -// // We want to export the Database into the overall node structure -// module.exports = Database; +"use-strict"; +var sqlite3 = require('sqlite3').verbose(); + +function Database(path) { // this creates our database class + this.path = path; +} + +// Here we will define our instance methods +Database.prototype = { + query: function(statement, callback) { + var db = new sqlite3.Database(this.path); + + db.serialize(function() { + // below: this is the callback pattern...parameters(ERRORS, RESULT) + db.all(statement, function(err, res) { + // error handling looks like -> if (err) { }; + if (callback) { callback(res); } + return res; + }); + }); + + db.close(); + }, + + test: function() { + return "yay, it works!"; + } +} + +// We want to export the Database into the overall node structure +module.exports = Database; diff --git a/movies.js b/movies.js new file mode 100644 index 0000000..4c17a6c --- /dev/null +++ b/movies.js @@ -0,0 +1,22 @@ +"use-strict"; +var sqlite3 = require('sqlite3').verbose(); +var Database = require('./database'); + +function Movie() {} + +Movie.prototype = { + all: function() { + console.log("hello"); + var db = new Database(); + + db.serialize(function() { + // var movies = db.query("SELECT * FROM movies;"); + movies = db.test(); + console.log("This should be yay it works: " + movies); + }); + + return movies; + } +} + +module.exports = Movie; diff --git a/npm-debug.log b/npm-debug.log index bd2156b..9ee0fe0 100644 --- a/npm-debug.log +++ b/npm-debug.log @@ -17,8 +17,8 @@ 10 verbose stack at maybeClose (child_process.js:1015:16) 10 verbose stack at Process.ChildProcess._handle.onexit (child_process.js:1087:5) 11 verbose pkgid C3Projects--VideoStoreAPI@0.0.0 -12 verbose cwd /Users/brennaleker/Documents/Projects/project-forks/C3Projects--VideoStoreAPI -13 error Darwin 14.3.0 +12 verbose cwd /Users/corinnepingul/ada/projects/project-forks/C3Projects--VideoStoreAPI +13 error Darwin 14.5.0 14 error argv "node" "/usr/local/bin/npm" "start" 15 error node v0.12.2 16 error npm v2.7.5 diff --git a/routes/movies.js b/routes/movies.js index 7c56887..fe48589 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -6,4 +6,8 @@ router.get('/zomg', function(req, res, next) { return movie_exports.moviesController.movies(req, res); }); +router.get('/', function(req, res, next) { + return movie_exports.moviesController.all(req, res); +}); + module.exports = router; From d9d9cc94507740caa731a6b0b9c98f8f2e1b6320 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Thu, 17 Sep 2015 17:00:26 -0700 Subject: [PATCH 08/93] /movies returns all movies in json. --- controllers/movies.js | 8 ++++---- database.js | 1 - movies.js | 14 +++++--------- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/controllers/movies.js b/controllers/movies.js index ce9e0b2..c1b707f 100644 --- a/controllers/movies.js +++ b/controllers/movies.js @@ -1,7 +1,6 @@ "use strict"; var Movie = require('../movies'); -var movie = new Movie(); exports.moviesController = { movies: function movies(req, res) { @@ -10,8 +9,9 @@ exports.moviesController = { }, all: function all(req, res) { - var movies = movie.all; - - return res.status(200).json(movies); + var movie = new Movie(); + var movies = movie.all(function(movies) { + return res.status(200).json(movies); + }); } } diff --git a/database.js b/database.js index 0e66668..85ea46b 100644 --- a/database.js +++ b/database.js @@ -15,7 +15,6 @@ Database.prototype = { db.all(statement, function(err, res) { // error handling looks like -> if (err) { }; if (callback) { callback(res); } - return res; }); }); diff --git a/movies.js b/movies.js index 4c17a6c..e2fd987 100644 --- a/movies.js +++ b/movies.js @@ -5,17 +5,13 @@ var Database = require('./database'); function Movie() {} Movie.prototype = { - all: function() { - console.log("hello"); - var db = new Database(); + all: function(callback) { + var db = new Database('./db/development.db'); + var movies; - db.serialize(function() { - // var movies = db.query("SELECT * FROM movies;"); - movies = db.test(); - console.log("This should be yay it works: " + movies); + db.query("SELECT * FROM movies;", function(res) { + callback(res); }); - - return movies; } } From 9d996a0715711bebff55e74a059bc5f53f563762 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Fri, 18 Sep 2015 10:14:15 -0700 Subject: [PATCH 09/93] Removes unecessary variable. --- movies.js | 1 - 1 file changed, 1 deletion(-) diff --git a/movies.js b/movies.js index e2fd987..218666a 100644 --- a/movies.js +++ b/movies.js @@ -7,7 +7,6 @@ function Movie() {} Movie.prototype = { all: function(callback) { var db = new Database('./db/development.db'); - var movies; db.query("SELECT * FROM movies;", function(res) { callback(res); From 5cf6f946cd1aecdc60ccb5d5689e967f91d14c4a Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Fri, 18 Sep 2015 10:14:27 -0700 Subject: [PATCH 10/93] Adds cl shortcuts. --- package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 87e6a93..976fe8c 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,10 @@ "version": "0.0.0", "private": true, "scripts": { - "start": "node ./bin/www" + "start": "nodemon ./bin/www", + "db:schema" : "node ./utils/schema", + "db:seed" : "node ./utils/seed", + "db:setup" : "npm run db:schema; npm run db:seed" }, "dependencies": { "body-parser": "~1.13.2", From 8878a8072867fcd27869323c341705364957ab7e Mon Sep 17 00:00:00 2001 From: Brenna Date: Fri, 18 Sep 2015 10:39:25 -0700 Subject: [PATCH 11/93] refactored to use a dynamic dtabase function for all --- database.js | 17 ++++++++++------- movies.js | 15 ++++----------- npm-debug.log | 4 ++-- package.json | 2 +- 4 files changed, 17 insertions(+), 21 deletions(-) diff --git a/database.js b/database.js index 85ea46b..7a4792d 100644 --- a/database.js +++ b/database.js @@ -1,14 +1,11 @@ "use-strict"; var sqlite3 = require('sqlite3').verbose(); - -function Database(path) { // this creates our database class - this.path = path; -} +var db_env = process.env.DB || 'development'; // Here we will define our instance methods -Database.prototype = { +module.exports = { query: function(statement, callback) { - var db = new sqlite3.Database(this.path); + var db = new sqlite3.Database('db/' + db_env + '.db'); db.serialize(function() { // below: this is the callback pattern...parameters(ERRORS, RESULT) @@ -21,10 +18,16 @@ Database.prototype = { db.close(); }, + all: function(callback) { + + this.query("SELECT * FROM " + this.table_name + ";", function(res) { + callback(res); + }); + }, + test: function() { return "yay, it works!"; } } // We want to export the Database into the overall node structure -module.exports = Database; diff --git a/movies.js b/movies.js index 218666a..2984cb7 100644 --- a/movies.js +++ b/movies.js @@ -1,17 +1,10 @@ "use-strict"; var sqlite3 = require('sqlite3').verbose(); -var Database = require('./database'); -function Movie() {} - -Movie.prototype = { - all: function(callback) { - var db = new Database('./db/development.db'); - - db.query("SELECT * FROM movies;", function(res) { - callback(res); - }); - } +function Movie() { + this.table_name = "movies"; } +Movie.prototype = require('./database'); + module.exports = Movie; diff --git a/npm-debug.log b/npm-debug.log index 9ee0fe0..bd2156b 100644 --- a/npm-debug.log +++ b/npm-debug.log @@ -17,8 +17,8 @@ 10 verbose stack at maybeClose (child_process.js:1015:16) 10 verbose stack at Process.ChildProcess._handle.onexit (child_process.js:1087:5) 11 verbose pkgid C3Projects--VideoStoreAPI@0.0.0 -12 verbose cwd /Users/corinnepingul/ada/projects/project-forks/C3Projects--VideoStoreAPI -13 error Darwin 14.5.0 +12 verbose cwd /Users/brennaleker/Documents/Projects/project-forks/C3Projects--VideoStoreAPI +13 error Darwin 14.3.0 14 error argv "node" "/usr/local/bin/npm" "start" 15 error node v0.12.2 16 error npm v2.7.5 diff --git a/package.json b/package.json index 976fe8c..ce7b906 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.0.0", "private": true, "scripts": { - "start": "nodemon ./bin/www", + "start": "node ./bin/www", "db:schema" : "node ./utils/schema", "db:seed" : "node ./utils/seed", "db:setup" : "npm run db:schema; npm run db:seed" From ff635127e25085e8b24c516e56496620087f44c1 Mon Sep 17 00:00:00 2001 From: Brenna Date: Fri, 18 Sep 2015 11:00:25 -0700 Subject: [PATCH 12/93] customrs.all is working and displaying in json on the page --- app.js | 6 ++---- controllers/customers.js | 13 +++++++++++++ controllers/movies.js | 4 ---- customers.js | 10 ++++++++++ routes/customers.js | 9 +++++++++ routes/movies.js | 4 ---- 6 files changed, 34 insertions(+), 12 deletions(-) create mode 100644 customers.js diff --git a/app.js b/app.js index bd058ff..937aeb5 100644 --- a/app.js +++ b/app.js @@ -7,9 +7,8 @@ var bodyParser = require('body-parser'); // establish our routes based on route files var routes = require('./routes/index'); -var users = require('./routes/users'); var movies = require('./routes/movies'); -// var customers = require('./routes/customers'); +var customers = require('./routes/customers'); // var rentals = require('./routes/rentals'); @@ -29,9 +28,8 @@ app.use(express.static(path.join(__dirname, 'public'))); // Establishes our routes app.use('/', routes); -app.use('/users', users); +app.use('/customers', customers); app.use('/movies', movies); -// app.use('/customers', customers); // app.use('/rentals', rentals); diff --git a/controllers/customers.js b/controllers/customers.js index e69de29..d81493d 100644 --- a/controllers/customers.js +++ b/controllers/customers.js @@ -0,0 +1,13 @@ +"use strict"; + +var Customer = require('../customers'); + +exports.customersController = { + + all: function all(req, res) { + var customer = new Customer(); + var customers = customer.all(function(customers) { + return res.status(200).json(customers); + }); + } +} diff --git a/controllers/movies.js b/controllers/movies.js index c1b707f..a85dd51 100644 --- a/controllers/movies.js +++ b/controllers/movies.js @@ -3,10 +3,6 @@ var Movie = require('../movies'); exports.moviesController = { - movies: function movies(req, res) { - - return res.status(200).json("it works!"); - }, all: function all(req, res) { var movie = new Movie(); diff --git a/customers.js b/customers.js new file mode 100644 index 0000000..3352ad6 --- /dev/null +++ b/customers.js @@ -0,0 +1,10 @@ +"use-strict"; +var sqlite3 = require('sqlite3').verbose(); + +function Customer() { + this.table_name = "customers"; +} + +Customer.prototype = require('./database'); + +module.exports = Customer; diff --git a/routes/customers.js b/routes/customers.js index e69de29..306c51c 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -0,0 +1,9 @@ +var express = require('express'); +var router = express.Router(); +var customer_exports = require('../controllers/customers'); + +router.get('/', function(req, res, next) { + return customer_exports.customersController.all(req, res); +}); + +module.exports = router; diff --git a/routes/movies.js b/routes/movies.js index fe48589..783357c 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -2,10 +2,6 @@ var express = require('express'); var router = express.Router(); var movie_exports = require('../controllers/movies'); -router.get('/zomg', function(req, res, next) { - return movie_exports.moviesController.movies(req, res); -}); - router.get('/', function(req, res, next) { return movie_exports.moviesController.all(req, res); }); From d1489d82c743bf7776342c6a550cbc307d3fbd6e Mon Sep 17 00:00:00 2001 From: Brenna Date: Fri, 18 Sep 2015 11:56:00 -0700 Subject: [PATCH 13/93] rental seeds --- db/development.db | Bin 144384 -> 144384 bytes npm-debug.log | 36 -------------------------------- utils/rentals.json | 51 +++++++++++++++++++++++++++++++++++++++++++++ utils/schema.js | 2 +- utils/seed.js | 22 +++++++++++++++++++ 5 files changed, 74 insertions(+), 37 deletions(-) delete mode 100644 npm-debug.log create mode 100644 utils/rentals.json diff --git a/db/development.db b/db/development.db index 9f206157c31a3c31f75751c6b09437a7dabda29e..f938731d7926b67cf7bb06af58daac5e5ed671f2 100644 GIT binary patch delta 1382 zcma)*KWr0M9LN3cJ)bXd)NZIsh*Bx8_~X*Jv18+;C4d6~f=UsB0;!19R1GRoL&!fu zfPj4@fPf&S>cYTK>5$w3q@Yvl4jDRjVCYb(3=A0>y*KF2> z-mjT+>PvLE2OaE2UB}UZW2o~e+Itx7`3&v;6z%FlJNBctPSo6iw(LUjcC`Kz6m3Im za;PSYuBOps3JrXOMn6PTAE3)yrDy*pbo71H5l1`UL)+@nUAdPlb?DN&XktAYkD>E# zp)nT?)u3}W`qm&@%Wc=`0uIdtt~0I+cf34*ZhNw)o1X0AhL^zCy+%CkN&YoYVm;5n z1rLQTOrVh=)OQA*=tcXwQT_S5_fmJE3?y?kLrgN^ei5T9c{FYL)x1a*ij$|8r)2!c=G0{F|9u&7^8w z&ZNre+C)LW8M-~0&Mr@&T4|q6rd!?33G2Mty949^GZNcOu?6HMYydgAD69e5Y!R-)Bn-eP+=3~%4E-SA zi+ma#uoJey29PiE3S5GVFahIm9>!o)x(!pv8+Q)mX_%m?_USs`Ogn)|s8|r5S<=2~ zcYQN!0&~c6%l4vL(m}XqDf*L9mI>^kO4K*^7@f9af&F(S;+y-dJ|ts5E=7azUy5qJ zveq{*jc=aB0<$P%3zbMLPeL%fQtF%Iip3zvX_c#R>jI@lI@o52TJBNS)`6JGAF|? zL4gTQUo>jV#w3i`xme^9)R%R1;F=go6oBWxciwdHm`58*Dw#@AOte&_p>$}`22DfJq)il+5Tie+D$2~O`rRfK z7M7ABVS!EV{6;u;{{~3yUuN0T#`S?{x8fbLYJK&OPVcmz|Gg=VMdrR@t8- zk;o)Ca0qIiCwE%*r;j~@cFFnv{`AFjeJ^J1Ix`x$veC}myTG38S+t}ZE$u|{Q>gSL zsyKlv+t8-tsOBiDYeDsg(cWgX{{U*-k5Ucj;2zXekD7O*L%YzC9jK)iwQfgk+tBGP zsB5#H*;9pjH=w>sbZtGlxejI4BEKAstw!Ue=z)hGu0W4m^mGY&7DW?+qPDhOZf9^L z9k{V!J9E`f@u%O{ng)EWV$iR~*Zl+@TFigL*R;ca43GFIa%%+L9zb_5p~)V!rW0*# zNBeXJ2U6&;rahrqFKf~}33R_4J<*IMvE^D&M8cKR#@M-9*El+~D}n39P38*AG+c## z(BlT-It;-L7zVB77TktWxC{3n3wqZ&gryJ%9nu=803GKh*a|gJ2U_o5*vEV$dTou6 z0=>tB&;(keemr{1M?l+c1^p8AlQ<1s&;z}28T#NF+=M%zcc7yjgZnTJ58xp@g2!6w z6BbY58BD-rkX$vpJdjySg6OY;9Z0qDa?Vc)oQC4EocxeLj#+LP^-RIeNw=4i?~;=N ze!uc)-136x7k%=|&B+3hcg72x=^~LYL_V*VD!e<+ZUSjAl)Ne!AH>WxTwU8CGwM#4Hn!SdAtgRJyj2v7}!al=<6@*!z=tx}b1#xhIWXy-)F(x9tBA^27-`aZ^ke~U-YGP}Hd*A$)Fz_iiU xCJdYYKr_ri3L1E6&hW(9MbEW5$0Xru!WA46M!zoJLj@&$)(+m0Pddzk{T~`M-oXF> diff --git a/npm-debug.log b/npm-debug.log deleted file mode 100644 index bd2156b..0000000 --- a/npm-debug.log +++ /dev/null @@ -1,36 +0,0 @@ -0 info it worked if it ends with ok -1 verbose cli [ 'node', '/usr/local/bin/npm', 'start' ] -2 info using npm@2.7.5 -3 info using node@v0.12.2 -4 verbose node symlink /usr/local/bin/node -5 verbose run-script [ 'prestart', 'start', 'poststart' ] -6 info prestart C3Projects--VideoStoreAPI@0.0.0 -7 info start C3Projects--VideoStoreAPI@0.0.0 -8 verbose unsafe-perm in lifecycle true -9 info C3Projects--VideoStoreAPI@0.0.0 Failed to exec start script -10 verbose stack Error: C3Projects--VideoStoreAPI@0.0.0 start: `node ./bin/www` -10 verbose stack Exit status 1 -10 verbose stack at EventEmitter. (/usr/local/lib/node_modules/npm/lib/utils/lifecycle.js:213:16) -10 verbose stack at EventEmitter.emit (events.js:110:17) -10 verbose stack at ChildProcess. (/usr/local/lib/node_modules/npm/lib/utils/spawn.js:14:12) -10 verbose stack at ChildProcess.emit (events.js:110:17) -10 verbose stack at maybeClose (child_process.js:1015:16) -10 verbose stack at Process.ChildProcess._handle.onexit (child_process.js:1087:5) -11 verbose pkgid C3Projects--VideoStoreAPI@0.0.0 -12 verbose cwd /Users/brennaleker/Documents/Projects/project-forks/C3Projects--VideoStoreAPI -13 error Darwin 14.3.0 -14 error argv "node" "/usr/local/bin/npm" "start" -15 error node v0.12.2 -16 error npm v2.7.5 -17 error code ELIFECYCLE -18 error C3Projects--VideoStoreAPI@0.0.0 start: `node ./bin/www` -18 error Exit status 1 -19 error Failed at the C3Projects--VideoStoreAPI@0.0.0 start script 'node ./bin/www'. -19 error This is most likely a problem with the C3Projects--VideoStoreAPI package, -19 error not with npm itself. -19 error Tell the author that this fails on your system: -19 error node ./bin/www -19 error You can get their info via: -19 error npm owner ls C3Projects--VideoStoreAPI -19 error There is likely additional logging output above. -20 verbose exit [ 1, true ] diff --git a/utils/rentals.json b/utils/rentals.json new file mode 100644 index 0000000..8d4024f --- /dev/null +++ b/utils/rentals.json @@ -0,0 +1,51 @@ + +[ + { + "check_out": "2015-06-16", + "check_in": "2015-06-17", + "due_date": "2015-06-19", + "overdue": 0, + "customer_id": 1, + "movie_id": 12 + }, + { + "check_out": "2015-04-27", + "check_in": "2015-05-12", + "due_date": "2015-04-30", + "overdue": 1, + "customer_id": 7, + "movie_id": 24 + }, + { + "check_out": "2015-05-14", + "check_in": "2015-05-16", + "due_date": "2015-04-17", + "overdue": 0, + "customer_id": 12, + "movie_id": 37 + }, + { + "check_out": "2015-06-03", + "check_in": "2015-06-07", + "due_date": "2015-06-06", + "overdue": 1, + "customer_id": 3, + "movie_id": 18 + }, + { + "check_out": "2015-07-03", + "check_in": "2015-07-06", + "due_date": "2015-07-06", + "overdue": 0, + "customer_id": 8, + "movie_id": 26 + }, + { + "check_out": "2015-07-03", + "check_in": "2015-07-06", + "due_date": "2015-07-06", + "overdue": 0, + "customer_id": 8, + "movie_id": 85 + } +] diff --git a/utils/schema.js b/utils/schema.js index 1644359..20dd6c8 100644 --- a/utils/schema.js +++ b/utils/schema.js @@ -27,7 +27,7 @@ var rental_fields = [ ['check_out', 'text'], ['check_in', 'text'], ['due_date', 'text'], - ['overdue', 'boolean'], + ['overdue', 'integer'], // 0 for false 1 for true ['customer_id', 'integer'], ['movie_id', 'integer'] ] diff --git a/utils/seed.js b/utils/seed.js index 941d587..37b7d11 100644 --- a/utils/seed.js +++ b/utils/seed.js @@ -16,6 +16,12 @@ var customer_statement = db.prepare( // we will use this statement later VALUES( ?, ?, ?, ?, ?, ?, ?, ?);" ); +var rentals = require('./rentals'); // requires in movies.json file +var rental_statement = db.prepare( // we will use this statement later + "INSERT INTO RENTALS(check_out, check_in, due_date, overdue, customer_id, movie_id) \ + VALUES( ?, ?, ?, ?, ?, ?);" +); + db.serialize(function() { // loop through movies for(var i = 0; i < movies.length; i++) { @@ -48,8 +54,24 @@ db.serialize(function() { ); } + // loop through rentals + for(var j = 0; j < rentals.length; j++) { + var rental = rentals[j]; + + // insert each rental into the db + rental_statement.run( + rental.check_out, + rental.check_in, + rental.due_date, + rental.overdue, + rental.customer_id, + rental.movie_id + ); + } + movie_statement.finalize(); customer_statement.finalize(); + rental_statement.finalize(); }) db.close(); From 3318e77ee2f04d93a9a7eeb7d784e81951c771a1 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Fri, 18 Sep 2015 13:36:53 -0700 Subject: [PATCH 14/93] Adds default value to rentals overdue table. --- db/development.db | Bin 144384 -> 144384 bytes utils/schema.js | 35 ++++++++++++++++++++--------------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/db/development.db b/db/development.db index f938731d7926b67cf7bb06af58daac5e5ed671f2..938412f2ee1dc58e2d832ae13019de3c6d015d54 100644 GIT binary patch delta 2321 zcmZ{lYitx%6vyYx+}TdM(+8#R7qf-R7TUVdQl3JEZh2UslvaxJlr2(dq4dS8(w$P| zRg^MBFj1q~U`fRIxZn^Y;s+8jV1h;o3H_i65<^tf1eHjr|I=84A8hjb@7;6fo_ppz zw&5R*@Q=okjKruDilQ6_ItYT!zJiHKuom9(#;RKtjZ}p$ld7I~eC81;sfD5{Q!_JZ zPtX~s+FRSUG}X7PZU|ZP7u5vk2CEAmZdz8;mX3z{ zNA{dowOL(Od9dQi+R7R$@aUrzi>rh4=Pt6I3NE+&kGRdZs)H55>foX|!KK!)-QN(( z|KG#Im;UGEkdcq&o1BYrS`kzkB~6j1b!D!@I%73t{|ZQ49b{`QWXDoSMK$EWB1m{4 zr1&XF**r+F0`hb@q~%G-wwaKw8IbO2ke(@!y`_*BOCSd)Kn?{Uy?k}kc*v@J$nvp# zXU!PM!dys+4^os3@n=A?(;?|;kdzci(nv^R0%SxSB*BE3(Gaf(VhD&w<2Ovxx}eHL zX&N0`*95x^UjjDARA_S)1-2hL-nO9mHv1oIv)eq|fR3>tO73=u)eOnm07+W|Nv(rq zRY5|WgCW2B*lj&~oyJZ_TaaXS8Ot7{j95vgp&3LzpU*IAo%r}1)2|!KzlIDpl={WL zhG;EuVqn6g!a!+Zp!nfx^21fBUmHGZ<~fJimpXhjD$Q}@bG&28P@;!!GoA0_bA~d3 zNVrs!z$UN-@SC-PcF+O%b$5an08h<0@C4xMauYOwU0@Gr1&yE+>;_ze7!VJ*MqI_m zz~i8c^D`ZAhs*-A!5qK=%>|sv`GA}3S+E9d1{(oq{&}z-tOL)1wSe1oCE)IP2GoIN zfcuu)b_w7zEyn#yB^KPb3jlZMR4^HEdvZo50&Y;QVIe30+@bkkEXV`gq1>Pr7zJ`b zCg3jRV($mslUu&nY5-5>G{B=)1cv$$pFBtDoPHjjWRL_B!3e52qwxSkq%phZNPh=}iuh`5i> za^Z?zIC1qeG^n}aBGyt54{H75I$Vo7?Ei(cXFVz(JqCY5g}o9Bb9j-Unh{Y2>zlBS z;V);zS%Fir@d~{@)OdSh>>Qaiua{IiTfWs7QeFKuT1k}Ugr=TX?MyfK4Z2CL=LE$P zWys{b8+bBZ{`OchNzVWx(~nU)QJUlP-Bs;WCpGs|)lQMua*L>6Bypst5$O@iBuaLz zKKenG`mdaU_r*y;3A`N<7x73MAszaDnygZioVjxpt{Lg9+V%Ev(L?W1qVrMP->N;r z{a`PRCQ6Xsb_D3S9;TBNFHbk0#?x_fdCNN#5i8*EIvj4NokX!R-0&_oO{ZwnwFC|I zQ`_kPm$AFu_R5sdHf+W?FV){x?P$4U{b9UnGc^(!vTbb~_M+sT=j{rbJfl()*hB-$m< z%&x+b8Hi)2<9*^D?U4G+7^3Y?!mPVe-!P~-qU0KFlQ&8>5_LEgrI)GQNu2z_kj z#}imUZE{JVgQ!(rnlM9kM8V(G@?qgsqOJ0)qGED{emT0s5Wn2nU za0yLh!HLMaO-;_7te>dS8OZLVO>%S2D|B2G(8sjVy-+|Gh#K6kBHD{kJ5l%zu9ZJj z_%(x?htz|LdQkezu&Q;pJ}<+fl|DK}!jPhwL^SD&mPlVCwLbGt&0etH`9r@Vzxg?! z_KS0xO9?}!s@`h+vt$g3kfbjXavJYgosV2mst Zqx;;P*TH83Ve)isAB3AWd@H}N{R8ws+Ux)T delta 2269 zcmYk6ZBP|e7{~WHdv;miB8Vsmr1zremB2s@HGzPXut?F==*2>X6y)Xdj*4FPN-r9k zu+^=mW~y7^2h8$_n=`#l<4pGAOf~5=V;}sW4mGCL)J#nc_J3%inECzK-Lw0gbDrlp zw{Ohq8?z3lCK@v}O*;q-uo7$@%wCj)r#V+*-B57_w7eWzx&peT z6q;8I`3j+Fw?Xksp_l?FdNH&&59-Z@8hPsWo1uLRpxyI%&ic8~x(uk)2Nm4}Wu-y~ zIZu01pj|Vdo@r250@OJL>hM5;XsE@6c1Xz7d50-_5Y`5i$Li99PuV57Ibidep0Ifp zkK2CuG209G+Z;b+b6DH9;Ghj@-91oS0IJ;%ZLEP-RzoFKP(J4%y#(sxu=_b`IR{Pl zLOVHRD@Tm7;uLu--Sqi<7LhYGewN4D;5RJozXt_Ys$Wh#h$dQ;n|EtYZb43N{^Zq? z$*TfA(XUT_`ZQvBGX3J;Pn}covw~46^XZ>Aq9s%es?FlO&jwz=1)T%9x|v`;;1qG;xdXC64&avH z{Be^k0^BjT0&brrU>V@1;_kW&a1T}jZpbyD3aka(ufg>Yckg|Gt93tk0C1me0uKXj z_RU}m;O?&jkAiJrJ7@r$kpb`&H~^jikAufRKL`Qt6W(w)XamiBTZ@Yt@F3U-R)bZb z0^A8!0#5lIpbV6N+W{Y-<$&8MAKU`w0Ut;Q-23q$25`^!fxVy?G=g@ppSQCQ7rQ|{ z;L}?UNUl?Z|JW4iG);UU|f&L3cU0ZI03!@Ps(ALOHd_ASB?>EbkGfbR0<)7 z%`><+M{w^NSK(p#D_Kf<$r?617&jyW8_)0@zhjPJ^IObmzRMHwB;SEC@T=v@(-?P6 zN#n7@a)2jHAOTQ#)Q(u(@i8|HV6deYQF_BV7R-UIGb)m9>sM{%D{W*0xiEDmQ za=l5k+lk%q2klbE#u%cV;e>Yj%`s{&(jIlC<}6XKIPIATv!cJD_Gjg%RZ{vv4)bz{?_&inp zJTHlq@y#Zpo1EHZ?+ZI!Wt_i+WmnR;9xrgN>E(&Ty)VX|t&%DR@YO8!>Z+}%>Jh^6 z`Unl(1NR>|4Dew8NQp ftVM(xoc?3IdV8qeDLB%8@-Runeh+I3{H6a57#7z| diff --git a/utils/schema.js b/utils/schema.js index 20dd6c8..f6607d2 100644 --- a/utils/schema.js +++ b/utils/schema.js @@ -27,9 +27,7 @@ var rental_fields = [ ['check_out', 'text'], ['check_in', 'text'], ['due_date', 'text'], - ['overdue', 'integer'], // 0 for false 1 for true - ['customer_id', 'integer'], - ['movie_id', 'integer'] + ['overdue', 'integer', 'DEFAULT 0'] // 0 for false 1 for true ] // I want these to work somewhat how rake db:reset works, so I need to do three things: @@ -44,31 +42,38 @@ db.serialize(function() { // 2. create fresh versions of those tables db.run("CREATE TABLE movies (id INTEGER PRIMARY KEY);"); db.run("CREATE TABLE customers (id INTEGER PRIMARY KEY);"); - db.run("CREATE TABLE rentals (id INTEGER PRIMARY KEY);"); + db.run("CREATE TABLE rentals (id INTEGER PRIMARY KEY, \ + customer_id INTEGER, \ + movie_id INTEGER, \ + FOREIGN KEY (customer_id) REFERENCES customer(id), \ + FOREIGN KEY (movie_id) REFERENCES movie(id));"); // 3. add the columns to those tables // CREATE MOVIES TABLE COLUMNS for(var i = 0; i < movie_fields.length; i++) { - var name = movie_fields[i][0], - type = movie_fields[i][1]; + var movie_name = movie_fields[i][0], + movie_type = movie_fields[i][1]; - db.run("ALTER TABLE movies ADD COLUMN " + name + " " + type + ";"); + db.run("ALTER TABLE movies ADD COLUMN " + movie_name + " " + movie_type + ";"); } // CREATE CUSTOMERS TABLE COLUMNS - for(var i = 0; i < customer_fields.length; i++) { - var name = customer_fields[i][0], - type = customer_fields[i][1]; + for(var l = 0; l < customer_fields.length; l++) { + var customer_name = customer_fields[l][0], + customer_type = customer_fields[l][1]; - db.run("ALTER TABLE customers ADD COLUMN " + name + " " + type + ";"); + db.run("ALTER TABLE customers ADD COLUMN " + customer_name + " " + customer_type + ";"); } // CREATE RENTALS TABLE COLUMNS - for(var i = 0; i < rental_fields.length; i++) { - var name = rental_fields[i][0], - type = rental_fields[i][1]; + for(var k = 0; k < rental_fields.length; k++) { + var rental_name = rental_fields[k][0], + rental_type = rental_fields[k][1]; + default_value = (rental_fields[k][2] === undefined) ? "" : rental_fields[k][2]; - db.run("ALTER TABLE rentals ADD COLUMN " + name + " " + type + ";"); + + db.run("ALTER TABLE rentals ADD COLUMN " + + rental_name + " " + rental_type + " " + default_value + ";"); } }); From c9797a1a44992c6986f73c1e99ccf43597daa566 Mon Sep 17 00:00:00 2001 From: Brenna Date: Fri, 18 Sep 2015 14:25:46 -0700 Subject: [PATCH 15/93] WIP - writing sort_by registered at query for customers --- controllers/customers.js | 10 ++++++++++ database.js | 6 +++--- routes/customers.js | 4 ++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/controllers/customers.js b/controllers/customers.js index d81493d..f248408 100644 --- a/controllers/customers.js +++ b/controllers/customers.js @@ -10,4 +10,14 @@ exports.customersController = { return res.status(200).json(customers); }); } + + registered_at_sort: function registered_at_sort(req, res) { + var customer = new Customer(); + var sort_type = "registered_at"; + var records_per_page = req.params.records_per_page; + var offset = req.param.offset; + var customers = customer.registered_at_sort(sort_type, records_per_page, offset, function(customers) { + return res.status(200).json(customers); + }); + } } diff --git a/database.js b/database.js index 7a4792d..b5d12ef 100644 --- a/database.js +++ b/database.js @@ -25,9 +25,9 @@ module.exports = { }); }, - test: function() { - return "yay, it works!"; - } + registered_at_sort: function(sort_type, records_per_page, offset, callback) { + this.query("SELECT * FROM " + this.table_name + " ORDER BY " + sort_type + " LIMIT " + records_per_page + " OFFSET " + offset + ";"); + } } // We want to export the Database into the overall node structure diff --git a/routes/customers.js b/routes/customers.js index 306c51c..6e267ba 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -6,4 +6,8 @@ router.get('/', function(req, res, next) { return customer_exports.customersController.all(req, res); }); +router.get('/registered_at_sort/:records_per_page/:offset', function(req, res, next) { + return customer_exports.customersController.registered_at_sort(req, res); +}); + module.exports = router; From bfc4c3c401a305512a0edf2a82a0c64f7cb851ac Mon Sep 17 00:00:00 2001 From: Brenna Date: Fri, 18 Sep 2015 14:53:16 -0700 Subject: [PATCH 16/93] WIP sort by date --- controllers/customers.js | 4 ++-- database.js | 6 +++++- db/development.db | Bin 144384 -> 144384 bytes utils/seed.js | 8 +++++++- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/controllers/customers.js b/controllers/customers.js index f248408..ed26c2d 100644 --- a/controllers/customers.js +++ b/controllers/customers.js @@ -9,13 +9,13 @@ exports.customersController = { var customers = customer.all(function(customers) { return res.status(200).json(customers); }); - } + }, registered_at_sort: function registered_at_sort(req, res) { var customer = new Customer(); var sort_type = "registered_at"; var records_per_page = req.params.records_per_page; - var offset = req.param.offset; + var offset = req.params.offset; var customers = customer.registered_at_sort(sort_type, records_per_page, offset, function(customers) { return res.status(200).json(customers); }); diff --git a/database.js b/database.js index b5d12ef..0f91fdc 100644 --- a/database.js +++ b/database.js @@ -26,7 +26,11 @@ module.exports = { }, registered_at_sort: function(sort_type, records_per_page, offset, callback) { - this.query("SELECT * FROM " + this.table_name + " ORDER BY " + sort_type + " LIMIT " + records_per_page + " OFFSET " + offset + ";"); + console.log(offset); + this.query("SELECT * FROM " + this.table_name + " ORDER BY " + sort_type + " LIMIT " + records_per_page + " OFFSET " + offset + ";", function(res) { + callback(res); + console.log(res); + }); } } diff --git a/db/development.db b/db/development.db index 938412f2ee1dc58e2d832ae13019de3c6d015d54..cfea88f618af5d2dabf696ba584002f095f8e5db 100644 GIT binary patch delta 9587 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 O=-b3n2csvJoc{yvYfW1K delta 13750 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 Date: Fri, 18 Sep 2015 15:30:31 -0700 Subject: [PATCH 17/93] Makes registered_at in customers table an integer and stores it in the format of YYYYMMDD. --- db/development.db | Bin 144384 -> 144384 bytes utils/schema.js | 2 +- utils/seed.js | 17 +++++++++++++---- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/db/development.db b/db/development.db index cfea88f618af5d2dabf696ba584002f095f8e5db..09be93aa70e47d1125b76ae1c4023374ad8858e7 100644 GIT binary patch delta 8943 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 AvH$=8 delta 9213 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 diff --git a/utils/schema.js b/utils/schema.js index f6607d2..6519782 100644 --- a/utils/schema.js +++ b/utils/schema.js @@ -14,7 +14,7 @@ var movie_fields = [ var customer_fields = [ ['name', 'text'], - ['registered_at', 'text'], + ['registered_at', 'integer'], ['address', 'text'], ['city', 'text'], ['state', 'text'], diff --git a/utils/seed.js b/utils/seed.js index fe370e5..86d18ce 100644 --- a/utils/seed.js +++ b/utils/seed.js @@ -42,10 +42,19 @@ db.serialize(function() { var customer = customers[j]; // this will format dates in sqlite to read year/month/day for easier sorting var dateObj = new Date(customer.registered_at); - var month = dateObj.getUTCMonth() + 1; //months from 1-12 - var day = dateObj.getUTCDate(); - var year = dateObj.getUTCFullYear(); - var formatted_date = newdate = year + month + day; + var month = (dateObj.getUTCMonth() + 1).toString(); //months from 1-12 + var day = (dateObj.getUTCDate()).toString(); + var year = (dateObj.getUTCFullYear()).toString(); + + if (month.length == 1) { // This will ensure month is two digits + month = "0" + month; + } + + if (day.length == 1) { // This will ensure day is two digits + day = "0" + day; + } + + var formatted_date = parseInt(year + month + day); // insert each customer into the db customer_statement.run( From 2e1f363c034663fa4a2efb46edb3f0f73d23f912 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Fri, 18 Sep 2015 15:36:58 -0700 Subject: [PATCH 18/93] Changes variables and adds semicolon. --- utils/seed.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/utils/seed.js b/utils/seed.js index 86d18ce..8518e3c 100644 --- a/utils/seed.js +++ b/utils/seed.js @@ -70,8 +70,8 @@ db.serialize(function() { } // loop through rentals - for(var j = 0; j < rentals.length; j++) { - var rental = rentals[j]; + for(var k = 0; k < rentals.length; k++) { + var rental = rentals[k]; // insert each rental into the db rental_statement.run( @@ -87,6 +87,6 @@ db.serialize(function() { movie_statement.finalize(); customer_statement.finalize(); rental_statement.finalize(); -}) +}); db.close(); From daa67b026990caa3a3feaec4e1929d29f6268cb1 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Mon, 21 Sep 2015 09:18:07 -0700 Subject: [PATCH 19/93] Refactor: pulls out date formatting into its own function. --- utils/seed.js | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/utils/seed.js b/utils/seed.js index 8518e3c..34a01ce 100644 --- a/utils/seed.js +++ b/utils/seed.js @@ -22,6 +22,23 @@ var rental_statement = db.prepare( // we will use this statement later VALUES( ?, ?, ?, ?, ?, ?);" ); +var formatDate = function(date) { + var dateObj = new Date(date); + var month = (dateObj.getUTCMonth() + 1).toString(); //months from 1-12 + var day = (dateObj.getUTCDate()).toString(); + var year = (dateObj.getUTCFullYear()).toString(); + + if (month.length == 1) { // This will ensure month is two digits + month = "0" + month; + } + + if (day.length == 1) { // This will ensure day is two digits + day = "0" + day; + } + + return parseInt(year + month + day); +} + db.serialize(function() { // loop through movies for(var i = 0; i < movies.length; i++) { @@ -41,20 +58,8 @@ db.serialize(function() { for(var j = 0; j < customers.length; j++) { var customer = customers[j]; // this will format dates in sqlite to read year/month/day for easier sorting - var dateObj = new Date(customer.registered_at); - var month = (dateObj.getUTCMonth() + 1).toString(); //months from 1-12 - var day = (dateObj.getUTCDate()).toString(); - var year = (dateObj.getUTCFullYear()).toString(); - - if (month.length == 1) { // This will ensure month is two digits - month = "0" + month; - } - - if (day.length == 1) { // This will ensure day is two digits - day = "0" + day; - } - var formatted_date = parseInt(year + month + day); + var formatted_date = formatDate(customer.registered_at); // insert each customer into the db customer_statement.run( From be34e3571b0c5bf19a31be678974bc681df592f3 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Mon, 21 Sep 2015 09:35:26 -0700 Subject: [PATCH 20/93] Changes name of sort function --- database.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/database.js b/database.js index 0f91fdc..88d1c4d 100644 --- a/database.js +++ b/database.js @@ -25,11 +25,9 @@ module.exports = { }); }, - registered_at_sort: function(sort_type, records_per_page, offset, callback) { - console.log(offset); + sort_by: function(sort_type, records_per_page, offset, callback) { this.query("SELECT * FROM " + this.table_name + " ORDER BY " + sort_type + " LIMIT " + records_per_page + " OFFSET " + offset + ";", function(res) { callback(res); - console.log(res); }); } } From 6ad1a4a19bfea7733f7fd1f48d92488f7fefc5cf Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Mon, 21 Sep 2015 09:35:45 -0700 Subject: [PATCH 21/93] Adds route for customers sort by name --- routes/customers.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/routes/customers.js b/routes/customers.js index 6e267ba..ef8e548 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -10,4 +10,8 @@ router.get('/registered_at_sort/:records_per_page/:offset', function(req, res, n return customer_exports.customersController.registered_at_sort(req, res); }); +router.get('/name_sort/:records_per_page/:offset', function(req, res, next) { + return customer_exports.customersController.name_sort(req, res); +}); + module.exports = router; From 52784d736a3196ee672d06f3c55df36ac2fdbabc Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Mon, 21 Sep 2015 09:36:02 -0700 Subject: [PATCH 22/93] Adds name sort function for customer. --- controllers/customers.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/controllers/customers.js b/controllers/customers.js index ed26c2d..ce9c53d 100644 --- a/controllers/customers.js +++ b/controllers/customers.js @@ -16,8 +16,18 @@ exports.customersController = { var sort_type = "registered_at"; var records_per_page = req.params.records_per_page; var offset = req.params.offset; - var customers = customer.registered_at_sort(sort_type, records_per_page, offset, function(customers) { + var customers = customer.sort_by(sort_type, records_per_page, offset, function(customers) { return res.status(200).json(customers); }); - } + }, + +name_sort: function name_sort(req, res) { + var customer = new Customer(); + var sort_type = "name"; + var records_per_page = req.params.records_per_page; + var offset = req.params.offset; + var customers = customer.sort_by(sort_type, records_per_page, offset, function(customers) { + return res.status(200).json(customers); + }); +} } From 416f7c7f995085e3efede962221b2c8f53caf171 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Mon, 21 Sep 2015 09:37:25 -0700 Subject: [PATCH 23/93] Refactors: pulls out customers variable to give it a larger scope. --- controllers/customers.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/controllers/customers.js b/controllers/customers.js index ce9c53d..4233da6 100644 --- a/controllers/customers.js +++ b/controllers/customers.js @@ -1,18 +1,17 @@ "use strict"; var Customer = require('../customers'); +var customer = new Customer(); exports.customersController = { all: function all(req, res) { - var customer = new Customer(); var customers = customer.all(function(customers) { return res.status(200).json(customers); }); }, registered_at_sort: function registered_at_sort(req, res) { - var customer = new Customer(); var sort_type = "registered_at"; var records_per_page = req.params.records_per_page; var offset = req.params.offset; @@ -22,7 +21,6 @@ exports.customersController = { }, name_sort: function name_sort(req, res) { - var customer = new Customer(); var sort_type = "name"; var records_per_page = req.params.records_per_page; var offset = req.params.offset; From 7ab2b83dbefb04d9fa6cc2397ce11299867aff46 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Mon, 21 Sep 2015 09:44:33 -0700 Subject: [PATCH 24/93] Adds route for customers sort by postal code. --- routes/customers.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/routes/customers.js b/routes/customers.js index ef8e548..e08baf3 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -14,4 +14,8 @@ router.get('/name_sort/:records_per_page/:offset', function(req, res, next) { return customer_exports.customersController.name_sort(req, res); }); +router.get('/postal_code_sort/:records_per_page/:offset', function(req, res, next) { + return customer_exports.customersController.postal_code_sort(req, res); +}) + module.exports = router; From 51e4df9f72b51591efe3108c8408b4ada3e8b41f Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Mon, 21 Sep 2015 09:44:59 -0700 Subject: [PATCH 25/93] Adds postal_code_sort function --- controllers/customers.js | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/controllers/customers.js b/controllers/customers.js index 4233da6..dd91526 100644 --- a/controllers/customers.js +++ b/controllers/customers.js @@ -20,12 +20,21 @@ exports.customersController = { }); }, -name_sort: function name_sort(req, res) { - var sort_type = "name"; - var records_per_page = req.params.records_per_page; - var offset = req.params.offset; - var customers = customer.sort_by(sort_type, records_per_page, offset, function(customers) { - return res.status(200).json(customers); - }); -} + name_sort: function name_sort(req, res) { + var sort_type = "name"; + var records_per_page = req.params.records_per_page; + var offset = req.params.offset; + var customers = customer.sort_by(sort_type, records_per_page, offset, function(customers) { + return res.status(200).json(customers); + }); + }, + + postal_code_sort: function postal_code_sort(req, res) { + var sort_type = "postal_code"; + var records_per_page = req.params.records_per_page; + var offset = req.params.offset; + var customers = customer.sort_by(sort_type, records_per_page, offset, function(customers) { + return res.status(200).json(customers); + }); + } } From f7858b4bdd1c2499ba954ce8d03a5ab82b1fb23b Mon Sep 17 00:00:00 2001 From: Brenna Date: Mon, 21 Sep 2015 09:45:40 -0700 Subject: [PATCH 26/93] movie title sort and release_date sort functioning --- controllers/movies.js | 20 +++++++++++++++++++- database.js | 3 ++- npm-debug.log | 36 ++++++++++++++++++++++++++++++++++++ routes/movies.js | 9 +++++++++ utils/seed.js | 3 +++ 5 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 npm-debug.log diff --git a/controllers/movies.js b/controllers/movies.js index a85dd51..28b08fe 100644 --- a/controllers/movies.js +++ b/controllers/movies.js @@ -1,13 +1,31 @@ "use strict"; var Movie = require('../movies'); +var movie = new Movie(); exports.moviesController = { all: function all(req, res) { - var movie = new Movie(); var movies = movie.all(function(movies) { return res.status(200).json(movies); }); + }, + + release_date_sort: function release_date_sort(req, res) { + var sort_type = "release_date"; + var records_per_page = req.params.records_per_page; + var offset = req.params.offset; + var movies = movie.sort_by(sort_type, records_per_page, offset, function(movies){ + return res.status(200).json(movies); + }); + }, + + title_sort: function title_sort(req, res) { + var sort_type = "title"; + var records_per_page = req.params.records_per_page; + var offset = req.params.offset; + var movies = movie.sort_by(sort_type, records_per_page, offset, function(movies){ + return res.status(200).json(movies); + }); } } diff --git a/database.js b/database.js index 0f91fdc..78073c0 100644 --- a/database.js +++ b/database.js @@ -25,13 +25,14 @@ module.exports = { }); }, - registered_at_sort: function(sort_type, records_per_page, offset, callback) { + sort_by: function(sort_type, records_per_page, offset, callback) { console.log(offset); this.query("SELECT * FROM " + this.table_name + " ORDER BY " + sort_type + " LIMIT " + records_per_page + " OFFSET " + offset + ";", function(res) { callback(res); console.log(res); }); } + } // We want to export the Database into the overall node structure diff --git a/npm-debug.log b/npm-debug.log new file mode 100644 index 0000000..bd2156b --- /dev/null +++ b/npm-debug.log @@ -0,0 +1,36 @@ +0 info it worked if it ends with ok +1 verbose cli [ 'node', '/usr/local/bin/npm', 'start' ] +2 info using npm@2.7.5 +3 info using node@v0.12.2 +4 verbose node symlink /usr/local/bin/node +5 verbose run-script [ 'prestart', 'start', 'poststart' ] +6 info prestart C3Projects--VideoStoreAPI@0.0.0 +7 info start C3Projects--VideoStoreAPI@0.0.0 +8 verbose unsafe-perm in lifecycle true +9 info C3Projects--VideoStoreAPI@0.0.0 Failed to exec start script +10 verbose stack Error: C3Projects--VideoStoreAPI@0.0.0 start: `node ./bin/www` +10 verbose stack Exit status 1 +10 verbose stack at EventEmitter. (/usr/local/lib/node_modules/npm/lib/utils/lifecycle.js:213:16) +10 verbose stack at EventEmitter.emit (events.js:110:17) +10 verbose stack at ChildProcess. (/usr/local/lib/node_modules/npm/lib/utils/spawn.js:14:12) +10 verbose stack at ChildProcess.emit (events.js:110:17) +10 verbose stack at maybeClose (child_process.js:1015:16) +10 verbose stack at Process.ChildProcess._handle.onexit (child_process.js:1087:5) +11 verbose pkgid C3Projects--VideoStoreAPI@0.0.0 +12 verbose cwd /Users/brennaleker/Documents/Projects/project-forks/C3Projects--VideoStoreAPI +13 error Darwin 14.3.0 +14 error argv "node" "/usr/local/bin/npm" "start" +15 error node v0.12.2 +16 error npm v2.7.5 +17 error code ELIFECYCLE +18 error C3Projects--VideoStoreAPI@0.0.0 start: `node ./bin/www` +18 error Exit status 1 +19 error Failed at the C3Projects--VideoStoreAPI@0.0.0 start script 'node ./bin/www'. +19 error This is most likely a problem with the C3Projects--VideoStoreAPI package, +19 error not with npm itself. +19 error Tell the author that this fails on your system: +19 error node ./bin/www +19 error You can get their info via: +19 error npm owner ls C3Projects--VideoStoreAPI +19 error There is likely additional logging output above. +20 verbose exit [ 1, true ] diff --git a/routes/movies.js b/routes/movies.js index 783357c..a8b6778 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -6,4 +6,13 @@ router.get('/', function(req, res, next) { return movie_exports.moviesController.all(req, res); }); + +router.get('/release_date_sort/:records_per_page/:offset', function(req, res, next){ + return movie_exports.moviesController.release_date_sort(req, res); +}); + +router.get('/title_sort/:records_per_page/:offset', function(req, res, next){ + return movie_exports.moviesController.title_sort(req, res); +}); + module.exports = router; diff --git a/utils/seed.js b/utils/seed.js index 34a01ce..eccf1b8 100644 --- a/utils/seed.js +++ b/utils/seed.js @@ -44,6 +44,9 @@ db.serialize(function() { for(var i = 0; i < movies.length; i++) { var movie = movies[i]; + + var formatted_date = formatDate(movie.release_date); + // insert each movie into the db movie_statement.run( movie.title, From a856e59c008fcfac9002c1cf300e08bf474c1e34 Mon Sep 17 00:00:00 2001 From: Brenna Date: Mon, 21 Sep 2015 09:59:55 -0700 Subject: [PATCH 27/93] refactored movies controller, added sortInfo variable to handle repeated code --- controllers/movies.js | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/controllers/movies.js b/controllers/movies.js index 28b08fe..ccd1b58 100644 --- a/controllers/movies.js +++ b/controllers/movies.js @@ -3,6 +3,14 @@ var Movie = require('../movies'); var movie = new Movie(); +var sortInfo = function (sort_type, params, res) { + var records_per_page = params.records_per_page; + var offset = params.offset; + var movies = movie.sort_by(sort_type, records_per_page, offset, function(movies){ + return res.status(200).json(movies); + }); +} + exports.moviesController = { all: function all(req, res) { @@ -13,19 +21,12 @@ exports.moviesController = { release_date_sort: function release_date_sort(req, res) { var sort_type = "release_date"; - var records_per_page = req.params.records_per_page; - var offset = req.params.offset; - var movies = movie.sort_by(sort_type, records_per_page, offset, function(movies){ - return res.status(200).json(movies); - }); + sortInfo(sort_type, req.params, res); }, title_sort: function title_sort(req, res) { var sort_type = "title"; - var records_per_page = req.params.records_per_page; - var offset = req.params.offset; - var movies = movie.sort_by(sort_type, records_per_page, offset, function(movies){ - return res.status(200).json(movies); - }); + sortInfo(sort_type, req.params, res); } + } From 1ca9b997e810f90055bef3327845aa26c7972075 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Mon, 21 Sep 2015 09:59:57 -0700 Subject: [PATCH 28/93] Refactor: pulls out sort info into separate function. This function now calls the model function. --- controllers/customers.js | 26 +++++++++++--------------- npm-debug.log | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 15 deletions(-) create mode 100644 npm-debug.log diff --git a/controllers/customers.js b/controllers/customers.js index dd91526..ecd4c0a 100644 --- a/controllers/customers.js +++ b/controllers/customers.js @@ -3,6 +3,14 @@ var Customer = require('../customers'); var customer = new Customer(); +var sortInfo = function(sort_type, params, res) { + var records_per_page = params.records_per_page; + var offset = params.offset; + var customers = customer.sort_by(sort_type, records_per_page, offset, function(customers) { + return res.status(200).json(customers); + }); +} + exports.customersController = { all: function all(req, res) { @@ -13,28 +21,16 @@ exports.customersController = { registered_at_sort: function registered_at_sort(req, res) { var sort_type = "registered_at"; - var records_per_page = req.params.records_per_page; - var offset = req.params.offset; - var customers = customer.sort_by(sort_type, records_per_page, offset, function(customers) { - return res.status(200).json(customers); - }); + sortInfo(sort_type, req.params, res); }, name_sort: function name_sort(req, res) { var sort_type = "name"; - var records_per_page = req.params.records_per_page; - var offset = req.params.offset; - var customers = customer.sort_by(sort_type, records_per_page, offset, function(customers) { - return res.status(200).json(customers); - }); + sortInfo(sort_type, req.params, res); }, postal_code_sort: function postal_code_sort(req, res) { var sort_type = "postal_code"; - var records_per_page = req.params.records_per_page; - var offset = req.params.offset; - var customers = customer.sort_by(sort_type, records_per_page, offset, function(customers) { - return res.status(200).json(customers); - }); + sortInfo(sort_type, req.params, res); } } diff --git a/npm-debug.log b/npm-debug.log new file mode 100644 index 0000000..9ee0fe0 --- /dev/null +++ b/npm-debug.log @@ -0,0 +1,36 @@ +0 info it worked if it ends with ok +1 verbose cli [ 'node', '/usr/local/bin/npm', 'start' ] +2 info using npm@2.7.5 +3 info using node@v0.12.2 +4 verbose node symlink /usr/local/bin/node +5 verbose run-script [ 'prestart', 'start', 'poststart' ] +6 info prestart C3Projects--VideoStoreAPI@0.0.0 +7 info start C3Projects--VideoStoreAPI@0.0.0 +8 verbose unsafe-perm in lifecycle true +9 info C3Projects--VideoStoreAPI@0.0.0 Failed to exec start script +10 verbose stack Error: C3Projects--VideoStoreAPI@0.0.0 start: `node ./bin/www` +10 verbose stack Exit status 1 +10 verbose stack at EventEmitter. (/usr/local/lib/node_modules/npm/lib/utils/lifecycle.js:213:16) +10 verbose stack at EventEmitter.emit (events.js:110:17) +10 verbose stack at ChildProcess. (/usr/local/lib/node_modules/npm/lib/utils/spawn.js:14:12) +10 verbose stack at ChildProcess.emit (events.js:110:17) +10 verbose stack at maybeClose (child_process.js:1015:16) +10 verbose stack at Process.ChildProcess._handle.onexit (child_process.js:1087:5) +11 verbose pkgid C3Projects--VideoStoreAPI@0.0.0 +12 verbose cwd /Users/corinnepingul/ada/projects/project-forks/C3Projects--VideoStoreAPI +13 error Darwin 14.5.0 +14 error argv "node" "/usr/local/bin/npm" "start" +15 error node v0.12.2 +16 error npm v2.7.5 +17 error code ELIFECYCLE +18 error C3Projects--VideoStoreAPI@0.0.0 start: `node ./bin/www` +18 error Exit status 1 +19 error Failed at the C3Projects--VideoStoreAPI@0.0.0 start script 'node ./bin/www'. +19 error This is most likely a problem with the C3Projects--VideoStoreAPI package, +19 error not with npm itself. +19 error Tell the author that this fails on your system: +19 error node ./bin/www +19 error You can get their info via: +19 error npm owner ls C3Projects--VideoStoreAPI +19 error There is likely additional logging output above. +20 verbose exit [ 1, true ] From caeb81fa9fa1505288a83b7d6b6a50ec5607c00d Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Mon, 21 Sep 2015 10:01:34 -0700 Subject: [PATCH 29/93] Refactor: Changes name of function to SortCustomers. --- controllers/customers.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/controllers/customers.js b/controllers/customers.js index ecd4c0a..431b6ac 100644 --- a/controllers/customers.js +++ b/controllers/customers.js @@ -3,7 +3,7 @@ var Customer = require('../customers'); var customer = new Customer(); -var sortInfo = function(sort_type, params, res) { +var sortCustomers = function(sort_type, params, res) { var records_per_page = params.records_per_page; var offset = params.offset; var customers = customer.sort_by(sort_type, records_per_page, offset, function(customers) { @@ -21,16 +21,16 @@ exports.customersController = { registered_at_sort: function registered_at_sort(req, res) { var sort_type = "registered_at"; - sortInfo(sort_type, req.params, res); + sortCustomers(sort_type, req.params, res); }, name_sort: function name_sort(req, res) { var sort_type = "name"; - sortInfo(sort_type, req.params, res); + sortCustomers(sort_type, req.params, res); }, postal_code_sort: function postal_code_sort(req, res) { var sort_type = "postal_code"; - sortInfo(sort_type, req.params, res); + sortCustomers(sort_type, req.params, res); } } From aecac72d5c49bc27edb47c958e61726913af625a Mon Sep 17 00:00:00 2001 From: Brenna Date: Mon, 21 Sep 2015 10:01:37 -0700 Subject: [PATCH 30/93] renamed sortInfo to sortMovies to be more explicit --- controllers/movies.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/controllers/movies.js b/controllers/movies.js index ccd1b58..e14d578 100644 --- a/controllers/movies.js +++ b/controllers/movies.js @@ -3,7 +3,7 @@ var Movie = require('../movies'); var movie = new Movie(); -var sortInfo = function (sort_type, params, res) { +var sortMovies = function (sort_type, params, res) { var records_per_page = params.records_per_page; var offset = params.offset; var movies = movie.sort_by(sort_type, records_per_page, offset, function(movies){ @@ -21,12 +21,12 @@ exports.moviesController = { release_date_sort: function release_date_sort(req, res) { var sort_type = "release_date"; - sortInfo(sort_type, req.params, res); + sortMovies(sort_type, req.params, res); }, title_sort: function title_sort(req, res) { var sort_type = "title"; - sortInfo(sort_type, req.params, res); + sortMovies(sort_type, req.params, res); } } From 27b874a5b42720911e5d1e06118febf16f023ab3 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Mon, 21 Sep 2015 10:49:24 -0700 Subject: [PATCH 31/93] Search movie by title functionality. --- controllers/movies.js | 9 ++++++++- database.js | 9 +++++++-- npm-debug.log | 41 ----------------------------------------- routes/movies.js | 5 ++++- 4 files changed, 19 insertions(+), 45 deletions(-) delete mode 100644 npm-debug.log diff --git a/controllers/movies.js b/controllers/movies.js index e14d578..1c01e6d 100644 --- a/controllers/movies.js +++ b/controllers/movies.js @@ -27,6 +27,13 @@ exports.moviesController = { title_sort: function title_sort(req, res) { var sort_type = "title"; sortMovies(sort_type, req.params, res); - } + }, + + movie_info: function movie_info(req, res) { + var title = req.params.title; + movie.movie_info(title, function(movie_info) { + return res.status(200).json(movie_info); + }); + } } diff --git a/database.js b/database.js index 786a99c..0174829 100644 --- a/database.js +++ b/database.js @@ -19,7 +19,6 @@ module.exports = { }, all: function(callback) { - this.query("SELECT * FROM " + this.table_name + ";", function(res) { callback(res); }); @@ -29,7 +28,13 @@ module.exports = { this.query("SELECT * FROM " + this.table_name + " ORDER BY " + sort_type + " LIMIT " + records_per_page + " OFFSET " + offset + ";", function(res) { callback(res); }); - } + }, + + movie_info: function(movie_title, callback) { + this.query("SELECT * FROM " + this.table_name + " WHERE title LIKE '%" + movie_title + "%';", function(res) { + callback(res); + }); + } } diff --git a/npm-debug.log b/npm-debug.log deleted file mode 100644 index ecc3d5d..0000000 --- a/npm-debug.log +++ /dev/null @@ -1,41 +0,0 @@ -0 info it worked if it ends with ok -1 verbose cli [ 'node', '/usr/local/bin/npm', 'start' ] -2 info using npm@2.7.5 -3 info using node@v0.12.2 -4 verbose node symlink /usr/local/bin/node -5 verbose run-script [ 'prestart', 'start', 'poststart' ] -6 info prestart C3Projects--VideoStoreAPI@0.0.0 -7 info start C3Projects--VideoStoreAPI@0.0.0 -8 verbose unsafe-perm in lifecycle true -9 info C3Projects--VideoStoreAPI@0.0.0 Failed to exec start script -10 verbose stack Error: C3Projects--VideoStoreAPI@0.0.0 start: `node ./bin/www` -10 verbose stack Exit status 1 -10 verbose stack at EventEmitter. (/usr/local/lib/node_modules/npm/lib/utils/lifecycle.js:213:16) -10 verbose stack at EventEmitter.emit (events.js:110:17) -10 verbose stack at ChildProcess. (/usr/local/lib/node_modules/npm/lib/utils/spawn.js:14:12) -10 verbose stack at ChildProcess.emit (events.js:110:17) -10 verbose stack at maybeClose (child_process.js:1015:16) -10 verbose stack at Process.ChildProcess._handle.onexit (child_process.js:1087:5) -11 verbose pkgid C3Projects--VideoStoreAPI@0.0.0 -<<<<<<< HEAD -12 verbose cwd /Users/corinnepingul/ada/projects/project-forks/C3Projects--VideoStoreAPI -13 error Darwin 14.5.0 -======= -12 verbose cwd /Users/brennaleker/Documents/Projects/project-forks/C3Projects--VideoStoreAPI -13 error Darwin 14.3.0 ->>>>>>> movie-sorts -14 error argv "node" "/usr/local/bin/npm" "start" -15 error node v0.12.2 -16 error npm v2.7.5 -17 error code ELIFECYCLE -18 error C3Projects--VideoStoreAPI@0.0.0 start: `node ./bin/www` -18 error Exit status 1 -19 error Failed at the C3Projects--VideoStoreAPI@0.0.0 start script 'node ./bin/www'. -19 error This is most likely a problem with the C3Projects--VideoStoreAPI package, -19 error not with npm itself. -19 error Tell the author that this fails on your system: -19 error node ./bin/www -19 error You can get their info via: -19 error npm owner ls C3Projects--VideoStoreAPI -19 error There is likely additional logging output above. -20 verbose exit [ 1, true ] diff --git a/routes/movies.js b/routes/movies.js index a8b6778..b8ec792 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -6,7 +6,6 @@ router.get('/', function(req, res, next) { return movie_exports.moviesController.all(req, res); }); - router.get('/release_date_sort/:records_per_page/:offset', function(req, res, next){ return movie_exports.moviesController.release_date_sort(req, res); }); @@ -15,4 +14,8 @@ router.get('/title_sort/:records_per_page/:offset', function(req, res, next){ return movie_exports.moviesController.title_sort(req, res); }); +router.get('/:title', function(req, res, next) { + return movie_exports.moviesController.movie_info(req, res); +}); + module.exports = router; From a851f9dcfa9663263f0d5e4f59a697cf4eefa249 Mon Sep 17 00:00:00 2001 From: Brenna Date: Mon, 21 Sep 2015 11:11:14 -0700 Subject: [PATCH 32/93] changed rental table to include movie title instead of id and updated seeds --- utils/rentals.json | 16 ++++++++-------- utils/schema.js | 13 +++++++------ 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/utils/rentals.json b/utils/rentals.json index 8d4024f..4aa4ee0 100644 --- a/utils/rentals.json +++ b/utils/rentals.json @@ -6,7 +6,7 @@ "due_date": "2015-06-19", "overdue": 0, "customer_id": 1, - "movie_id": 12 + "movie_title": "Jaws" }, { "check_out": "2015-04-27", @@ -14,7 +14,7 @@ "due_date": "2015-04-30", "overdue": 1, "customer_id": 7, - "movie_id": 24 + "movie_title": "Alien" }, { "check_out": "2015-05-14", @@ -22,7 +22,7 @@ "due_date": "2015-04-17", "overdue": 0, "customer_id": 12, - "movie_id": 37 + "movie_title": "Psycho" }, { "check_out": "2015-06-03", @@ -30,7 +30,7 @@ "due_date": "2015-06-06", "overdue": 1, "customer_id": 3, - "movie_id": 18 + "movie_title": "The Birds" }, { "check_out": "2015-07-03", @@ -38,14 +38,14 @@ "due_date": "2015-07-06", "overdue": 0, "customer_id": 8, - "movie_id": 26 + "movie_title": "The Godfather" }, { "check_out": "2015-07-03", - "check_in": "2015-07-06", + "check_in": null, "due_date": "2015-07-06", - "overdue": 0, + "overdue": 1, "customer_id": 8, - "movie_id": 85 + "movie_title": "King Kong" } ] diff --git a/utils/schema.js b/utils/schema.js index 6519782..78eb8cb 100644 --- a/utils/schema.js +++ b/utils/schema.js @@ -27,7 +27,9 @@ var rental_fields = [ ['check_out', 'text'], ['check_in', 'text'], ['due_date', 'text'], - ['overdue', 'integer', 'DEFAULT 0'] // 0 for false 1 for true + ['overdue', 'integer', 'DEFAULT 0'], // 0 for false 1 for true + ['movie_title', 'string'], + ['customer_id', 'integer'] ] // I want these to work somewhat how rake db:reset works, so I need to do three things: @@ -42,11 +44,10 @@ db.serialize(function() { // 2. create fresh versions of those tables db.run("CREATE TABLE movies (id INTEGER PRIMARY KEY);"); db.run("CREATE TABLE customers (id INTEGER PRIMARY KEY);"); - db.run("CREATE TABLE rentals (id INTEGER PRIMARY KEY, \ - customer_id INTEGER, \ - movie_id INTEGER, \ - FOREIGN KEY (customer_id) REFERENCES customer(id), \ - FOREIGN KEY (movie_id) REFERENCES movie(id));"); + db.run("CREATE TABLE rentals (id INTEGER PRIMARY KEY);"); + // FOREIGN KEY (customer_id) REFERENCES customer(id), \ + // FOREIGN KEY (movie_id) REFERENCES movie(id));"); + // 3. add the columns to those tables // CREATE MOVIES TABLE COLUMNS From ac894c1d8edc2edf0b3fe891771557cf3ad54662 Mon Sep 17 00:00:00 2001 From: Brenna Date: Mon, 21 Sep 2015 11:15:35 -0700 Subject: [PATCH 33/93] fixed db seed issues for rentals --- db/development.db | Bin 144384 -> 144384 bytes utils/seed.js | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/db/development.db b/db/development.db index 09be93aa70e47d1125b76ae1c4023374ad8858e7..3a0f327dfdb20baaa65a1883c7d54b45c90cf3e6 100644 GIT binary patch delta 1381 zcmX|z^U1mA{Lb(E z`(^j^?4JHrYkiZZD9R(?08@%0e%%fZy3rf@^PO7RsYtP_sJF$gJevy`kG9KCo|JD2 zN5Jb9i@DF$mKtkJRyE^qeHy=Kauf1GWI6F!+?-Fx(@Um5l}^T27K8qUo2hhS*-XyI zqyG3x+FUe~{k-Bac>-1}+n^qq*;qh3G!G44f!uS@-A|ygkD=a=ppFlr;6-S18tOX_ zJv;~9nSi{fq5e~lc@o+hgQBBQ(+D&afi4a}!(k}POP@OqHTFX-y}aiAZYbFaJqSQu z?a+}{=tc{)?t#Kh&{_l3=7O4!Kz;+dS`B&lLQfE+Nj_nN{03HfY(w9cnOTdsdEDZS zxh&pA#5xMsS#9vRRSz#)I^6mNw3>uAW6-^;Q2Q*Dxd3(Y887j9e7yI|9Z;*<)8)WcL6#H_*az;Gx$5(*C;w%$E#jqt29@nke5L-HV9i^zTH^wrIz z))rz3Bd8waX%@MkoxW42m*VD1)iH4p+F1R6qJfda)?xC2_ol9|rrw@~uc6yETwNl= zZ`K3&diXv0S@>@1z&Kb2{D!N*0vlixguo!+i@OKz0)ClZz&9EMTmX}x4?F~SKn8dL zU%kn{TWCZ9*9}+45a1de23c?kaFI3wuA}>apVkK+fG)sgbOWq|%Ychx4RB#J1D?Zg z>jzv6T#9^fQtVLu@9jnHxhTmzeMfm3r2?e|*%VeOuTAKA?Ijg8T`ftQx>YJ@F9rJh z$ksmKDNC606pUjUVVGm`w1N32k;IWLBPN2LzrhxIuc?^1Q<6n81PA=X0XrDvwXbjz z0nG|3(qqA~PfM~uyI7N+VIaZ{Kl0p0!|^o|yed0wdcmpo$_)kbtMokySDyYwG`b7q z5uQBVs?0@W3ym30vWdo=&}~YqIA2thkmfPs9k+zrc8r#>!#)+;aO{Y(H&1g2|4|qP zdd-t}@%KWwiu6b25c_6o>D9_ssLDPaSmNj1j(%>zQ-z zJ@?#~+cI)n#%fzr=)MqQ1q8rxA>`^>-#`e_#Gkcw+MH0r7xHJ}YmeQ==*pV^gZr8G zr0PUVBqFcb?wI#mnHj|0(-208<%0X{b zmV;at=Zn9s_QPVAXHt*K4qwFj?0G2nDRgiG8ao3WI1TMiL3_uc%owyh3QZk@;=@p6 z2+Dp4UH<^OdjyIdhU`O7`+HDd658`F)Y}go=A&=ygKoy5P%oc3&VJq zEr6$S73>21x;&|~AO{YDNx&b$0l?3}50(LoU>QsS9!vzxfh@QV?(#B*g$?-O_T!*qcg;3nXi4uAx>18#vO;DF13KaCDB3kE?W;Ai0)emwp{_!CP5zIaG@iKgG% z^ZFop`cg^d=@1p^7pYM}e<~@j4;h|*p`;#=MtQnN1=>KAz9WxTH7e>aB-cDcC>fcE9^kba4#j9jV6=^|ok>#rb4OI%JQ61$5 zHc@rI+*}x0`UIDr;L@k1h5|k0{H;)do=JK@GRT)H(AN?Q%P_X!RZ@oY6vN^aXK!FJ zAq^zp#+2cjBRJ!Vlp!zh(8u=wN-74{r5`EMbF@|r{3!j}0=?wwe$@OVg9X~;opEZB zeksnV Date: Mon, 21 Sep 2015 11:19:38 -0700 Subject: [PATCH 34/93] Formats rental date seeds. --- db/development.db | Bin 144384 -> 144384 bytes utils/seed.js | 10 +++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/db/development.db b/db/development.db index 3a0f327dfdb20baaa65a1883c7d54b45c90cf3e6..fb92f284e11d9ba0ea0626c2b5ac50d3f5fb1a23 100644 GIT binary patch delta 1339 zcmY+DOK1~O6o%){Ju^-_p*Dha$y=?Lk6@+S@fi1I z#%J>~Puje&pv|lB+8bcM?T4?~b+Bn0@XZ_0<#Fgv8frWVtxiB|_ChVZ$1dK_F<$$0 z3$&^MTDH6z)}>J7SNTfL$`i5+jmqy$llnu=Y|;%S5C~MYh_GqJ%pNmhZRs&h%d{%( z_~6Ls`QYH#=y{`CE5#b2f3bgK{yr1wRB-oL^4ys#>D0KfiT=wSHzTFExY<*A#uFI~ z*f}zuoRA?|PTo{b967(8RT~=`qg+wVc&k4vdD&*92hZoTo_4> zE^8CzgpF0@*(!?f|}@S-{272)GinAO^TdBY?{#3Fbfw@P(}bx4>P{f#OmI@X`tRB13=+L4@>GQ@(ak}b02VCkG zf}Ut9Ia+T~=BU%iQ9t-d3*^IBx&-MT3h0_cYrjC?1wpRlcrfOeEKcJS1_7?R*T^B|4J3vMjpm%gG;r%DlK1>3-mzvb2N;O*TUn{7opOEp5`>~MWJSaz6l)B61u4J3W7gD(T>C&OS#kSsId484W!>Q!xF`A2FN&W!|XYd99 delta 1359 zcmZvbO-vI(6vuaV-Y$!&TKOy>(h69Vu4zjtXp8|Pej&yv8cd8rXr&|y3MNRRY1g2l zVj_trBnl1fa%xXk9IIsRp|4gThtNbUC!q3stX!{2u5`DdgjGZYM~WeAIIJ5LTKU zk1;RP{T7$mYH?v+i>ruPTi^}WM!3r=gD+SHTzd_gnt*0g(5*92eLs{w2yNywp5*gv z;@VF&Kx-?Yk~M2#UHz`eMfprl$sV~L55=ET6Z@d1x9ElvPy(e5A{vggo8b;K+_oCU zdq>Ac{JrC2BSuWayg58xe${IB_-b}U9axpdmI&j# zY|rRKVp5v2uu)BMqjobAE2KvhFGMjj(s6WhdN?)i38{r0s*BTOW|Z?HEv85RPHzi$ zpC3(*m24A*-zXa;=s+$;Ra`QA5x zE^q;Ge@p=j%z#;7f+*mRatqu9{MCbizg7rvbM=50a2MPFX;26FvnKg*4nYENPjctA z0q*~HkO3zF{{boi_vmfFZL(FmOuC|ab$0vl()qWx7 z6n>jtAlHB}vgA_{C4|?e5P~bB!lq7C@rbKVQKX|?T#--ncQlL9$H-B^r5{DvO)4U7*>JQazKjDH`Yo2_ANFYW Aga7~l diff --git a/utils/seed.js b/utils/seed.js index 291cdc1..42dcfbc 100644 --- a/utils/seed.js +++ b/utils/seed.js @@ -81,11 +81,15 @@ db.serialize(function() { for(var k = 0; k < rentals.length; k++) { var rental = rentals[k]; + var formattedCheckOutDate = formatDate(rental.check_out); + var formattedCheckInDate = formatDate(rental.check_in); + var formattedDueDate = formatDate(rental.due_date); + // insert each rental into the db rental_statement.run( - rental.check_out, - rental.check_in, - rental.due_date, + formattedCheckOutDate, + formattedCheckInDate, + formattedDueDate, rental.overdue, rental.customer_id, rental.movie_title From 42ba3138c17405c0a542faed723dc37d9ca749a1 Mon Sep 17 00:00:00 2001 From: Brenna Date: Mon, 21 Sep 2015 11:41:43 -0700 Subject: [PATCH 35/93] WIP - current_Rentals --- controllers/customers.js | 8 ++++++++ routes/customers.js | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/controllers/customers.js b/controllers/customers.js index 431b6ac..d93ffe6 100644 --- a/controllers/customers.js +++ b/controllers/customers.js @@ -32,5 +32,13 @@ exports.customersController = { postal_code_sort: function postal_code_sort(req, res) { var sort_type = "postal_code"; sortCustomers(sort_type, req.params, res); + }, + + current_rentals: funcion current_rentals(req, res) { + var id = req.params.id; + + customer.current_rentals(id, function(current_rentals) { + return res.status(200).json(current_rentals); + }); } } diff --git a/routes/customers.js b/routes/customers.js index e08baf3..6b2060b 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -18,4 +18,8 @@ router.get('/postal_code_sort/:records_per_page/:offset', function(req, res, nex return customer_exports.customersController.postal_code_sort(req, res); }) +router.get('/:id/current_rentals', function(req, res, next){ + return customer_exports.customersController.current_rentals(req, res); +}) + module.exports = router; From a8059cc17122ae1b15052dc8b9589a41e3b4330e Mon Sep 17 00:00:00 2001 From: Brenna Date: Mon, 21 Sep 2015 13:26:11 -0700 Subject: [PATCH 36/93] WIP - current_rentals --- controllers/customers.js | 4 ++-- database.js | 11 ++++++++++- db/database.db | 0 db/development.db | Bin 144384 -> 144384 bytes utils/rentals.json | 2 +- 5 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 db/database.db diff --git a/controllers/customers.js b/controllers/customers.js index d93ffe6..0d71510 100644 --- a/controllers/customers.js +++ b/controllers/customers.js @@ -34,9 +34,9 @@ exports.customersController = { sortCustomers(sort_type, req.params, res); }, - current_rentals: funcion current_rentals(req, res) { + current_rentals: function current_rentals(req, res) { var id = req.params.id; - + customer.current_rentals(id, function(current_rentals) { return res.status(200).json(current_rentals); }); diff --git a/database.js b/database.js index 0174829..44058df 100644 --- a/database.js +++ b/database.js @@ -6,7 +6,6 @@ var db_env = process.env.DB || 'development'; module.exports = { query: function(statement, callback) { var db = new sqlite3.Database('db/' + db_env + '.db'); - db.serialize(function() { // below: this is the callback pattern...parameters(ERRORS, RESULT) db.all(statement, function(err, res) { @@ -34,8 +33,18 @@ module.exports = { this.query("SELECT * FROM " + this.table_name + " WHERE title LIKE '%" + movie_title + "%';", function(res) { callback(res); }); + }, + + current_rentals: function(id, callback) { + // list of current rentals out based on customer id + this.query("SELECT * FROM rentals WHERE customer_id=" + id + " AND check_in IS null;", function(res) { + callback(res); + }); } +// Get a list of customers that have currently checked out a copy of the film + // rentals = select * from rentals where movie_title = title and check_in = null + } // We want to export the Database into the overall node structure diff --git a/db/database.db b/db/database.db new file mode 100644 index 0000000..e69de29 diff --git a/db/development.db b/db/development.db index 3a0f327dfdb20baaa65a1883c7d54b45c90cf3e6..d77f9a9bc374e73e9aa3e80d1a204d4cdb864d26 100644 GIT binary patch delta 1045 zcmW-eO-NKx6oBWxcW0bvw5N_b>S*RqDvmPg7$Ok{D)wVUnJAPAjWCOZlt6`I=86AK zpx`3HMequPTokXEt&0{eTC@mi(b9#RAfknY%=8@>-^ab@o_Fs#=cNw)sYCxpMNw$m zVYMXPP7t_2k|qqatQbFLm0)}qmK zsI>~6tw5FKs5FGuO3_p?nzvB20F?z$%_%hILqi(*Olh^)e2G2vZot23-fyv`Ov{$S zVzyK*b%{E#^)gk>0oR*>#0K?Yv}YcK`#ATyM2 zWPW8(12QXVyv^gb7JaYE=!8<*_1;q2@pWm}_cm+p=w5cZ*YD^TdPk2d^jjiNAq`)l zhv1$BqY!5kHdw?U0xA7T8-~vKf+}k|dPBSVhCH*CWA~VZLr4&PZSZDVa*l|sz&O!_ zL`NjL$L>IOUD-TW*UKH>a%UX9D|ZAP{aL@!%5wBJ6-1@bkP10^fkjLfVHUKO(Seg{ zMpQPBe1dUhxw=UzoK?AE*E=AEZE>)r!jAsJ;-d=e=%121Bp2)}!*YGcGM$s)D>*q( z!HoWKGQfS3d?7<>enidks5h)~q#wzYX5k6fyeB#1-Q^&|*Ydt)GD6u{@3c{^;h+2(HBYO9uiazl+xw}^-^$mkD7)D{Z;gEsI`P!Xty*qu-_ zH7M{9(IMDmf;tpqOot8<9XxdCAQhcGc&JOK2yy#855M1h^Ub{Xz4yNIO0>KZeOzCg zaxKex1Q9rCS?1G|&Tc#9zPtL`FH@uO(_5w!a-x_$`F97M$fD77E;r0fcHu2v2KRck_@)=d_4m;59W*(F9$ZEZ1ynkLnzhFZ+E1g_KG=jd1^+hw zv5gh{u4y!;HHgJqOi9~m1C7*HwPFq10=;k(w7p^QU<@Xq3%Vf*4`2ec=yuSkNw`=ty;NJ)qaO56W->^!~Pjj`$&H*Nrd*Eua&=4fkOXbZ(=d zGus9lvk7*9&Pi`c8y73+s{P(jksDHx5m<~?q{#DVG?2$ef=J#-#cdVe{i=(s1n&Hr zQ;}N|$Ol_Ocgg7MQ}HEjqo|Qkz8H-xR~=t+M9EvY2s1FtPcg$Ovt)Q_lkbowSmslX z&{sycUaS$itf33A%Kj?*q5GD@Lix3xeyO@Skk9(}%38vgA4cZH#4GZKh)FHSqMH3I@qxmM`&k@s+2qFinR8!{5tjUCuvFRr=Z>k$BGDPBD zN?9~^Jaqq>suM;QurCXma@iz(iR%pB(7lXlWd&_5PfTIG{H(1p8Di$dCfi+peqrRj PtT*&rPd-lQ(5mwv2r9hX diff --git a/utils/rentals.json b/utils/rentals.json index 4aa4ee0..b78a009 100644 --- a/utils/rentals.json +++ b/utils/rentals.json @@ -42,7 +42,7 @@ }, { "check_out": "2015-07-03", - "check_in": null, + "check_in": "", "due_date": "2015-07-06", "overdue": 1, "customer_id": 8, From bdea364738be182440e980944a2ed2507e482ac7 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Mon, 21 Sep 2015 13:26:49 -0700 Subject: [PATCH 37/93] WIP --- controllers/movies.js | 12 ++++++++++-- database.js | 14 +++++++++++--- db/development.db | Bin 144384 -> 144384 bytes routes/movies.js | 4 ++++ utils/rentals.json | 2 +- 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/controllers/movies.js b/controllers/movies.js index 1c01e6d..fa8f3a4 100644 --- a/controllers/movies.js +++ b/controllers/movies.js @@ -30,10 +30,18 @@ exports.moviesController = { }, movie_info: function movie_info(req, res) { - var title = req.params.title; + var movie_title = req.params.title; - movie.movie_info(title, function(movie_info) { + movie.movie_info(movie_title, function(movie_info) { return res.status(200).json(movie_info); }); + }, + + current_customers: function current_customers(req, res) { + var movie_title = req.params.title; + + movie.current_customers(movie_title, function(current_customers) { + return res.status(200).json(current_customers); + }) } } diff --git a/database.js b/database.js index 0174829..cb991a8 100644 --- a/database.js +++ b/database.js @@ -10,6 +10,8 @@ module.exports = { db.serialize(function() { // below: this is the callback pattern...parameters(ERRORS, RESULT) db.all(statement, function(err, res) { + console.log(statement); + console.log(err); // error handling looks like -> if (err) { }; if (callback) { callback(res); } }); @@ -25,17 +27,23 @@ module.exports = { }, sort_by: function(sort_type, records_per_page, offset, callback) { - this.query("SELECT * FROM " + this.table_name + " ORDER BY " + sort_type + " LIMIT " + records_per_page + " OFFSET " + offset + ";", function(res) { + this.query("SELECT * FROM " + this.table_name + " ORDER BY " + sort_type + " LIMIT " + records_per_page + " OFFSET " + offset + ";", function(res) { callback(res); - }); + }); }, movie_info: function(movie_title, callback) { this.query("SELECT * FROM " + this.table_name + " WHERE title LIKE '%" + movie_title + "%';", function(res) { callback(res); }); - } + }, + current_customers: function(movie_title, callback) { + // we want customers who currently have a rental with this movie title + this.query("SELECT customers.name FROM customers, rentals WHERE customers.id=rentals.customer_id AND rentals.movie_title LIKE '%" + movie_title + "%' AND rentals.check_in IS NULL;", function(res) { + callback(res); + }); + } } // We want to export the Database into the overall node structure diff --git a/db/development.db b/db/development.db index fb92f284e11d9ba0ea0626c2b5ac50d3f5fb1a23..d8282677e817c5c0b28c965d3506d6d8c2831d70 100644 GIT binary patch delta 1085 zcmXYuPi#z46o=n^_ssJugK0Z-I_+q+Qzcp%V~U7S3F1#kLp7BYO;pl_CWr(HnR!yQ z{v?EzmE@6G*x-?|u&}V`!a~GC#KOX2HWCYqMx^6A6O(-3ygPI5JHLBwsp^-i{=IZl zI^#IbU5LSc$8mSu@5{UC%!~17)^tR1>9NKBQ~cL>5?vlc>qpV~qiFUBYCVkh973go zXyXAiu@~LhgHG>4w|Am7+tKcAsBbIUx&NZ$LdcG`Jp(tV3OEQMOlmUd*EQ zE_8Dh>ekc)X|%Q#^`_9u6{y&ZG6^)Z6ivlZp#dd4loI4wJ!-Rkgq`6i?%%h?6M@F; z3^Z6vpeb^}YJ4qd$LE43d@JzrimRyYJUTXsmYzTdhtc(Y=!TwgiJoV=%|*%P3VRJ&?)pn04t#gdUrFRd-MvYKu4yxrl-{RS;vX; zO`kHMJeN?0V2ebu#+8aUX%=iGyNn;jvNcc4j(BU)Y5m9hLV$td^ScZ zu^*eKB{YBq{}t}WBdp;VKhyqDKvOd^bx2;mc=EGd%;Wtb!deR##g5D8_j9%a<{ z6))>9*osUTHxYVc9OjZ)XpZDJ!DHWe%|lab3*`fQUKuxD@xF7`vLtmFbF`AbJbckr zLG{BV>&sB)Sfz+5XN_?dHr=M9n;(TaU-ef@AKx5{RcFt Bz=Hq) delta 1130 zcmXYvO-LI-6vuaV-mbAkjT%jiiKZH>RwJ7jtCdnLsMrsSw5cexR%iq-LKQ&^Ey+s! zwxH;t^i+stgk8P(1dKV-Gz_(*Fw${C?TlnR)Zxn@!~$shnfiSLIn( z6y+_@z&%A#%l0~>s%QQ4^d~9GZ6~$JWb+HmEj))dpF(vL(C`x|^%&}T1dTp~x<{eJ zeQ0L{ni+=L2cgwF(DrSp?G`lD4|VoItv8_l7_=6F+y)fwg3=w3*$%a|@|go6sH_QU zxC)I2pe7%btb+nxXrmTds)l?nXs#TJIU!dm)S*Kmf^^BHR?GLW(q%gxdot-YIn61P z6APN0g~z-G`%ORm%B+G7(*du%f#w&Wty!pM3aX7m^>?90t})E@Omgn)jZmcryE4m;53(2TY&T41l+V5z&DfvJ%BH-8*m#FUpb=>3wMUj zkwOk@4}{<16tnbIs7_m-<;AnbfafA#VbKNGT@(_v=(lj&oQb7*Iqx*r6-TTzBE*YX fpK=5zx_6?hdCV?iSB$q#b6N*n&fmO5kW2XwCSA$U diff --git a/routes/movies.js b/routes/movies.js index b8ec792..31ac70d 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -18,4 +18,8 @@ router.get('/:title', function(req, res, next) { return movie_exports.moviesController.movie_info(req, res); }); +router.get('/:title/current_customers', function(req, res, next) { + return movie_exports.moviesController.current_customers(req, res); +}) + module.exports = router; diff --git a/utils/rentals.json b/utils/rentals.json index 4aa4ee0..b78a009 100644 --- a/utils/rentals.json +++ b/utils/rentals.json @@ -42,7 +42,7 @@ }, { "check_out": "2015-07-03", - "check_in": null, + "check_in": "", "due_date": "2015-07-06", "overdue": 1, "customer_id": 8, From 5addacd6aaa7509b843284f6475f970a6663e373 Mon Sep 17 00:00:00 2001 From: Brenna Date: Mon, 21 Sep 2015 13:34:24 -0700 Subject: [PATCH 38/93] current_rentals is now functioning --- db/{database.db => development} | 0 db/development.db | Bin 0 -> 68608 bytes 2 files changed, 0 insertions(+), 0 deletions(-) rename db/{database.db => development} (100%) create mode 100644 db/development.db diff --git a/db/database.db b/db/development similarity index 100% rename from db/database.db rename to db/development diff --git a/db/development.db b/db/development.db new file mode 100644 index 0000000000000000000000000000000000000000..259f8bd93061be3acf89498ce4a281ebc4e54d6b GIT binary patch literal 68608 zcmeFa4Rl=TdEYmK;qHQzw5yf0TCG;p-sNgVP>aFN_s6cNogn~{AOR2rKw>Ga#J!lg zz|3MW7n%=(prTkHmn++{Y=L*Kv2w_GFr8*h1A>O>-y{E5WapGy8j z>hKlcmh})%uzFS#R`f zZ=&7w<`!3H&&@7-OUrW$_2p~c#o23f!fyP%-)Mxx?%;ZZYqtm9Mkn+K zr}m#oKJ@q#Pb6@J7(%I=iDs>I8m2xZXS% zX}fzP=nlf(-oX=&es$fy;kP@Q+4zsASc|8hd@{LdW9;!sztfNYIbx&Se)K8~=BJ~$jKa%=^)c2*nH}xN;zBBc$sXM7Zo!UzcQeo<~RFHZ#^|92| z)aBHC>Rjqf>U64-%DW5e;$QLWc0V11-X6?n5Z!(Iac%;wU2f!|Aqou;=O zZ2Dbq!EY=E?T)vOfOZkY5SjFM1|EM3Ztis2$fVb0&3D)dVb||SME$;^&C z>o?j#w-Ipbrq>_phD>rh>@uUC?=^!yzmlx2Gs%pz@81YKU99O3H(Ts2wiBNmb_Q(} zZqQ*X4SVj9^sbKIA9$^BCwRd->)Rk^{B3UNUG#fBzt4xgK`$I4pG|M4$95TbyRFb` z+p`WgH#;n}x7!}HycWOXfxHc$pQf_aaz4$x=1LDew0~i2Jn`7=PcrKl{M~+CL+|^8 zwn_aaQ=)6iDD+!?Zwtxm^}=5JmL`Ik(=73f;SO7bsjF{muIKt4o@&xtk)X3 zRy)|x!+K#O@Vnt=&)?A#>gj!NlMCL`L%4gi&<*^p9|YVl)GYFpObwS??}TA<&}uW! zdn^L;qlYP`Go^I4`rw1NPbbF{PrSau!z}gp8m(}x#cXx_UL)v+!#*mFb>?zfl13-s zc^3ShmTMZ(2)xaZ$Kog5spD_Esq?*Ezp007`2Cg*SS!N&Hjv^DlKH*=y1wH*Q_hvs)l#PHEwSZ;rY2zzFa6z6m!{AUN%=q7t6(b?ecq1@BGlO9DDibu|)bv@hM&Og5UV$ zFkn*z-V$QG$Av$y3+F18bUBx+cr)yh<>pkqi{$kD&7gj^_x{Fry>jiLV~J;uoO?n;UiM$}Tg<}dCYN3E zb=gWKo6c8r8AP`e^oOXvXf77zwRJCD%$KtH!bGuHDP1XMv)f zE%n;l+>*&y_0gvOTD_dl6|)o7T#=+3U7O&K9?{a3pVmA~`@OKU$3AT_ z(QMpge);>e`Fy%kMjqB`a=4D>3%e}ec@4VAa0!JEYxXvpVLy6yh@u(!EX=jlu3iF}Ub z%jeNO2u5u#Ys2=(B*x{FPixpi^mLaGW5b!?eOCkhrbzj(na}H7sKx6_|yZu=lJpQlVA3p z_`Py~&V|hl^WDZjbj02tU$Ycl6N_f=FJ(%4|Cx5L*-xFs71p(%aMvzo3-+F3wq*Yn zvSsJry!C^4Z@ls7tn{#i>XX+h1#)m$DW26f{cGTT0x=<+_-8@^B_ow}z zN_;vo_TMFcmw&##U-$k0`~JVh7=Kdye_-L>WWYUa+(J2>O zb$miA!ldoKhuhWL+MD#&0Sh+paKHGOAMpsIh?1iSrx`TbL{bW<2L2WiD+3L8gC6ly zDP!?dX?$G!Kbbt9;J^D{UpfPKUqyjuKbIu9WUUCQ*Y~t&gVrt)<$~XA<2*)QD1ZcD z46%TOg9XO9)Do`}R&-l!PzRO>32C*ralJQ?ksipMP#6{mdD#tnfE|RK{T+gO$w?Q~ zKyf|ZvsRBl9?|ga(u~4nOu*d;y#OKDA%2?j@P~u;CP2l`p0~uU+dJM>#VXs|E|le( zT)olKAm;U>GAIQrd2J6)H1M6D%9Z!9xHfIf2@iK=p%e-$tO(5G%74+?Y3d z46SJ+-X8Xvh#b?l8^_tbArI3Fx9uSuT3{b^+rs2^J+x7AwOod2p9a1eGQ@d?H{il< zV`xIATkVFw8Acn6_iqOQNRKb1U^r-R48e>#p`eLbaF~niQV<~R!;qnNc5FfH$#3|= zEx7<6W6gkcf<9mnljW9%Zv@nE^WjdPZRIruuIv#f_?te^PrPEFjRxnmPz1VVyWc(O zR6@Jk1qta65F%Ez%dBX&xS4Pv(;>S)w_FUlB=W)yL9oEJ+-}#-MZhLKZqSsBv0T7S zOf<+%1DFE@*nv`f=kM^XyXzp_k&G-1rWE$Iwh<2Yf3cb-w#}BE|38-aZ^7ny`4jea z=QKXs<8NGHdz#BLGZfCroC)^PYMJU|l39~M3;Z+O1}bl~L4^7{DAIn5y|D;xjWB|t z34&?_J0?DC?SWz5eYO(sH+f~gwHaAL?X-X?UDG}Vl56#XAiW)Iud}Fw033-aw@uLl zl;lGVA+-|AM$5N1H9~OYcGnhCx*mBDzT^dj{qa6=Hxc9qYVPwq0(wpMgsVq)un+iy zf#2BT`VJ0djoERldT{IkALH}85~yL<-^I+tpKWjNupu;tZW|fg)}Q)FG@^ywKvpH} z4jcm+)1%r3k$36s_`s0@2{lUX$!KVr{9%`^IpAheBuuYvz20UCf~K%LWDks@c;v{P zB>wd2yJgl-gI#HN3|WnyY@V6wpFJ~&a$=@}z?%lu6SBC14K|!ps4la@E|D6QZoJvv z9&V@mq(#`lf`Iorpc?#fr`-Tq$Q|E41a@VdS3AmuI^cCf3Z16kPQ3EjPr3axkq zafV@E`@fn^XL9LmA(e9e|8FJ6wvxY=_^m%-3gD|8?*3~>#}m)pc@lYBW*(6Dy_0g# z*7xe(9=_Hl8e%A1o8-wzs)UYj_}g;j7THDDLLg)x=^t#HE(iOH)iJ68B+3VI-)?vI zv;o;#$~q{EfCkYX3vA1y*y924=QyR&AA+klfd3JOVRzk<4vZ}_A$@-Xr4IJbu0)XA zpyg3^ql>w3@%FwPyNWq>xv{bRN5;n!<^5~X<~mF2sevU8yIt;qbk*6yT!amo z#}+Eh#1>fuJP$D{ObxrsA9ADNwlZSqEN66vn_hoA&NjRjuE(%>bQ6?YbQ5j&Y&wg# zSsow1^Nxqc6Hnd!)YC_gYP(z5EBlRHOD9X2EFk*bcHqtEwS#f2PJ6Sh;h_bYvp{J*K5-AmMq)@N7F&p-oz!k%pP~MS9XTx#Vw3^e z(UM>!aL{>X3#8PeB#oR2nIG>Aso6~*dEb+u6pK7zds?E5yhE zcX!f6bWzq%?~AU0=vZQzA+jp?@>(U|vjhYmJQ$@uqx}k?%`#+i$Bx~;{+98?$-76R z{W=1XR#|a(QG6C93i(;tQDQ~;(AjFCsK>&mE84R+TD`E_<{{i$H`=z_F+Fo6t`Vtp z9Ulm%8DyQ91OH#{L0bwcQd{QJkPl@G-eUBJ|HwAPCfWjBZFAGn71psa$XRqan zt0RZOHYr*bPaDcb%KFYUtrC|6Pm|sP=^kI9F)JOZpeS5bK&;u;1Mh~zPBXn8#5N5# z*eAy#15kb0lf$8acU;NCUb$gWra5LQ>S`4z&3pXG|5Q8X~cumn<%iqDF zGULop8CTE=a5Ll`Y0ms0?1Um%*af9zOgy4!Zc}@-Yet2cRel<2*RyvZVGylfVqFD6p|Nvb^dKaXvXJ(B$Kbs65P94cVsiZPF>5jNm zYXM9bWodt`oU4|-RU*I;xFSm0<310YP|lb0WNIM^6e`M~my5N<-`LRCD~}qd;rNqW`5g8M z|K+?Kwq$%q zV@!chyj|lir#0@YZFp{7?}Ea{2ATJjTjgpd%`<126c!#Z(&h!%#lq$DiW3I?g}GvZ z8%z{SN@W*_#!1N6R{syE6Q@7<$|K5>zvSdB6gY=}aJCJ?&C*`}$Hf8(_)LMcK9`60 zg!OX^e6bteyrI~3bupJGbu~e*i!64wnnoB3wF|#!SKoYCQhe^&u(d0;M|j%rr9C(vu)XaV~4@2_*pGP86$|-l*b{*@x$Olim+vdG_r+nvanJr7qUfG zS+t5wHeIR~%C*u@!`GPj{q?unlRWhVH>h_uaPxe?LYxH%5FZ#lNx8_AlyYU4_;)jP zKsABuwdGfd#kq%wELFByyT@zZX_3i^xoh)NXQsRp7lMtA6P{iT z4PPfl275CnH-LNx?G<62tBTEqV{M*J8>DQlOLC*j}up@M->CRpgUemol8z^Z=V1$hgdMIN>T1s(5 zlgi%Nv=G#=lIRjkup-e)qbn0p!;svyI3R*h2<$RKe)zoC3)i6;ZF=i|7ct=tSEg2` zJQ%CGk4xAwaeE$_IlOg?kTI!yF4T!4-NT{iYbagCz`$2qx}0X+XEs`a5&?p)EQr_w z4`e~zsz|KPgL3TcLZ)QKO0tIOOyS58xBnLt$-kKpYw`c%*X_aE1@XMd{DbTO05b*{ zU^f)Y1bcyZLFV~fo6t}Zp(4d_!$o+=))s*{Bs>6C(op&Yi_ixM<1=73JG~&iW?8Z| z1buGKTS53SOJ=wu2TBPWMcjl`hciG2_|m3iBGc9mIN@Rz*?{C zb7BvhmeB`fY*|5WO#(-GDlHv5)6l~PXuCzbD5F4+t;iO!FX0_L_~7f6N6=&6`V!MV z1004Q2DdC&MKGrQ77!GPC9+6R^aKNeQOSEmax9gp88rSgCX$Cdlv=<(!Kzl`L3&VF zxSRo^a)c_{A3&Z105o(Sn9VNs-(l4FrJ`Mr5Uch!X~lcsQa(>MMTrt8z{rS_Tkb*< zYGrTif|Lq`=%Aqkg?MzK3S+$*( z77q11AMEn13qg}OdutMH-DS$O>9qgSTLFQ4)0=HFFShtpR^Wdqt@c-Te$( zd(T_#wTb&32)_%ikVev*-i&fCXSgVDWY*J?1mz8po+ul?EfRRTiFReZL;k{bzT$jn zGDb-bdl%ENcaqueDkrEss|brGnVO)cW}hkQ!_JPdo^^a0R4?kLC-hICNI9L)jE!mk zrxL%KNIfz(%|G8TU$t;?7 zP?ubZa5m-@v|PIYi51|4dY6`Q$(kF6ej!>c$>{TS)*eA{pFspwU*m8cQ_7Z?^36yd zWUNlOo2EgRLYxfUND_k?^knO`x`aERJ4zo%n~;>A5=s;pC=usi<7WDC?rc|_=8zwC!&yyf570gs6V81=dCMJP z3$g&3BjAizPmaW7a`p6f7Ri=BXr5|K z6*(DJ&tr0R)T-t56)K?$)_X%7I4(-=jyId0=JGs&f)Z&B<7)MB^x*g~72p8u2BuV-z?kHOk8-D=4UK_ty0i|NkwC4<=GSl)4E1|Jkuj@_$MGnPe^T>xmouI{I3CN}yKy zaRGCeI(yqYDC(I#gZnOLxmYn*^e#2qp#TUHuT6vBfU!#13CeSTv2ZwYnS8c(@p~M6 z@_qq*^(O_AUFqzhkNYfWdq6_7)1(}u4qlNiS4$qRca-(RUjI{ zaRRf>sa_6it*Va&vM%y4xd)Xn(6s@~lsKifr1tWT&CUG#RJ!x5m8<~0aGPm4zW`dl zPuWftM`PPf3Ld=TvT&Mb%jc;i(bclWJb)bl=<>fdcyIAZUG0=zZN_hV3kVjOX|TOV zv)t92?Y6fk?RpsRo36B|Udk5>)rnk&d9GIT=|Z(qtX=t6e~zy|zw}-~NcqQwgPn%~ z2rA*734B#ptvsG%j!XGU0r;r5-Ztoqg!UjKaYKtp*eO-A% zSIj=6E1nV5#0I03uFVs#e5wrnppqpaIg7%w3!Wzp$S$+VTmk9=u*3Oep!rG~F# zv*$kb>U)Gco<60^UTn()V{-{_-4w8S(*Rj&wn{m`&3dQ($syBPzcF>S-Ge=WFxo?1 ztpn4QsQ;;`wg{XRB7dPa^UvQU2>sQ^1qr_NtnM%)+2JCP5E!4TmXlo*tE;M<&t1JOnlx6*;Ulwq{X0Xv@$6NC9d*DpZinL+Yk}S;eCof8em8IjXpRU!<1?&?Trq_BI54& z@SBAs^1wZrHaQ+fEC9cTxB@ugJO~1HFoh1WFDe8h*XtW~j?07mXi8<%v9P#PP^lm} zfOQmbSIOefKR%wwzAj$VyuT|}lL1Bbo=^1f<-d{D)~Fd8o>}9Nshq)u19+56EWgfz zktMli-lZ>o=FhE$cpx^o^*8|1Wdz->w;doX>yKv-I~vXoXaR8;*Nev_<9*2a-cSKE zCP*}IJa8(EaYcmBNgN!N%(1%9h{hv%$68v}n>#LZ7yR%Oa^nSaK7_NdB!nnbZ zI$jQxFDvu+vLua0jSO~?lCCw|AUnebC#YBh2!%torT0S{CS7Zy>exQ)I@}NnRXc_{o77M1Mb*!q%#1k?o-zSBi^jg$CS0Mt+5!msWJuS`(PaIO6S{+*+1)e))BY>F?XGA z1vs~afjn2gjb@jkgyI*CoN#ALx{fuIlCVeQEeZyp+c5R&bAT;?r6*#Jy$St*f^lnY zdc;kUSl*+g08s;(V`=nwiW#DU3a3ppSOaNqgnKC5c%_Qsx@)NvQRQBsZrp||S}QDr z?k4-cimS~2uRidA+yCJIUjy|2tJpr@pl`kV{ChD@-~N=e0t*f|f=mYqbi9JFyRt)+ z==LIPFa$R;O<)3M!oHNVdVrR(xZQ>^iv0lrt_ojP6jzKcxIoU4=*2GU4278Bm=(eG zBUA5c#q`N0Z7)=p(rJ^AaUT}Kj;P9VG`7GRU6G9S$G{VjSjXd3{v8`82vRK8U3`-W zo#tIeDTZ_yyl78qA4Loej1aos+hgN&H+c$|Bp|`%?$2Z>WfJWcYiS~@6|2m%op29L z0~ps|XC~(2x|n+gqZy5}1I~jQA%B_-o0*;L?aPYVhc6mt?427@G12Aoakmv3j`WNtPF|B;tKGSwN-SLo1N zUX@Db$Ql2y0OY}cl^Fkr|NmXdKm11L|KEQ2xG+AY`&mnG1wmwaP5rNiYTFx0D!=4Qw1FBl$t1xGyRXReI{%svKp#J=hp(Hpn@CS(*@ z8V24Ww@AoUfSyGkCdZlLFRI`S;xvs1;@$MbQ?%c$H2`>s3S)mZtF zOkzjT@lhTNM@+t2s`ay+9s_U2^ z^468DJ*h#SS9fkkxmpbed#?&3veg}&1C@rw8C)kTy1pt3toagD0Z1avVdyRA(lgj^ zE;gOcFJ01@xSvY=^Z|g)sJIc|%uRvbD!I|V-vQxqhDNkxl}tqrfQu;*fie@02o&A^ zKazm|{~yBu_(Q(=T72z4`!s#MZa*Gvw6nuaLx;tzR(l`CNdkE~Y@11mw*PMVg=NW zq*)QWNGfI*Rb2x51givTWbh-!h2~M-&SsySJ$`}d9#jFss7+!fKQ6BT9x>O)MH{9( zM4NX~DXUaUrEYJ&pGvJ!_I4&O@2oY3Z>vMixEt!CfX$PQ<9{-SLv*k=1+K zjQ=1V7N=trjcfNf7CpEnLxR39lC9!!#5IIHkXA{*Jz-ajMUptKl7*!vd$H}K<*051 zheU`k^g@zv6P^z-|W~I#@-lvCi#oW z&m`ZS_$hw*|KiI(WyHuQMDdKO&zC@S)MV)p?4HX4yTh6#!-5Cpfc*#wmCHp7D!_BP zWo0Y$LMme(XylZuWgQ;sPv{meKJ%1rfx<>M7N~dexy90T!K~0*;Wm`A-s%v3QYqnzA)^f`PHM0!l8*m1w1#87ARLM1-hSo0iO7$ zETF$uEgX`BZs1iF(I%b8McqFCjU6}p(^i`9H> z{u4jLY&_+EK$o1eWX%jDDaNAaRa;P9-!YnsLKf7#Kx?iQxHOFc%mPwDQIaP5r<~2? zN)y2Afb&RSj#;U#{*L(ApTG8uZjpUb^IhKtB?QqIwm}-@Ulpp=bfE~cy+BR3QZ!RB zL6~aSg~B2aed3KJS~LYvB?+OBI*vp zEpdS_e^T;T%0ui0-p5z4nPKuBI^XseW=f@MjPy;8Wf+GZjBp>vQggH>AMyfX=y$KI7BkfnB;zuadnMNRp;TM^ zZR=g;;{Wl)H*@Y^YVPjv1jS*WdpdGi7RC39ZKtz5Y6eF~4f-&kY@KuLfGTIUF+m~h8(NC245r}&S_8*1L3JW;)#ooea!MT^CK(>g65L9#t z)F%?H_vGqD?!K{!F+(yo+&~RAacZsltm7<(vhO4rcz@(Fo#8e-4sNg+8ZsVy0<$N- zDaukPCCyFcP?;S!Yd!KNK7hz&G8wxcs3I8GCB?K{m+=x*1qZk%G0&uNT^wL1hTg#+ zV_^(X;c*;3iE1j4ri=_hN92VI6#On)&m0xZgY$SqsJQj13(ca~YfX9=wg~e~}ZR=a%gFeky-9kvbfC$># znpn*TkG2~qqZsvSu%&j8vF>K`VRT8y2y{~enSvY^Z3PfJYr;Sdi;gIA9m$Q-9uXH< z`+qF?$;8-ac)9=e$3FwN-}(U(2X{gg&6y#Vc`%6nkyPSUWBy!uZd5mLFO6(O>2R5< zYXAokVnkA>G8KE93u=3cpew`X;AUJOlOCFCB52YN+djZ~8u!);>qnT9useheC1emq z1W)mPc*8@BQi)aM-#eU9)DzNW+=SbaRcB8jx8nWph#6y(bLCD2FF;tmjm(#Z&_^|Pj61?8=HU3-v`%Pb#YaP#%0 z8DYB;I6yAVdGy!}84)lxu86s?0)jM@pC)8-)t!$(8g;%wHk`DOLE;KpjdjR$n?rV` z8c4Aeuv*lLNj%!t2gN=+3HOvHP_BL4azt&zJ`m|}12-$W5b0)30*@T$e$TfDjaEY` zL02!*>4*tt+r-`3o-=M_ehw?d>KPN-BzmNITn{n~?=nd*ppy$Mw&;&8p!dD#laNag zvwmM!k+tPXnJ@&8x_8C+CJLe}wCTY^RLsNDZ5Ze!TfFnov*U@U?_L*R;rG!hV6Xnc zccuzQkELy6KzCFr!n`uiEVCRS^-++YW)ZN8+fjiM7-swYaC?WC7`G$@+ILk&b6q-* zH!ubPAGxv|f(-|BWT7|9_5``(Iz*8MyP@Db*i7%Ql!H zXS63>+uK`{7L+1-*Ht>m+MhKu00-lOkej-+7YR!L7yBo|GN;|zCqVWXP z@3;#qLEiDvRf4ks-=%jYp3)&wndxpw;ejd~EC&ypIm9!Te((6Z*kRt=aK&YO-agZ( zG|TOCVXNA7(rPwX2c6O|gsh@H*5TSV@rgvGjvt79s0ZYRhUc^IOp)q>BDpua{*DJ@ zf!asW4^V@QNfk{BRs_5YY9))-f`*}8AYL!f(ylWS+te;%>$gy4arps**AG3FC0Xrd z7fyr?fhlkM4P97$8c|t}9h}RdpO+`-sB~LOE0@V+Ul7$!ZRB9Siov>vzTv~HqC*l{ zK^bLd-oo|Q#Gir(sg%k(&WsZKdgcy&((r4BJ=gySUFYnJ>f%DXlx6%e2bM@N?V!(@ zxniQu*XIf9Ge7|PEzwX%wQR1+qe;DbgZtSz703Y%j~EaSr8ZG8s)`RiWd48R#}Z># zdHMhI*PRbNCl=rFs4`=%eG3tn=D&375;li#^!)bRk!Z_RLL4F+AuFPHIO>GyL-Phl zWs#b0g-Xa~h+@75fWGO?&_6*=s9RFp59{7(W3sP$(O96T$&H97)Nmy2b)L-aJXeP3Dii6- zBMOTG?O+?Z%0m{ekXO2M@+LLT}@qLYrHU z*m(X?kThLH!>hKFas#ThP?*Y9=wUUd+h}v1<|R#nRsV1pjQ0Oq68QvYd(4gf_SpB0 zolgGCFatyT^{fz2(0X|7*|N^ZfME+D zsiQll5gML2#2s5*R1*p~^+lR1Kvhat!JlhapSR{5*Yd{_Pak>C&QrLgNDh~C$k`p2 zzgQ_`s*vEIhlidZY-ZpqouiN`mx~ky2xvwkVegk}XP1nl{n4Bt)%-K+Tr!8_$*xje zENn4`{?qwVk;5~JSqC-Cm9$&bq3w6up>;1Q(9a^m$-!OIB~JCIP5U74x4v*KdvLFjDX*q{!U^go7!<#_L0kfO)W>g5llhc$WyxCS4jJys+$%A_r$qaBv zMx|E$DJur}_>__tFCDio7!I9rChOE zpveY{WoHyAmvNp)=Dd}av}FaJ(B-L#(J3RBXxK-dXZPpS6h)P{>`(Fdxvb@Bg6N`@ zHI(R}LTabP5U6)4*Uo>=%0jMAN&-$E*I^y7Y~V-AcS0=HN{0qInW8HN(F{mBZVZDp zm(S<IV-i8_P13RQQxFRcTWWjzcvEvv$E8z z4aoo}#%v90M0WhS89L!qvJ*L>^qd1iTb4?tw&Ic)FMmkI3wd`i3cg(@ge0x>mL)PS z{|lPcug3pGu7Vz2uLR z^ZS$VwZAvTkxzFnTJR{23Np+q>P;nI9;St;NWJSE-%TpFj|m?L5CiQpQwCWaKhgY1 zXB<)1l{jG+v8hNN>>Ea-JM%b{AF6BKs56Brv=@g_bvq%X4vBh(iwFC+aLDWI4( zgky{6D(|49DozIweJeF@ahQy7AP&WA{^z(X@SFa?CPLz)Lyuma0o*h9~VDIje>X*7v~y~Vh)0a$Qfbk)QRU&H5esV z7#q9&+~jzo{`x~q(d^Xflr8tHwRXTE!0IZ}@6<=jQCis>qzUg4 zH%g(Uhx$=j0RbTriRs6bh(NFccfW(-qmc-hz8Irl;`QPo0UfK8Djops5EMzN|M{0g zB-nqF|B@-k{}~&5F_HQhFZaLh&%nR?4BS4R8BaWaM_j!b(diZ}1e0;;7wt`oK5!r>-teepid3iei_>`un46OoDGd!1Bo-x5l>NVd{>PgL{oPlyr@*Y+@c4w^yCh}{f$0FR2LfubEquApHJmM!9w^(>#3q#%KdT-`dHWGku? zDOL~ic%#^v|>JR~Mm4i-i@Qk{j@$&TKQyM;=B|a6Yim+q(E9+Xs)Lc;a zp%&{W?r!W;0PFXBH4buK5({Ddd}w#gU2tr1e~7Y$6*)J;-Y0q~HzJU-x+19s>qrnP zy?75vTe>Q0Goalswl(~JSO1erzCSVcOJncipZj0;%)oxXzzHLF>L>uZt!_DJ-T{7W zu^W54)>0Ec^rqwo=!bSabyDeYyy3SMD=I!hFu3zZHQnb@lj?EEX#3A z2X>IP#G1_cI@(&BmiGJB=$XY;o)LvY;#CpG4)9>OC9z;=;tf)8CsGMF37SJ`dWit8 zw@JJtz_$~D*uu2JB2wfOZi-)tC%2FZI)W%CL>ImN59dis7%h5P#8w(z!BnVY(w$9l z9wzX3dIU4^a7;qbLj}D?jG(6KO7qet#L`}j%Eeuy#vT$+H3(-4T(tn!ljn0K(%MQw z71`|iR@uBsViR0vKMen46sdh`=c>!u^6$(2T((6bRCqKnGVHdce%fUN|Gj${h=EJQvbs#0f|C8@XjQw+7?td`@cdnHn z)4!n;rD=x&5>5&jF^kfyh~o+Yp5e9^+s!$hHH}1ND^(gkMnqSNZ}0ga3oS90%W5?b zkd@Ktcm-sxSY^aQ*fOFQi3@VAgd3TOQ94>Kf_IM4nq(T6Yl!8KEfXpZ%7}nR_rQ-( z_kRoI)23NY93Jk8DbE8W&}h^_ zK$zR{RM>Vlnwok9aTl;&RdY1MO^%|`9b~^$$EHYu1_wHKL$`1z*2JChlsnO{qx1(i zvM!G?DN1`YK8l-kqGL3HXm|u^wdiBS?Z0Y z(g1XfI3YM4ZH+u>9}la+J57=TYy=e256F*-NHj#e7> z#06!RME5ru6G4jUP_6@miL5U34a&h?Rh|{i1@4bN<@*0u4gb#;-1%R}5(|mc52tEl ze}8Ou?5X76PIl-v{$KFRulDQOM}&b^qw||#Q3}2Ai9vMm_RlFXkfSRLPHssaA8oq< zSy%8}a2)+%XJHX=G*_MAWMzQ+qRuBPRcq(J+pyqQPYYa68;#repxzl|eM@9qaNB=c zrlJ{0ItQJ_U6r-4oX7d7={3|1bwbv$syfq}tOLD*U_hw(_*)DZe)Ypbn`fUCQT!4W z3sjXEFNMp0#|XZ)!i7?4)Mp*^b_T~SY!BjI%Q*<;Ik?v9#)C;M<#W~Abj1MeS6LLLZ?^-kS6&bpf6`j$(C$#X6+9lFQkjiHkzxz#gNI7Rd}-Glj<(Ln@G!^_jhgbc z(+^nU;c8XP_PPzZj(HqaTCDtnmXi+Lq(DI8NusH*C?d^Z=lxxP!EFOCb1VP589sCuo1v?kGj!*xXFYoSq<02PV!7 zCqqH63>8tkyv+HqOQxnXJP$j&-A21t$jsy=m-NrhWGmU)xj&%M_z(TcdPyQ*f7;r; z`|<_i!;7d!nWqC51qP%X>tEW&iqnsT`Qb6vJN~-A?dMAwx;RlM0{YKma4Z471}M_Qo(XLfy}Od;N9Q;dF%#%Qz|Rct&Xg03qgg!*Qs5@u?I#p4v9f|ZEu zwQmw~;;&M=808Pd;5T?JItvp+cf|aZMU@jH+}@xuJO-ToLCdf)4t9W7%7kzT7YqyD5s!UT+$<+R z0FCC12Li{$Wh3Zt@L~LRd^kn<3bSHnq#HDeqLBLQL%xlroT6-xm?bWHz+UM=M3&`9 z0unTuk&y>DI&%(tKwCmNAPR!g@&oWdjk&CLBlvPg6pCqrx|Gd`o_f$4ZrU+%7*|<8 z*Z*fM@n|CXpYo!wJI7uaPt4v`$cv4l3`=Q51BLj>K^_;;iS<#0As57&Q_ez#6|S*# zY0b(u&J4*kX+DHVGIhq%W!R)}bV+{0DNGE>SPpUVwR3^-|1R*rB$VLekV!IjG()k@ zNLtM8N$eny)JCj9lm9^6>mmfD>ov7R0)<4s&yJGQiU~zjU}fCiq!R@ z(W9UQ|#Ya#hL5M+{E(ZRStJn(0+334QDGs;)j14xQ& z6K+7#)7W@qVa$fj+UjIDo$2-KRjQJ{b;x4W**SUy%2gEfcGU=EA?VIUA@Z;*H2Dku!bK0w7H!Hl&t2ODXE{HZiktafGqSC?8$pi3tTCiIH%i7;p*$>epo zI58HpqX%dP8#aXmt1Okxmwp>11Wel0jl?NATyW+@P(8x495~~lg1W&0x-e-D6~!Z03NDJvZ0@8Cm_M?YCe%92*p!=w?Y4r3tB`RM zy{Dd&Ho5xcG>9UgBl=JlK#L_MvZ@MVHz8aC5DUVM zBnhG&QGg;@P+Lt%{8mo}x)6~Xabna_E$aWDd^9muMf+D z(FAP->@aC-3B|L>3JOWai?@dKHmXe(G1$H`W`H|U5(j~jTxd0!+=CC^IsM{zBKw9; zd{{z#xyB26j`~i}U-kFkQo8+1sf^3N`GWDfR4q!0DvymK=5d><*K3Ir@#OYo|nRj8!<$=SrrInFS|dEDDbg_L#d`bfgJGrf@@QM@dN= zzpHXkB_?}ZdtKEu5brwn9310dy?k^uqO}&|Fj%c5wqLszO0`G<8i7sKKEv>}RA{MF!7j+I-=UqG)(0X-{Jali%m+7gHQ89U3ddwM7 z#-*cVM;#*%u}i2*MTUenGFqrjrVn(#6?B!8VfB1wgW!c(nNJBUUf?oEe82y+*7On9 zbQ;<7&ay=mADn?Z72r6rZB;_V4kFp8H%MxAK8!i)3qC!LpC%;4Z!4@@)7HX5_Fs%1S zXmhXaq=(0Ip>oh3gLmQhD$m33<bO?gGB2Z$#dEZH9j7hYc+n{iIN?USM>5#VWM?rg6nyB-SXMj?LI#33wWD%* zx*I+Lf-?3SqaAO^Fc-2iafyQlAx1xU9qArH>qh!E^=}g4w42Old=E(g1XB`z#bd`l zRiglR-{QS6I%Q`T#f9qZZB6QkB1HwUZ_BkDlS#AcoSq*`heV$RLvs(e;ORIPg z&Ip>|BLtDxuL=e!(TM+!W`vU(RLX2}jbm_-|5yKCT9{;G{{O{9>My0PjQ#7eA0Asw{$BD2k_(C7P5fZu;#Z{) zuFMGvEj})8Jq&31#uz_gu0ZI|(>R3_6m>SG<2{4BG|$lJCzxyct*{IRTbcmC7hAoW zE>{Yb)&w-0$<)YC5EARw@(#a2i2v?(J3uu{NUu3zvwnel_!Zh!L0kYa{R-tezYM zP@tVTfJfmsS1FL+@-ME?S}DU?71aWtyjosoE-d{ACMv7b8tik1hU@$SI0;RdM9l0R z5)cI%*Z0~ErFMBeNKT|s?X2w_ZSM;cBosKKQnrbVe(k*mu^+p7Mho`*v+8Lyk5%M& z0qm{BYUOqbUjtIU_rqp*a}>(fowscFp(`WyV^2Y%4ljY z+6e~lT7F3zENxXF%N!iD<*JupHIQEWuhdhC#y;+{%1aTFbVY5NtCL6L#EDXs{6)q3 z|8p$D(*JEk75<+}Jf9f*+2q6g^Kbjwe`Q8B>Tf|`pC?iz=nU>@lNV7qr3CTT26QPD zAY=#0Q=kPzXUY{0z01#<1vA2^6r-Fmr&&3f%Z}(fsqWcntQh=jqNZrstLyNepQ`4BEHkuvUc?a2&Nm_*@)Nast)@-Ak z5AeEN5eI?c2&jy(athUN-IB3^iK@i8fG8LAN1=(7(!rr}uK|6#kLp4BzK^Tz>i9Ng z0{M-e8h$KpK9jAAH685dMxiLd(RD^$Y}G}st={su+-8&9>3A{l?$QjptfF*TBi+W~ zs?pgu_9@|zRv_WL1oMJ|hzNk!t(G?!`Uu1}uZDy{WCA0j%uVnFK>vuvtR8}6G-$1^ z<7;kz^S|#ud=>`%zADOR!cEd@5NnlI zqeK#|Dscs7RakrH}okYCM~IJ_!$&20RBYG zbjHOdqCdrMF>u^MSdwMLv{6tlM1jqK%Hg4a`9Q=jptIaw&;yA>BU!dC8^$X}YtI;y ziqw)&!)?**w#3s_uT*A~a z)j!z8A;GN00cJ-CSGq2YB$q-=AZ#%@It9%g zAcn>_kDyCwA**Sc#1I){l2Y~|Sz7KMbyF3YQC>4Lreo_AF=5eJRHhuwW{q>1KpUF$ zAM?cdM`n-!rff0wYiOEQo~Llrw=Ox1mYAjT#^O2j{dcIQ;vCbCJVD#yTxL7;L{mrc zX|#J)7*{sA`(o z;br3k$QD`fDB#G!w5|%nI_UF|mbK<#ppd8|0NYo#07KJL%0ZE>d}#|@zlV;EU&M{iXn(d>7b677S<5#4@Mv_bQ}abwtQw)gV@#ms%jyo;QM8Z#0!2p(qg6BT-3002nk<|^ zeUa7k1==ES$+!*6hFR{Z}C;ron9x4^F9u@lCf%(6{ zg9yZwsDcCVy|4-c1V}M;#l=Ds0h+pt#c6Zb1O#(nO|XeF)pEUT{y*V<>U%f=VBu?S z;l8;pc>AS`U}>+<#o>eH0T!U1Q#cbtk~`v^?y}Y7PO@ss1ERRV?FQ+!HPB5osc?h1 z&5h{{OV3FPqHUvX4GBZG$hiY}{2cnkPUSbGy}9l}Z3i>^9- zOUbbVg^Dw(GX^UF2}h6KPF)Z|*T~l$9hb6fr2IK|Q%*yp-FJ(^Y9b$sa6-HQKQlpNOBo%805GqKiZYMROHquXO>Xe6?>YK{;dN4c0x^Ns zH1C$`bK$A!(^)LP@Y}$7+=ks5)dN4xVY!hyQ0rv&EVE~+OlcO&A<^^0XdkX9H&;A* zv^_`F$$lC!65`{Nc*dGx+Ygck8$5x@&AolW-62yBjf^T2?MT!E>%gLG!X5uN>*{~r zlBgt7e=)T>_WNVsGxm|>KS+L8@`c1dOnf)Le$%hDRl{VS5+@N#!xkzKOD;0*a-B06 zGlq@Ao}eJSIb}3A=3;P>NhS>5t5m8*PJ+y<)j__TE@uEFF8*1=&=yt%a-1^8=~ddP z5^gs(pm?b5!^*>4n#LGVSqH*;4*Fr!TVsOm8Bjn=s%t8hYL6Nz_Vmlk>YVVrVLbGW zCPcr=E|G)ii#R-)FHmvE=0u2B3=p^%>?`IgkV{Kt&gz7D3wo5HC&NpIoUB|ntjqYe zbKT&UcaBrFb(ZAr-zd;Dik1vHZ?O@c!CA+9W zJW%Lw2tVwti^6-E4&Age$rmY8(?#ouFfQh9cc~8d73i#71u_DhOlJxJa*v7K`SZW< z@k^S`vH^0Ol0i9691?TMzaoq)%jV0{+FGZ0_O)0G1fZKF=6ibw%v8`L06`edCHY~T z9(m;_4V%5PsNoh3@La^jikxXC_BYC+j02ZvO2?*0d_mgzFTrJer9l(S;99jy=g$HbqXRY1akj%|+s`9zRb)=Hk}sqS$Z@Uu18!C>YWV3V)u4V^jTdki zhuu&Y|5f^u04I)4Fb%+x1ZA#?+C*leOQZ8_g|;|AbyZMBCOlhPbzJO~3lim1#;(7H zCWBVb-oP`u)kf;}KEZIa-UV7dT5lZDocj(Cp67_!JOU#Aa$ZGJoF!XZ`*qtO&j0_T z#8@}+M{l~>zhVDydwYRi5qBREd^GA&#hGbLV{_9i0x|g_KpIF@HWMXu%mD0=m&AlP zQ1fsjDHVMX(M2$i3;>cT{;9>^M2w@hRU_BVHNSExAw>rkRj6@>1JK-`jR3$Ov2e1# zgnmS*vglDyRlG)b@QJfI)U2yY#i%ffHh6$|9O`a%Nm#5Uh21?4E{A=KPw+JJM$(W_ zMIe}(=kYi(Etd8mFbvFQ_QA|tYgoC|GV<==zNk|bXcMIhZ1L=!N9L924V;4{<^Dm; zHw}jZXlflIZo(cSZuL4P4@)G?<-p5`pvYsnH|nn;rda5kYnI+pGc^2Q8?KQE@Nl>` z*sRXWad}et?nVQ)aQPmOC;~T)p9>2CLZ7CPu+~D47WoR63=9^(L5HdcfD@u@J`@g< zEio%1NRbHMPP)O%svo8^FVg zovimczi&+O$dvkw$#W1mkOW2Chz8|Q z%#grlmv*-ltq23GO5FGynivkO+$ADNu5hov#K}&?hXZ0kT2ZmEb%8d{LuRePPUPWQ zh^2)PZQJ5_F`Z2~qSP(d71#!GsNH1{=9jb6-2>S+*U)rE7TH*3(>o%FL}j0-5HJh} z;!1ZMIPUD(D4$}Glh%^pxd||l4T)|I(XnoyTH|+mAh|7l0!m=%my$w3&pE3Eo>D; z9N^i7H1a>PPbkA_WlAn<&!T+ktt0eMGl<%1H%9X!P>S5IAS*Ybco>R$jB}?CGeZE7 zQ}JZ-H+NK+34`ek_u(N)FO_)OI3NPC22%J4o(i4OJaUD$`NJgS5j)ZGo)b#xhH8z` zJXv>5n9KTrjHs(G9yU&yFrc_vGiEEJq0k+%3~NgId#n#nD{eOH5w9b049JS}|JnbU z!uYuC|B=KO5_tdrYx3v$<{Ry6zqLG`ICuL~QA{q3U1H#(wiO^wFd%ALI(7E2wMo(Z zVFv6dHrwUcBs>5#l>_vx?bey{VQqlQi9;8M zcqsTu49z~Pd)UoXjs=F$j%TJ=U}hXaGnaS#-{jb2g8%M+-JgMf;|$!nyfU6R{l;1( z*Gn+$2Uyie4h>niyUL7-4^(KZk#TWFLa*X}wIUE>5%hvHQ%6$zu0 zE~n|79eFM??dHdgj{kt|>Fm1ehlFKCEBWT_t6~Z5A)KE9+#n2?cV~iV17i%OoeUxs zV-$_uq4A&7f$;-DssJIvCD2>tFp^?G&mG)KzXL1rLo__D4M5E%hXBYHDBWOQLC|3Y zPCp4zb-Gt0=mGh6k#Ss^IO?P{lya>d+;nK-v zI38R2D8n^^olMCzZVkdlrTl0o$^0oDs$k+EfYlb&VHReVRjlbuJ7<4vwy^smZCTqb zO%?KJ53a*oFW&Num#-|sUk)}g_eQC5~Ld#9%13`m(3RM za2v{*cvs*ANG)Q_E$8dw0UaD#D(@p!PP%+l;%q{qG=fD`j4?VP2pWLzPCjsDTBDj{ zoqanWz+HoVAd(V3;fiwk_~WOfl@1Vkqz7V!4aJ?vc4)1Iy)dyV>>>tJC}*X_8dy}t zFp6_rr0C*9W);5xUl(OJkk9B+4RQV7u|!AxKQ4{^&e(U4olE|1@_UjWPW&3b{2G64 zed1W+`6HLC`F6b%++-aQ+cU_Ebu!rf`4RiHT&6i4O$#_q5+bKI35Yix#HllJF?!o| z<1QES)#3!FWCG9Q?d1w!$ZJ2cp)ddAf~FUai;cW27L?oQbj<$V(QWd%f=*7Pe+BR8 zaY~K53qASR3|FHcKU4p5SDVTn#)d*trLw@?Y8p8+7-trK7UP+_sPc| zWwx&c;pprgvJC&F=0W6a>r9RG_hx2G9PXN(;22G?{~T!zx_Q@TAGJm=*I(9^&bjXL z3S2tu8`gs>ePpz7K>2jhCL`lTY;y4V!?N*mm2^U3BA+3_1gSh-%oVdQ{f=YNer!#T zKl`MHI!o645Qcv9yGM7Z+bTP@qNGzV$v@dz8UOQ3a!2g6p7Wha+w^yz@+Dg68H7 zIG3gW2j_oYRKDr=J}>*9O3?q~X7U&L=WG9UyYn&`-Mc#DMwK~qyCG}gVxYLn+w?ga zO+;6n$|$0mf$aETN^!@3e@!PWNYyzWiSbS30NL+*Qu@N4?EGhuR3fsH>gX`qt@J1b z&n4*0-VrTIMCC4r&ajbiM;!Jg)$25>%&Pn|EJEayV9uO#30i;^>bLLj4OA0`SnJ55f?%+()XP_6!F2~)mG`Cj*CC)R zb+nKw^Tx}G#)$H#ZV_P6;K@GM)ce48<-_|p5jvG)qk|R~g$hTj=`l zMq_^=(26&ZHND9=0(Lg3us?>;hj!29491oJrlBblgRvqhgf$M);WO(aWEI)J3MJn4ASJ(rJ z9*LSm#v(PQrv>vNAtcw$@evL%R>_}&C-dtLH9dB1AdqsMI;pxmE(2Rxq^t;Xk<)_k zaJURjOK*SZV`6A3gL(vw zOBL}k%UWox^&5c-XJ@d)OxLJguc~w@6h(k=sC;&c0L#?_^Gh{GM%R)_Wsf>8rrwQ{<*+rMIso!5nnKrOfQzw?b^@ufS>r4l>dA#& zC`f_i$X{E)E46T>%h)&QVs@?@j4SSr5;4#-FqsWWe_4Sc|D{s<-*Rm{QM?mtp>qKE z8p9&Q3*?2453ygb&vIc-j6tuV1suXpsU?T~$v_F=k1H=DKI9A9@T0O)dk0yjuH^?* zI_ge0Xj@g8?OMZ#X&IrJQ8IBO%WD^sAN=n@{m5p>-SX$E#+l8esByC6#L5Bfwp;vG|Hh|WOKvGk@{@f#_y zMD9dT#)d`dALM79ng~WfEs<0{4SS{iUD>Wn6`PS$+g;*LwUkDSNWd^S=Z6+NVQdKm zvYf`T_KERC_H~`*t4%bGeZt+_qxBWGNEvOR-ukT6q@@vA9Oz_N2OBALY)lo8Pf!c{ zq_@dku`w1sBU7Purl!X`rBsdRbLcZF3c=^G0BaV-6NgLjD>}x0HPlKIfj~BVuRElS zor$q?L=2mPkL5mv5)zy2-~_y=-!Mu=@<&R{T}P=_^KBd`g<7`kCAToXpd}`46EaA~ zCP*DbN2gMvqoOmoQ59Nwwg`nSv6>v+L30CN&YIF%QA!qA>h{LRfg111_S|z6`@B2X zcLx1wP~*Ki17*Tp$(P@7FoBYNqA4=#wy3e=ax2^hSrMI2OBC-D7Fg+j(bks;N&9;p zj?V)%*`RdKqG_@aoJf4o5P*4dTG3t46e5{D2~7NyhsGP{HdIbT@>2ScacQ!dG*Kxa z%<}*zqKiS30$JWwr2DD4g9gg7j9yI+y{C?E(YJ(85!6P*f|m+ojs_kGk^bbuEG` zsitsVN0n*ykd)so63POfaQtRFbc@@8j_f#ZtBZwfxteA4z$;XOW9~Sr>*`4>D8A$$ zOB|1a^g2m)D8vxxF8>pw7IMT{wE(bC*QCs%S8qm=Qp^|fd1#QJAHr)&Q2%N#I?UqL zS2Z1{4cHw+hUBUl}A|0FCds4-3=G>h9Z4aG`?iXe}L+GD?G zywJ7lnugO)2+f+saG=~oMLlV$ zv!@h1U#LCmYOA&Xk0d^oNWEw5wd7yro3G#3?H3!+oT=SZzaOeV5A(QJ*6OS1MGhR7 z{$7=nZ^_|94(~cjoRqkT6+(;U4KDe60^i|3<8r%{%eMa-iWcXI@DSyQCYi!FC46<5 zC&6xq27Qn*F3wB9^^W{(aJ?FJSG?JmzwF@tCc&{&*z$Ci;>PuT`p zZ35{1sde=gJ;m&uQB>}&U|*^JcTtn>@*0@78bgRD=X%SC#^>749Kg*yvMjZ3CC3Tv zh(ChMVkh#*)+iEF%*16ZF13UlSclz|PejE51T6v>%u{0QHW&uXNt4KC26n>!bG`=r zjFy{j_H2=PLW!p>`-Km{++ztj+yHakL%^vS*G!vjWVINhTHUOh!30pS#{bw)p!dVe zM5&Le8slOIg$-aCQQcSEfm7)>dU`W8?vngjP7R~Y5fn4vEQj|5uaY&o^Mp+=UNuzo z8^K@|3mcR7j1(Z}1z|ye%t;kdgnKHNVcvvu*W=br4zJL1;HC0p6!sSIpqRIU?y5D zx?*kRNR{u4ks7(_hS04LjdHN9!hmyaax7#;N$1L+>X6GHkaSgnvkOv)MqTKGdeGTS zx`fQ)wEEUUT zdYV^MK0YDTcL>z{V}Ta%cteOl>+%R z!}pjW8_=eH-xJSWxUSDQX@Rv)hm6T(OMHV8d_iA=`Voq&!U{cx)l5XKY2MVO2(~mx z`4x3bR5*ErMzg66tJqn*CI%KB)RNcMRA@_q^oCx)`5Z%Y)uJaw{v$2Okh(;mbp#Ph z>Bmspw7d5R2&NVcWjCvdpFQ~-22n3w6-}BrsCeCs;lN=uIIQD0d+S0y8|xAhU+U5f zNjD5gRR^ZEv07Xq)=Ku}Ouw#mR^>U5E&#k#g$)e=X< z3!^wp2n^pQT}ewkwt4kwDMFLYBp{qfMHK5x30FB}6m)h#e5>)D`E@ajV`hFe8{gJz zTaAT$(Wk$ai`Zfh-*0(w!pja)6-vKedZPG7@mGss z-=Fv0>wApzf0sY*{7nC{KK?|PuWO1o9Wteh!}l78eD#-#sDG~6H#$YOvfg`9f~tj!&j~{;W(TAxS9I&^V(D2i1j#mA~tA*92DMl`_DK%m+nT?id`upA_aA7c5Cdh^N~6Q0 zrA@hkvirTPi-^Z>A6T{JD*ZZwBZ)RKP(RFhg2ApkQ9cWUwV#YG_d7ltXtXi?o zWbYbm4}oZPr8YtD7Caw2E+Xoak&wjMNtg7nd{^Im!m1rl11cecR#90; z@FRTy^A^cv!pG{3;aVEN!d=B*l{5qBaF9JJ-*oe(_8q;r8>2DI@M5rPlavG%Jx6>s9udvZ>|QdjUJN(kYoRibK;MUJF5Hq9!`hAowz7i&?wpsV4l z%-${|0@3ZvCZv#RLPm&A`&^6D!dvsMG7H=`ACS%bn%y+>w@tyZnco&JBHwER*VKBc z_sWz7DwCzklj&%oq^|ar5y?m+qg5|tOnnlGl~Y$q$R^5;eZWrK+J@eB(vExAD~+t* zl^@xDW#`#RirZrZ49-@eDp75@jsGL~;n4&v8;?wc za_8SGl)hA2EA97D#O>*D6tOc{orJ!&aCPoK}tP+q#Xv0*rSErDhlnF#4$1~^0jB_P=Ok{laHF8wF=F4-Y-Wn`iOE$T%yj-n%vv$Swp3YHL$FKwHQ=6^H6Pb zl`E~?saR#%y^xe3tRSp1E{PY<=Jvamh)qogIszW`wH0qLv|3)4Bnp!>8!`KOekw0&Ny^q1a_p9xijkZ$VaVnWeYzsz<*KHh zvf6be#8^Yfn4ODVmql!sAw#~OHNIlbxSlhf>PUa`2x3^DgwvjdY&};cvpuFUANQ+E zywV(7P!C$)g#VVQl6>MvYteRXqNHT#W^Y1S|hof$>z;3|pDL%b}vuNI)!trEvg2TYA9 z0sxgG%F?rW2hpC&f5L5#z~z{ln@^{GiA2*kF7A`>P3dD>zTNYuAzOb!$xg zN~ks$92K_)Ju$#fcfQC$5Ydz$BWvF}oxF|&u z#PpivG6P1WvT%=wzq{ie-lm6-*_}T_lmM#NHQt%5=N)225|Ho-RG^PJR8?Qu67Xcz zwl?N!0m3tb%S2BivZoU-@U!XvHgjv|KW_Vb^e8*faSym(gDTB$h7#dvd`LOkP{+AV zqce4(Cih;l!cQl9*XF9vDhyV8#>V?v0 zOYbgzv-rW{k-k^^)|mzJyZqsO|19P|r^r)iBy)ssyG)*G)_Q-=h37p zh8#d&DSg&6_tI`GS(hteAwC&~PH*J1C41SW{AYz}MxAf~mSE=*l}L(GcL>bxKX)yR za-BUzwyY@$7fq*q3M}>6wn#<5eJl6H$s`aJWQ_+c_H;2npoNc*$h!-1D-1V})`j~m z$@GG-!g;8G5G)0CsELAcebuz@UWCtQ&B$)$@w8VayOoii$W8kzKxWyFK+1u?kUL9Q}4Y)cOy$G#H{cQYzL50Qq zL5qYM=pVy5GLV~Gi@J?pVdcN2*RQIZ2xwy$C7dVoj1xA|MA8AQ(qtHnPB&gQwUP~= zw+($N|7rP@#6Y?Wf+E_Ht@kuX^0XaEdLDrM@mIfsUx(U~wrO)!oU9O7S? zUbCG4l%79nU4(&=O0QsLjB+=x?d+>3?Sq~#kO2JIW}E0Ao^el4VeUSJn<(a6;D*Yc zhi7b!*$TP)f4)$90sjAb@%iEb?*B`L|0(=_VgA04|IYu=${&->96uq|W|}w@JYk$7 z6vbJ8g?=~b4oI!D+iQviK_n>kuFplG7o)-{6I$a!>9dSl^SAcwdVbUnk?rTCWu1+Y zBQ73(G>u`*OvW6jQ>HF6p{7H9Y3Ywc!aPnz6CzW!RHnst_JH>A-nTC1Kd(hTW4LSt z(UhPN*~wQ#XlB0DTV#M8hbQ!e|2D5(+cuCfY&cmrgLJ)6&IDzMJxr5q>Ko>`FXu;e zKEtEJ?iLwVLio;|cK2A7cr)D6Bh9?qfk+`wD1%9p-Q;jQVoZSCBEx96K*sDrCw4aT zcWR|WN5{oyaUc{gvC@qF|nQ}J37#C2s%)~gjH zA`~J4Q_iN6T(Wcf%`>+1gW7}%TcAxNL zLtV@tms&7v&Y-z0C5pzd_7EIG^J~2YqEi$LB=&7RuK1{$v>k|XjV@h2Hlz`?!W;17 zFnfocfbdd2q|F_*gEg*9Il?i@m{}6$`l7yrRB-ZcQZl%ykl9gScGzK!dK$`yppINl zbUK4X###9zhTI!@Sts|1r7ekfSQd@T8M(~BS;T_t+Q}y2?mgukj2NaN7bi>S79EXo z#M#^@EHUR&{tI@Q8j&A26fn@FHlH^(iJ!WGEqM?*7zVT5J^6NMFXf;PJz+$F z@=|ECk6luivT)Ok?Na_OonWU3E^H$va)Q;eZF`Zb9DF!MMY|sD4sUCdt_B>gjdty7 z+lK0boRB=KSPx1xc#NW&`3H=U&*aDTMUL83fld-X--Ah=9NmjJ6i~v3)0f^fQ6L}< zBZ2AZG+{H47|Nh-SYNS5KB$KtKOm?yv0@k0G?pPIIrDo#hzxj|cU0})(A2f|TD!io zM9$Q+O#da3%K=i2vW}H&)pBNjAwMQNEZde6A0vxuc@1x7qE&NU)oadyIbCVb3a`_t zOe2y#U@Pk^6&hW+5+y9d%NAI0=YLc6f3@OwiytXQec$f;VBfn6uN5}$)AG(jFtvNAeB3Jv@JTM1eu^wYd@Lf_+zO4Rt>Ms}6>X8k-pNrv zAd8B9U~h%@R7IA}zhK^YHfLrv7p>zqw7`(a;WXLijgX8Af=n@wMdme`U@xzU5*tT? zAtu~aUIYR=tH;u!FK0^ivHsx>;kd?&thR|Gt|AUKzpmvVAC1eonjlWE(*m=rAex9m zHP7v})zWUmJ?(U%49RO)TnwhXCU>VPLylv7U8i?^7uIa$Mm*xF@hXBxrIZ$ zg33|iaN;t0D*FrUMu{3bW$t__kMy2RC(y55y}>Ez631qL&$E!cq8I>>V_LpPMUf)Z zn8*Yvvjii?&mbOYno5ZKqQVo*K^V9C6-y_a%0qp~4kl^V+erdaf6`PFpPm zFU(!8((_@`1?zJFDpdoOv^c`%k#DzDd0u3!|H8>#F)3GV@2}n?}-QD|a?m<{<+yX`E5g@!o-S zy7#n9VOYo+Gy|M-Y!MuY>)1iPCIpK=z^0sF+cASFNTGcb5=%mWGnHx1n zwVc04WPQ|bg-)OYDuX6&0hH}4y^jbK??<%pJ5|akzI*Qn+ygdKt;%ND38-P3Ex7Bn zl|La$cEVuYFg%HLVn!5$&O5Ac6p1YE=$QgY6Dzk71DL5~kyq3y1`6rgk%|G+oBbS3`4d%cnXY>DL{QRl> zq)dG5Au-4a;UH4XZ-G%-<=%3@dSNm&y&X75a2)Rdy6BM8Z6g{OPl&Q;y-KU3E`vg| z5#Io#&VPTA{GXRf!^OYn7eD;@;R^i!uE3?-CcKSVa=UaZH=M)nh+P6E2__QffzUM= zZa0Xkj2+8yhnFkIM|T_m9f3LKj$1Umaxov1Umvy*WQQm!Job#L6}DdOog=^E6C(*x zrn_OjodI>|)$)oJ5CGnX5IRTn0yM)PKy%e-M(Ic`txI%DQgt#eO;QoKj&gf!3st<^*)%01qClf!|SaaI( mKa*4=2B_vi6j5;la`@lm*r$jl3(HBu5IXaslu>XlF8RL@v*F4B literal 0 HcmV?d00001 From 82b3a03096a891f85860af8b84943a0869868be7 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Mon, 21 Sep 2015 13:38:44 -0700 Subject: [PATCH 39/93] Finishes writing find current customers with the specific movie checked out. --- database.js | 2 +- routes/movies.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/database.js b/database.js index cb991a8..4adf4f4 100644 --- a/database.js +++ b/database.js @@ -40,7 +40,7 @@ module.exports = { current_customers: function(movie_title, callback) { // we want customers who currently have a rental with this movie title - this.query("SELECT customers.name FROM customers, rentals WHERE customers.id=rentals.customer_id AND rentals.movie_title LIKE '%" + movie_title + "%' AND rentals.check_in IS NULL;", function(res) { + this.query("SELECT * FROM customers, rentals WHERE customers.id=rentals.customer_id AND rentals.movie_title LIKE '%" + movie_title + "%' AND rentals.check_in IS NULL;", function(res) { callback(res); }); } diff --git a/routes/movies.js b/routes/movies.js index 31ac70d..92d8f7d 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -20,6 +20,6 @@ router.get('/:title', function(req, res, next) { router.get('/:title/current_customers', function(req, res, next) { return movie_exports.moviesController.current_customers(req, res); -}) +}); module.exports = router; From 371a7bdad9a1b03d064c46f7161fa6751a5cc1f6 Mon Sep 17 00:00:00 2001 From: Brenna Date: Mon, 21 Sep 2015 13:52:44 -0700 Subject: [PATCH 40/93] past_rentals is functioning --- controllers/customers.js | 8 ++++++++ database.js | 9 ++++++++- db/development.db | Bin 68608 -> 68608 bytes routes/customers.js | 9 +++++++-- utils/rentals.json | 2 +- 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/controllers/customers.js b/controllers/customers.js index 0d71510..979a554 100644 --- a/controllers/customers.js +++ b/controllers/customers.js @@ -40,5 +40,13 @@ exports.customersController = { customer.current_rentals(id, function(current_rentals) { return res.status(200).json(current_rentals); }); + }, + + past_rentals: function past_rentals(req, res) { + var id = req.params.id; + + customer.past_rentals(id, function(past_rentals) { + return res.status(200).json(past_rentals); + }); } } diff --git a/database.js b/database.js index f9738da..0664902 100644 --- a/database.js +++ b/database.js @@ -39,7 +39,14 @@ module.exports = { current_rentals: function(id, callback) { // list of current rentals out based on customer id - this.query("SELECT * FROM rentals WHERE customer_id=" + id + " AND check_in IS null;", function(res) { + this.query("SELECT * FROM rentals WHERE customer_id=" + id + " AND check_in IS NULL;", function(res) { + callback(res); + }); + }, + + past_rentals: function(id, callback) { + // list of past rentals based on customer id + this.query("SELECT * FROM rentals WHERE customer_id=" + id + " AND check_in IS NOT NULL ORDER BY check_out" + ";", function(res) { callback(res); }); }, diff --git a/db/development.db b/db/development.db index 259f8bd93061be3acf89498ce4a281ebc4e54d6b..0da3e64b5fbcecd55bf06d3a9161be7a952b4ce9 100644 GIT binary patch delta 977 zcmXw%IcQW-6ozNsy)({CCYkK}WZyH{_kBeoE{H}*5n@2W6c!?af`-W>76vR5#v+J? zkcfg7nkQ&sVPRomVPPR+ks^hKh=qk9`9Omf6knITt&gY#eh#IBOYYUqyLKsCWTY&Z7Ebs7*cgs-H~N-c^o9bJ3AVIu4qM&wMdEX3Z>^ zRu=z$UeWFkCl!v(MjCC%7mvro<>Az&SY>K0b~9<6RiD{5Q_da_6bWibo#{-q8G|fP znHqrJm6m@wG&;ni12b%W~=&Kk3jc*LbLEp@zj?#e!tQQSj_rF?=_?P`V znbvx?#<7ore(MGI56qUGw_A3O=x@hv1%DC!d0;&I-Qj6g`ETU+U>Cl!@3S(emHEW# zW59ah4}Vy_C;tvkz*{nJcthazA(@v%o)ei-I;6&p_`q^h`i^0n+2JGY_dT=*&TK1a@S>9)|6M5buXruevjuhHYK2H3eZCLU9Pj zU`rGN5oixVTL)O};IqK%gH0xw5>rR`&9-e{QmH^?vP%BUe-^JhymprM;@720@bl#BHb z>Za!{;mRj!%_A^Z)y4N&&>(lnGPzA|kt(@CuCe*5+Hy%9TcLA-%+sCoNY^*}n0je))m981sC+cQICp> diff --git a/routes/customers.js b/routes/customers.js index 6b2060b..9e9fffd 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -16,10 +16,15 @@ router.get('/name_sort/:records_per_page/:offset', function(req, res, next) { router.get('/postal_code_sort/:records_per_page/:offset', function(req, res, next) { return customer_exports.customersController.postal_code_sort(req, res); -}) +}); router.get('/:id/current_rentals', function(req, res, next){ return customer_exports.customersController.current_rentals(req, res); -}) +}); + +router.get('/:id/past_rentals', function(req, res, next){ + return customer_exports.customersController.past_rentals(req, res); +}); + module.exports = router; diff --git a/utils/rentals.json b/utils/rentals.json index b78a009..cc38556 100644 --- a/utils/rentals.json +++ b/utils/rentals.json @@ -29,7 +29,7 @@ "check_in": "2015-06-07", "due_date": "2015-06-06", "overdue": 1, - "customer_id": 3, + "customer_id": 1, "movie_title": "The Birds" }, { From 0ac820060dce694e46711bd5288281d29da68cc9 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Mon, 21 Sep 2015 14:05:56 -0700 Subject: [PATCH 41/93] Adds semicolon. --- controllers/movies.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/controllers/movies.js b/controllers/movies.js index fa8f3a4..db9d114 100644 --- a/controllers/movies.js +++ b/controllers/movies.js @@ -42,6 +42,14 @@ exports.moviesController = { movie.current_customers(movie_title, function(current_customers) { return res.status(200).json(current_customers); - }) + }); + }, + + past_customers: function past_customers(req, res) { + var movie_title = req.params.title; + + movie.past_customers(movie_title, function(past_customers) { + return res.status(200).json(past_customers); + }); } } From bc6960dcdfb75a865bceaf3868d33da17ab1705c Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Mon, 21 Sep 2015 14:06:19 -0700 Subject: [PATCH 42/93] Adds new route for past_customers. --- routes/movies.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/routes/movies.js b/routes/movies.js index 92d8f7d..e481648 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -22,4 +22,8 @@ router.get('/:title/current_customers', function(req, res, next) { return movie_exports.moviesController.current_customers(req, res); }); +router.get('/:title/past_customers', function(req, res, next) { + return movie_exports.moviesController.past_customers(req, res); +}); + module.exports = router; From dde32230d1ed86b25ed5bd9fb643772b86ec4ae4 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Mon, 21 Sep 2015 14:09:06 -0700 Subject: [PATCH 43/93] Adds current_customers and past_customers to model methods. --- database.js | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/database.js b/database.js index 4adf4f4..33e6bb8 100644 --- a/database.js +++ b/database.js @@ -39,8 +39,25 @@ module.exports = { }, current_customers: function(movie_title, callback) { - // we want customers who currently have a rental with this movie title - this.query("SELECT * FROM customers, rentals WHERE customers.id=rentals.customer_id AND rentals.movie_title LIKE '%" + movie_title + "%' AND rentals.check_in IS NULL;", function(res) { + this.query("SELECT customers.id, customers.name, customers.registered_at, \ + customers.address, customers.city, customers.state, \ + customers.postal_code, customers.phone, customers.account_credit \ + FROM customers, rentals \ + WHERE customers.id=rentals.customer_id \ + AND rentals.movie_title LIKE '%" + movie_title + "%' \ + AND rentals.check_in IS NULL;", function(res) { + callback(res); + }); + }, + + past_customers: function(movie_title, callback) { + this.query("SELECT customers.id, customers.name, customers.registered_at, \ + customers.address, customers.city, customers.state, \ + customers.postal_code, customers.phone, customers.account_credit \ + FROM customers, rentals \ + WHERE customers.id=rentals.customer_id \ + AND rentals.movie_title LIKE '%" + movie_title + "%' \ + AND rentals.check_in IS NOT NULL;", function(res) { callback(res); }); } From 074f35f0aac2288ffdb817ba7dec4caaf56e797f Mon Sep 17 00:00:00 2001 From: Brenna Date: Mon, 21 Sep 2015 14:18:53 -0700 Subject: [PATCH 44/93] created initial rentals files (controller, model, routes) --- controllers/rentals.js | 20 ++++++++++++++++++++ database.js | 6 ++++++ rentals.js | 10 ++++++++++ routes/rentals.js | 13 +++++++++++++ 4 files changed, 49 insertions(+) create mode 100644 rentals.js diff --git a/controllers/rentals.js b/controllers/rentals.js index e69de29..715b916 100644 --- a/controllers/rentals.js +++ b/controllers/rentals.js @@ -0,0 +1,20 @@ +"use strict"; + +var Rentals = require('../rentals'); +var rental = new Rental(); + +exports.rentalsController = { + + all: function all(req, res) { + var rentals = rental.all(function(rentals) { + return res.status(200).json(rentals); + }); + }, + + rental_info: function(movie_title, callback) { + // list of past rentals based on customer id + this.query("SELECT * FROM rentals WHERE customer_id=" + id + " AND check_in IS NOT NULL ORDER BY check_out" + ";", function(res) { + callback(res); + }); + } +} diff --git a/database.js b/database.js index 0664902..fa90fc7 100644 --- a/database.js +++ b/database.js @@ -53,12 +53,18 @@ module.exports = { // Get a list of customers that have currently checked out a copy of the film // rentals = select * from rentals where movie_title = title and check_in = null + // select current_customers: function(movie_title, callback) { // we want customers who currently have a rental with this movie title this.query("SELECT customers.name FROM customers, rentals WHERE customers.id=rentals.customer_id AND rentals.movie_title LIKE '%" + movie_title + "%' AND rentals.check_in IS NULL;", function(res) { callback(res); }); + }, + + // current customers with movie checkout out + rental_info: function(movie_title, callback) { + } } diff --git a/rentals.js b/rentals.js new file mode 100644 index 0000000..7555f3d --- /dev/null +++ b/rentals.js @@ -0,0 +1,10 @@ +"use-strict"; +var sqlite3 = require('sqlite3').verbose(); + +function Rental() { + this.table_name = "rentals"; +} + +Rental.prototype = require('./database'); + +module.exports = Rental; diff --git a/routes/rentals.js b/routes/rentals.js index e69de29..a513d48 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -0,0 +1,13 @@ +var express = require('express'); +var router = express.Router(); +var rental_exports = require('../controllers/rentals'); + +router.get('/', function(req, res, next) { + return rental_exports.rentalsController.all(req, res); +}); + +router.get('/:movie_title/rental_info', function(req, res, next) { + return rental_exports.rentalsController.rental_info(req, res); +}); + +module.exports = router; From 7203214e06b63b354dd1de9bf2bc94597d2b47a9 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Mon, 21 Sep 2015 14:33:31 -0700 Subject: [PATCH 45/93] Adds route for past customers sorted by id. --- routes/movies.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/routes/movies.js b/routes/movies.js index e481648..4830319 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -26,4 +26,8 @@ router.get('/:title/past_customers', function(req, res, next) { return movie_exports.moviesController.past_customers(req, res); }); +router.get('/:title/past_customers/customer_id_sort', function(req, res, next) { + return movie_exports.moviesController.past_customers_id_sort(req, res); +}); + module.exports = router; From 61da6864a43954dc2c42dc5c55a9d6bbf9b7e943 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Mon, 21 Sep 2015 14:33:59 -0700 Subject: [PATCH 46/93] Adds some seed data for rentals for testing. --- db/development.db | Bin 144384 -> 144384 bytes utils/rentals.json | 24 ++++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/db/development.db b/db/development.db index d8282677e817c5c0b28c965d3506d6d8c2831d70..a6de205097ddff97ac57ccbea68c8d852c918b19 100644 GIT binary patch delta 1179 zcmYk4&udgy6oB7-_q@rQI+`&VHHkCHm>(uFiHym_h9D(^ifv30JBC=S4K!j3P1;C7 z10bSt2HOWn6%ma&Tn`(`!&j+M|ESU}G1!mWgCy<@YVdsE z)AwOK{O>sY?ewMe@b}Y~>;eCOx&0qE0HXAndeyQ+2 zBV~DIG<`wSza#B0O1V1oh*DlbvrbD%l7@HV1Q`wP5{S#kaZ<~XXGXtXWr1aFV$CqO zzBSiM@>A&M-7~HFTr&&IJYpuRGcPLDp|`HURpTbY$oSwuH*vSLdzuC*q4E_*&pgpt)vTb6fQ33Hmz>eAvE3{dE?9?K*=rQm}N F`yO}d(T@NC delta 1081 zcmXYu&r4KM6oB7-_snx9CYyA$anv#$Q%S?jLL$nbqF;uTg@KvS1TGR%0u79r7gkyZ zMlB**1XIkS7S$`pWeXQBTC@m)aM7a0`~j^hX8KMz@O^XNz4zRE&birQI9m)aC99H+ zj^jLp5S(-z_t2xx9yi(eZtS%++k&XH+Dz9K);3>8H%HK}VKj9fEu2GjXVI}UC_8}m zoI>g2Xz>`jdIUW7hJtALkQNxur;_rtjM7OI~@7spZMC>j_-cTS+YTH{8or$%%4x1nSlRczRZ zJsWZCcl+Kh*h{vHkM&=n?xmS@A2&7329Zs!F*}23ti@!s2YR&L(F9vSbGr?ba38ej zdeED?;38~>o1l%8s5vUZ(8w_z~IAa2lG{mL>3 z>-se*NYS|Azpvqpl@@iNo>>>Pn*xWURNSMuHumc12?>SS62zM5DN z>eGN?JTGsIyb=>zzf7-Am_$yN81$M%UT)~rpdo=(<4VCBHl>PJ!pV}>s96?fj2jQU zUz`|PlS1f;Dc9%av&MZe(VV>C-g!P&xmU*Zj5SlTdOVXqO}rp6S8MoNrg<~koTnvQ mpl}_&)s8;bpcR5X%Kse3OxYGf2~4)ypJmE=qnnn@Z~G5<=e%72 diff --git a/utils/rentals.json b/utils/rentals.json index b78a009..efd1693 100644 --- a/utils/rentals.json +++ b/utils/rentals.json @@ -47,5 +47,29 @@ "overdue": 1, "customer_id": 8, "movie_title": "King Kong" + }, + { + "check_out": "2015-07-03", + "check_in": "", + "due_date": "2015-07-06", + "overdue": 1, + "customer_id": 9, + "movie_title": "King Kong" + }, + { + "check_out": "2015-07-03", + "check_in": "2015-07-06", + "due_date": "2015-07-06", + "overdue": 0, + "customer_id": 9, + "movie_title": "King Kong" + }, + { + "check_out": "2014-07-03", + "check_in": "2014-07-06", + "due_date": "2014-07-06", + "overdue": 0, + "customer_id": 3, + "movie_title": "King Kong" } ] From 9b99d30dfdef2c7e8f9be5dd15b5bc1dbae07f21 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Mon, 21 Sep 2015 14:34:40 -0700 Subject: [PATCH 47/93] Adds past_customers_id_sort endpoint. --- controllers/movies.js | 8 ++++++++ database.js | 15 ++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/controllers/movies.js b/controllers/movies.js index db9d114..519ed7c 100644 --- a/controllers/movies.js +++ b/controllers/movies.js @@ -51,5 +51,13 @@ exports.moviesController = { movie.past_customers(movie_title, function(past_customers) { return res.status(200).json(past_customers); }); + }, + + past_customers_id_sort: function past_customers_id_sort(req, res) { + var movie_title = req.params.title; + + movie.past_customers_id_sort(movie_title, function(past_customers_sorted_by_id) { + return res.status(200).json(past_customers_sorted_by_id); + }); } } diff --git a/database.js b/database.js index 33e6bb8..162fd71 100644 --- a/database.js +++ b/database.js @@ -60,7 +60,20 @@ module.exports = { AND rentals.check_in IS NOT NULL;", function(res) { callback(res); }); + }, + + past_customers_id_sort: function(movie_title, callback) { + this.query("SELECT customers.id, customers.name, customers.registered_at, \ + customers.address, customers.city, customers.state, \ + customers.postal_code, customers.phone, customers.account_credit \ + FROM customers, rentals \ + WHERE customers.id=rentals.customer_id \ + AND rentals.movie_title LIKE '%" + movie_title + "%' \ + AND rentals.check_in IS NOT NULL \ + ORDER BY rentals.customer_id;", function(res) { + callback(res); + }); } } -// We want to export the Database into the overall node structure +// SELECT customers.id, customers.name FROM customers, rentals WHERE customers.id=rentals.customer_id AND rentals.movie_title LIKE '%" + movie_title + "%' AND rentals.check_in IS NOT NULL ORDER BY rentals.customer_id; From 3e45a98b063a6895dbfb8412e7e3f1d34118108d Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Mon, 21 Sep 2015 14:57:23 -0700 Subject: [PATCH 48/93] Adds route for past customers sorted by name. --- routes/movies.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/routes/movies.js b/routes/movies.js index 4830319..aebbaa4 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -30,4 +30,8 @@ router.get('/:title/past_customers/customer_id_sort', function(req, res, next) { return movie_exports.moviesController.past_customers_id_sort(req, res); }); +router.get('/:title/past_customers/customer_name_sort', function(req, res, next) { + return movie_exports.moviesController.past_customers_name_sort(req, res); +}); + module.exports = router; From 51977efdf69c51999b1a8e948e4daba11991f5f2 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Mon, 21 Sep 2015 14:57:47 -0700 Subject: [PATCH 49/93] Adds endpoint for past_customers_sort_by_name --- controllers/movies.js | 12 +++++++++++- database.js | 4 ++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/controllers/movies.js b/controllers/movies.js index 519ed7c..f81b0d2 100644 --- a/controllers/movies.js +++ b/controllers/movies.js @@ -55,9 +55,19 @@ exports.moviesController = { past_customers_id_sort: function past_customers_id_sort(req, res) { var movie_title = req.params.title; + var sort_type = "id"; - movie.past_customers_id_sort(movie_title, function(past_customers_sorted_by_id) { + movie.past_customers_sort(movie_title, sort_type, function(past_customers_sorted_by_id) { return res.status(200).json(past_customers_sorted_by_id); }); + }, + + past_customers_name_sort: function past_customers_name_sort(req, res) { + var movie_title = req.params.title; + var sort_type = "name"; + + movie.past_customers_sort(movie_title, sort_type, function(past_customers_sorted_by_name) { + return res.status(200).json(past_customers_sorted_by_name); + }); } } diff --git a/database.js b/database.js index 162fd71..db0a839 100644 --- a/database.js +++ b/database.js @@ -62,7 +62,7 @@ module.exports = { }); }, - past_customers_id_sort: function(movie_title, callback) { + past_customers_sort: function(movie_title, sort_type, callback) { this.query("SELECT customers.id, customers.name, customers.registered_at, \ customers.address, customers.city, customers.state, \ customers.postal_code, customers.phone, customers.account_credit \ @@ -70,7 +70,7 @@ module.exports = { WHERE customers.id=rentals.customer_id \ AND rentals.movie_title LIKE '%" + movie_title + "%' \ AND rentals.check_in IS NOT NULL \ - ORDER BY rentals.customer_id;", function(res) { + ORDER BY customers." + sort_type + ";", function(res) { callback(res); }); } From 39be395b2a2ec6845930d0b53354511170c67b12 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Mon, 21 Sep 2015 15:14:22 -0700 Subject: [PATCH 50/93] Adds some seed data. --- db/development.db | Bin 144384 -> 144384 bytes utils/rentals.json | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/db/development.db b/db/development.db index a6de205097ddff97ac57ccbea68c8d852c918b19..ae2ac88179247889a606056703906901aaf14616 100644 GIT binary patch delta 1070 zcmW-e%}Z2K7>DQFd+u<<4@Mnz{4PII@qwA7Eb z?x9#OYUx3fU8wsus=tLgZldN6)Y*wM@2zF1+WVLG&B$sA z-w3xfhnwWtCQt8YW<;romma84Q8^-A=Yw3o4Wl3vU4vYZq*Jg8(v}32ITV46YaKFR z7NnyFSOS^n7Q~QmxS_L+)f0xn;%f_zWU2t9MxpNTgHIh@z=^7LzLA>bEQwRnXOE^i@NOg#SP# zi#%N;g+8iO8k3M-j@bBB1rqu<&Bv_(iL475#2*!m>th1xzmjqwNo$i*$2KHZ@G{mR epTA4R3CXHIUk>0@ju#sgK9d_>)4`s)F#iMHZNZ5E delta 1070 zcmW-f%}W$v7{K?Pd1l&ZlTp`iT`e^gS6Ou}kq847`y|R_1v8-yI^;nK)I+!vS*8XG z9wIsf8*EUAVvP0Bp<{;*9fArxcGy3lLqx3o9uL3YJoA1$^FGfznL;>I2yfPw#hg$m z^c3`YJ`}Rnw&J~3%y~ca#x|otL|X0T(p$_uxQUjhP<0A5Uq=hqP|H;`aTyI=LcJHz z;24UJqLE>=aTcY|puW>6Gl-rHpzf1sDT%sz(0BsPb)%!5=urpiY}0SnwV;OMsN@)` zZ$J-g(d`;kQ;jMr(MmbGGzdo*>uOQp@ep8AxZ)`-B!QUfatkV9( zsYG9IqDP-6^%;CGNgC4>M7(CR+{8jnrCVoV6=Ki^n&~k_VI8!srQpK@SO#rCKQzMv zXuBq02wI^Rw758oKs#(e8u~OvhTsWkWqJWi&;?rB9B8kP!XwbTsRO-)gDc^weR>GD zL9awBuYeWM-(nJUk6zLmXpgI)2|7bTSJ}^oz#S^uAH*05oPm8iEA^6^CFf-__D}kn#plX^6re$*RQ;$G+{<}E|M%EIf)p89j3N* zWrCGCiCau~%~&*<(kEj-E89bR)zRL5Si$lc?NdERyY Z3j14VsSHrwJr3(`YUR5{3VQL+{tsMPz>xp| diff --git a/utils/rentals.json b/utils/rentals.json index efd1693..0873bb7 100644 --- a/utils/rentals.json +++ b/utils/rentals.json @@ -57,9 +57,9 @@ "movie_title": "King Kong" }, { - "check_out": "2015-07-03", - "check_in": "2015-07-06", - "due_date": "2015-07-06", + "check_out": "2013-07-03", + "check_in": "2013-07-06", + "due_date": "2013-07-06", "overdue": 0, "customer_id": 9, "movie_title": "King Kong" From c79192cd4c6ba3151e66789bdcbec17e1e570473 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Mon, 21 Sep 2015 15:14:57 -0700 Subject: [PATCH 51/93] Adds sort by checkout date to movies. --- controllers/movies.js | 13 +++++++++++-- database.js | 2 +- routes/movies.js | 4 ++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/controllers/movies.js b/controllers/movies.js index f81b0d2..6d3c5b2 100644 --- a/controllers/movies.js +++ b/controllers/movies.js @@ -55,7 +55,7 @@ exports.moviesController = { past_customers_id_sort: function past_customers_id_sort(req, res) { var movie_title = req.params.title; - var sort_type = "id"; + var sort_type = "customers.id"; movie.past_customers_sort(movie_title, sort_type, function(past_customers_sorted_by_id) { return res.status(200).json(past_customers_sorted_by_id); @@ -64,10 +64,19 @@ exports.moviesController = { past_customers_name_sort: function past_customers_name_sort(req, res) { var movie_title = req.params.title; - var sort_type = "name"; + var sort_type = "customers.name"; movie.past_customers_sort(movie_title, sort_type, function(past_customers_sorted_by_name) { return res.status(200).json(past_customers_sorted_by_name); }); + }, + + past_customers_checkout_date_sort: function past_customers_checkout_date_sort(req, res) { + var movie_title = req.params.title; + var sort_type = "rentals.check_out"; + + movie.past_customers_sort(movie_title, sort_type, function(past_customers_sorted_by_checkout_date) { + return res.status(200).json(past_customers_sorted_by_checkout_date); + }); } } diff --git a/database.js b/database.js index db0a839..a8708ad 100644 --- a/database.js +++ b/database.js @@ -70,7 +70,7 @@ module.exports = { WHERE customers.id=rentals.customer_id \ AND rentals.movie_title LIKE '%" + movie_title + "%' \ AND rentals.check_in IS NOT NULL \ - ORDER BY customers." + sort_type + ";", function(res) { + ORDER BY " + sort_type + ";", function(res) { callback(res); }); } diff --git a/routes/movies.js b/routes/movies.js index aebbaa4..d061ae3 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -34,4 +34,8 @@ router.get('/:title/past_customers/customer_name_sort', function(req, res, next) return movie_exports.moviesController.past_customers_name_sort(req, res); }); +router.get('/:title/past_customers/checkout_date_sort', function(req, res, next) { + return movie_exports.moviesController.past_customers_checkout_date_sort(req, res); +}); + module.exports = router; From d433ef5125e3b403b4f782b19fd11188516c88b7 Mon Sep 17 00:00:00 2001 From: Brenna Date: Mon, 21 Sep 2015 15:26:32 -0700 Subject: [PATCH 52/93] overdue in rentals endpoints is functioning --- app.js | 4 ++-- controllers/rentals.js | 9 ++++----- database.js | 35 ++++++++++++++++++++++------------- routes/rentals.js | 8 ++++++-- 4 files changed, 34 insertions(+), 22 deletions(-) diff --git a/app.js b/app.js index 937aeb5..f5bd25b 100644 --- a/app.js +++ b/app.js @@ -9,7 +9,7 @@ var bodyParser = require('body-parser'); var routes = require('./routes/index'); var movies = require('./routes/movies'); var customers = require('./routes/customers'); -// var rentals = require('./routes/rentals'); +var rentals = require('./routes/rentals'); var app = express(); @@ -30,7 +30,7 @@ app.use(express.static(path.join(__dirname, 'public'))); app.use('/', routes); app.use('/customers', customers); app.use('/movies', movies); -// app.use('/rentals', rentals); +app.use('/rentals', rentals); // catch 404 and forward to error handler diff --git a/controllers/rentals.js b/controllers/rentals.js index 715b916..e64013e 100644 --- a/controllers/rentals.js +++ b/controllers/rentals.js @@ -1,6 +1,6 @@ "use strict"; -var Rentals = require('../rentals'); +var Rental = require('../rentals'); var rental = new Rental(); exports.rentalsController = { @@ -11,10 +11,9 @@ exports.rentalsController = { }); }, - rental_info: function(movie_title, callback) { - // list of past rentals based on customer id - this.query("SELECT * FROM rentals WHERE customer_id=" + id + " AND check_in IS NOT NULL ORDER BY check_out" + ";", function(res) { - callback(res); + overdue: function overdue(req, res) { + rental.overdue(function(overdue) { + return res.status(200).json(overdue); }); } } diff --git a/database.js b/database.js index fa90fc7..0889b90 100644 --- a/database.js +++ b/database.js @@ -31,6 +31,7 @@ module.exports = { }); }, + // MOVIES movie_info: function(movie_title, callback) { this.query("SELECT * FROM " + this.table_name + " WHERE title LIKE '%" + movie_title + "%';", function(res) { callback(res); @@ -51,21 +52,29 @@ module.exports = { }); }, -// Get a list of customers that have currently checked out a copy of the film - // rentals = select * from rentals where movie_title = title and check_in = null - // select - + // CUSTOMERS current_customers: function(movie_title, callback) { - // we want customers who currently have a rental with this movie title - this.query("SELECT customers.name FROM customers, rentals WHERE customers.id=rentals.customer_id AND rentals.movie_title LIKE '%" + movie_title + "%' AND rentals.check_in IS NULL;", function(res) { + this.query("SELECT customers.id, customers.name, customers.registered_at, \ + customers.address, customers.city, customers.state, \ + customers.postal_code, customers.phone, customers.account_credit \ + FROM customers, rentals \ + WHERE customers.id=rentals.customer_id \ + AND rentals.movie_title LIKE '%" + movie_title + "%' \ + AND rentals.check_in IS NULL;", function(res) { + callback(res); + }); + }, + + // RENTALS + overdue: function(callback) { + this.query("SELECT customers.id, customers.name, customers.registered_at, \ + customers.address, customers.city, customers.state, \ + customers.postal_code, customers.phone, customers.account_credit \ + FROM customers, rentals \ + WHERE customers.id=rentals.customer_id \ + AND rentals.overdue = 1;", function(res) { callback(res); }); - }, - - // current customers with movie checkout out - rental_info: function(movie_title, callback) { - } -} -// We want to export the Database into the overall node structure +} diff --git a/routes/rentals.js b/routes/rentals.js index a513d48..cd06118 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -5,9 +5,13 @@ var rental_exports = require('../controllers/rentals'); router.get('/', function(req, res, next) { return rental_exports.rentalsController.all(req, res); }); +// +// router.get('/:movie_title', function(req, res, next) { +// return rental_exports.rentalsController.rented_by(req, res); +// }); -router.get('/:movie_title/rental_info', function(req, res, next) { - return rental_exports.rentalsController.rental_info(req, res); +router.get('/overdue', function(req, res, next){ + return rental_exports.rentalsController.overdue(req, res); }); module.exports = router; From 076f564830b0c307cfec86218fa26bd5d2a33f8f Mon Sep 17 00:00:00 2001 From: Brenna Date: Tue, 22 Sep 2015 11:21:33 -0700 Subject: [PATCH 53/93] WIP - setting up for testing --- test/controllers/rentals.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 test/controllers/rentals.js diff --git a/test/controllers/rentals.js b/test/controllers/rentals.js new file mode 100644 index 0000000..6509dd7 --- /dev/null +++ b/test/controllers/rentals.js @@ -0,0 +1,18 @@ +var request = require('supertest'), + assert = require('assert'), + app = require('../../app'), + sqlite3 = require('sqlite3').verbose(), + agent = request.agent(app); + +describe("rentals controller", function() { + describe("GET '/rentals'", function() { + it("knows about the route", function(done) { + agent.get('/rentals').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, result) { + assert.equal(error, undefined); + done(); + }) + }) + }) +}) From c295d72d4416bf16e464ae9bbf57c8ea78fcbf50 Mon Sep 17 00:00:00 2001 From: Brenna Date: Tue, 22 Sep 2015 11:49:43 -0700 Subject: [PATCH 54/93] 2 running tests but running into no rentals table error again --- db/development.db | Bin 0 -> 68608 bytes db/{development => test.db} | 0 package.json | 11 ++++++---- test/controllers/rentals.js | 39 +++++++++++++++++++++++++++++++++--- 4 files changed, 43 insertions(+), 7 deletions(-) create mode 100644 db/development.db rename db/{development => test.db} (100%) diff --git a/db/development.db b/db/development.db new file mode 100644 index 0000000000000000000000000000000000000000..5e7623bd4e2f9c39ec10f2b767ddb205d8465e6d GIT binary patch literal 68608 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 literal 0 HcmV?d00001 diff --git a/db/development b/db/test.db similarity index 100% rename from db/development rename to db/test.db diff --git a/package.json b/package.json index ce7b906..6dae3d2 100644 --- a/package.json +++ b/package.json @@ -4,18 +4,21 @@ "private": true, "scripts": { "start": "node ./bin/www", - "db:schema" : "node ./utils/schema", - "db:seed" : "node ./utils/seed", - "db:setup" : "npm run db:schema; npm run db:seed" + "test": "clear; DB=test mocha --recursive", + "db:schema": "node ./utils/schema", + "db:seed": "node ./utils/seed", + "db:setup": "npm run db:schema; npm run db:seed" }, "dependencies": { "body-parser": "~1.13.2", "cookie-parser": "~1.3.5", "debug": "~2.2.0", "express": "~4.13.1", + "mocha": "^2.3.2", "jade": "~1.11.0", "morgan": "~1.6.1", "serve-favicon": "~2.3.0", - "sqlite3": "^3.1.0" + "sqlite3": "^3.1.0", + "supertest": "^1.1.0" } } diff --git a/test/controllers/rentals.js b/test/controllers/rentals.js index 6509dd7..07cf522 100644 --- a/test/controllers/rentals.js +++ b/test/controllers/rentals.js @@ -2,9 +2,30 @@ var request = require('supertest'), assert = require('assert'), app = require('../../app'), sqlite3 = require('sqlite3').verbose(), - agent = request.agent(app); + agent = request.agent(app), + Rental = require('../../rentals'); describe("rentals controller", function() { + var rental, db_cleaner + + beforeEach(function(done) { + rental = new Rental(); + + db_cleaner = new sqlite3.Database('db/test.db'); + db_cleaner.serialize(function() { + db_cleaner.exec( + "BEGIN; \ + DELETE FROM rentals; \ + INSERT INTO rentals(check_out, check_in, due_date, overdue, movie_title, customer_id) \ + VALUES('2015-06-16', '2015-06-17', '2015-06-19', 0, 1, 'Jaws'), \ + ('2015-06-16', '2015-06-17', '2015-06-19', 0, 1, 'Alien'); COMMIT;" + , function(err) { + db_cleaner.close(); + done(); + } + ); + }); + }) describe("GET '/rentals'", function() { it("knows about the route", function(done) { agent.get('/rentals').set('Accept', 'application/json') @@ -12,7 +33,19 @@ describe("rentals controller", function() { .expect(200, function(error, result) { assert.equal(error, undefined); done(); - }) - }) + }); + }); + + it("returns an array of rental objects", function() { + agent.get('/rentals').set("Accept", "application/json") + .expect(200, function(error, result) { + console.log(result.body); + assert.equal(result.body.length, 2); + + var keys = ['id', 'check_out', 'check_in', 'due_date', 'overdue', 'movie_title', 'customer_id']; + assert.deepEqual(Object.keys(result.body[0]), keys); + done(); + }); + }); }) }) From 0d0e825b435d4eab0527393df3139568c06a4351 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Tue, 22 Sep 2015 11:52:38 -0700 Subject: [PATCH 55/93] removes development file. --- db/development | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 db/development diff --git a/db/development b/db/development deleted file mode 100644 index e69de29..0000000 From a851f1e68d66d56f54275a4fdb016e95b431712e Mon Sep 17 00:00:00 2001 From: Brenna Date: Tue, 22 Sep 2015 13:16:12 -0700 Subject: [PATCH 56/93] added db to git ignore and created test db --- .gitignore | 1 + db/test.db | Bin 0 -> 4096 bytes 2 files changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 7595163..2cbab91 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .DS_Store node_modules npm-debug.log +db diff --git a/db/test.db b/db/test.db index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ff7c67038335866c11206c4bb99fe88aea2a9a76 100644 GIT binary patch literal 4096 zcmeHGPjAyO6t|N~9YQ-oH|?+&xKK!?4zwXS5k^2|1wko?og$NXokbcW`?X^dm-fqW z-G|{b@HueP#M>mgi5r@1$@cqa`~80J`P0X~Kn_PzjTyod(jb(Q7XXBi4Ko{N*5j@b zF6y*)T(NJE&hOjn{ypN;GvfWAXa4>b(av=(1GApjY;AATIYag(=jlYF9CM|u;O`IO zXc)sVdfAV`n&E-Sp!a?lzljI%VbFUQ4G!TTJ`AB?V-Co_V+e|mghsA-mY8M`1@aMB zA+Rh{T|vt=fpzFInzAJ&NCIolou$~={Z7cO4yW%e8Ft( zY@3n;YRsmoEFTa6?==IPf&POv7s)J0LL+2j(E z1y*CKQ-xRY>*#ZT2;C4$%91598kHzUp>2l5v_e(f_WGjZF8=CkJJ1C<1{?!7g#q{f zZ%QQ{4#&X1GqCvop8u2hzs%x>W56-+KQi#hTO&abtlero?(Xb%x_h0SJu5x6(z7TR Sym&~f;5*jw*WkD8ME?O Date: Tue, 22 Sep 2015 13:18:04 -0700 Subject: [PATCH 57/93] typo --- test/controllers/rentals.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/controllers/rentals.js b/test/controllers/rentals.js index 07cf522..5109972 100644 --- a/test/controllers/rentals.js +++ b/test/controllers/rentals.js @@ -18,7 +18,7 @@ describe("rentals controller", function() { DELETE FROM rentals; \ INSERT INTO rentals(check_out, check_in, due_date, overdue, movie_title, customer_id) \ VALUES('2015-06-16', '2015-06-17', '2015-06-19', 0, 1, 'Jaws'), \ - ('2015-06-16', '2015-06-17', '2015-06-19', 0, 1, 'Alien'); COMMIT;" + ('2015-06-16', '2015-06-17', '2015-06-19', 1, 1, 'Alien'); COMMIT;" , function(err) { db_cleaner.close(); done(); From 8e1251a869929f8ca0c65823f373e375f2d09724 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Tue, 22 Sep 2015 13:18:26 -0700 Subject: [PATCH 58/93] Adds db file to gitignore. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 7595163..2cbab91 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .DS_Store node_modules npm-debug.log +db From 4aae28945a5a27d13e8c11d5db28684f6554a39a Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Tue, 22 Sep 2015 13:19:38 -0700 Subject: [PATCH 59/93] Adds db to gitignore. --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 2cbab91..d7f09c1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ .DS_Store node_modules npm-debug.log -db +./db From 4b31ffdc12fe496de62ca4e326b7dc3c5a5198db Mon Sep 17 00:00:00 2001 From: Brenna Date: Tue, 22 Sep 2015 13:23:52 -0700 Subject: [PATCH 60/93] fixed git ignore file --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 2cbab91..f923ceb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ .DS_Store node_modules npm-debug.log -db +db/ From 3eed1ab11a9218b3b84497bd151c9904411235b5 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Tue, 22 Sep 2015 13:48:34 -0700 Subject: [PATCH 61/93] Adds test for /rentals/overdue endpoint. --- database.js | 6 ++--- db/test.db | Bin 4096 -> 4096 bytes test/controllers/rentals.js | 43 ++++++++++++++++++++++++++++-------- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/database.js b/database.js index f3bd92c..52f54ba 100644 --- a/database.js +++ b/database.js @@ -9,8 +9,8 @@ module.exports = { db.serialize(function() { // below: this is the callback pattern...parameters(ERRORS, RESULT) db.all(statement, function(err, res) { - console.log(statement); - console.log(err); + // console.log(statement); + // console.log(err); // error handling looks like -> if (err) { }; if (callback) { callback(res); } }); @@ -97,7 +97,7 @@ module.exports = { customers.postal_code, customers.phone, customers.account_credit \ FROM customers, rentals \ WHERE customers.id=rentals.customer_id \ - AND rentals.overdue = 1;", function(res) { + AND rentals.overdue=1;", function(res) { callback(res); }); } diff --git a/db/test.db b/db/test.db index ff7c67038335866c11206c4bb99fe88aea2a9a76..6a8e5717a940d003abf5ebeecc5002ebdfe75fd2 100644 GIT binary patch delta 172 zcmZorXi%6SEm+9Fz`z2;FrYtC$C$BjV?rS#Bg^DVj7J%nC(mG7%E&a?j#&vvCNeMP zVPam+zM@%NdxjFfZRM$T6FlOPh& Date: Tue, 22 Sep 2015 13:59:05 -0700 Subject: [PATCH 62/93] WIP movie controller tests --- db/test.db | Bin 4096 -> 4096 bytes test/controllers/movies.js | 76 +++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 test/controllers/movies.js diff --git a/db/test.db b/db/test.db index 6a8e5717a940d003abf5ebeecc5002ebdfe75fd2..38f7b97ac2cf43985c52820163b16111e656cf7f 100644 GIT binary patch delta 17 YcmZorXi%6S%~(27#+k8nW5NP{05DPohyVZp delta 17 YcmZorXi%6S%~&{5#+k8jW5NP{05BE>fB*mh diff --git a/test/controllers/movies.js b/test/controllers/movies.js new file mode 100644 index 0000000..4f02a4a --- /dev/null +++ b/test/controllers/movies.js @@ -0,0 +1,76 @@ +var request = require('supertest'), + assert = require('assert'), + app = require('../../app'), + sqlite3 = require('sqlite3').verbose(), + agent = request.agent(app), + Movie = require('../../movies'); + +describe("movies controller", function() { + var movie, db_cleaner; + + beforeEach(function(done) { + movie = new Movie(); + + db_cleaner = new sqlite3.Database('db/test.db'); + db_cleaner.serialize(function() { + db_cleaner.exec( + "BEGIN; \ + DELETE FROM movies; DELETE FROM customers; \ + INSERT INTO movies(title, overview, release_date, overdue, movie_title, customer_id) \ + VALUES('2015-06-16', '2015-06-17', '2015-06-19', 0, 'Jaws', 1), \ + ('2015-06-16', '2015-06-17', '2015-06-19', 1, 'Alien', 1); \ + INSERT INTO customers(name, registered_at, address, city, state, postal_code, phone, account_credit) \ + VALUES('Harry', '2015-06-16', '1234', 'Seattle', 'WA', '98103', '1234567', 123);\ + COMMIT;" + , function(err) { + db_cleaner.close(); + done(); + } + ); + }); + }); + + describe("GET '/rentals'", function() { + it("knows about the route", function(done) { + agent.get('/rentals').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, result) { + assert.equal(error, undefined); + done(); + }); + }); + + it("returns an array of rental objects", function(done) { + agent.get('/rentals').set("Accept", "application/json") + .expect(200, function(error, result) { + assert.equal(result.body.length, 2); + + var keys = ['id', 'check_out', 'check_in', 'due_date', 'overdue', 'movie_title', 'customer_id']; + assert.deepEqual(Object.keys(result.body[0]), keys); + done(); + }); + }); + }); + + describe("GET '/rentals/overdue'", function() { + it("knows about the route", function(done) { + agent.get('/rentals/overdue').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, result) { + assert.equal(error, undefined); + done(); + }); + }); + + it("returns an array of overdue rental objects", function(done) { + agent.get('/rentals/overdue').set("Accept", "application/json") + .expect(200, function(error, result) { + assert.equal(result.body.length, 1); + + var keys = ['id', 'name', 'registered_at', 'address', 'city', 'state', 'postal_code', 'phone', 'account_credit']; + assert.deepEqual(Object.keys(result.body[0]), keys); + done(); + }); + }); + }); +}); From 0dd001f7e7da38a920cc40bb492fd2e334286b56 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Tue, 22 Sep 2015 14:28:49 -0700 Subject: [PATCH 63/93] Adds tests for /customers. --- db/test.db | Bin 4096 -> 4096 bytes test/controllers/customers.js | 56 ++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 test/controllers/customers.js diff --git a/db/test.db b/db/test.db index 6a8e5717a940d003abf5ebeecc5002ebdfe75fd2..bfa3c93f602df703721b568bf0ea3b6cf356a02f 100644 GIT binary patch delta 83 zcmZorXi%6S&Db(g#+k8YW5OzKCgy3I1zEb7O^unj7=#r?Wd+5hnS%23j0_A-bPddO l4NVM Date: Tue, 22 Sep 2015 14:50:37 -0700 Subject: [PATCH 64/93] working test for all, release_date_sort and title_sort --- db/test.db | Bin 4096 -> 4096 bytes test/controllers/movies.js | 79 ++++++++++++++++++++++++++++--------- 2 files changed, 60 insertions(+), 19 deletions(-) diff --git a/db/test.db b/db/test.db index 38f7b97ac2cf43985c52820163b16111e656cf7f..8ddff4847dbedaad6e530647848bcad88149819b 100644 GIT binary patch delta 124 zcmZorXi%6S&G>Dij5Fi6jR{Mbc^Ft27?`gxFK1w2VA(9lF`aqxa`spbCg!~i%y*dg z0!215JIgY$Gl(mTGBP^mWTxij=cX$pf*8e$hL$FlEG$Zl> Date: Tue, 22 Sep 2015 15:05:15 -0700 Subject: [PATCH 65/93] current customers test working --- controllers/movies.js | 3 ++- db/test.db | Bin 4096 -> 4096 bytes test/controllers/movies.js | 25 +++++++++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/controllers/movies.js b/controllers/movies.js index 6d3c5b2..2f0ecd5 100644 --- a/controllers/movies.js +++ b/controllers/movies.js @@ -39,8 +39,9 @@ exports.moviesController = { current_customers: function current_customers(req, res) { var movie_title = req.params.title; - + console.log("movie title:" + movie_title) movie.current_customers(movie_title, function(current_customers) { + console.log(current_customers); return res.status(200).json(current_customers); }); }, diff --git a/db/test.db b/db/test.db index 8ddff4847dbedaad6e530647848bcad88149819b..45a47f1b92a88efe0e398eabb7fc25ab7007a3b1 100644 GIT binary patch delta 63 zcmZorXi%6S#l+||QN{^KZcJFh%)`XIk%9RNkYHe7*(}I0omoJeiGx8=QIS)eQxU{s On7o! Date: Tue, 22 Sep 2015 15:45:08 -0700 Subject: [PATCH 66/93] Adds tests for /customers/registered_at_sort/:number_of_responses/:offset --- db/test.db | Bin 4096 -> 4096 bytes test/controllers/customers.js | 38 ++++++++++++++++++++++++++++++---- test/controllers/rentals.js | 2 +- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/db/test.db b/db/test.db index bfa3c93f602df703721b568bf0ea3b6cf356a02f..a28f97a8342020d484253f91eaf253c4c1fb9a43 100644 GIT binary patch delta 127 zcmZorXi%6S%@{IK#+fl>W5P0Swu=nR7n$d87G#;soM^zr#URTfDk&%~&E%0N&|H;dL$MVRWce^Mu234 VQxi){a#F(`EiDWUj3MgHs{wjQAt3+& delta 136 zcmZorXi%6S&Db(g#+k8YW5P0Sw$lvErG%}aE4v@|d>G6D&i7#lG<8Z&Y+h%1Up12r*vBo-A_0=1cf cwV8p`1g9pJl;os_J6c*88W@8_OwG)z0R?6tvH$=8 diff --git a/test/controllers/customers.js b/test/controllers/customers.js index 3ce06ea..600a691 100644 --- a/test/controllers/customers.js +++ b/test/controllers/customers.js @@ -3,7 +3,8 @@ var request = require('supertest'), app = require('../../app'), sqlite3 = require('sqlite3').verbose(), agent = request.agent(app), - Customer = require('../../customers'); + Customer = require('../../customers'), + keys = ['id', 'name', 'registered_at', 'address', 'city', 'state', 'postal_code', 'phone', 'account_credit']; describe("customers controller", function() { var customer, db_cleaner; @@ -20,8 +21,8 @@ describe("customers controller", function() { VALUES('2015-06-16', '2015-06-17', '2015-06-19', 0, 'Jaws', 1), \ ('2015-06-16', '2015-06-17', '2015-06-19', 1, 'Alien', 1); \ INSERT INTO customers(name, registered_at, address, city, state, postal_code, phone, account_credit) \ - VALUES('Harry', '2015-06-16', '1234', 'Seattle', 'WA', '98103', '1234567', 123), \ - ('Ron', '2014-06-14', '1234', 'Pasadena', 'CA', '90222', '1234432', 321);\ + VALUES('Harry', 20150616, '1234', 'Seattle', 'WA', '98103', '1234567', 123), \ + ('Hermione', 20150501, '5678', 'London', 'UK', '99999', '1234568', 213); \ COMMIT;" , function(err) { db_cleaner.close(); @@ -47,10 +48,39 @@ describe("customers controller", function() { .expect(200, function(error, result) { assert.equal(result.body.length, 2); - var keys = ['id', 'name', 'registered_at', 'address', 'city', 'state', 'postal_code', 'phone', 'account_credit']; assert.deepEqual(Object.keys(result.body[0]), keys); done(); }); }); }); + + describe("GET '/customers/registered_at_sort/:records_per_page/:offset'", function() { + it("knows about the route", function(done) { + agent.get('/customers/registered_at_sort/1/2').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, result) { + assert.equal(error, undefined); + done(); + }); + }); + + it("returns an array of n customer objects offset by p", function(done) { + agent.get('/customers/registered_at_sort/1/0').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, result) { + assert.equal(result.body.length, 1); + + assert.deepEqual(Object.keys(result.body[0]), keys); + done(); + }); + }); + + it("the returned array is sorted by registered_at field", function(done) { + agent.get('/customers/registered_at_sort/1/0') + .expect(200, function(error, result) { + assert.equal(result.body[0].name, "Hermione"); + done(); + }); + }); + }); }); diff --git a/test/controllers/rentals.js b/test/controllers/rentals.js index c8e85b2..5de9681 100644 --- a/test/controllers/rentals.js +++ b/test/controllers/rentals.js @@ -20,7 +20,7 @@ describe("rentals controller", function() { VALUES('2015-06-16', '2015-06-17', '2015-06-19', 0, 'Jaws', 1), \ ('2015-06-16', '2015-06-17', '2015-06-19', 1, 'Alien', 1); \ INSERT INTO customers(name, registered_at, address, city, state, postal_code, phone, account_credit) \ - VALUES('Harry', '2015-06-16', '1234', 'Seattle', 'WA', '98103', '1234567', 123);\ + VALUES('Harry', 20150616, '1234', 'Seattle', 'WA', '98103', '1234567', 123); \ COMMIT;" , function(err) { db_cleaner.close(); From 0014c9ed8ae04fcf7a5dabc88c8b6d5bd05e0439 Mon Sep 17 00:00:00 2001 From: Brenna Date: Tue, 22 Sep 2015 15:58:45 -0700 Subject: [PATCH 67/93] movies/:title/past_customers/customer_id_sort tests passing --- controllers/movies.js | 1 - db/test.db | Bin 4096 -> 4096 bytes test/controllers/movies.js | 56 ++++++++++++++++++++++++++++++++++++- 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/controllers/movies.js b/controllers/movies.js index 2f0ecd5..c9c6678 100644 --- a/controllers/movies.js +++ b/controllers/movies.js @@ -41,7 +41,6 @@ exports.moviesController = { var movie_title = req.params.title; console.log("movie title:" + movie_title) movie.current_customers(movie_title, function(current_customers) { - console.log(current_customers); return res.status(200).json(current_customers); }); }, diff --git a/db/test.db b/db/test.db index 45a47f1b92a88efe0e398eabb7fc25ab7007a3b1..5bd3d12284113e464fdda71e3198b315428fbbac 100644 GIT binary patch delta 172 zcmZorXi%6S#l&PVQN{^KZcJFh%)`vw!oYlmc{z|`*(}IX!px+|Jb5#_qOLX*2ZN%b zB8MoWk%6J9u7R1Zp#hv_1ZNq0C6*U6ZN9>8z{0`AJduIE9?d=Y>dpO8JJH4Rjgs2I6-vsX?{}xx(5=x diff --git a/test/controllers/movies.js b/test/controllers/movies.js index f7b77b2..216e65f 100644 --- a/test/controllers/movies.js +++ b/test/controllers/movies.js @@ -19,12 +19,14 @@ describe.only("movies controller", function() { DELETE FROM movies; DELETE FROM customers; DELETE FROM rentals; \ INSERT INTO rentals(check_out, check_in, due_date, overdue, movie_title, customer_id) \ VALUES('2015-06-16', '2015-06-17', '2015-06-19', 0, 'Jaws', 1), \ + ('2015-06-10', '2015-06-12', '2015-06-13', 0, 'Jaws', 2),\ ('2015-06-16', null, '2015-06-19', 1, 'Alien', 1); \ INSERT INTO movies(title, overview, release_date, inventory, inventory_available) \ VALUES('Jaws', 'omg sharks!', '1975-06-19', 6, 6), \ ('Alien', 'omg aliens!', 1979-05-25, 4, 4); \ INSERT INTO customers(name, registered_at, address, city, state, postal_code, phone, account_credit) \ - VALUES('Harry', '2015-06-16', '1234', 'Seattle', 'WA', '98103', '1234567', 123);\ + VALUES('Harry', '2015-06-16', '1234', 'Seattle', 'WA', '98103', '1234567', 123),\ + ('Hermione', '2015-06-10', '1234', 'Pasadena', 'CA', '97123', '7654321', 231);\ COMMIT;" , function(err) { db_cleaner.close(); @@ -139,4 +141,56 @@ describe.only("movies controller", function() { }); }); + describe("GET '/movies/Jaws/past_customers'", function() { + it("knows about the route", function(done) { + agent.get('/movies/Jaws/past_customers').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, result) { + assert.equal(error, undefined); + done(); + }); + }); + + it("returns an array of customers who have checked the movie out in the past", function(done) { + agent.get('/movies/Jaws/past_customers').set("Accept", "application/json") + .expect(200, function(error, result) { + assert.equal(result.body.length, 2); + customer_keys; + assert.deepEqual(Object.keys(result.body[0]), customer_keys); + done(); + }); + }); + }); + + describe("GET '/movies/Jaws/past_customers/customer_id_sort'", function() { + it("knows about the route", function(done) { + agent.get('/movies/Jaws/past_customers/customer_id_sort').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, result) { + assert.equal(error, undefined); + done(); + }); + }); + + it("returns an array of customers who have checked the movie out in the past", function(done) { + agent.get('/movies/Jaws/past_customers/customer_id_sort').set("Accept", "application/json") + .expect(200, function(error, result) { + assert.equal(result.body.length, 2); + customer_keys; + assert.deepEqual(Object.keys(result.body[0]), customer_keys); + done(); + }); + }); + + it("sorts the customers by id", function(done) { + agent.get('/movies/Jaws/past_customers/customer_id_sort').set("Accept", "application/json") + .expect(200, function(error, result) { + assert.equal(result.body[0].id, 1); + customer_keys; + assert.deepEqual(Object.keys(result.body[0]), customer_keys); + done(); + }); + }) + }); + }); // top level describe From 47787d894da142dc7ac74b6d97f9b89a49641386 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Tue, 22 Sep 2015 15:59:53 -0700 Subject: [PATCH 68/93] Adds tests for /customers/name_sort/:number_of_records/:offset --- controllers/customers.js | 2 +- db/test.db | Bin 4096 -> 4096 bytes test/controllers/customers.js | 34 +++++++++++++++++++++++++++++++++- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/controllers/customers.js b/controllers/customers.js index 979a554..d5d1223 100644 --- a/controllers/customers.js +++ b/controllers/customers.js @@ -9,7 +9,7 @@ var sortCustomers = function(sort_type, params, res) { var customers = customer.sort_by(sort_type, records_per_page, offset, function(customers) { return res.status(200).json(customers); }); -} +}; exports.customersController = { diff --git a/db/test.db b/db/test.db index a28f97a8342020d484253f91eaf253c4c1fb9a43..a2eb86510d46b87f2436caf77e31616829bedfc2 100644 GIT binary patch delta 17 YcmZorXi%6S&Db+h#+k8aW5NP{05Pitwg3PC delta 17 YcmZorXi%6S%@{IK#+fl>W5NP{04`$%MgRZ+ diff --git a/test/controllers/customers.js b/test/controllers/customers.js index 600a691..d632105 100644 --- a/test/controllers/customers.js +++ b/test/controllers/customers.js @@ -76,11 +76,43 @@ describe("customers controller", function() { }); it("the returned array is sorted by registered_at field", function(done) { - agent.get('/customers/registered_at_sort/1/0') + agent.get('/customers/registered_at_sort/1/0').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) .expect(200, function(error, result) { assert.equal(result.body[0].name, "Hermione"); done(); }); }); }); + + describe("GET /customers/name_sort/:records_per_page/:offset", function() { + it("knows about the route", function(done) { + agent.get("/customers/name_sort/1/0").set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, result) { + assert.equal(error, undefined); + done(); + }); + }); + + it("returns an array of n customer objects offset by p", function(done) { + agent.get('/customers/name_sort/2/0').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, result) { + assert.equal(result.body.length, 2); + + assert.deepEqual(Object.keys(result.body[0]), keys); + done(); + }); + }); + + it("the returned array is sorted by name field", function(done) { + agent.get('/customers/name_sort/1/0').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, result) { + assert.equal(result.body[0].name, "Harry"); + done(); + }); + }); + }); }); From 41ee01845564024ecdf06cdaae74173d376aedea Mon Sep 17 00:00:00 2001 From: Brenna Date: Tue, 22 Sep 2015 16:06:37 -0700 Subject: [PATCH 69/93] /:title/past_customers/customer_name_sort --- db/test.db | Bin 4096 -> 4096 bytes test/controllers/movies.js | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/db/test.db b/db/test.db index 5bd3d12284113e464fdda71e3198b315428fbbac..65ced3d1fcea7a0718fb6cb3167cf3cdb66088eb 100644 GIT binary patch delta 17 YcmZorXi%6S%~&x}#+k8VW5NP{05E?AjsO4v delta 17 YcmZorXi%6S&1f)D#+lJzW5NP{04zrY{r~^~ diff --git a/test/controllers/movies.js b/test/controllers/movies.js index 216e65f..757697a 100644 --- a/test/controllers/movies.js +++ b/test/controllers/movies.js @@ -193,4 +193,36 @@ describe.only("movies controller", function() { }) }); + // /:title/past_customers/customer_name_sort + describe("GET '/movies/Jaws/past_customers/customer_name_sort'", function() { + it("knows about the route", function(done) { + agent.get('/movies/Jaws/past_customers/customer_name_sort').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, result) { + assert.equal(error, undefined); + done(); + }); + }); + + it("returns an array of customers who have checked the movie out in the past", function(done) { + agent.get('/movies/Jaws/past_customers/customer_name_sort').set("Accept", "application/json") + .expect(200, function(error, result) { + assert.equal(result.body.length, 2); + customer_keys; + assert.deepEqual(Object.keys(result.body[0]), customer_keys); + done(); + }); + }); + + it("sorts the customers by name", function(done) { + agent.get('/movies/Jaws/past_customers/customer_name_sort').set("Accept", "application/json") + .expect(200, function(error, result) { + assert.equal(result.body[0].id, 1); + customer_keys; + assert.deepEqual(Object.keys(result.body[0]), customer_keys); + done(); + }); + }) + }); + }); // top level describe From f922ae6cc7b5126c874fbb696a01ccb385df7d4e Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Tue, 22 Sep 2015 16:13:15 -0700 Subject: [PATCH 70/93] Adds tests for /customers/postal_code_sort/:records_per_page/:offset --- db/test.db | Bin 4096 -> 4096 bytes test/controllers/customers.js | 31 +++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/db/test.db b/db/test.db index a2eb86510d46b87f2436caf77e31616829bedfc2..73d66546a1880024de682e4a5d24eeddc62f4e9f 100644 GIT binary patch delta 17 YcmZorXi%6S%{Y6aj5FixjR_0*0WypQ)Bpeg delta 17 YcmZorXi%6S&Db+h#+k8aW5NP{05Pitwg3PC diff --git a/test/controllers/customers.js b/test/controllers/customers.js index d632105..6b77fa6 100644 --- a/test/controllers/customers.js +++ b/test/controllers/customers.js @@ -115,4 +115,35 @@ describe("customers controller", function() { }); }); }); + + describe("GET /customers/postal_code_sort/:records_per_page/:offset", function(done) { + it("knows about the route", function(done) { + agent.get("/customers/postal_code_sort/1/0").set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, result) { + assert.equal(error, undefined); + done(); + }); + }); + + it("returns an array of n customer objects offset by p", function(done) { + agent.get('/customers/postal_code_sort/2/0').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, result) { + assert.equal(result.body.length, 2); + + assert.deepEqual(Object.keys(result.body[0]), keys); + done(); + }); + }); + + it("the returned array is sorted by postal_code field", function(done) { + agent.get('/customers/postal_code_sort/1/0').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, result) { + assert.equal(result.body[0].name, "Harry"); + done(); + }); + }); + }); }); From bf5964272070f53c0338006a888ff7daa7683637 Mon Sep 17 00:00:00 2001 From: Brenna Date: Tue, 22 Sep 2015 16:15:38 -0700 Subject: [PATCH 71/93] all movie api endpoint tests completed and passing hooray --- db/test.db | Bin 4096 -> 4096 bytes test/controllers/movies.js | 57 +++++++++++++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/db/test.db b/db/test.db index 65ced3d1fcea7a0718fb6cb3167cf3cdb66088eb..de74b2c06a14153441c9db5badcb5569285241b0 100644 GIT binary patch delta 19 ZcmZorXi%6S#l$Q+QN{^KZcJFf4*)O51kL~e delta 19 ZcmZorXi%6S#l%!GQN{^KZcJFf4*)gf1(E;& diff --git a/test/controllers/movies.js b/test/controllers/movies.js index 757697a..f377b3b 100644 --- a/test/controllers/movies.js +++ b/test/controllers/movies.js @@ -20,7 +20,7 @@ describe.only("movies controller", function() { INSERT INTO rentals(check_out, check_in, due_date, overdue, movie_title, customer_id) \ VALUES('2015-06-16', '2015-06-17', '2015-06-19', 0, 'Jaws', 1), \ ('2015-06-10', '2015-06-12', '2015-06-13', 0, 'Jaws', 2),\ - ('2015-06-16', null, '2015-06-19', 1, 'Alien', 1); \ + ('2015-06-16', null, '2015-06-19', 1, 'Alien', 1); \ INSERT INTO movies(title, overview, release_date, inventory, inventory_available) \ VALUES('Jaws', 'omg sharks!', '1975-06-19', 6, 6), \ ('Alien', 'omg aliens!', 1979-05-25, 4, 4); \ @@ -193,7 +193,6 @@ describe.only("movies controller", function() { }) }); - // /:title/past_customers/customer_name_sort describe("GET '/movies/Jaws/past_customers/customer_name_sort'", function() { it("knows about the route", function(done) { agent.get('/movies/Jaws/past_customers/customer_name_sort').set('Accept', 'application/json') @@ -225,4 +224,58 @@ describe.only("movies controller", function() { }) }); + //:title/past_customers/checkout_date_sort + describe("GET '/movies/Jaws/past_customers/checkout_date_sort'", function() { + it("knows about the route", function(done) { + agent.get('/movies/Jaws/past_customers/checkout_date_sort').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, result) { + assert.equal(error, undefined); + done(); + }); + }); + + it("returns an array of customers who have checked the movie out in the past", function(done) { + agent.get('/movies/Jaws/past_customers/checkout_date_sort').set("Accept", "application/json") + .expect(200, function(error, result) { + assert.equal(result.body.length, 2); + customer_keys; + assert.deepEqual(Object.keys(result.body[0]), customer_keys); + done(); + }); + }); + + it("sorts the customers by name", function(done) { + agent.get('/movies/Jaws/past_customers/checkout_date_sort').set("Accept", "application/json") + .expect(200, function(error, result) { + assert.equal(result.body[0].id, 2); + customer_keys; + assert.deepEqual(Object.keys(result.body[0]), customer_keys); + done(); + }); + }) + }); + + //:title + describe("GET '/movies/Jaws'", function() { + it("knows about the route", function(done) { + agent.get('/movies/jaws').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, result) { + assert.equal(error, undefined); + done(); + }); + }); + + it("returns an array of movie objects", function(done) { + agent.get('/movies/jaws').set("Accept", "application/json") + .expect(200, function(error, result) { + assert.equal(result.body[0].overview, 'omg sharks!'); + + movie_keys; + assert.deepEqual(Object.keys(result.body[0]), movie_keys); + done(); + }); + }); + }); }); // top level describe From f6c567e299bef8a7510f6c2ad5d18518f49a3dea Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Tue, 22 Sep 2015 16:22:44 -0700 Subject: [PATCH 72/93] Adds tests for /customers/:id/current_rentals --- db/test.db | Bin 4096 -> 4096 bytes test/controllers/customers.js | 36 ++++++++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/db/test.db b/db/test.db index 73d66546a1880024de682e4a5d24eeddc62f4e9f..5bd73fe0df974269530ad3bcbbc215b05d8a621b 100644 GIT binary patch delta 17 YcmZorXi%6S&3JF3j5FiCjR_0*0XBICS^xk5 delta 17 YcmZorXi%6S%{Y6aj5FixjR_0*0WypQ)Bpeg diff --git a/test/controllers/customers.js b/test/controllers/customers.js index 6b77fa6..b712014 100644 --- a/test/controllers/customers.js +++ b/test/controllers/customers.js @@ -4,7 +4,8 @@ var request = require('supertest'), sqlite3 = require('sqlite3').verbose(), agent = request.agent(app), Customer = require('../../customers'), - keys = ['id', 'name', 'registered_at', 'address', 'city', 'state', 'postal_code', 'phone', 'account_credit']; + customer_keys = ['id', 'name', 'registered_at', 'address', 'city', 'state', 'postal_code', 'phone', 'account_credit'], + rental_keys = ['id', 'check_out', 'check_in', 'due_date', 'overdue', 'movie_title', 'customer_id']; describe("customers controller", function() { var customer, db_cleaner; @@ -19,7 +20,7 @@ describe("customers controller", function() { DELETE FROM rentals; DELETE FROM customers; \ INSERT INTO rentals(check_out, check_in, due_date, overdue, movie_title, customer_id) \ VALUES('2015-06-16', '2015-06-17', '2015-06-19', 0, 'Jaws', 1), \ - ('2015-06-16', '2015-06-17', '2015-06-19', 1, 'Alien', 1); \ + ('2015-06-16', null, '2015-06-19', 1, 'Alien', 1); \ INSERT INTO customers(name, registered_at, address, city, state, postal_code, phone, account_credit) \ VALUES('Harry', 20150616, '1234', 'Seattle', 'WA', '98103', '1234567', 123), \ ('Hermione', 20150501, '5678', 'London', 'UK', '99999', '1234568', 213); \ @@ -48,7 +49,7 @@ describe("customers controller", function() { .expect(200, function(error, result) { assert.equal(result.body.length, 2); - assert.deepEqual(Object.keys(result.body[0]), keys); + assert.deepEqual(Object.keys(result.body[0]), customer_keys); done(); }); }); @@ -70,7 +71,7 @@ describe("customers controller", function() { .expect(200, function(error, result) { assert.equal(result.body.length, 1); - assert.deepEqual(Object.keys(result.body[0]), keys); + assert.deepEqual(Object.keys(result.body[0]), customer_keys); done(); }); }); @@ -101,7 +102,7 @@ describe("customers controller", function() { .expect(200, function(error, result) { assert.equal(result.body.length, 2); - assert.deepEqual(Object.keys(result.body[0]), keys); + assert.deepEqual(Object.keys(result.body[0]), customer_keys); done(); }); }); @@ -132,7 +133,7 @@ describe("customers controller", function() { .expect(200, function(error, result) { assert.equal(result.body.length, 2); - assert.deepEqual(Object.keys(result.body[0]), keys); + assert.deepEqual(Object.keys(result.body[0]), customer_keys); done(); }); }); @@ -146,4 +147,27 @@ describe("customers controller", function() { }); }); }); + + describe("GET /customers/:id/current_rentals", function() { + it("knows about the route", function(done) { + agent.get("/customers/2/current_rentals").set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, result) { + assert.equal(error, undefined); + done(); + }); + }); + + it("retuns an array of the customer with current rentals", function(done) { + agent.get("/customers/1/current_rentals").set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, result) { + assert.equal(result.body.length, 1); + assert.equal(result.body[0].movie_title, "Alien"); + + assert.deepEqual(Object.keys(result.body[0]), rental_keys); + done(); + }); + }); + }); }); From e0995dc6e42a7c8ac3505df47800c1675f6e9eb0 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Tue, 22 Sep 2015 16:25:29 -0700 Subject: [PATCH 73/93] Adds tests for /customers/:id/past_rentals --- db/test.db | Bin 4096 -> 4096 bytes test/controllers/customers.js | 25 ++++++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/db/test.db b/db/test.db index 5bd73fe0df974269530ad3bcbbc215b05d8a621b..a6378b754a5adbf5e7911fcca88df5d04880e25c 100644 GIT binary patch delta 19 ZcmZorXi%6S#l*-mQN{^KZcJFf4*)Kb1gHQ2 delta 19 ZcmZorXi%6S#l&!LqKp%e+?cR{9{@Zc23i0B diff --git a/test/controllers/customers.js b/test/controllers/customers.js index b712014..e3ffaf7 100644 --- a/test/controllers/customers.js +++ b/test/controllers/customers.js @@ -150,7 +150,7 @@ describe("customers controller", function() { describe("GET /customers/:id/current_rentals", function() { it("knows about the route", function(done) { - agent.get("/customers/2/current_rentals").set('Accept', 'application/json') + agent.get("/customers/1/current_rentals").set('Accept', 'application/json') .expect('Content-Type', /application\/json/) .expect(200, function(error, result) { assert.equal(error, undefined); @@ -170,4 +170,27 @@ describe("customers controller", function() { }); }); }); + + describe("GET /customers/:id/past_rentals", function() { + it("knows about the route", function(done) { + agent.get("/customers/1/past_rentals").set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, result) { + assert.equal(error, undefined); + done(); + }); + }); + + it("retuns an array of the customer with current rentals", function(done) { + agent.get("/customers/1/past_rentals").set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, result) { + assert.equal(result.body.length, 1); + assert.equal(result.body[0].movie_title, "Jaws"); + + assert.deepEqual(Object.keys(result.body[0]), rental_keys); + done(); + }); + }); + }); }); From 259d6677abca4a79414655a1b02a2668988b6594 Mon Sep 17 00:00:00 2001 From: Brenna Date: Tue, 22 Sep 2015 16:32:28 -0700 Subject: [PATCH 74/93] refactor - changed all routes to paths --- db/test.db | Bin 4096 -> 4096 bytes test/controllers/movies.js | 64 ++++++++++++++++++++----------------- 2 files changed, 35 insertions(+), 29 deletions(-) diff --git a/db/test.db b/db/test.db index de74b2c06a14153441c9db5badcb5569285241b0..09b6a7990f34c716264de473b572609344fea68d 100644 GIT binary patch delta 19 ZcmZorXi%6S#l+$;QN{^KZcJFf4*)WV1ttIh delta 19 ZcmZorXi%6S#l$Q+QN{^KZcJFf4*)O51kL~e diff --git a/test/controllers/movies.js b/test/controllers/movies.js index f377b3b..f2b1931 100644 --- a/test/controllers/movies.js +++ b/test/controllers/movies.js @@ -35,10 +35,10 @@ describe.only("movies controller", function() { ); }); }); - - describe("GET '/movies'", function() { + var movies_path = '/movies'; + describe("GET movies_path", function() { it("knows about the route", function(done) { - agent.get('/movies').set('Accept', 'application/json') + agent.get(movies_path).set('Accept', 'application/json') .expect('Content-Type', /application\/json/) .expect(200, function(error, result) { assert.equal(error, undefined); @@ -47,7 +47,7 @@ describe.only("movies controller", function() { }); it("returns an array of movie objects", function(done) { - agent.get('/movies').set("Accept", "application/json") + agent.get(movies_path).set("Accept", "application/json") .expect(200, function(error, result) { assert.equal(result.body.length, 2); @@ -58,9 +58,10 @@ describe.only("movies controller", function() { }); }); - describe("GET '/movies/title_sort/1/2'", function() { + var title_sort_path = '/movies/title_sort/1/1'; + describe("GET title_sort_path", function() { it("knows about the route", function(done) { - agent.get('/movies/title_sort/1/2').set('Accept', 'application/json') + agent.get('/movies/title_sort/1/1').set('Accept', 'application/json') .expect('Content-Type', /application\/json/) .expect(200, function(error, result) { assert.equal(error, undefined); @@ -69,7 +70,7 @@ describe.only("movies controller", function() { }); it("returns an array of movie objects 1 per page offset by 2", function(done) { - agent.get('/movies/title_sort/1/1').set("Accept", "application/json") + agent.get(title_sort_path).set("Accept", "application/json") .expect(200, function(error, result) { assert.equal(result.body.length, 1); movie_keys; @@ -79,7 +80,7 @@ describe.only("movies controller", function() { }); it("sorts the movies by title", function(done) { - agent.get('/movies/title_sort/1/1').set("Accept", "application/json") + agent.get(title_sort_path).set("Accept", "application/json") .expect(200, function(error, result) { assert.equal(result.body[0].title, 'Jaws'); movie_keys; @@ -89,9 +90,10 @@ describe.only("movies controller", function() { }) }); - describe("GET '/movies/release_date_sort/1/2'", function() { + var release_date_sort_path = '/movies/title_sort/1/1'; + describe("GET release_date_sort_path", function() { it("knows about the route", function(done) { - agent.get('/movies/title_sort/1/2').set('Accept', 'application/json') + agent.get(release_date_sort_path).set('Accept', 'application/json') .expect('Content-Type', /application\/json/) .expect(200, function(error, result) { assert.equal(error, undefined); @@ -100,7 +102,7 @@ describe.only("movies controller", function() { }); it("returns an array of movie objects 1 per page offset by 2", function(done) { - agent.get('/movies/release_date_sort/1/1').set("Accept", "application/json") + agent.get(release_date_sort_path).set("Accept", "application/json") .expect(200, function(error, result) { assert.equal(result.body.length, 1); movie_keys; @@ -110,7 +112,7 @@ describe.only("movies controller", function() { }); it("sorts the movies by release date", function(done) { - agent.get('/movies/release_date_sort/1/1').set("Accept", "application/json") + agent.get(release_date_sort_path).set("Accept", "application/json") .expect(200, function(error, result) { assert.equal(result.body[0].title, 'Jaws'); movie_keys; @@ -120,7 +122,8 @@ describe.only("movies controller", function() { }) }); - describe("GET '/movies/Alien/current_customers'", function() { + var current_customers_path = '/movies/Alien/current_customers'; + describe("GET current_customers_path", function() { it("knows about the route", function(done) { agent.get('/movies/Jaws/current_customers').set('Accept', 'application/json') .expect('Content-Type', /application\/json/) @@ -131,7 +134,7 @@ describe.only("movies controller", function() { }); it("returns an array of customers who currently have the movie checked out", function(done) { - agent.get('/movies/Alien/current_customers').set("Accept", "application/json") + agent.get(current_customers_path).set("Accept", "application/json") .expect(200, function(error, result) { assert.equal(result.body.length, 1); customer_keys; @@ -141,9 +144,10 @@ describe.only("movies controller", function() { }); }); - describe("GET '/movies/Jaws/past_customers'", function() { + var past_customers_path = '/movies/Jaws/past_customers' + describe("GET past_customers_path", function() { it("knows about the route", function(done) { - agent.get('/movies/Jaws/past_customers').set('Accept', 'application/json') + agent.get(past_customers_path).set('Accept', 'application/json') .expect('Content-Type', /application\/json/) .expect(200, function(error, result) { assert.equal(error, undefined); @@ -162,9 +166,10 @@ describe.only("movies controller", function() { }); }); - describe("GET '/movies/Jaws/past_customers/customer_id_sort'", function() { + var past_customers_id_sort_path = '/movies/Jaws/past_customers/customer_id_sort' + describe("GET past_customers_id_sort_path", function() { it("knows about the route", function(done) { - agent.get('/movies/Jaws/past_customers/customer_id_sort').set('Accept', 'application/json') + agent.get(past_customers_id_sort_path).set('Accept', 'application/json') .expect('Content-Type', /application\/json/) .expect(200, function(error, result) { assert.equal(error, undefined); @@ -173,7 +178,7 @@ describe.only("movies controller", function() { }); it("returns an array of customers who have checked the movie out in the past", function(done) { - agent.get('/movies/Jaws/past_customers/customer_id_sort').set("Accept", "application/json") + agent.get(past_customers_id_sort_path).set("Accept", "application/json") .expect(200, function(error, result) { assert.equal(result.body.length, 2); customer_keys; @@ -183,7 +188,7 @@ describe.only("movies controller", function() { }); it("sorts the customers by id", function(done) { - agent.get('/movies/Jaws/past_customers/customer_id_sort').set("Accept", "application/json") + agent.get(past_customers_id_sort_path).set("Accept", "application/json") .expect(200, function(error, result) { assert.equal(result.body[0].id, 1); customer_keys; @@ -193,9 +198,10 @@ describe.only("movies controller", function() { }) }); - describe("GET '/movies/Jaws/past_customers/customer_name_sort'", function() { + var past_customer_name_sort_path = '/movies/Jaws/past_customers/customer_name_sort' + describe("GET past_customer_name_sort_path", function() { it("knows about the route", function(done) { - agent.get('/movies/Jaws/past_customers/customer_name_sort').set('Accept', 'application/json') + agent.get(past_customer_name_sort_path).set('Accept', 'application/json') .expect('Content-Type', /application\/json/) .expect(200, function(error, result) { assert.equal(error, undefined); @@ -204,7 +210,7 @@ describe.only("movies controller", function() { }); it("returns an array of customers who have checked the movie out in the past", function(done) { - agent.get('/movies/Jaws/past_customers/customer_name_sort').set("Accept", "application/json") + agent.get(past_customer_name_sort_path).set("Accept", "application/json") .expect(200, function(error, result) { assert.equal(result.body.length, 2); customer_keys; @@ -214,7 +220,7 @@ describe.only("movies controller", function() { }); it("sorts the customers by name", function(done) { - agent.get('/movies/Jaws/past_customers/customer_name_sort').set("Accept", "application/json") + agent.get(past_customer_name_sort_path).set("Accept", "application/json") .expect(200, function(error, result) { assert.equal(result.body[0].id, 1); customer_keys; @@ -224,10 +230,10 @@ describe.only("movies controller", function() { }) }); - //:title/past_customers/checkout_date_sort - describe("GET '/movies/Jaws/past_customers/checkout_date_sort'", function() { + var past_customers_checkout_sort_path = '/movies/Jaws/past_customers/checkout_date_sort' + describe("GET past_customers_checkout_sort_path", function() { it("knows about the route", function(done) { - agent.get('/movies/Jaws/past_customers/checkout_date_sort').set('Accept', 'application/json') + agent.get(past_customers_checkout_sort_path).set('Accept', 'application/json') .expect('Content-Type', /application\/json/) .expect(200, function(error, result) { assert.equal(error, undefined); @@ -236,7 +242,7 @@ describe.only("movies controller", function() { }); it("returns an array of customers who have checked the movie out in the past", function(done) { - agent.get('/movies/Jaws/past_customers/checkout_date_sort').set("Accept", "application/json") + agent.get(past_customers_checkout_sort_path).set("Accept", "application/json") .expect(200, function(error, result) { assert.equal(result.body.length, 2); customer_keys; @@ -246,7 +252,7 @@ describe.only("movies controller", function() { }); it("sorts the customers by name", function(done) { - agent.get('/movies/Jaws/past_customers/checkout_date_sort').set("Accept", "application/json") + agent.get(past_customers_checkout_sort_path).set("Accept", "application/json") .expect(200, function(error, result) { assert.equal(result.body[0].id, 2); customer_keys; From 9affe2f1998b36f47a8145ca6f00f34803d43445 Mon Sep 17 00:00:00 2001 From: Brenna Date: Tue, 22 Sep 2015 16:34:27 -0700 Subject: [PATCH 75/93] refactor- rentals controller tests use path variables --- db/test.db | Bin 4096 -> 4096 bytes test/controllers/movies.js | 2 +- test/controllers/rentals.js | 14 ++++++++------ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/db/test.db b/db/test.db index 09b6a7990f34c716264de473b572609344fea68d..03844b32df72c925816ffd5bc80d2462901bc1b4 100644 GIT binary patch delta 75 zcmZorXi%6S%@{pV#+fmCW5N<<9wz4H49r)Umov98uxu9OC}E!5!mh={DL(lwyF9C7 fPG)M}<}2(5EF6r?rx}<}GfxDnX=R=~kv|^*6`~a~ delta 114 zcmZorXi%6S&FC;u#+lJ!W5N<<9%kki2Iecw%YhWjWD CIvTqG diff --git a/test/controllers/movies.js b/test/controllers/movies.js index f2b1931..171e099 100644 --- a/test/controllers/movies.js +++ b/test/controllers/movies.js @@ -5,7 +5,7 @@ var request = require('supertest'), agent = request.agent(app), Movie = require('../../movies'); -describe.only("movies controller", function() { +describe("movies controller", function() { var movie, db_cleaner; var movie_keys = ['id', 'title', 'overview', 'release_date', 'inventory', 'inventory_available']; var customer_keys = ['id', 'name', 'registered_at', 'address', 'city', 'state', 'postal_code', 'phone', 'account_credit']; diff --git a/test/controllers/rentals.js b/test/controllers/rentals.js index c8e85b2..d1bf8ee 100644 --- a/test/controllers/rentals.js +++ b/test/controllers/rentals.js @@ -30,9 +30,10 @@ describe("rentals controller", function() { }); }); - describe("GET '/rentals'", function() { + var rentals_path = '/rentals'; + describe("GET rentals_path", function() { it("knows about the route", function(done) { - agent.get('/rentals').set('Accept', 'application/json') + agent.get(rentals_path).set('Accept', 'application/json') .expect('Content-Type', /application\/json/) .expect(200, function(error, result) { assert.equal(error, undefined); @@ -41,7 +42,7 @@ describe("rentals controller", function() { }); it("returns an array of rental objects", function(done) { - agent.get('/rentals').set("Accept", "application/json") + agent.get(rentals_path).set("Accept", "application/json") .expect(200, function(error, result) { assert.equal(result.body.length, 2); @@ -52,9 +53,10 @@ describe("rentals controller", function() { }); }); - describe("GET '/rentals/overdue'", function() { + var rentals_overdue_path = '/rentals/overdue'; + describe("GET rentals_overdue_path", function() { it("knows about the route", function(done) { - agent.get('/rentals/overdue').set('Accept', 'application/json') + agent.get(rentals_overdue_path).set('Accept', 'application/json') .expect('Content-Type', /application\/json/) .expect(200, function(error, result) { assert.equal(error, undefined); @@ -63,7 +65,7 @@ describe("rentals controller", function() { }); it("returns an array of overdue rental objects", function(done) { - agent.get('/rentals/overdue').set("Accept", "application/json") + agent.get(rentals_overdue_path).set("Accept", "application/json") .expect(200, function(error, result) { assert.equal(result.body.length, 1); From 8823d8078e8298df0ccb423ec67cd0e457e69c91 Mon Sep 17 00:00:00 2001 From: Brenna Date: Tue, 22 Sep 2015 16:58:38 -0700 Subject: [PATCH 76/93] deleted db files --- db/development.db | Bin 68608 -> 0 bytes db/test.db | Bin 4096 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 db/development.db delete mode 100644 db/test.db diff --git a/db/development.db b/db/development.db deleted file mode 100644 index 5e7623bd4e2f9c39ec10f2b767ddb205d8465e6d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68608 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 diff --git a/db/test.db b/db/test.db deleted file mode 100644 index 03844b32df72c925816ffd5bc80d2462901bc1b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeHK%}(1u5Z?7h1gJRl5LqZftjVQm6Ez`_ke=#Nw@_$BL#hh(U~TOsS>f2#?j{tq z7oxsEpMondz!PxovFG+Rx^`kiDk2U@oE$0k{CqQ>`F3_K@4w$=lH$XF_lU$bkO2^a z=NJQ!`2^HO{o~(LC0y5G?3jL6Im&+?ET9#D;5pE~!*jGb9i4h^XW(>O%j(O^a7ZNi z>`|vLWYD8rBtmAhWtnXYx6K#37Ea9g5p(hOySDY(YT>=s_FJ=cfOo8e681@tVoATs z66UnSgruChwi*WJOWL8lgo*2ND#RG%FnKZ-g(PZrMzLQ4rFpg!xQV43__0hJC+Pdq zc2sUA@u3$GSv)PktiHGihep&(FBmW?Mprb^#mF|j1<9lrKPebcuJRlwEqRm(YP(mJ zGJimQ8Ss;<4il42284Mbv$3ad$`qH1Us|us54&w#DdC7Rdqj+oocWznG7PpFh4JDR z7gT#1Is@nzIzvAu_V?|>m?BaJQU>nKfPrR#0gO3)ZnaWfFIVd2YCVyfrpKuNL{kuB z3Z(HL_%V#Yv$>n{T?4-%$6~bqF97h`iM&2@0IFmZEcST;!>Y%n$3pN8};?I+G-X2t-*Pq8@arSgj Date: Wed, 23 Sep 2015 12:05:41 -0700 Subject: [PATCH 77/93] WIP - rental check_in endpoint --- controllers/rentals.js | 7 +++++++ database.js | 16 ++++++++++++++++ routes/rentals.js | 12 ++++++++++-- test/controllers/rentals.js | 35 +++++++++++++++++++++++++++++++++-- 4 files changed, 66 insertions(+), 4 deletions(-) diff --git a/controllers/rentals.js b/controllers/rentals.js index e64013e..348edeb 100644 --- a/controllers/rentals.js +++ b/controllers/rentals.js @@ -15,5 +15,12 @@ exports.rentalsController = { rental.overdue(function(overdue) { return res.status(200).json(overdue); }); + }, + + check_out: function check_out(req, res) { + rental.check_out(req.body, function(check_out) { + return res.status(200).json(check_out); + }) } + } diff --git a/database.js b/database.js index 52f54ba..60a58a3 100644 --- a/database.js +++ b/database.js @@ -100,5 +100,21 @@ module.exports = { AND rentals.overdue=1;", function(res) { callback(res); }); + }, + + // passing req.body to data + check_out: function(data, callback) { + // data will be an object with a key value pair with each item for rental + console.log(data); + var check_out_date = new Date(); + var due_date = new Date(check_out_date); + due_date.setDate(check_out_date.getDate() + 3); + var movie_title = data.movie_title; + var customer_id = data.customer_id; + var statement = "INSERT INTO " + this.table_name + "(check_out, check_in, due_date, overdue, movie_title, customer_id) VALUES(" + check_out_date + ", null, " + due_date + ", 0, " + movie_title + ", " + customer_id + ")" + this.query(statement, function(res) { + callback(res); + }); + console.log(statement); } } diff --git a/routes/rentals.js b/routes/rentals.js index cd06118..3df322d 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -5,13 +5,21 @@ var rental_exports = require('../controllers/rentals'); router.get('/', function(req, res, next) { return rental_exports.rentalsController.all(req, res); }); -// +// // router.get('/:movie_title', function(req, res, next) { // return rental_exports.rentalsController.rented_by(req, res); // }); -router.get('/overdue', function(req, res, next){ +router.get('/overdue', function(req, res, next) { return rental_exports.rentalsController.overdue(req, res); }); +router.get('/check_out', function(req, res, next) { + return rental_exports.rentalsController.check_out(req, res); +}); + +router.post('/check_out', function(req, res, next) { + return rental_exports.rentalsController.check_out(req, res); +}); + module.exports = router; diff --git a/test/controllers/rentals.js b/test/controllers/rentals.js index 4d3485d..944afce 100644 --- a/test/controllers/rentals.js +++ b/test/controllers/rentals.js @@ -5,7 +5,7 @@ var request = require('supertest'), agent = request.agent(app), Rental = require('../../rentals'); -describe("rentals controller", function() { +describe.only("rentals controller", function() { var rental, db_cleaner; beforeEach(function(done) { @@ -75,4 +75,35 @@ describe("rentals controller", function() { }); }); }); -}); + + var check_out_path = '/rentals/check_out'; + describe("POST check_out_path", function() { + it("can make a post request", function(done) { + agent.post(check_out_path).set('Accept', 'application/json') + .field('check_out', '2015-09-23') + .field('check_in', null) + .field('due_date', '2015-09-26') + .field('movie_title', 'Jaws') + .field('customer_id', 1) + + .expect(201, function(error, result) { + assert.equal(error, undefined); + done(); + }); + }); + }); + + describe("GET check_out_path", function(){ + it('should respond with JSON array', function(done) { + agent.get(check_out_path).set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) return done(err); + res.body.should.be.instanceof(Array); + done(); + }); + }); + }); + +}); //final describe close From 48c28d8491c2d39e08f9ed73f390d891aa1f7137 Mon Sep 17 00:00:00 2001 From: Brenna Date: Wed, 23 Sep 2015 15:00:35 -0700 Subject: [PATCH 78/93] our check_in rental function is creating a rental record, updating customer account credit and updating movie inventory_available --- database.js | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/database.js b/database.js index 60a58a3..14792a7 100644 --- a/database.js +++ b/database.js @@ -9,8 +9,8 @@ module.exports = { db.serialize(function() { // below: this is the callback pattern...parameters(ERRORS, RESULT) db.all(statement, function(err, res) { - // console.log(statement); - // console.log(err); + console.log(statement); + console.log(err); // error handling looks like -> if (err) { }; if (callback) { callback(res); } }); @@ -105,16 +105,38 @@ module.exports = { // passing req.body to data check_out: function(data, callback) { // data will be an object with a key value pair with each item for rental - console.log(data); var check_out_date = new Date(); + var check_out = formatDate(check_out_date); var due_date = new Date(check_out_date); due_date.setDate(check_out_date.getDate() + 3); - var movie_title = data.movie_title; + var due = formatDate(due_date); + var title = data.movie_title; var customer_id = data.customer_id; - var statement = "INSERT INTO " + this.table_name + "(check_out, check_in, due_date, overdue, movie_title, customer_id) VALUES(" + check_out_date + ", null, " + due_date + ", 0, " + movie_title + ", " + customer_id + ")" - this.query(statement, function(res) { - callback(res); - }); - console.log(statement); + + var db = new sqlite3.Database('db/' + db_env + '.db'); + db.exec( + "BEGIN; \ + INSERT INTO " + this.table_name + "(check_out, check_in, due_date, overdue, movie_title, customer_id) VALUES(" + check_out + ", null, " + due + ", 0, '" + title + "', " + customer_id + "); \ + UPDATE movies SET inventory_available=inventory_available - 1 WHERE title='" + title + "'; \ + UPDATE customers SET account_credit=account_credit - 3 WHERE id=" + customer_id + "; \ + COMMIT;"); + db.close(); + } +} + +var formatDate = function(date) { + var dateObj = new Date(date); + var month = (dateObj.getUTCMonth() + 1).toString(); //months from 1-12 + var day = (dateObj.getUTCDate()).toString(); + var year = (dateObj.getUTCFullYear()).toString(); + + if (month.length == 1) { // This will ensure month is two digits + month = "0" + month; } + + if (day.length == 1) { // This will ensure day is two digits + day = "0" + day; + } + + return parseInt(year + month + day); } From b14341257f3c5269e0a564e3b0890fda3bba23a5 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Wed, 23 Sep 2015 15:19:14 -0700 Subject: [PATCH 79/93] Adds checkin functionality. Check_in updates the movie inventory, and updates the rental to have a check_in date and overdue is set to 0. --- controllers/rentals.js | 8 +++++++- database.js | 25 +++++++++++++++++++++++-- routes/rentals.js | 8 ++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/controllers/rentals.js b/controllers/rentals.js index 348edeb..775cbd0 100644 --- a/controllers/rentals.js +++ b/controllers/rentals.js @@ -20,7 +20,13 @@ exports.rentalsController = { check_out: function check_out(req, res) { rental.check_out(req.body, function(check_out) { return res.status(200).json(check_out); - }) + }); + }, + + check_in: function check_in(req, res) { + rental.check_in(req.body, function(check_in) { + return res.status(200).json(check_in); + }); } } diff --git a/database.js b/database.js index 14792a7..628fcd7 100644 --- a/database.js +++ b/database.js @@ -116,13 +116,34 @@ module.exports = { var db = new sqlite3.Database('db/' + db_env + '.db'); db.exec( "BEGIN; \ - INSERT INTO " + this.table_name + "(check_out, check_in, due_date, overdue, movie_title, customer_id) VALUES(" + check_out + ", null, " + due + ", 0, '" + title + "', " + customer_id + "); \ + INSERT INTO " + this.table_name + "(check_out, check_in, due_date, overdue, movie_title, customer_id) \ + VALUES(" + check_out + ", null, " + due + ", 0, '" + title + "', " + customer_id + "); \ UPDATE movies SET inventory_available=inventory_available - 1 WHERE title='" + title + "'; \ UPDATE customers SET account_credit=account_credit - 3 WHERE id=" + customer_id + "; \ COMMIT;"); + db.close(); + }, + + // data will include movie_title and customer_id + check_in: function(data, callback) { + var check_in_date = new Date(); + var check_in = formatDate(check_in_date); + var title = data.movie_title; + var customer_id = data.customer_id; + + var db = new sqlite3.Database('db/' + db_env + '.db'); + db.exec( + // update rental: check_in_date and overdue + // update movie: inventory_available + "BEGIN; \ + UPDATE rentals SET check_in=" + check_in + ", overdue=0 WHERE movie_title='" + title + "'; \ + UPDATE movies SET inventory_available=inventory_available + 1 WHERE title='" + title + "'; \ + COMMIT;" + ); + db.close(); } -} +}; var formatDate = function(date) { var dateObj = new Date(date); diff --git a/routes/rentals.js b/routes/rentals.js index 3df322d..9fceaee 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -22,4 +22,12 @@ router.post('/check_out', function(req, res, next) { return rental_exports.rentalsController.check_out(req, res); }); +router.get('/check_in', function(req, res, next) { + return rental_exports.rentalsController.check_in(req, res); +}); + +router.post('/check_in', function(req, res, next) { + return rental_exports.rentalsController.check_in(req, res); +}); + module.exports = router; From 59e60c6ced4a981b72d1d7041853a48e04c30008 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Wed, 23 Sep 2015 15:39:58 -0700 Subject: [PATCH 80/93] Adds to check that overdueselects rentals that both do not have a checkin date and are overdue. --- database.js | 2 +- utils/rentals.json | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/database.js b/database.js index 628fcd7..bb87e3a 100644 --- a/database.js +++ b/database.js @@ -97,7 +97,7 @@ module.exports = { customers.postal_code, customers.phone, customers.account_credit \ FROM customers, rentals \ WHERE customers.id=rentals.customer_id \ - AND rentals.overdue=1;", function(res) { + AND rentals.overdue=1 AND rentals.check_in IS NULL;", function(res) { callback(res); }); }, diff --git a/utils/rentals.json b/utils/rentals.json index 62f9d1f..6947298 100644 --- a/utils/rentals.json +++ b/utils/rentals.json @@ -48,6 +48,14 @@ "customer_id": 8, "movie_title": "King Kong" }, + { + "check_out": "2015-07-03", + "check_in": "", + "due_date": "2015-07-06", + "overdue": 0, + "customer_id": 9, + "movie_title": "King Kong" + }, { "check_out": "2015-07-03", "check_in": "", From 2a841547e79066a4172840c8efd3c37e73e4b4d7 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Wed, 23 Sep 2015 16:20:58 -0700 Subject: [PATCH 81/93] WIP overdue. --- database.js | 29 ++++++++++++++++++---- utils/rentals.json | 61 +++++++++++++++++++++++----------------------- utils/schema.js | 6 ++--- 3 files changed, 57 insertions(+), 39 deletions(-) diff --git a/database.js b/database.js index bb87e3a..2743347 100644 --- a/database.js +++ b/database.js @@ -92,16 +92,35 @@ module.exports = { // RENTALS overdue: function(callback) { - this.query("SELECT customers.id, customers.name, customers.registered_at, \ + var newDate = new Date(); + var today = formatDate(newDate); + var db = new sqlite3.Database('db/' + db_env + '.db'); + + db.exec("BEGIN; \ + UPDATE rentals SET overdue=1 WHERE due_date<" + today + " \ + AND check_in IS NULL; \ + SELECT customers.id, customers.name, customers.registered_at, \ customers.address, customers.city, customers.state, \ customers.postal_code, customers.phone, customers.account_credit \ FROM customers, rentals \ WHERE customers.id=rentals.customer_id \ - AND rentals.overdue=1 AND rentals.check_in IS NULL;", function(res) { - callback(res); - }); + AND rentals.overdue=1 AND rentals.check_in IS NULL; \ + COMMIT;"); + // console.log(today); + + db.close(); }, + // update_overdue: function(callback) { + // var newDate = new Date(); + // var today = formatDate(newDate); + // this.query("UPDATE rentals SET overdue=1 WHERE due_date<" + today + " \ + // AND check_in IS NULL;", + // function(res) { + // callback(res); + // }); + // }, + // passing req.body to data check_out: function(data, callback) { // data will be an object with a key value pair with each item for rental @@ -160,4 +179,4 @@ var formatDate = function(date) { } return parseInt(year + month + day); -} +}; diff --git a/utils/rentals.json b/utils/rentals.json index 6947298..174ff63 100644 --- a/utils/rentals.json +++ b/utils/rentals.json @@ -1,81 +1,80 @@ - [ { - "check_out": "2015-06-16", - "check_in": "2015-06-17", - "due_date": "2015-06-19", + "check_out": 20150616, + "check_in": 20150617, + "due_date": 20150619, "overdue": 0, "customer_id": 1, "movie_title": "Jaws" }, { - "check_out": "2015-04-27", - "check_in": "2015-05-12", - "due_date": "2015-04-30", + "check_out": 20150427, + "check_in": 20150512, + "due_date": 20150430, "overdue": 1, "customer_id": 7, "movie_title": "Alien" }, { - "check_out": "2015-05-14", - "check_in": "2015-05-16", - "due_date": "2015-04-17", + "check_out": 20150514, + "check_in": 20150516, + "due_date": 20150417, "overdue": 0, "customer_id": 12, "movie_title": "Psycho" }, { - "check_out": "2015-06-03", - "check_in": "2015-06-07", - "due_date": "2015-06-06", + "check_out": 20150603, + "check_in": 20150607, + "due_date": 20150606, "overdue": 1, "customer_id": 1, "movie_title": "The Birds" }, { - "check_out": "2015-07-03", - "check_in": "2015-07-06", - "due_date": "2015-07-06", + "check_out": 20150703, + "check_in": 20150706, + "due_date": 20150706, "overdue": 0, "customer_id": 8, "movie_title": "The Godfather" }, { - "check_out": "2015-07-03", - "check_in": "", - "due_date": "2015-07-06", + "check_out": 20150703, + "check_in" : null, + "due_date": 20150706, "overdue": 1, "customer_id": 8, "movie_title": "King Kong" }, { - "check_out": "2015-07-03", - "check_in": "", - "due_date": "2015-07-06", + "check_out": 20150703, + "check_in" : null, + "due_date": 20150706, "overdue": 0, "customer_id": 9, "movie_title": "King Kong" }, { - "check_out": "2015-07-03", - "check_in": "", - "due_date": "2015-07-06", + "check_out": 20150703, + "check_in" : null, + "due_date": 20150706, "overdue": 1, "customer_id": 9, "movie_title": "King Kong" }, { - "check_out": "2013-07-03", - "check_in": "2013-07-06", - "due_date": "2013-07-06", + "check_out": 20130703, + "check_in": 20130706, + "due_date": 20130706, "overdue": 0, "customer_id": 9, "movie_title": "King Kong" }, { - "check_out": "2014-07-03", - "check_in": "2014-07-06", - "due_date": "2014-07-06", + "check_out": 20140703, + "check_in": 20140706, + "due_date": 20140706, "overdue": 0, "customer_id": 3, "movie_title": "King Kong" diff --git a/utils/schema.js b/utils/schema.js index 78eb8cb..8c69d5c 100644 --- a/utils/schema.js +++ b/utils/schema.js @@ -24,9 +24,9 @@ var customer_fields = [ ] var rental_fields = [ - ['check_out', 'text'], - ['check_in', 'text'], - ['due_date', 'text'], + ['check_out', 'integer'], + ['check_in', 'integer'], + ['due_date', 'integer'], ['overdue', 'integer', 'DEFAULT 0'], // 0 for false 1 for true ['movie_title', 'string'], ['customer_id', 'integer'] From 98ccd64d5d07a65cc0a59771f2cdb27b00b0e093 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Wed, 23 Sep 2015 16:57:07 -0700 Subject: [PATCH 82/93] Finishes overdue functionality. --- database.js | 25 +++++++++------- utils/rentals.json | 74 +--------------------------------------------- utils/seed.js | 10 ++----- 3 files changed, 18 insertions(+), 91 deletions(-) diff --git a/database.js b/database.js index 2743347..e222c4b 100644 --- a/database.js +++ b/database.js @@ -9,8 +9,8 @@ module.exports = { db.serialize(function() { // below: this is the callback pattern...parameters(ERRORS, RESULT) db.all(statement, function(err, res) { - console.log(statement); - console.log(err); + // console.log(statement); + // console.log(err); // error handling looks like -> if (err) { }; if (callback) { callback(res); } }); @@ -97,16 +97,19 @@ module.exports = { var db = new sqlite3.Database('db/' + db_env + '.db'); db.exec("BEGIN; \ - UPDATE rentals SET overdue=1 WHERE due_date<" + today + " \ + UPDATE rentals SET overdue=1 WHERE due_date < " + today + " \ AND check_in IS NULL; \ - SELECT customers.id, customers.name, customers.registered_at, \ - customers.address, customers.city, customers.state, \ - customers.postal_code, customers.phone, customers.account_credit \ - FROM customers, rentals \ - WHERE customers.id=rentals.customer_id \ - AND rentals.overdue=1 AND rentals.check_in IS NULL; \ - COMMIT;"); - // console.log(today); + COMMIT;", function() { + db.all( + "SELECT customers.id, customers.name, customers.registered_at, \ + customers.address, customers.city, customers.state, \ + customers.postal_code, customers.phone, customers.account_credit \ + FROM customers, rentals \ + WHERE customers.id=rentals.customer_id \ + AND rentals.overdue=1 AND rentals.check_in IS NULL;", function(err, res) { + if (callback) { callback(res); } + }); + }); db.close(); }, diff --git a/utils/rentals.json b/utils/rentals.json index 174ff63..c91d598 100644 --- a/utils/rentals.json +++ b/utils/rentals.json @@ -1,82 +1,10 @@ [ { "check_out": 20150616, - "check_in": 20150617, + "check_in": null, "due_date": 20150619, "overdue": 0, "customer_id": 1, "movie_title": "Jaws" - }, - { - "check_out": 20150427, - "check_in": 20150512, - "due_date": 20150430, - "overdue": 1, - "customer_id": 7, - "movie_title": "Alien" - }, - { - "check_out": 20150514, - "check_in": 20150516, - "due_date": 20150417, - "overdue": 0, - "customer_id": 12, - "movie_title": "Psycho" - }, - { - "check_out": 20150603, - "check_in": 20150607, - "due_date": 20150606, - "overdue": 1, - "customer_id": 1, - "movie_title": "The Birds" - }, - { - "check_out": 20150703, - "check_in": 20150706, - "due_date": 20150706, - "overdue": 0, - "customer_id": 8, - "movie_title": "The Godfather" - }, - { - "check_out": 20150703, - "check_in" : null, - "due_date": 20150706, - "overdue": 1, - "customer_id": 8, - "movie_title": "King Kong" - }, - { - "check_out": 20150703, - "check_in" : null, - "due_date": 20150706, - "overdue": 0, - "customer_id": 9, - "movie_title": "King Kong" - }, - { - "check_out": 20150703, - "check_in" : null, - "due_date": 20150706, - "overdue": 1, - "customer_id": 9, - "movie_title": "King Kong" - }, - { - "check_out": 20130703, - "check_in": 20130706, - "due_date": 20130706, - "overdue": 0, - "customer_id": 9, - "movie_title": "King Kong" - }, - { - "check_out": 20140703, - "check_in": 20140706, - "due_date": 20140706, - "overdue": 0, - "customer_id": 3, - "movie_title": "King Kong" } ] diff --git a/utils/seed.js b/utils/seed.js index 42dcfbc..291cdc1 100644 --- a/utils/seed.js +++ b/utils/seed.js @@ -81,15 +81,11 @@ db.serialize(function() { for(var k = 0; k < rentals.length; k++) { var rental = rentals[k]; - var formattedCheckOutDate = formatDate(rental.check_out); - var formattedCheckInDate = formatDate(rental.check_in); - var formattedDueDate = formatDate(rental.due_date); - // insert each rental into the db rental_statement.run( - formattedCheckOutDate, - formattedCheckInDate, - formattedDueDate, + rental.check_out, + rental.check_in, + rental.due_date, rental.overdue, rental.customer_id, rental.movie_title From bf69d7683034ed48e69589cfb7eb99abcfe2d8de Mon Sep 17 00:00:00 2001 From: Brenna Date: Thu, 24 Sep 2015 10:22:41 -0700 Subject: [PATCH 83/93] rewrote rentals:all to all_rentals so that it would update overdue rentals --- controllers/rentals.js | 4 ++-- database.js | 28 ++++++++++++++++++---------- routes/rentals.js | 2 +- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/controllers/rentals.js b/controllers/rentals.js index 775cbd0..9c07fd1 100644 --- a/controllers/rentals.js +++ b/controllers/rentals.js @@ -5,8 +5,8 @@ var rental = new Rental(); exports.rentalsController = { - all: function all(req, res) { - var rentals = rental.all(function(rentals) { + all_rentals: function all_rentals(req, res) { + var rentals = rental.all_rentals(function(rentals) { return res.status(200).json(rentals); }); }, diff --git a/database.js b/database.js index e222c4b..4f43399 100644 --- a/database.js +++ b/database.js @@ -91,6 +91,24 @@ module.exports = { }, // RENTALS + all_rentals: function(callback) { + var newDate = new Date(); + var today = formatDate(newDate); + var db = new sqlite3.Database('db/' + db_env + '.db'); + + db.exec("BEGIN; \ + UPDATE rentals SET overdue=1 WHERE due_date < " + today + " \ + AND check_in IS NULL; \ + COMMIT;", function() { + db.all( + "SELECT * FROM rentals", function(err, res) { + if (callback) { callback(res); } + }); + }); + + db.close(); + }, + overdue: function(callback) { var newDate = new Date(); var today = formatDate(newDate); @@ -114,16 +132,6 @@ module.exports = { db.close(); }, - // update_overdue: function(callback) { - // var newDate = new Date(); - // var today = formatDate(newDate); - // this.query("UPDATE rentals SET overdue=1 WHERE due_date<" + today + " \ - // AND check_in IS NULL;", - // function(res) { - // callback(res); - // }); - // }, - // passing req.body to data check_out: function(data, callback) { // data will be an object with a key value pair with each item for rental diff --git a/routes/rentals.js b/routes/rentals.js index 9fceaee..9240edf 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -3,7 +3,7 @@ var router = express.Router(); var rental_exports = require('../controllers/rentals'); router.get('/', function(req, res, next) { - return rental_exports.rentalsController.all(req, res); + return rental_exports.rentalsController.all_rentals(req, res); }); // // router.get('/:movie_title', function(req, res, next) { From 44d36cca3e7953bcd5a168e8cc0b72f4bd562316 Mon Sep 17 00:00:00 2001 From: Brenna Date: Thu, 24 Sep 2015 10:48:36 -0700 Subject: [PATCH 84/93] added endpoints for rentals/:title and rentals/:title/current_customers --- controllers/movies.js | 2 +- controllers/rentals.js | 16 ++++++++++++++++ database.js | 12 ++++++++++-- routes/rentals.js | 7 +++++++ test/controllers/rentals.js | 2 +- 5 files changed, 35 insertions(+), 4 deletions(-) diff --git a/controllers/movies.js b/controllers/movies.js index c9c6678..8f54d0d 100644 --- a/controllers/movies.js +++ b/controllers/movies.js @@ -39,7 +39,7 @@ exports.moviesController = { current_customers: function current_customers(req, res) { var movie_title = req.params.title; - console.log("movie title:" + movie_title) + movie.current_customers(movie_title, function(current_customers) { return res.status(200).json(current_customers); }); diff --git a/controllers/rentals.js b/controllers/rentals.js index 9c07fd1..68c3ea8 100644 --- a/controllers/rentals.js +++ b/controllers/rentals.js @@ -11,6 +11,22 @@ exports.rentalsController = { }); }, + current_customers: function current_customers(req, res) { + var movie_title = req.params.movie_title; + + rental.current_customers(movie_title, function(current_customers){ + return res.status(200).json(current_customers); + }) + }, + + rental_log: function rental_log(req, res) { + var movie_title = req.params.movie_title; + + rental.rental_log(movie_title, function(rental_log){ + return res.status(200).json(rental_log); + }) + }, + overdue: function overdue(req, res) { rental.overdue(function(overdue) { return res.status(200).json(overdue); diff --git a/database.js b/database.js index 4f43399..db8da40 100644 --- a/database.js +++ b/database.js @@ -9,8 +9,8 @@ module.exports = { db.serialize(function() { // below: this is the callback pattern...parameters(ERRORS, RESULT) db.all(statement, function(err, res) { - // console.log(statement); - // console.log(err); + console.log(statement); + console.log(err); // error handling looks like -> if (err) { }; if (callback) { callback(res); } }); @@ -109,6 +109,14 @@ module.exports = { db.close(); }, + rental_log: function(movie_title, callback) { + movie_title = movie_title.toLowerCase(); + var capitalize_title = movie_title[0].toUpperCase() + movie_title.substring(1); + this.query("SELECT * FROM rentals WHERE movie_title ='" + capitalize_title + "';", function(res) { + callback(res); + }); + }, + overdue: function(callback) { var newDate = new Date(); var today = formatDate(newDate); diff --git a/routes/rentals.js b/routes/rentals.js index 9240edf..f64c4b5 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -9,6 +9,13 @@ router.get('/', function(req, res, next) { // router.get('/:movie_title', function(req, res, next) { // return rental_exports.rentalsController.rented_by(req, res); // }); +router.get('/:movie_title/current_customers', function(req, res, next) { + return rental_exports.rentalsController.current_customers(req, res); +}); + +router.get('/:movie_title', function(req, res, next) { + return rental_exports.rentalsController.rental_log(req, res); +}) router.get('/overdue', function(req, res, next) { return rental_exports.rentalsController.overdue(req, res); diff --git a/test/controllers/rentals.js b/test/controllers/rentals.js index 944afce..449517b 100644 --- a/test/controllers/rentals.js +++ b/test/controllers/rentals.js @@ -5,7 +5,7 @@ var request = require('supertest'), agent = request.agent(app), Rental = require('../../rentals'); -describe.only("rentals controller", function() { +describe("rentals controller", function() { var rental, db_cleaner; beforeEach(function(done) { From 70d229b1e28684183ac1363e7b52fbc3066ae6ee Mon Sep 17 00:00:00 2001 From: Brenna Date: Thu, 24 Sep 2015 14:02:38 -0700 Subject: [PATCH 85/93] fixed overdue path and test --- database.js | 1 + routes/rentals.js | 2 +- test/controllers/rentals.js | 7 ++++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/database.js b/database.js index db8da40..a1324b8 100644 --- a/database.js +++ b/database.js @@ -133,6 +133,7 @@ module.exports = { FROM customers, rentals \ WHERE customers.id=rentals.customer_id \ AND rentals.overdue=1 AND rentals.check_in IS NULL;", function(err, res) { + console.log(res); if (callback) { callback(res); } }); }); diff --git a/routes/rentals.js b/routes/rentals.js index f64c4b5..c7748ef 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -13,7 +13,7 @@ router.get('/:movie_title/current_customers', function(req, res, next) { return rental_exports.rentalsController.current_customers(req, res); }); -router.get('/:movie_title', function(req, res, next) { +router.get('/:movie_title/rental_log', function(req, res, next) { return rental_exports.rentalsController.rental_log(req, res); }) diff --git a/test/controllers/rentals.js b/test/controllers/rentals.js index 449517b..a3fc7a8 100644 --- a/test/controllers/rentals.js +++ b/test/controllers/rentals.js @@ -5,7 +5,7 @@ var request = require('supertest'), agent = request.agent(app), Rental = require('../../rentals'); -describe("rentals controller", function() { +describe.only("rentals controller", function() { var rental, db_cleaner; beforeEach(function(done) { @@ -17,8 +17,8 @@ describe("rentals controller", function() { "BEGIN; \ DELETE FROM rentals; DELETE FROM customers; \ INSERT INTO rentals(check_out, check_in, due_date, overdue, movie_title, customer_id) \ - VALUES('2015-06-16', '2015-06-17', '2015-06-19', 0, 'Jaws', 1), \ - ('2015-06-16', '2015-06-17', '2015-06-19', 1, 'Alien', 1); \ + VALUES('20150616', '20150617', '20150619', 0, 'Jaws', 1), \ + ('20150616', null, '20150619', 1, 'Alien', 1); \ INSERT INTO customers(name, registered_at, address, city, state, postal_code, phone, account_credit) \ VALUES('Harry', 20150616, '1234', 'Seattle', 'WA', '98103', '1234567', 123); \ COMMIT;" @@ -68,6 +68,7 @@ describe("rentals controller", function() { agent.get(rentals_overdue_path).set("Accept", "application/json") .expect(200, function(error, result) { assert.equal(result.body.length, 1); + console.log(result); var keys = ['id', 'name', 'registered_at', 'address', 'city', 'state', 'postal_code', 'phone', 'account_credit']; assert.deepEqual(Object.keys(result.body[0]), keys); From 161176638f0ac0c1c8d404b640c3cf8cf6ec5188 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Thu, 24 Sep 2015 14:22:29 -0700 Subject: [PATCH 86/93] Does some syntax changes. --- database.js | 6 +++--- routes/rentals.js | 4 ++-- test/controllers/rentals.js | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/database.js b/database.js index a1324b8..7fc5b41 100644 --- a/database.js +++ b/database.js @@ -9,8 +9,8 @@ module.exports = { db.serialize(function() { // below: this is the callback pattern...parameters(ERRORS, RESULT) db.all(statement, function(err, res) { - console.log(statement); - console.log(err); + // console.log(statement); + // console.log(err); // error handling looks like -> if (err) { }; if (callback) { callback(res); } }); @@ -133,7 +133,7 @@ module.exports = { FROM customers, rentals \ WHERE customers.id=rentals.customer_id \ AND rentals.overdue=1 AND rentals.check_in IS NULL;", function(err, res) { - console.log(res); + // console.log(res); if (callback) { callback(res); } }); }); diff --git a/routes/rentals.js b/routes/rentals.js index c7748ef..30716ce 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -15,7 +15,7 @@ router.get('/:movie_title/current_customers', function(req, res, next) { router.get('/:movie_title/rental_log', function(req, res, next) { return rental_exports.rentalsController.rental_log(req, res); -}) +}); router.get('/overdue', function(req, res, next) { return rental_exports.rentalsController.overdue(req, res); @@ -33,7 +33,7 @@ router.get('/check_in', function(req, res, next) { return rental_exports.rentalsController.check_in(req, res); }); -router.post('/check_in', function(req, res, next) { +router.post('/check_in', function(req, res, next) { // THIS SHOULD BE PUT/PATCH return rental_exports.rentalsController.check_in(req, res); }); diff --git a/test/controllers/rentals.js b/test/controllers/rentals.js index a3fc7a8..bd27cdd 100644 --- a/test/controllers/rentals.js +++ b/test/controllers/rentals.js @@ -5,7 +5,7 @@ var request = require('supertest'), agent = request.agent(app), Rental = require('../../rentals'); -describe.only("rentals controller", function() { +describe("rentals controller", function() { var rental, db_cleaner; beforeEach(function(done) { @@ -68,7 +68,6 @@ describe.only("rentals controller", function() { agent.get(rentals_overdue_path).set("Accept", "application/json") .expect(200, function(error, result) { assert.equal(result.body.length, 1); - console.log(result); var keys = ['id', 'name', 'registered_at', 'address', 'city', 'state', 'postal_code', 'phone', 'account_credit']; assert.deepEqual(Object.keys(result.body[0]), keys); @@ -80,10 +79,11 @@ describe.only("rentals controller", function() { var check_out_path = '/rentals/check_out'; describe("POST check_out_path", function() { it("can make a post request", function(done) { + console.log(check_out_path); agent.post(check_out_path).set('Accept', 'application/json') - .field('check_out', '2015-09-23') + .field('check_out', 20150923) .field('check_in', null) - .field('due_date', '2015-09-26') + .field('due_date', 20150926) .field('movie_title', 'Jaws') .field('customer_id', 1) From 8543159b238144ccf75b1ec8386fa57ca7aa84e1 Mon Sep 17 00:00:00 2001 From: Brenna Date: Thu, 24 Sep 2015 15:43:37 -0700 Subject: [PATCH 87/93] added rental log tests --- database.js | 5 +- test/controllers/rentals.js | 111 +++++++++++++++++++++++++++--------- utils/rentals.json | 16 ++++++ 3 files changed, 101 insertions(+), 31 deletions(-) diff --git a/database.js b/database.js index a1324b8..f4d650d 100644 --- a/database.js +++ b/database.js @@ -9,8 +9,8 @@ module.exports = { db.serialize(function() { // below: this is the callback pattern...parameters(ERRORS, RESULT) db.all(statement, function(err, res) { - console.log(statement); - console.log(err); + // console.log(statement); + // console.log(err); // error handling looks like -> if (err) { }; if (callback) { callback(res); } }); @@ -133,7 +133,6 @@ module.exports = { FROM customers, rentals \ WHERE customers.id=rentals.customer_id \ AND rentals.overdue=1 AND rentals.check_in IS NULL;", function(err, res) { - console.log(res); if (callback) { callback(res); } }); }); diff --git a/test/controllers/rentals.js b/test/controllers/rentals.js index a3fc7a8..bb691ae 100644 --- a/test/controllers/rentals.js +++ b/test/controllers/rentals.js @@ -5,7 +5,7 @@ var request = require('supertest'), agent = request.agent(app), Rental = require('../../rentals'); -describe.only("rentals controller", function() { +describe("rentals controller", function() { var rental, db_cleaner; beforeEach(function(done) { @@ -53,10 +53,10 @@ describe.only("rentals controller", function() { }); }); - var rentals_overdue_path = '/rentals/overdue'; - describe("GET rentals_overdue_path", function() { + var rental_log_path = '/rentals/Jaws/rental_log'; + describe("GET rental_log_path", function() { it("knows about the route", function(done) { - agent.get(rentals_overdue_path).set('Accept', 'application/json') + agent.get(rental_log_path).set('Accept', 'application/json') .expect('Content-Type', /application\/json/) .expect(200, function(error, result) { assert.equal(error, undefined); @@ -64,47 +64,102 @@ describe.only("rentals controller", function() { }); }); - it("returns an array of overdue rental objects", function(done) { - agent.get(rentals_overdue_path).set("Accept", "application/json") + it("returns an array of all rentals of that movie title", function(done) { + agent.get(rental_log_path).set("Accept", "application/json") .expect(200, function(error, result) { assert.equal(result.body.length, 1); - console.log(result); - var keys = ['id', 'name', 'registered_at', 'address', 'city', 'state', 'postal_code', 'phone', 'account_credit']; + var keys = ['id', 'check_out', 'check_in', 'due_date', 'overdue', 'movie_title', 'customer_id']; assert.deepEqual(Object.keys(result.body[0]), keys); done(); }); }); }); - var check_out_path = '/rentals/check_out'; - describe("POST check_out_path", function() { - it("can make a post request", function(done) { - agent.post(check_out_path).set('Accept', 'application/json') - .field('check_out', '2015-09-23') - .field('check_in', null) - .field('due_date', '2015-09-26') - .field('movie_title', 'Jaws') - .field('customer_id', 1) - - .expect(201, function(error, result) { + var rentals_overdue_path = '/rentals/overdue'; + describe("GET rentals_overdue_path", function() { + it("knows about the route", function(done) { + agent.get(rentals_overdue_path).set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, result) { assert.equal(error, undefined); done(); }); }); - }); - describe("GET check_out_path", function(){ - it('should respond with JSON array', function(done) { - agent.get(check_out_path).set('Accept', 'application/json') - .expect(200) - .expect('Content-Type', /json/) - .end(function(err, res) { - if (err) return done(err); - res.body.should.be.instanceof(Array); + it("returns an array of overdue rental objects", function(done) { + agent.get(rentals_overdue_path).set("Accept", "application/json") + .expect(200, function(error, result) { + assert.equal(result.body.length, 1); + + var keys = ['id', 'name', 'registered_at', 'address', 'city', 'state', 'postal_code', 'phone', 'account_credit']; + assert.deepEqual(Object.keys(result.body[0]), keys); done(); }); }); }); + +//request = agent +// .post(path) +// .send('key':'value') +// done() + + // var check_out_path = '/rentals/check_out' + // .post(check_out_path) + // .send(check_out:'', check_in:'', due_date:'', movie_title:'', customer_id:'') + // var check_out_path = '/rentals/check_out'; + // describe("POST check_out_path", function() { + // it("can make a post request", function(done) { + // agent.post(check_out_path).set('Accept', 'application/json') + // .field('check_out', 20150923) + // .field('check_in', null) + // .field('due_date', 20150926) + // .field('movie_title', 'Jaws') + // .field('customer_id', 1) + // + // .expect(201, function(error, result) { + // assert.equal(error, undefined); + // done(); + // }); + // }); + // }); + // + // describe("GET check_out_path", function(){ + // it('should respond with JSON array', function(done) { + // agent.get(check_out_path).set('Accept', 'application/json') + // .expect(200) + // .expect('Content-Type', /json/) + // .end(function(err, res) { + // console.log(res); + // if (err) return done(err); + // res.body.should.be.instanceof(Array); + // done(); + // }); + // }); + // }); + + // var check_in_path = '/rentals/check_in'; + // describe("GET check_in_path", function() { + // it("knows about the route", function(done) { + // agent.get(check_in_path).set('Accept', 'application/json') + // .expect('Content-Type', /application\/json/) + // .expect(200, function(error, result) { + // assert.equal(error, undefined); + // done(); + // }); + // }); + + // it("returns an array of overdue rental objects", function(done) { + // agent.get(check_in_path).set("Accept", "application/json") + // .expect(200, function(error, result) { + // assert.equal(result.body.length, 1); + // + // var keys = ['id', 'name', 'registered_at', 'address', 'city', 'state', 'postal_code', 'phone', 'account_credit']; + // assert.deepEqual(Object.keys(result.body[0]), keys); + // done(); + // }); + // }); + // }); + }); //final describe close diff --git a/utils/rentals.json b/utils/rentals.json index c91d598..f3411d5 100644 --- a/utils/rentals.json +++ b/utils/rentals.json @@ -6,5 +6,21 @@ "overdue": 0, "customer_id": 1, "movie_title": "Jaws" + }, + { + "check_out": 20150616, + "check_in": null, + "due_date": 20150619, + "overdue": 0, + "customer_id": 1, + "movie_title": "Alien" + }, + { + "check_out": 20150616, + "check_in": null, + "due_date": 20150619, + "overdue": 0, + "customer_id": 1, + "movie_title": "The Birds" } ] From 4b6f4129e3c14f88825889908f550ef3c0077221 Mon Sep 17 00:00:00 2001 From: Brenna Date: Thu, 24 Sep 2015 15:51:11 -0700 Subject: [PATCH 88/93] added more rentals seeds --- utils/rentals.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/utils/rentals.json b/utils/rentals.json index f3411d5..46fc5a5 100644 --- a/utils/rentals.json +++ b/utils/rentals.json @@ -9,10 +9,10 @@ }, { "check_out": 20150616, - "check_in": null, + "check_in": 20150618, "due_date": 20150619, "overdue": 0, - "customer_id": 1, + "customer_id": 2, "movie_title": "Alien" }, { @@ -20,7 +20,7 @@ "check_in": null, "due_date": 20150619, "overdue": 0, - "customer_id": 1, + "customer_id": 3, "movie_title": "The Birds" } ] From 62d1337d7a75b48388b1cf66359009bae5c7d203 Mon Sep 17 00:00:00 2001 From: Brenna Date: Thu, 24 Sep 2015 16:30:52 -0700 Subject: [PATCH 89/93] rentals post test is functioning --- routes/rentals.js | 2 +- test/controllers/rentals.js | 84 ++++++++++--------------------------- 2 files changed, 24 insertions(+), 62 deletions(-) diff --git a/routes/rentals.js b/routes/rentals.js index 30716ce..400ff3f 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -33,7 +33,7 @@ router.get('/check_in', function(req, res, next) { return rental_exports.rentalsController.check_in(req, res); }); -router.post('/check_in', function(req, res, next) { // THIS SHOULD BE PUT/PATCH +router.put('/check_in', function(req, res, next) { return rental_exports.rentalsController.check_in(req, res); }); diff --git a/test/controllers/rentals.js b/test/controllers/rentals.js index bb691ae..c2addda 100644 --- a/test/controllers/rentals.js +++ b/test/controllers/rentals.js @@ -99,67 +99,29 @@ describe("rentals controller", function() { }); }); + var check_out_path = '/rentals/check_out'; + var new_rental = { movie_title: 'Jaws', customer_id: 1}; + describe("POST check_out_path", function(){ + it("creates a new rental record", function(){ + request(check_out_path) + .post(check_out_path) + .send(new_rental) + .expect(200) + .expect(rental.all.length, 3); + }); + }); + + var check_in_path = '/rentals/check_in'; + var update_rental = { movie_title: 'Alien', customer_id: 1}; + describe("PUT check_in_path", function(){ + it("updates an existing rental record", function(done){ + request(check_in_path) + .put(check_in_path) + .send(update_rental) + .expect(200) + .expect("Alien is updated", done); + }); + }); -//request = agent -// .post(path) -// .send('key':'value') -// done() - - // var check_out_path = '/rentals/check_out' - // .post(check_out_path) - // .send(check_out:'', check_in:'', due_date:'', movie_title:'', customer_id:'') - // var check_out_path = '/rentals/check_out'; - // describe("POST check_out_path", function() { - // it("can make a post request", function(done) { - // agent.post(check_out_path).set('Accept', 'application/json') - // .field('check_out', 20150923) - // .field('check_in', null) - // .field('due_date', 20150926) - // .field('movie_title', 'Jaws') - // .field('customer_id', 1) - // - // .expect(201, function(error, result) { - // assert.equal(error, undefined); - // done(); - // }); - // }); - // }); - // - // describe("GET check_out_path", function(){ - // it('should respond with JSON array', function(done) { - // agent.get(check_out_path).set('Accept', 'application/json') - // .expect(200) - // .expect('Content-Type', /json/) - // .end(function(err, res) { - // console.log(res); - // if (err) return done(err); - // res.body.should.be.instanceof(Array); - // done(); - // }); - // }); - // }); - - // var check_in_path = '/rentals/check_in'; - // describe("GET check_in_path", function() { - // it("knows about the route", function(done) { - // agent.get(check_in_path).set('Accept', 'application/json') - // .expect('Content-Type', /application\/json/) - // .expect(200, function(error, result) { - // assert.equal(error, undefined); - // done(); - // }); - // }); - - // it("returns an array of overdue rental objects", function(done) { - // agent.get(check_in_path).set("Accept", "application/json") - // .expect(200, function(error, result) { - // assert.equal(result.body.length, 1); - // - // var keys = ['id', 'name', 'registered_at', 'address', 'city', 'state', 'postal_code', 'phone', 'account_credit']; - // assert.deepEqual(Object.keys(result.body[0]), keys); - // done(); - // }); - // }); - // }); }); //final describe close From 7b65edd7468b170966e3367ae8b90cb364f4e15d Mon Sep 17 00:00:00 2001 From: Brenna Date: Thu, 24 Sep 2015 16:57:29 -0700 Subject: [PATCH 90/93] working update tests for rentals --- test/controllers/rentals.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/controllers/rentals.js b/test/controllers/rentals.js index c2addda..c85b67e 100644 --- a/test/controllers/rentals.js +++ b/test/controllers/rentals.js @@ -102,12 +102,12 @@ describe("rentals controller", function() { var check_out_path = '/rentals/check_out'; var new_rental = { movie_title: 'Jaws', customer_id: 1}; describe("POST check_out_path", function(){ - it("creates a new rental record", function(){ - request(check_out_path) - .post(check_out_path) + it("creates a new rental record", function(done){ + agent.post(check_out_path).set('Accept', 'application/json') .send(new_rental) .expect(200) .expect(rental.all.length, 3); + done(); }); }); @@ -115,11 +115,11 @@ describe("rentals controller", function() { var update_rental = { movie_title: 'Alien', customer_id: 1}; describe("PUT check_in_path", function(){ it("updates an existing rental record", function(done){ - request(check_in_path) - .put(check_in_path) + agent.put(check_in_path).set('Accept', 'application/json') .send(update_rental) .expect(200) - .expect("Alien is updated", done); + .expect("Alien is updated"); + done(); }); }); From 95aff6b7cf2a869c27dbea953c5566193f6a6d15 Mon Sep 17 00:00:00 2001 From: Brenna Date: Fri, 25 Sep 2015 09:29:06 -0700 Subject: [PATCH 91/93] switched check-in back to post --- routes/rentals.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/rentals.js b/routes/rentals.js index 400ff3f..3c06b83 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -33,7 +33,7 @@ router.get('/check_in', function(req, res, next) { return rental_exports.rentalsController.check_in(req, res); }); -router.put('/check_in', function(req, res, next) { +router.post('/check_in', function(req, res, next) { //doesn't work with put return rental_exports.rentalsController.check_in(req, res); }); From 35a87a03296b0b76e757661b7c4c873c9535af54 Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Fri, 25 Sep 2015 13:23:36 -0700 Subject: [PATCH 92/93] Refactors database model. --- controllers/rentals.js | 8 +- customers.js | 14 +++ database.js | 182 ++++-------------------------------- movies.js | 43 +++++++++ rentals.js | 95 +++++++++++++++++++ routes/rentals.js | 7 +- test/controllers/rentals.js | 7 +- test/models/database.js | 61 ++++++++++++ 8 files changed, 238 insertions(+), 179 deletions(-) create mode 100644 test/models/database.js diff --git a/controllers/rentals.js b/controllers/rentals.js index 68c3ea8..c9437a1 100644 --- a/controllers/rentals.js +++ b/controllers/rentals.js @@ -4,7 +4,6 @@ var Rental = require('../rentals'); var rental = new Rental(); exports.rentalsController = { - all_rentals: function all_rentals(req, res) { var rentals = rental.all_rentals(function(rentals) { return res.status(200).json(rentals); @@ -16,7 +15,7 @@ exports.rentalsController = { rental.current_customers(movie_title, function(current_customers){ return res.status(200).json(current_customers); - }) + }); }, rental_log: function rental_log(req, res) { @@ -24,7 +23,7 @@ exports.rentalsController = { rental.rental_log(movie_title, function(rental_log){ return res.status(200).json(rental_log); - }) + }); }, overdue: function overdue(req, res) { @@ -44,5 +43,4 @@ exports.rentalsController = { return res.status(200).json(check_in); }); } - -} +}; diff --git a/customers.js b/customers.js index 3352ad6..6ca979b 100644 --- a/customers.js +++ b/customers.js @@ -7,4 +7,18 @@ function Customer() { Customer.prototype = require('./database'); +Customer.prototype.current_rentals = function(id, callback) { + // list of current rentals out based on customer id + this.query("SELECT * FROM rentals WHERE customer_id=" + id + " AND check_in IS NULL;", function(res) { + callback(res); + }); +}; + +Customer.prototype.past_rentals = function(id, callback) { + // list of past rentals based on customer id + this.query("SELECT * FROM rentals WHERE customer_id=" + id + " AND check_in IS NOT NULL ORDER BY check_out" + ";", function(res) { + callback(res); + }); +}; + module.exports = Customer; diff --git a/database.js b/database.js index f4d650d..cc7a2a1 100644 --- a/database.js +++ b/database.js @@ -4,7 +4,7 @@ var db_env = process.env.DB || 'development'; // Here we will define our instance methods module.exports = { - query: function(statement, callback) { + query: function(statement, callback) { // shared var db = new sqlite3.Database('db/' + db_env + '.db'); db.serialize(function() { // below: this is the callback pattern...parameters(ERRORS, RESULT) @@ -19,183 +19,35 @@ module.exports = { db.close(); }, - all: function(callback) { + all: function(callback) { // shared this.query("SELECT * FROM " + this.table_name + ";", function(res) { callback(res); }); }, - sort_by: function(sort_type, records_per_page, offset, callback) { + sort_by: function(sort_type, records_per_page, offset, callback) { // shared this.query("SELECT * FROM " + this.table_name + " ORDER BY " + sort_type + " LIMIT " + records_per_page + " OFFSET " + offset + ";", function(res) { callback(res); }); }, - // MOVIES - movie_info: function(movie_title, callback) { - this.query("SELECT * FROM " + this.table_name + " WHERE title LIKE '%" + movie_title + "%';", function(res) { - callback(res); - }); - }, - - current_rentals: function(id, callback) { - // list of current rentals out based on customer id - this.query("SELECT * FROM rentals WHERE customer_id=" + id + " AND check_in IS NULL;", function(res) { - callback(res); - }); - }, - - past_rentals: function(id, callback) { - // list of past rentals based on customer id - this.query("SELECT * FROM rentals WHERE customer_id=" + id + " AND check_in IS NOT NULL ORDER BY check_out" + ";", function(res) { - callback(res); - }); - }, - - // CUSTOMERS - current_customers: function(movie_title, callback) { - this.query("SELECT customers.id, customers.name, customers.registered_at, \ - customers.address, customers.city, customers.state, \ - customers.postal_code, customers.phone, customers.account_credit \ - FROM customers, rentals \ - WHERE customers.id=rentals.customer_id \ - AND rentals.movie_title LIKE '%" + movie_title + "%' \ - AND rentals.check_in IS NULL;", function(res) { - callback(res); - }); - }, + formatDate: function(date, callback) { // shared + var dateObj = new Date(date); + var month = (dateObj.getUTCMonth() + 1).toString(); //months from 1-12 + var day = (dateObj.getUTCDate()).toString(); + var year = (dateObj.getUTCFullYear()).toString(); + var newDate; - past_customers: function(movie_title, callback) { - this.query("SELECT customers.id, customers.name, customers.registered_at, \ - customers.address, customers.city, customers.state, \ - customers.postal_code, customers.phone, customers.account_credit \ - FROM customers, rentals \ - WHERE customers.id=rentals.customer_id \ - AND rentals.movie_title LIKE '%" + movie_title + "%' \ - AND rentals.check_in IS NOT NULL;", function(res) { - callback(res); - }); - }, + if (month.length == 1) { // This will ensure month is two digits + month = "0" + month; + } - past_customers_sort: function(movie_title, sort_type, callback) { - this.query("SELECT customers.id, customers.name, customers.registered_at, \ - customers.address, customers.city, customers.state, \ - customers.postal_code, customers.phone, customers.account_credit \ - FROM customers, rentals \ - WHERE customers.id=rentals.customer_id \ - AND rentals.movie_title LIKE '%" + movie_title + "%' \ - AND rentals.check_in IS NOT NULL \ - ORDER BY " + sort_type + ";", function(res) { - callback(res); - }); - }, + if (day.length == 1) { // This will ensure day is two digits + day = "0" + day; + } - // RENTALS - all_rentals: function(callback) { - var newDate = new Date(); - var today = formatDate(newDate); - var db = new sqlite3.Database('db/' + db_env + '.db'); + newDate = parseInt(year + month + day); - db.exec("BEGIN; \ - UPDATE rentals SET overdue=1 WHERE due_date < " + today + " \ - AND check_in IS NULL; \ - COMMIT;", function() { - db.all( - "SELECT * FROM rentals", function(err, res) { - if (callback) { callback(res); } - }); - }); - - db.close(); - }, - - rental_log: function(movie_title, callback) { - movie_title = movie_title.toLowerCase(); - var capitalize_title = movie_title[0].toUpperCase() + movie_title.substring(1); - this.query("SELECT * FROM rentals WHERE movie_title ='" + capitalize_title + "';", function(res) { - callback(res); - }); - }, - - overdue: function(callback) { - var newDate = new Date(); - var today = formatDate(newDate); - var db = new sqlite3.Database('db/' + db_env + '.db'); - - db.exec("BEGIN; \ - UPDATE rentals SET overdue=1 WHERE due_date < " + today + " \ - AND check_in IS NULL; \ - COMMIT;", function() { - db.all( - "SELECT customers.id, customers.name, customers.registered_at, \ - customers.address, customers.city, customers.state, \ - customers.postal_code, customers.phone, customers.account_credit \ - FROM customers, rentals \ - WHERE customers.id=rentals.customer_id \ - AND rentals.overdue=1 AND rentals.check_in IS NULL;", function(err, res) { - if (callback) { callback(res); } - }); - }); - - db.close(); - }, - - // passing req.body to data - check_out: function(data, callback) { - // data will be an object with a key value pair with each item for rental - var check_out_date = new Date(); - var check_out = formatDate(check_out_date); - var due_date = new Date(check_out_date); - due_date.setDate(check_out_date.getDate() + 3); - var due = formatDate(due_date); - var title = data.movie_title; - var customer_id = data.customer_id; - - var db = new sqlite3.Database('db/' + db_env + '.db'); - db.exec( - "BEGIN; \ - INSERT INTO " + this.table_name + "(check_out, check_in, due_date, overdue, movie_title, customer_id) \ - VALUES(" + check_out + ", null, " + due + ", 0, '" + title + "', " + customer_id + "); \ - UPDATE movies SET inventory_available=inventory_available - 1 WHERE title='" + title + "'; \ - UPDATE customers SET account_credit=account_credit - 3 WHERE id=" + customer_id + "; \ - COMMIT;"); - db.close(); - }, - - // data will include movie_title and customer_id - check_in: function(data, callback) { - var check_in_date = new Date(); - var check_in = formatDate(check_in_date); - var title = data.movie_title; - var customer_id = data.customer_id; - - var db = new sqlite3.Database('db/' + db_env + '.db'); - db.exec( - // update rental: check_in_date and overdue - // update movie: inventory_available - "BEGIN; \ - UPDATE rentals SET check_in=" + check_in + ", overdue=0 WHERE movie_title='" + title + "'; \ - UPDATE movies SET inventory_available=inventory_available + 1 WHERE title='" + title + "'; \ - COMMIT;" - ); - - db.close(); - } -}; - -var formatDate = function(date) { - var dateObj = new Date(date); - var month = (dateObj.getUTCMonth() + 1).toString(); //months from 1-12 - var day = (dateObj.getUTCDate()).toString(); - var year = (dateObj.getUTCFullYear()).toString(); - - if (month.length == 1) { // This will ensure month is two digits - month = "0" + month; + if(callback) { callback(newDate); } } - - if (day.length == 1) { // This will ensure day is two digits - day = "0" + day; - } - - return parseInt(year + month + day); }; diff --git a/movies.js b/movies.js index 2984cb7..a35b21c 100644 --- a/movies.js +++ b/movies.js @@ -7,4 +7,47 @@ function Movie() { Movie.prototype = require('./database'); +Movie.prototype.movie_info = function(movie_title, callback) { + this.query("SELECT * FROM " + this.table_name + " WHERE title LIKE '%" + movie_title + "%';", function(res) { + callback(res); + }); +}; + +Movie.prototype.current_customers = function(movie_title, callback) { + this.query("SELECT customers.id, customers.name, customers.registered_at, \ + customers.address, customers.city, customers.state, \ + customers.postal_code, customers.phone, customers.account_credit \ + FROM customers, rentals \ + WHERE customers.id=rentals.customer_id \ + AND rentals.movie_title LIKE '%" + movie_title + "%' \ + AND rentals.check_in IS NULL;", function(res) { + callback(res); + }); +}; + +Movie.prototype.past_customers = function(movie_title, callback) { + this.query("SELECT customers.id, customers.name, customers.registered_at, \ + customers.address, customers.city, customers.state, \ + customers.postal_code, customers.phone, customers.account_credit \ + FROM customers, rentals \ + WHERE customers.id=rentals.customer_id \ + AND rentals.movie_title LIKE '%" + movie_title + "%' \ + AND rentals.check_in IS NOT NULL;", function(res) { + callback(res); + }); +}; + +Movie.prototype.past_customers_sort = function(movie_title, sort_type, callback) { + this.query("SELECT customers.id, customers.name, customers.registered_at, \ + customers.address, customers.city, customers.state, \ + customers.postal_code, customers.phone, customers.account_credit \ + FROM customers, rentals \ + WHERE customers.id=rentals.customer_id \ + AND rentals.movie_title LIKE '%" + movie_title + "%' \ + AND rentals.check_in IS NOT NULL \ + ORDER BY " + sort_type + ";", function(res) { + callback(res); + }); + }; + module.exports = Movie; diff --git a/rentals.js b/rentals.js index 7555f3d..2de9b81 100644 --- a/rentals.js +++ b/rentals.js @@ -1,5 +1,6 @@ "use-strict"; var sqlite3 = require('sqlite3').verbose(); +var db_env = process.env.DB || 'development'; function Rental() { this.table_name = "rentals"; @@ -7,4 +8,98 @@ function Rental() { Rental.prototype = require('./database'); +Rental.prototype.all_rentals = function(callback) { + var newDate = new Date(); + var today = this.formatDate(newDate); + var db = new sqlite3.Database('db/' + db_env + '.db'); + + db.exec("BEGIN; \ + UPDATE rentals SET overdue=1 WHERE due_date < " + today + " \ + AND check_in IS NULL; \ + COMMIT;", function() { + db.all( + "SELECT * FROM rentals", function(err, res) { + if (callback) { callback(res); } + }); + }); + + db.close(); +}; + +Rental.prototype.rental_log = function(movie_title, callback) { + movie_title = movie_title.toLowerCase(); + var capitalize_title = movie_title[0].toUpperCase() + movie_title.substring(1); + this.query("SELECT * FROM rentals WHERE movie_title ='" + capitalize_title + "';", function(res) { + callback(res); + }); +}; + +Rental.prototype.overdue = function(callback) { + var newDate = new Date(); + var today = this.formatDate(newDate); + var db = new sqlite3.Database('db/' + db_env + '.db'); + + db.exec("BEGIN; \ + UPDATE rentals SET overdue=1 WHERE due_date < " + today + " \ + AND check_in IS NULL; \ + COMMIT;", function() { + db.all( + "SELECT customers.id, customers.name, customers.registered_at, \ + customers.address, customers.city, customers.state, \ + customers.postal_code, customers.phone, customers.account_credit \ + FROM customers, rentals \ + WHERE customers.id=rentals.customer_id \ + AND rentals.overdue=1 AND rentals.check_in IS NULL;", function(err, res) { + if (callback) { callback(res); } + }); + }); + + db.close(); +}; + +Rental.prototype.check_out = function(data, callback) { +// passing req.body to data + // data will be an object with a key value pair with each item for rental + var check_out_date = new Date(); + var check_out = this.formatDate(check_out_date); + var due_date = new Date(check_out_date); + due_date.setDate(check_out_date.getDate() + 3); + var due = this.formatDate(due_date); + var title = data.movie_title; + var customer_id = data.customer_id; + + var db = new sqlite3.Database('db/' + db_env + '.db'); + db.exec( + "BEGIN; \ + INSERT INTO " + this.table_name + "(check_out, check_in, due_date, overdue, movie_title, customer_id) \ + VALUES(" + check_out + ", null, " + due + ", 0, '" + title + "', " + customer_id + "); \ + UPDATE movies SET inventory_available=inventory_available - 1 WHERE title='" + title + "'; \ + UPDATE customers SET account_credit=account_credit - 3 WHERE id=" + customer_id + "; \ + COMMIT;", function(err) { + if(callback) { callback(err); } + db.close(); + }); +}; + +Rental.prototype.check_in = function(data, callback) { +// data will include movie_title and customer_id + var check_in_date = new Date(); + var check_in = this.formatDate(check_in_date); + var title = data.movie_title; + var customer_id = data.customer_id; + + var db = new sqlite3.Database('db/' + db_env + '.db'); + db.exec( + // update rental: check_in_date and overdue + // update movie: inventory_available + "BEGIN; \ + UPDATE rentals SET check_in=" + check_in + ", overdue=0 WHERE movie_title='" + title + "'; \ + UPDATE movies SET inventory_available=inventory_available + 1 WHERE title='" + title + "'; \ + COMMIT;", function(err) { + if(callback) { callback(err); } + db.close(); + }); +}; + + module.exports = Rental; diff --git a/routes/rentals.js b/routes/rentals.js index 400ff3f..fdf9e85 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -5,10 +5,7 @@ var rental_exports = require('../controllers/rentals'); router.get('/', function(req, res, next) { return rental_exports.rentalsController.all_rentals(req, res); }); -// -// router.get('/:movie_title', function(req, res, next) { -// return rental_exports.rentalsController.rented_by(req, res); -// }); + router.get('/:movie_title/current_customers', function(req, res, next) { return rental_exports.rentalsController.current_customers(req, res); }); @@ -33,7 +30,7 @@ router.get('/check_in', function(req, res, next) { return rental_exports.rentalsController.check_in(req, res); }); -router.put('/check_in', function(req, res, next) { +router.put('/check_in', function(req, res, next) { return rental_exports.rentalsController.check_in(req, res); }); diff --git a/test/controllers/rentals.js b/test/controllers/rentals.js index c85b67e..2a5e05f 100644 --- a/test/controllers/rentals.js +++ b/test/controllers/rentals.js @@ -17,12 +17,11 @@ describe("rentals controller", function() { "BEGIN; \ DELETE FROM rentals; DELETE FROM customers; \ INSERT INTO rentals(check_out, check_in, due_date, overdue, movie_title, customer_id) \ - VALUES('20150616', '20150617', '20150619', 0, 'Jaws', 1), \ - ('20150616', null, '20150619', 1, 'Alien', 1); \ + VALUES(20150616, 20150617, 20150619, 0, 'Jaws', 1), \ + (20150616, null, 20150619, 1, 'Alien', 1); \ INSERT INTO customers(name, registered_at, address, city, state, postal_code, phone, account_credit) \ VALUES('Harry', 20150616, '1234', 'Seattle', 'WA', '98103', '1234567', 123); \ - COMMIT;" - , function(err) { + COMMIT;", function(err) { db_cleaner.close(); done(); } diff --git a/test/models/database.js b/test/models/database.js new file mode 100644 index 0000000..d2765b9 --- /dev/null +++ b/test/models/database.js @@ -0,0 +1,61 @@ +var assert = require('assert'), + Database = require('../../database'), + Movie = require('../../movies'), + Customer = require('../../customers'), + Rental = require('../../rentals'), + sqlite3 = require('sqlite3').verbose(); + +describe("Database", function() { + var movie, customer, rental, db_cleaner; + + beforeEach(function(done) { + movie = new Movie(); + customer = new Customer(); + rental = new Rental(); + + + db_cleaner = new sqlite3.Database('db/test.db'); + db_cleaner.serialize(function() { + db_cleaner.exec( + "BEGIN; \ + DELETE FROM rentals; DELETE FROM customers; DELETE FROM movies; \ + INSERT INTO rentals(check_out, check_in, due_date, overdue, movie_title, customer_id) \ + VALUES(20150616, 20150617, 20150619, 0, 'Jaws', 1), \ + (20150616, null, 20150619, 1, 'Alien', 1); \ + INSERT INTO customers(name, registered_at, address, city, state, postal_code, phone, account_credit) \ + VALUES('Harry', 20150616, '1234', 'Seattle', 'WA', '98103', '1234567', 123); \ + INSERT INTO movies(title, overview, release_date, inventory, inventory_available) \ + VALUES('Jaws', 'something', 19750619, 6, 6), \ + ('Alien', 'something else', 19790525, 4, 4); \ + COMMIT;", function(err) { + db_cleaner.close(); + done(); + } + ); + }); + }); + + describe("models that inherit from database", function() { + it("Movie can be instantiated", function(done) { + assert(movie instanceof Movie); + done(); + }); + + it("Customer can be instantiated", function(done) { + assert(customer instanceof Customer); + done(); + }); + + it("Rental can be instantiated", function(done) { + assert(rental instanceof Rental); + done(); + }); + }); + + describe("formatDate", function() { + it("returns date as an integer in the form of YYYYMMDD", function(done) { + Database.formatDate(); + }); + }); + +}); From 623c6e6084012ed1c507b049c99abd68eabc874e Mon Sep 17 00:00:00 2001 From: Corinne Pingul Date: Fri, 25 Sep 2015 13:54:52 -0700 Subject: [PATCH 93/93] Fixes formatDate function. --- database.js | 6 ++---- test/models/database.js | 10 +++++----- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/database.js b/database.js index cc7a2a1..a82f9b9 100644 --- a/database.js +++ b/database.js @@ -31,7 +31,7 @@ module.exports = { }); }, - formatDate: function(date, callback) { // shared + formatDate: function(date) { // shared var dateObj = new Date(date); var month = (dateObj.getUTCMonth() + 1).toString(); //months from 1-12 var day = (dateObj.getUTCDate()).toString(); @@ -46,8 +46,6 @@ module.exports = { day = "0" + day; } - newDate = parseInt(year + month + day); - - if(callback) { callback(newDate); } + return parseInt(year + month + day); } }; diff --git a/test/models/database.js b/test/models/database.js index d2765b9..0051f74 100644 --- a/test/models/database.js +++ b/test/models/database.js @@ -52,10 +52,10 @@ describe("Database", function() { }); }); - describe("formatDate", function() { - it("returns date as an integer in the form of YYYYMMDD", function(done) { - Database.formatDate(); - }); - }); + // describe("formatDate", function() { + // it("returns date as an integer in the form of YYYYMMDD", function(done) { + // Database.formatDate(); + // }); + // }); });