Initial commit, including all apps previously in course
This commit is contained in:
18
todoapp/nodejs_api/README.md
Normal file
18
todoapp/nodejs_api/README.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# DO276 JavaScript/Node.js To Do List App
|
||||
|
||||
Based on Restify 4.0 and Sequelize 3.14. Tested on Node.js 0.10 from SCL with Mariadb 5.5.
|
||||
|
||||
Do `npm install` do download dependencies.
|
||||
|
||||
Run as `node app.js`
|
||||
|
||||
* Don't do pagination yet.
|
||||
|
||||
* Database connection parameters hardcoded (as a novice developer would usually do).
|
||||
|
||||
* There is a lot of boiler plate code in the controller and the model. There should be a way to have more centralized error handling.
|
||||
|
||||
* Have mysql database initialized and running, and front end deployed to apache and running
|
||||
|
||||
* Access as http://localhost:30000/todo
|
||||
|
||||
35
todoapp/nodejs_api/app.js
Normal file
35
todoapp/nodejs_api/app.js
Normal file
@@ -0,0 +1,35 @@
|
||||
var restify = require('restify');
|
||||
|
||||
var controller = require('./controllers/items');
|
||||
var serverinfo = require('./controllers/serverinfo');
|
||||
|
||||
var db = require('./models/db');
|
||||
var model = require('./models/items');
|
||||
|
||||
model.connect(db.params, function(err) {
|
||||
if (err) throw err;
|
||||
});
|
||||
|
||||
var server = restify.createServer()
|
||||
.use(restify.fullResponse())
|
||||
.use(restify.queryParser())
|
||||
.use(restify.bodyParser())
|
||||
.use(restify.CORS());
|
||||
|
||||
controller.context(server, '/todo/api', model);
|
||||
serverinfo.context(server, '/todo/api');
|
||||
|
||||
var port = process.env.PORT || 30080;
|
||||
server.listen(port, function (err) {
|
||||
if (err)
|
||||
console.error(err);
|
||||
else
|
||||
console.log('App is ready at : ' + port);
|
||||
});
|
||||
|
||||
if (process.env.environment == 'production')
|
||||
process.on('uncaughtException', function (err) {
|
||||
console.error(JSON.parse(JSON.stringify(err, ['stack', 'message', 'inner'], 2)))
|
||||
});
|
||||
|
||||
|
||||
6
todoapp/nodejs_api/compile.sh
Normal file
6
todoapp/nodejs_api/compile.sh
Normal file
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
source /opt/rh/nodejs010/enable
|
||||
|
||||
npm install
|
||||
|
||||
118
todoapp/nodejs_api/controllers/items.js
Normal file
118
todoapp/nodejs_api/controllers/items.js
Normal file
@@ -0,0 +1,118 @@
|
||||
|
||||
var model = undefined;
|
||||
|
||||
exports.context = function(server, path, itemsModel) {
|
||||
if (!server)
|
||||
done('has to provide a restify server object');
|
||||
|
||||
var context = "/items";
|
||||
if (path)
|
||||
context = path + context;
|
||||
|
||||
server.get(context + '/', this.list);
|
||||
server.get(context + '/:id', this.read);
|
||||
server.post(context + '/', this.save);
|
||||
server.del(context + '/:id', this.destroy);
|
||||
|
||||
model = itemsModel;
|
||||
};
|
||||
|
||||
exports.list = function(req, res, next) {
|
||||
var page_no = req.query.page || 1;
|
||||
var sortField = req.query.sortFields || "id";
|
||||
var sortDirection = req.query.sortDirections || "asc";
|
||||
|
||||
model.listAll(page_no, sortField, sortDirection, function(err, items) {
|
||||
if (err) {
|
||||
next(err);
|
||||
}
|
||||
else {
|
||||
if (items) {
|
||||
model.countAll(function(err, n) {
|
||||
if (err) {
|
||||
next(err);
|
||||
}
|
||||
else {
|
||||
if (n) {
|
||||
var page = {
|
||||
"currentPage" : page_no,
|
||||
"list" : items,
|
||||
"pageSize" : 10,
|
||||
"sortDirections" : sortDirection,
|
||||
"sortFields" : sortField,
|
||||
"totalResults" : n
|
||||
};
|
||||
res.json(page);
|
||||
next();
|
||||
}
|
||||
else {
|
||||
next(new Error("Can't count items"));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
next(new Error("Can't retrieve items"));
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
exports.read = function(req, res, next) {
|
||||
var key = req.params.id;
|
||||
model.read(key, function(err, item) {
|
||||
if (err) {
|
||||
next(err);
|
||||
}
|
||||
else {
|
||||
if (item) {
|
||||
res.json(item);
|
||||
next();
|
||||
}
|
||||
else {
|
||||
next(new Error("Can't retrieve items"));
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
exports.save = function(req, res, next) {
|
||||
if (req.params.id) {
|
||||
model.update(req.params.id, req.params.description, req.params.done, function(err, item) {
|
||||
if (err) {
|
||||
next(err);
|
||||
}
|
||||
else {
|
||||
res.json(item);
|
||||
next();
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
model.create(req.params.description, req.params.done, function(err, item) {
|
||||
if (err) {
|
||||
next(err);
|
||||
}
|
||||
else {
|
||||
res.json(item);
|
||||
next();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
exports.destroy = function(req, res, next) {
|
||||
if (req.params.id) {
|
||||
model.destroy(req.params.id, function(err, item) {
|
||||
if (err) {
|
||||
next(err);
|
||||
}
|
||||
else {
|
||||
//XXX jee_api does NOT return item on delete
|
||||
res.json(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
29
todoapp/nodejs_api/controllers/serverinfo.js
Normal file
29
todoapp/nodejs_api/controllers/serverinfo.js
Normal file
@@ -0,0 +1,29 @@
|
||||
var os = require('os');
|
||||
|
||||
exports.context = function(server, path) {
|
||||
if (!server)
|
||||
done('has to provide a restify server object');
|
||||
|
||||
server.get(path + '/host', this.serverInfo);
|
||||
};
|
||||
|
||||
exports.serverInfo = function(req, res, next) {
|
||||
var address;
|
||||
var ifaces = os.networkInterfaces();
|
||||
|
||||
for (var dev in ifaces) {
|
||||
var iface = ifaces[dev].filter(function(details) {
|
||||
return details.family === 'IPv4' && details.internal === false;
|
||||
});
|
||||
if (iface.length > 0)
|
||||
address = iface[0].address;
|
||||
}
|
||||
|
||||
var reply = {
|
||||
ip: address,
|
||||
hostname: os.hostname()
|
||||
};
|
||||
res.json(reply);
|
||||
next();
|
||||
};
|
||||
|
||||
12
todoapp/nodejs_api/models/db.js
Normal file
12
todoapp/nodejs_api/models/db.js
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
module.exports.params = {
|
||||
dbname: process.env.MYSQL_ENV_MYSQL_DATABASE,
|
||||
username: process.env.MYSQL_ENV_MYSQL_USER,
|
||||
password: process.env.MYSQL_ENV_MYSQL_PASSWORD,
|
||||
params: {
|
||||
host: "mysql",
|
||||
port: "3306",
|
||||
dialect: 'mysql'
|
||||
}
|
||||
};
|
||||
|
||||
126
todoapp/nodejs_api/models/items.js
Normal file
126
todoapp/nodejs_api/models/items.js
Normal file
@@ -0,0 +1,126 @@
|
||||
var Sequelize = require("sequelize");
|
||||
|
||||
var Item = undefined;
|
||||
|
||||
module.exports.connect = function(params, callback) {
|
||||
var sequlz = new Sequelize(
|
||||
params.dbname, params.username, params.password,
|
||||
params.params);
|
||||
Item = sequlz.define('Item', {
|
||||
id: { type: Sequelize.BIGINT,
|
||||
primaryKey: true, unique: true, allowNull: false,
|
||||
autoIncrement: true },
|
||||
description: { type: Sequelize.STRING,
|
||||
allowNull: true },
|
||||
done: { type: Sequelize.BOOLEAN,
|
||||
allowNull: true }
|
||||
}, {
|
||||
timestamps: false,
|
||||
freezeTableName: true
|
||||
});
|
||||
// drop and create tables, better done globally
|
||||
/*
|
||||
Item.sync({ force: true }).then(function() {
|
||||
callback();
|
||||
}).error(function(err) {
|
||||
callback(err);
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
exports.disconnect = function(callback) {
|
||||
//XXX shouln'd to something to close or release the db connection?
|
||||
callback();
|
||||
}
|
||||
|
||||
exports.create = function(description, done, callback) {
|
||||
Item.create({
|
||||
//id: id,
|
||||
description: description,
|
||||
done: (done) ? true : false
|
||||
}).then(function(item) {
|
||||
callback(null, item);
|
||||
}).error(function(err) {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
|
||||
exports.update = function(key, description, done, callback) {
|
||||
Item.find({ where:{ id: key } }).then(function(item) {
|
||||
if (!item) {
|
||||
callback(new Error("Nothing found for key " + key));
|
||||
}
|
||||
else {
|
||||
item.updateAttributes({
|
||||
description: description,
|
||||
done: (done) ? true : false
|
||||
}).then(function() {
|
||||
callback(null, item);
|
||||
}).error(function(err) {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
}).error(function(err) {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
exports.read = function(key, callback) {
|
||||
Item.find({ where:{ id: key } }).then(function(item) {
|
||||
if (!item) {
|
||||
callback(new Error("Nothing found for key " + key));
|
||||
}
|
||||
else {
|
||||
//XXX why recreating the item object?
|
||||
callback(null, {
|
||||
id: item.id,
|
||||
description: item.description,
|
||||
done: item.done
|
||||
});
|
||||
}
|
||||
}).error(function(err) {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
|
||||
exports.destroy = function(key, callback) {
|
||||
Item.find({ where:{ id: key } }).then(function(item) {
|
||||
if (!item) {
|
||||
callback(new Error("Nothing found for " + key));
|
||||
}
|
||||
else {
|
||||
item.destroy().then(function() {
|
||||
callback(null, item);
|
||||
}).error(function(err) {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
}).error(function(err) {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
|
||||
exports.countAll = function(callback) {
|
||||
Item.findAll({ attributes: [[Sequelize.fn('COUNT', Sequelize.col('id')), 'no_items']] } ).then(function(n) {
|
||||
callback(null, n[0].get('no_items'));
|
||||
}).error(function(err) {
|
||||
callback(err);
|
||||
});
|
||||
//callback(null, 100);
|
||||
}
|
||||
|
||||
exports.listAll = function(page, sortField, sortDirection, callback) {
|
||||
Item.findAll({ offset: 10 * (page - 1), limit: 10, order: [[sortField, sortDirection]] }).then(function(items) {
|
||||
var theitems = [];
|
||||
items.forEach(function(item) {
|
||||
//XXX why recreating the item objects for theitems?
|
||||
theitems.push({
|
||||
id: item.id, description: item.description, done: item.done });
|
||||
});
|
||||
callback(null, theitems);
|
||||
}).error(function(err) {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
|
||||
10
todoapp/nodejs_api/package.json
Normal file
10
todoapp/nodejs_api/package.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "todo",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"restify": "4.0.3",
|
||||
"sequelize": "3.14.2",
|
||||
"mysql": "2.9.0"
|
||||
}
|
||||
}
|
||||
6
todoapp/nodejs_api/run.sh
Normal file
6
todoapp/nodejs_api/run.sh
Normal file
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
source /opt/rh/nodejs010/enable
|
||||
|
||||
node app.js
|
||||
|
||||
Reference in New Issue
Block a user