From e0bb61aab05e012a9842a5ebd16809aa38b38143 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Thu, 5 Jul 2012 16:51:28 +0200 Subject: o Adding DELETE support for employees. o Adding proper error handling when PostgreSQL is failing. --- routes/index.js | 108 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 77 insertions(+), 31 deletions(-) diff --git a/routes/index.js b/routes/index.js index de7e0b1..782d361 100644 --- a/routes/index.js +++ b/routes/index.js @@ -44,6 +44,17 @@ function pager(req, count) { }; } +function connect(cb) { + pg.connect(process.env.DATABASE_URL, function(err, client) { + if(err) { + res.send('Unable to connect to PostgreSQL.', {'Content-Type': 'text/plain'}, 500); + } + else { + cb(client); + } + }); +} + function after(res, callback) { return function(err, queryResult) { if(err) { @@ -67,6 +78,16 @@ function method(handlers) { } } +function send_text(res, status, text) { + res.writeHead(status, { + 'Content-Type': 'text/plain', + 'Content-Length': text.length + }); + res.write(text); + res.write('\n'); + res.end(); +} + function send_html(req, res, render) { if(req.method == 'HEAD') { // Can't be bothered to calculate Content-Length even if I @@ -81,19 +102,17 @@ function send_html(req, res, render) { } } -function send_cj(req, res, c) { +function send_cj(status, req, res, c) { var text = JSON.stringify(collection_json.fromObject(c)); var headers = { 'Content-Type': 'application/vnd.collection+json', 'Content-Length': text.length }; - if(req.method == 'HEAD') { - res.writeHead(200, headers); - res.end(); - } - else { - res.send(text, headers, 200); + res.writeHead(status, headers); + if(req.method == 'GET') { + res.write(text); } + res.end(); } function linksFromPager(req, p, urlgenerator) { @@ -136,7 +155,7 @@ function getIndex(req, res) { href: res.urlgenerator.employees() } ] }}; - send_cj(req, res, c); + send_cj(200, req, res, c); break; default: res.send(406); @@ -148,8 +167,7 @@ exports.index = method({ }); function getDepartments(req, res) { - pg.connect(process.env.DATABASE_URL, function(err, client) { - if(err) throw err; + connect(function(client) { var sql = 'SELECT n_live_tup FROM pg_stat_user_tables WHERE relname=\'departments\''; var sql2 = 'SELECT dept_no, dept_name FROM departments OFFSET $1 LIMIT $2'; client.query(sql, after(res, function(rs) { @@ -170,7 +188,7 @@ function getDepartments(req, res) { items: mapDepartments(res, rs2.rows), links: linksFromPager(req, p, res.urlgenerator.departments), }}; - send_cj(req, res, c); + send_cj(200, req, res, c); break; default: res.send(406); @@ -208,7 +226,7 @@ function getDepartment(req, res) { href: res.urlgenerator.departments() } ] }}; - send_cj(req, res, c); + send_cj(200, req, res, c); break; default: res.send(406); @@ -220,8 +238,7 @@ exports.department = method({ }); function getEmployeesInDepartment(req, res) { - pg.connect(process.env.DATABASE_URL, function(err, client) { - if(err) throw err; + connect(function(client) { var dept_no = req.params.dept_no; // TODO: Add dept_name to view // TODO: Add manager as a link @@ -251,7 +268,7 @@ function getEmployeesInDepartment(req, res) { } ], items: mapEmployees(res, rs2.rows) }}; - send_cj(req, res, c); + send_cj(200, req, res, c); break; default: res.send(406); @@ -266,8 +283,7 @@ exports.employeesInDepartment = method({ }); function getEmployees(req, res) { - pg.connect(process.env.DATABASE_URL, function(err, client) { - if(err) throw err; + connect(function(client) { var emp_no = req.params.emp_no; var sql1, sql2; var sql1Params = []; @@ -320,7 +336,7 @@ function getEmployees(req, res) { }], items: mapEmployees(res, rs2.rows) }}; - send_cj(req, res, c); + send_cj(200, req, res, c); break; default: res.send(406); @@ -335,26 +351,40 @@ exports.employees = method({ }); function getEmployee(req, res) { - pg.connect(process.env.DATABASE_URL, function(err, client) { - if(err) throw err; + connect(function(client) { var emp_no = req.params.emp_no; var sql = 'SELECT * FROM employees WHERE employees.emp_no=$1'; client.query(sql, [ emp_no ], after(res, function(rs) { switch(req.accept.types.getBestMatch(['text/html', 'application/vnd.collection+json', '*/*'])) { case 'text/html': - send_html(req, res, _.bind(res.render, res, 'employee', { - title: 'Employee: #' + emp_no, - urlgenerator: res.urlgenerator, - employee: rs.rows[0] - })); + if(rs.rowCount > 0) { + send_html(req, res, _.bind(res.render, res, 'employee', { + title: 'Employee: #' + emp_no, + urlgenerator: res.urlgenerator, + employee: rs.rows[0] + })); + } + else { + send_text(res, 404, 'No employee with emp_no=' + emp_no + '.'); + } break; case 'application/vnd.collection+json': case '*/*': - var c = {collection: { - href: res.urlgenerator.employee(emp_no), - items: [ mapRow(rs.rows[0]) ], - }}; - send_cj(req, res, c); + var c; + if(rs.rowCount > 0) { + c = {collection: { + href: res.urlgenerator.employee(emp_no), + items: mapEmployees(res, rs.rows) + }}; + } + else { + c = {collection: { + error: { + title: 'No employee with emp_no=' + emp_no + '.' + } + }}; + } + send_cj(rs.rowCount > 0 ? 200 : 404, req, res, c); break; default: res.send(406); @@ -363,6 +393,22 @@ function getEmployee(req, res) { }); } +function deleteEmployee(req, res) { + connect(function(client) { + var emp_no = parseInt(req.params.emp_no) || 0; + if(emp_no < 10000 || emp_no > 999999) { + return send_text(res, 404, 'Illegal emp_no.'); + } + client.query('DELETE FROM employees WHERE emp_no=$1', [ emp_no ], after(res, function(rs) { + if(rs.rowCount == 0) { + return send_text(res, 404, 'No employee with emp_no=' + emp_no + '.'); + } + res.send(204); + })); + }); +} + exports.employee = method({ - GET: getEmployee + GET: getEmployee, + DELETE: deleteEmployee }); -- cgit v1.2.3