var collection_json = require('collection_json') , pg = require('pg').native , _ = require('underscore'); function mapRow(row) { var data = _.map(row, function(value, key) { return {name: key, value: value}; }); return { data: data }; } function mapDepartments(res, departments) { return _.map(departments, function(row) { var item = mapRow(row); item.href = res.urlgenerator.department(row.dept_no); return item; }); } function mapEmployees(res, employees) { return _.map(employees, function(row) { var item = mapRow(row); item.href = res.urlgenerator.employee(row.emp_no); return item; }); } function pager(req) { var pageSize = 10; var offset = parseInt(req.query.offset) || 0; var limit = parseInt(req.query.limit) || pageSize; var prevOffset = offset - pageSize; var nextOffset = offset + pageSize; return { offset: offset, limit: limit, prevOffset: prevOffset >= 0 ? prevOffset : 0, nextOffset: function(length) { return length > 0 ? nextOffset : undefined; } }; } exports.index = function(req, res) { if(req.accepts('html')) { res.render('index', { title: 'Employee DB', urlgenerator: res.urlgenerator }); } else { var c = {collection: { links: [ { rel: 'departments', prompt: 'Department List', href: res.urlgenerator.departments() }, { rel: 'employees', prompt: 'Employee List', href: res.urlgenerator.employees() } ] }}; res.contentType('application/vnd.collection+json'); res.send(JSON.stringify(collection_json.fromObject(c)), 200); } }; exports.departments = function(req, res) { pg.connect(process.env.DATABASE_URL, function(err, client) { if(err) throw err; var p = pager(req); var departments = []; client.query('SELECT dept_no, dept_name FROM departments OFFSET $1 LIMIT $2', [ p.offset, p.limit ] ). on('row', function(row) { departments.push(row); }). on('end', function() { if(req.accepts('html')) { res.render('departments', { title: 'Department List', urlgenerator: res.urlgenerator, pager: p, departments: departments }); } else { var c = {collection: { href: res.urlgenerator.departments(), items: mapDepartments(res, departments) }}; res.contentType('application/vnd.collection+json'); res.send(JSON.stringify(collection_json.fromObject(c)), 200); } }); }); }; exports.department = function(req, res) { var dept_no = req.params.dept_no; if(req.accepts('html')) { res.render('department', { title: 'Department ' + dept_no, urlgenerator: res.urlgenerator, dept_no: dept_no }); } else { var c = {collection: { href: res.urlgenerator.department(dept_no), links: [ { rel: 'employees', prompt: 'Employees in department ' + dept_no, href: res.urlgenerator.employees_in_department(dept_no) },{ rel: 'departments', prompt: 'All departments', href: res.urlgenerator.departments() } ] }}; res.contentType('application/vnd.collection+json'); res.send(collection_json.fromObject(c)); } } exports.employees_in_department = function(req, res) { pg.connect(process.env.DATABASE_URL, function(err, client) { if(err) throw err; var dept_no = req.params.dept_no; var p = pager(req); var employees = []; // TODO: Add dept_name to view // TODO: Add manager as a link client.query('SELECT employees.* FROM employees, dept_emp WHERE employees.emp_no=dept_emp.emp_no AND dept_emp.dept_no=$1 AND dept_emp.to_date > now() AND now() > dept_emp.from_date OFFSET $2 LIMIT $3', [ dept_no, p.offset, p.limit ]). on('row', function(row) { employees.push(row); }). on('end', function() { if(req.accepts('html')) { res.render('employees_in_department', { title: 'Department: #' + dept_no, urlgenerator: res.urlgenerator, pager: p, dept_no: dept_no, employees: employees }); } else { var c = {collection: { href: res.urlgenerator.employees_in_department(dept_no), links: [ { rel: 'department', prompt: 'Department: #' + dept_no, href: res.urlgenerator.department(dept_no) } ], items: mapEmployees(res, employees) }}; res.contentType('application/vnd.collection+json'); res.send(collection_json.fromObject(c)); } }); }); }; exports.employees = function(req, res) { pg.connect(process.env.DATABASE_URL, function(err, client) { if(err) throw err; var p = pager(req); var emp_no = req.params.emp_no; var employees = []; client.query('SELECT * FROM employees ORDER BY emp_no OFFSET $1 LIMIT $2', [ p.offset, p.limit ]). on('row', function(row) { employees.push(row); }). on('end', function() { if(req.accepts('html')) { res.render('employees', { title: 'Employee List', urlgenerator: res.urlgenerator, pager: p, employees: employees }); } else { var c = {collection: { href: res.urlgenerator.employees(), items: mapEmployees(res, employees) }}; res.contentType('application/vnd.collection+json'); res.send(JSON.stringify(collection_json.fromObject(c)), 200); } }); }); }; exports.employee = function(req, res) { pg.connect(process.env.DATABASE_URL, function(err, client) { if(err) throw err; var emp_no = req.params.emp_no; var employee; client.query('SELECT * FROM employees WHERE employees.emp_no=$1', [ emp_no ]). on('row', function(row) { employee = row; }). on('end', function() { if(req.accepts('html')) { res.render('employee', { title: 'Employee: #' + emp_no, urlgenerator: res.urlgenerator, employee: employee }); } else { var c = {collection: { href: res.urlgenerator.employee(emp_no), items: [ mapRow(employee) ], }}; res.contentType('application/vnd.collection+json'); res.send(JSON.stringify(collection_json.fromObject(c)), 200); } }); }); };