diff options
-rw-r--r-- | app.js | 20 | ||||
-rw-r--r-- | routes/index.js | 88 | ||||
-rw-r--r-- | views/department.jade | 11 | ||||
-rw-r--r-- | views/departments.jade | 15 | ||||
-rw-r--r-- | views/employee.jade | 7 | ||||
-rw-r--r-- | views/employees.jade | 15 | ||||
-rw-r--r-- | views/employees_in_department.jade | 18 | ||||
-rw-r--r-- | views/index.jade | 6 | ||||
-rw-r--r-- | views/layout.jade | 2 | ||||
-rw-r--r-- | views/lib/pager.jade | 14 |
10 files changed, 167 insertions, 29 deletions
@@ -14,7 +14,7 @@ app.configure(function(){ app.use(express.methodOverride()); app.use(urlgenerator); app.use(app.router); - app.use(express.static(__dirname + '/public')); + app.use(express.static(__dirname + '/public', {maxAge: 60 * 60 * 1000})); }); app.configure('development', function(){ @@ -24,14 +24,22 @@ app.configure('development', function(){ function urlgenerator(req, res, next) { var host = req.headers.host; res.urlgenerator = { - departments: function() { + start: function() { return 'http://' + host + '/'; }, + + departments: function(offset) { + return 'http://' + host + '/department/' + (offset ? '?offset=' + offset : ''); + }, department: function(dept_no) { return 'http://' + host + '/department/' + dept_no; }, - employees_in_department: function(dept_no) { - return 'http://' + host + '/department/' + dept_no + '/employees'; + employees_in_department: function(dept_no, offset) { + return 'http://' + host + '/department/' + dept_no + '/employees' + (offset ? '?offset=' + offset : ''); + }, + + employees: function(offset) { + return 'http://' + host + '/employee/' + (offset ? '?offset=' + offset : ''); }, employee: function(emp_no) { return 'http://' + host + '/employee/' + emp_no; @@ -40,9 +48,11 @@ function urlgenerator(req, res, next) { next(); } -app.get('/', routes.departments); +app.get('/', routes.index); +app.get('/department', routes.departments); app.get('/department/:dept_no', routes.department); app.get('/department/:dept_no/employees', routes.employees_in_department); +app.get('/employee', routes.employees); app.get('/employee/:emp_no', routes.employee); http.createServer(app).listen(app.get('port'), function(){ diff --git a/routes/index.js b/routes/index.js index 9d0b8ac..dcb6e23 100644 --- a/routes/index.js +++ b/routes/index.js @@ -25,22 +25,60 @@ function mapEmployees(res, employees) { }); } -function limit(req) { - return "LIMIT " + (_.isString(limit) ? limit : 10); +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'). + 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: 'Departments', + title: 'Department List', + urlgenerator: res.urlgenerator, pager: p, departments: departments }); } @@ -87,19 +125,20 @@ 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 ' + limit(req), [ dept_no ]). + 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, + title: 'Department: #' + dept_no, + urlgenerator: res.urlgenerator, pager: p, dept_no: dept_no, - urlgenerator: res.urlgenerator, employees: employees }); } @@ -108,7 +147,7 @@ exports.employees_in_department = function(req, res) { href: res.urlgenerator.employees_in_department(dept_no), links: [ { rel: 'department', - prompt: 'Departments ' + dept_no, + prompt: 'Department: #' + dept_no, href: res.urlgenerator.department(dept_no) } ], items: mapEmployees(res, employees) @@ -120,6 +159,36 @@ exports.employees_in_department = function(req, res) { }); }; +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; @@ -132,7 +201,8 @@ exports.employee = function(req, res) { on('end', function() { if(req.accepts('html')) { res.render('employee', { - title: 'Employee ' + emp_no, + title: 'Employee: #' + emp_no, + urlgenerator: res.urlgenerator, employee: employee }); } diff --git a/views/department.jade b/views/department.jade index e2a5bde..32952a9 100644 --- a/views/department.jade +++ b/views/department.jade @@ -3,6 +3,13 @@ extends layout block content h1= title - p: a(href=urlgenerator.departments()) All departments + p + a(href=urlgenerator.start()) Employee DB + | >> + a(href=urlgenerator.departments()) Department List + | >> + a(href=urlgenerator.department(dept_no)) Department ##{dept_no} - p: a(href=urlgenerator.employees_in_department(dept_no)) Employees + p: a(href=urlgenerator.employees_in_department(dept_no)) Employees in this department + + p TODO: add links to manager and department name. diff --git a/views/departments.jade b/views/departments.jade index 711e0ec..bdcb0ae 100644 --- a/views/departments.jade +++ b/views/departments.jade @@ -1,8 +1,15 @@ extends layout +include lib/pager block content - h1= title - each department in departments - table + p + a(href=urlgenerator.start()) Employee DB + | >> + a(href=urlgenerator.departments()) Department List + + table + each department in departments tr - td: a(href='/department/#{department.dept_no}') #{department.dept_name} + td: a(href=urlgenerator.department(department.dept_no)) #{department.dept_name} + + mixin pager(pager, departments.length, urlgenerator.departments) diff --git a/views/employee.jade b/views/employee.jade index 6cd2c10..6728540 100644 --- a/views/employee.jade +++ b/views/employee.jade @@ -1,7 +1,12 @@ extends layout block content - h1= title + p + a(href=urlgenerator.start()) Employee DB + | >> + a(href=urlgenerator.employees()) Employee List + | >> + a(href=urlgenerator.employee(employee.emp_no)) Employee ##{employee.emp_no} table tr diff --git a/views/employees.jade b/views/employees.jade new file mode 100644 index 0000000..d7d9005 --- /dev/null +++ b/views/employees.jade @@ -0,0 +1,15 @@ +extends layout +include lib/pager + +block content + p + a(href=urlgenerator.start()) Employee DB + | >> + a(href=urlgenerator.employees()) Employee List + + table + each employee in employees + tr + td: a(href=urlgenerator.employee(employee.emp_no)) #{employee.first_name} #{employee.last_name} + + mixin pager(pager, employees.length, urlgenerator.employees) diff --git a/views/employees_in_department.jade b/views/employees_in_department.jade index f835a29..c341647 100644 --- a/views/employees_in_department.jade +++ b/views/employees_in_department.jade @@ -1,13 +1,21 @@ extends layout +include lib/pager block content h1= title - p: a(href=urlgenerator.department(dept_no)) Department #{dept_no} + p + a(href=urlgenerator.start()) Employee DB + | >> + a(href=urlgenerator.departments()) Department List + | >> + a(href=urlgenerator.department(dept_no)) Department ##{dept_no} + | >> + a(href=urlgenerator.employees_in_department(dept_no)) Employees in Department ##{dept_no} - p This department has #{employees.length} employees. - - each employee in employees - table + table + each employee in employees tr td: a(href=urlgenerator.employee(employee.emp_no)) #{employee.first_name} #{employee.last_name} + + mixin pager(pager, employees.length, function(offset) { return urlgenerator.employees_in_department(dept_no, offset) }) diff --git a/views/index.jade b/views/index.jade index ef7b09f..f195915 100644 --- a/views/index.jade +++ b/views/index.jade @@ -1,5 +1,7 @@ extends layout block content - h1= title - p Welcome to #{title}
\ No newline at end of file + p Available resources + ul + li: a(href=urlgenerator.departments()) Departments list + li: a(href=urlgenerator.employees()) Employees list diff --git a/views/layout.jade b/views/layout.jade index 1b7b305..367640e 100644 --- a/views/layout.jade +++ b/views/layout.jade @@ -4,4 +4,4 @@ html title= title link(rel='stylesheet', href='/stylesheets/style.css') body - block content
\ No newline at end of file + block content diff --git a/views/lib/pager.jade b/views/lib/pager.jade new file mode 100644 index 0000000..a762735 --- /dev/null +++ b/views/lib/pager.jade @@ -0,0 +1,14 @@ +mixin pager(pager, length, f) + p + if pager.offset > 0 + a(href=f(pager.prevOffset)) prev + | + else + | prev + + - var nextOffset = pager.nextOffset(length) + if nextOffset > 0 + a(href=f(nextOffset)) next + else + | next + |