Browse Source

Merge branch 'master' of github.com:TechEmpower/FrameworkBenchmarks

Hamilton Turner 10 years ago
parent
commit
7a208efba6

+ 2 - 2
frameworks/JavaScript/express/README.md

@@ -12,8 +12,8 @@ This is the Express portion of a [benchmarking test suite](../) comparing a vari
 
 ## Infrastructure Software Versions
 The tests were run with:
-* [Node.js v0.10.0](http://nodejs.org/)
-* [Express 3.1](http://expressjs.com/)
+* [Node.js v0.12.2](http://nodejs.org/)
+* [Express 4.12.3](http://expressjs.com/)
 
 ## Resources
 * http://nodejs.org/api/cluster.html

+ 104 - 64
frameworks/JavaScript/express/app.js

@@ -5,28 +5,56 @@
 
 var cluster = require('cluster')
   , numCPUs = require('os').cpus().length
-  , windows = require('os').platform() == 'win32'
   , express = require('express')
+  , Sequelize = require('sequelize')
   , mongoose = require('mongoose')
-  , async = require('async')
   , conn = mongoose.connect('mongodb://localhost/hello_world')
-  , connMap = { user: 'benchmarkdbuser', password: 'benchmarkdbpass', database: 'hello_world', host: 'localhost', charset: 'utf8' };
+  , async = require('async');
+
+// Middleware
+var bodyParser = require('body-parser')
+  , methodOverride = require('method-override')
+  , errorHandler = require('errorhandler');
 
 var Schema = mongoose.Schema
   , ObjectId = Schema.ObjectId;
 
-var WorldSchema = new Schema({
-    id                           : Number
-  , randomNumber                 : Number
-}, { collection : 'world' });
-var MWorld = conn.model('World', WorldSchema);
-
-if (!windows) {
-  var Mapper = require('mapper');
-  Mapper.connect(connMap, {verbose: false, strict: false});
-  var World = Mapper.map("World", "id", "randomNumber");
-  var Fortune = Mapper.map("Fortune", "id", "message");
-}
+var WorldSchema = new mongoose.Schema({
+    id          : Number,
+    randomNumber: Number
+  }, {
+    collection: 'world'
+  }),
+  MWorld = conn.model('World', WorldSchema);
+
+var sequelize = new Sequelize('hello_world', 'benchmarkdbuser', 'benchmarkdbpass', {
+  host: 'localhost',
+  dialect: 'mysql',
+  logging: false
+});
+
+var World = sequelize.define('World', {
+  id: {
+    type: 'Sequelize.INTEGER'
+  },
+  randomNumber: {
+    type: 'Sequelize.INTEGER'
+  }
+}, {
+  timestamps: false,
+  freezeTableName: true
+});
+var Fortune = sequelize.define('Fortune', {
+  id: {
+    type: 'Sequelize.INTEGER'
+  },
+  message: {
+    type: 'Sequelize.STRING'
+  }
+}, {
+  timestamps: false,
+  freezeTableName: true
+});
 
 if (cluster.isMaster) {
   // Fork workers.
@@ -41,95 +69,104 @@ if (cluster.isMaster) {
   var app = module.exports = express();
 
   // Configuration
-  app.configure(function(){
-    app.use(express.bodyParser());
-    app.use(express.methodOverride());
-    app.use(app.router);
+  // https://github.com/expressjs/method-override#custom-logic
+  app.use(bodyParser.urlencoded({extended: true}));
+  app.use(methodOverride(function(req, res){
+    if (req.body && typeof req.body === 'object' && '_method' in req.body) {
+      // look in urlencoded POST bodies and delete it
+      var method = req.body._method
+      delete req.body._method
+      return method
+    }
+  }));
 
-    app.set('view engine', 'jade');
-    app.set('views', __dirname + '/views');
+  // Set headers for all routes
+  app.use(function(req, res, next) {
+    res.setHeader("Server", "Express");
+    return next();
   });
 
-  app.configure('development', function() {
-    app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
-  });
+  app.set('view engine', 'jade');
+  app.set('views', __dirname + '/views');
 
-  app.configure('production', function() {
-    app.use(express.errorHandler());
-  });
+  // Check Node env.
+  var env = process.env.NODE_ENV || 'development';
+  if ('development' == env) {
+    app.use(errorHandler({ dumpExceptions: true, showStack: true }));
+  }
+  if ('production' == env) {
+    app.use(errorHandler());
+  }
 
   // Routes
 
   app.get('/json', function(req, res) {
-    res.send({ message: 'Hello, World!' })
+    res.send({ message: 'Hello, World!' });
+  });
+
+  app.get('/plaintext', function(req, res) {
+    res.header('Content-Type', 'text/plain').send('Hello, World!');
   });
   
   app.get('/mongoose', function(req, res) {
-    var queries = req.query.queries || 1,
-        worlds  = [],
-        queryFunctions = [];
+    var queries = isNaN(req.query.queries) ? 1 : parseInt(req.query.queries, 10)
+      , queryFunctions = [];
+
+    queries = Math.min(Math.max(queries, 1), 500);
 
     for (var i = 1; i <= queries; i++ ) {
       queryFunctions.push(function(callback) {
-        MWorld.findOne({ id: (Math.floor(Math.random() * 10000) + 1 )}).exec(function (err, world) {
-          worlds.push(world);
-          callback(null, 'success');
-        });
+        MWorld.findOne({ id: (Math.floor(Math.random() * 10000) + 1) }).exec(callback);
       });
     }
 
     async.parallel(queryFunctions, function(err, results) {
-      if (queries == 1) {
-        worlds = worlds[0];
+      if (!req.query.queries) {
+        results = results[0];
       }
-      res.send(worlds);
+      res.send(results);
     });
   });
 
-  app.get('/mysql-orm', function(req, res) {
-    if (windows) return res.send(501, 'Not supported on windows');
-    
+  app.get('/mysql-orm', function(req, res) {    
     var queries = isNaN(req.query.queries) ? 1 : parseInt(req.query.queries, 10)
-      , worlds  = []
       , queryFunctions = [];
 
     queries = Math.min(Math.max(queries, 1), 500);
 
     for (var i = 1; i <= queries; i++ ) {
       queryFunctions.push(function(callback) {
-        World.findById(Math.floor(Math.random()*10000) + 1, function (err, world) {
-          worlds.push(world);
-          callback(null, 'success');
-        });
+        World.findOne({
+          where: {
+            id: Math.floor(Math.random() * 10000) + 1}
+          }
+        ).complete(callback);
       });
     }
 
     async.parallel(queryFunctions, function(err, results) {
       if (!req.query.queries) {
-        worlds = worlds[0];
+        results = results[0];
       }
-      res.send(worlds);
+      res.setHeader("Content-Type", "application/json");
+      res.send(results);
     });
   });
 
   app.get('/fortune', function(req, res) {
-    if (windows) return res.send(501, 'Not supported on windows');
-    
-    Fortune.all(function (err, fortunes) {
+    Fortune.findAll().complete(function (err, fortunes) {
       var newFortune = {id: 0, message: "Additional fortune added at request time."};
       fortunes.push(newFortune);
-      fortunes.sort(sortFortunes);
+      fortunes.sort(function (a, b) {
+        return (a.message < b.message) ? -1 : 1;
+      });
 
       res.render('fortunes', {fortunes: fortunes});
     });
   });
 
-  function sortFortunes(a, b) {
-    return (a.message < b.message) ? -1 : (a.message > b.message) ? 1 : 0;
-  }
-
   app.get('/mongoose-update', function(req, res) {
-    var queries = req.query.queries || 1
+    var queries = isNaN(req.query.queries) ? 1 : parseInt(req.query.queries, 10)
       , selectFunctions = [];
 
     queries = Math.min(queries, 500);
@@ -163,16 +200,18 @@ if (cluster.isMaster) {
   });
 
   app.get('/mysql-orm-update', function(req, res) {
-    if (windows) return res.send(501, 'Not supported on windows');
-
-    var queries = req.query.queries || 1
+    var queries = isNaN(req.query.queries) ? 1 : parseInt(req.query.queries, 10)
       , selectFunctions = [];
 
-    queries = Math.min(queries, 500);
+    queries = Math.max(Math.min(queries, 500), 1);
 
     for (var i = 1; i <= queries; i++ ) {
       selectFunctions.push(function(callback) {
-        World.findById(Math.floor(Math.random() * 10000) + 1, callback);
+        World.findOne({
+          where: {
+            id: Math.floor(Math.random() * 10000) + 1}
+          }
+        ).complete(callback);
       });
     }
 
@@ -183,7 +222,7 @@ if (cluster.isMaster) {
         (function(i){
           updateFunctions.push(function(callback){
             worlds[i].randomNumber = Math.ceil(Math.random() * 10000);
-            World.save(worlds[i], callback);
+            worlds[i].save().complete(callback);
           });
         })(i);
       }
@@ -191,7 +230,8 @@ if (cluster.isMaster) {
       async.parallel(updateFunctions, function(err, updates) {
         res.send(worlds);
       });
-    });   
+    });  
+
   });
 
   app.listen(8080);

+ 1 - 0
frameworks/JavaScript/express/benchmark_config.json

@@ -4,6 +4,7 @@
     "default": {
       "setup_file": "setup",
       "json_url": "/json",
+      "plaintext_url": "/plaintext",
       "port": 8080,
       "approach": "Realistic",
       "classification": "Micro",

+ 8 - 5
frameworks/JavaScript/express/package.json

@@ -3,11 +3,14 @@
   , "version": "0.0.1"
   , "private": true
   , "dependencies": {
-      "express": "3.1.0"
-    , "mongoose": "3.5.5" 
-    , "async": "0.2.5"
-    , "mysql-libmysqlclient": "1.5.2"
-    , "mapper": "0.2.4-pre"
+      "express": "4.12.3"
+    , "body-parser": "1.12.3"
+    , "method-override": "2.3.2"
+    , "errorhandler": "1.3.5"
+    , "mongoose": "4.0.1" 
+    , "async": "0.9.0"
     , "jade": "0.29.0"
+    , "sequelize": "2.0.6"
+    , "mysql": "2.6.2"
   }
 }

+ 2 - 2
frameworks/JavaScript/express/setup.sh

@@ -7,8 +7,8 @@ export NVM_HOME=${IROOT}/nvm
 # Used to avoid nvm's return 2 error.
 # Sourcing this functions if 0 is returned.
 source $NVM_HOME/nvm.sh || 0
-nvm install 0.10.8
-nvm use 0.10.8
+nvm install 0.12.2
+nvm use 0.12.2
 
 # update npm before app init
 npm install -g npm

+ 2 - 2
frameworks/JavaScript/hapi/README.md

@@ -12,8 +12,8 @@ This is the Hapi portion of a [benchmarking test suite](../) comparing a variety
 
 ## Infrastructure Software Versions
 The tests were run with:
-* [Node.js v0.10.0](http://nodejs.org/)
-* [Hapi 1.2.0](http://spumko.github.io/)
+* [Node.js v0.12.2](http://nodejs.org/)
+* [Hapi 8.4.0](http://hapijs.com/)
 
 ## Resources
 * http://nodejs.org/api/cluster.html

+ 73 - 38
frameworks/JavaScript/hapi/app.js

@@ -4,12 +4,11 @@
 
 var cluster = require('cluster'),
 	numCPUs = require('os').cpus().length,
-	windows = require('os').platform() == 'win32',
 	Hapi = require('hapi'),
+	Sequelize = require('sequelize'),
 	mongoose = require('mongoose'),
-	async = require('async'),
 	conn = mongoose.connect('mongodb://localhost/hello_world'),
-	connMap = { user: 'benchmarkdbuser', password: 'benchmarkdbpass', database: 'hello_world', host: 'localhost', charset: 'utf8' };
+	async = require('async');
 
 var WorldSchema = new mongoose.Schema({
 		id          : Number,
@@ -19,12 +18,34 @@ var WorldSchema = new mongoose.Schema({
 	}),
 	MWorld = conn.model('World', WorldSchema);
 
-if (!windows) {
-	var Mapper = require('mapper');
-	Mapper.connect(connMap, {verbose: false, strict: false});
-	var World = Mapper.map('World', 'id', 'randomNumber');
-	var Fortune = Mapper.map('Fortune', 'id', 'message');
-}
+var sequelize = new Sequelize('hello_world', 'benchmarkdbuser', 'benchmarkdbpass', {
+	host: 'localhost',
+	dialect: 'mysql',
+	logging: false
+});
+
+var World = sequelize.define('World', {
+	id: {
+		type: 'Sequelize.INTEGER'
+	},
+	randomNumber: {
+		type: 'Sequelize.INTEGER'
+	}
+}, {
+	timestamps: false,
+	freezeTableName: true
+});
+var Fortune = sequelize.define('Fortune', {
+	id: {
+		type: 'Sequelize.INTEGER'
+	},
+	message: {
+		type: 'Sequelize.STRING'
+	}
+}, {
+	timestamps: false,
+	freezeTableName: true
+});
 
 if (cluster.isMaster) {
 	// Fork workers.
@@ -36,28 +57,38 @@ if (cluster.isMaster) {
 		console.log('worker ' + worker.pid + ' died');
 	});
 } else {
-	var server = module.exports = Hapi.createServer(null, 8080, {
-		views: {
-			engines: {
-				handlebars: 'handlebars'
-			},
-			path: __dirname + '/views'
-		}
+	var server = module.exports = new Hapi.Server();
+	server.connection({port: 8080});
+	server.views({
+		engines: {
+			html: require('handlebars')
+		},
+		path: __dirname + '/views'
 	});
 
 	server.route({
 		method: 'GET',
 		path: '/json',
-		handler: function(req) {
-			req.reply({ message: 'Hello, World!' })
+		handler: function(req, reply) {
+			reply({ message: 'Hello, World!' }).header('Server', 'hapi');
+		}
+	});
+
+	server.route({
+		method: 'GET',
+		path: '/plaintext',
+		handler: function(req, reply) {
+			reply('Hello, World!')
+			 .header('Server', 'hapi')
+			 .header('Content-Type', 'text/plain');
 		}
 	});
 
 	server.route({
 		method: 'GET',
 		path: '/mongoose/{queries?}',
-		handler: function(req){
-			var queries = req.params.queries || 1,
+		handler: function(req, reply){
+			var queries = isNaN(req.params.queries) ? 1 : parseInt(req.params.queries, 10),
 				queryFunctions = [];
 
 			queries = Math.min(Math.max(queries, 1), 500);
@@ -69,10 +100,10 @@ if (cluster.isMaster) {
 			}
 
 			async.parallel(queryFunctions, function(err, results){
-				if (queries == 1) {
+				if (!req.params.queries) {
 					results = results[0];
 				}
-				req.reply(results).header('Server', 'hapi');
+				reply(results).header('Server', 'hapi');
 			});
 		}
 	});
@@ -81,8 +112,6 @@ if (cluster.isMaster) {
 		method: 'GET',
 		path: '/mysql-orm/{queries?}',
 		handler: function(req, reply){
-			if (windows) return req.reply(Hapi.error.internal('Not supported on windows'));
-
 			var queries = isNaN(req.params.queries) ? 1 : parseInt(req.params.queries, 10),
 				queryFunctions = [];
 
@@ -90,7 +119,11 @@ if (cluster.isMaster) {
 
 			for (var i = 1; i <= queries; i++) {
 				queryFunctions.push(function(callback){
-					World.findById(Math.floor(Math.random() * 10000) + 1, callback);
+					World.findOne({
+						where: {
+							id: Math.floor(Math.random() * 10000) + 1}
+						}
+					).complete(callback);
 				});
 			}
 
@@ -106,10 +139,8 @@ if (cluster.isMaster) {
 	server.route({
 		method: 'GET',
 		path: '/fortune',
-		handler: function(req){
-			if (windows) return req.reply(Hapi.error.internal('Not supported on windows'));
-
-			Fortune.all(function(err, fortunes){
+		handler: function(req,reply){
+			Fortune.findAll().complete(function(err, fortunes){
 				fortunes.push({
 					id: 0,
 					message: 'Additional fortune added at request time.'
@@ -118,7 +149,7 @@ if (cluster.isMaster) {
 					return (a.message < b.message) ? -1 : 1;
 				});
 
-				req.reply.view('fortunes.handlebars', {
+				reply.view('fortunes', {
 					fortunes: fortunes
 				}).header('Server', 'hapi');
 			});
@@ -128,8 +159,8 @@ if (cluster.isMaster) {
 	server.route({
 		method: 'GET',
 		path: '/mongoose-update/{queries?}',
-		handler: function(req){
-			var queries = req.params.queries || 1,
+		handler: function(req, reply){
+			var queries = isNaN(req.params.queries) ? 1 : parseInt(req.params.queries, 10),
 				selectFunctions = [];
 
 			queries = Math.max(Math.min(queries, 500), 1);
@@ -157,7 +188,7 @@ if (cluster.isMaster) {
 				}
 
 				async.parallel(updateFunctions, function(err, updates) {
-					req.reply(worlds).header('Server', 'hapi');
+					reply(worlds).header('Server', 'hapi');
 				});
 			});
 		}		
@@ -166,15 +197,19 @@ if (cluster.isMaster) {
 	server.route({
 		method: 'GET',
 		path: '/mysql-orm-update/{queries?}',
-		handler: function(req){
-			var queries = req.params.queries || 1,
+		handler: function(req,reply){
+			var queries = isNaN(req.params.queries) ? 1 : parseInt(req.params.queries, 10),
 				selectFunctions = [];
 
 			queries = Math.max(Math.min(queries, 500), 1);
 
 			for (var i = 1; i <= queries; i++) {
 				selectFunctions.push(function(callback){
-					World.findById(Math.floor(Math.random() * 10000) + 1, callback);
+					World.findOne({
+						where: {
+							id: Math.floor(Math.random() * 10000) + 1}
+						}
+					).complete(callback);
 				});
 			}
 
@@ -185,13 +220,13 @@ if (cluster.isMaster) {
 					(function(i){
 						updateFunctions.push(function(callback){
 							worlds[i].randomNumber = Math.ceil(Math.random() * 10000);
-							World.save(worlds[i], callback);
+							worlds[i].save().complete(callback);
 						});
 					})(i);
 				}
 
 				async.parallel(updateFunctions, function(err, updates) {
-					req.reply(worlds).header('Server', 'hapi');
+					reply(worlds).header('Server', 'hapi');
 				});
 			});
 		}

+ 1 - 0
frameworks/JavaScript/hapi/benchmark_config.json

@@ -4,6 +4,7 @@
     "default": {
       "setup_file": "setup",
       "json_url": "/json",
+      "plaintext_url": "/plaintext",
       "port": 8080,
       "approach": "Realistic",
       "classification": "Micro",

+ 6 - 5
frameworks/JavaScript/hapi/package.json

@@ -3,10 +3,11 @@
 	"version": "0.0.1",
 	"private": true,
 	"dependencies": {
-		"hapi": "1.2.0",
-		"mongoose": "3.5.5",
-		"async": "0.2.5",
-		"mapper": "0.2.4-pre",
-		"handlebars": "1.0.11"
+		"hapi": "8.4.0",
+		"mongoose": "4.0.1",
+		"async": "0.9.0",
+		"handlebars": "3.0.1",
+		"sequelize": "2.0.6",
+		"mysql": "2.6.2"
 	}
 }

+ 2 - 2
frameworks/JavaScript/hapi/setup.sh

@@ -6,8 +6,8 @@ export NVM_HOME=${IROOT}/nvm
 # Used to avoid nvm's return 2 error.
 # Sourcing this functions if 0 is returned.
 source $NVM_HOME/nvm.sh || 0
-nvm install 0.10.8
-nvm use 0.10.8
+nvm install 0.12.2
+nvm use 0.12.2
 
 # update npm before app init
 npm install -g npm

+ 0 - 0
frameworks/JavaScript/hapi/views/fortunes.handlebars → frameworks/JavaScript/hapi/views/fortunes.html


+ 5 - 0
frameworks/JavaScript/koa/app.js

@@ -80,16 +80,19 @@ if (cluster.isMaster) {
 
   // Route handlers
   function *jsonHandler() {
+    this.set('Server', 'Koa');
     this.body = {
       message: "Hello, world!"
     }
   }
 
   function *dbHandler() {
+    this.set('Server', 'Koa');
     this.body = yield worldQuery;
   }
 
   function *queriesHandler() {
+    this.set('Server', 'Koa');
     var numOfQueries = validateParam(this.query.queries);
     var queries = [];
     for (var i = 0; i < numOfQueries; i++) {
@@ -112,6 +115,7 @@ if (cluster.isMaster) {
   }
 
   function *updateHandler() {
+    this.set('Server', 'Koa');
     var numOfUpdates = validateParam(this.query.queries);
     var queries = [];
     for (var i = 0; i < numOfUpdates; i++) {
@@ -121,6 +125,7 @@ if (cluster.isMaster) {
   }
 
   function *textHandler() {
+    this.set('Server', 'Koa');
     this.body = 'Hello, world!';
   }
 

+ 2 - 2
frameworks/JavaScript/koa/setup.sh

@@ -6,8 +6,8 @@ export NVM_HOME=${IROOT}/nvm
 # Used to avoid nvm's return 2 error.
 # Sourcing this functions if 0 is returned.
 source $NVM_HOME/nvm.sh || 0
-nvm install 0.11.16
-nvm use 0.11.16
+nvm install 0.12.2
+nvm use 0.12.2
 
 # update npm before app init
 npm install -g npm

+ 16 - 5
frameworks/JavaScript/nodejs/README.md

@@ -12,23 +12,31 @@ This is the NodeJS portion of a [benchmarking test suite](../) comparing a varie
 
 ## Infrastructure Software Versions
 The tests were run with:
-* [Node.js v0.10.0](http://nodejs.org/)
-* [Mongoose 3.5.5](http://mongoosejs.com/)
-* [Mapper 0.2.4-pre](https://github.com/mgutz/mapper)
-* [MySQL 5.5.29](https://dev.mysql.com/)
+* [Node.js v0.12.2](http://nodejs.org/)
+* [Mongoose 4.0.1](http://mongoosejs.com/)
+* [Sequelize 2.0.6](https://github.com/sequelize/sequelize)
+* [Node MySQL 2.6.2](https://github.com/felixge/node-mysql/)
+* [Node MongoDB Driver 2.0.27](https://github.com/mongodb/node-mongodb-native)
 
 ## Test URLs
 ### JSON Encoding Test
 
 http://localhost:8080/json
 
+### Plaintext Test
+
+http://localhost:8080/plaintext
+
 ### Data-Store/Database Mapping Test
 
 MongoDB:
 http://localhost:8080/mongoose
 
+MongoDB Raw:
+http://localhost:8080/mongodb
+
 MySQL:
-http://localhost:8080/sequelize
+http://localhost:8080/mysql-orm
 
 MySQL Raw:
 http://localhost:8080/mysql
@@ -38,6 +46,9 @@ http://localhost:8080/mysql
 MongoDB:
 http://localhost:8080/mongoose?queries=2
 
+MongoDB Raw:
+http://localhost:8080/mongodb?queries=2
+
 MySQL:
 http://localhost:8080/mysql-orm?queries=2
 

+ 6 - 4
frameworks/JavaScript/nodejs/benchmark_config.json

@@ -24,6 +24,7 @@
       "setup_file": "setup",
       "db_url": "/mongoose",
       "query_url": "/mongoose?queries=",
+      "update_url": "/mongoose-update?queries=",
       "port": 8080,
       "approach": "Realistic",
       "classification": "Platform",
@@ -41,9 +42,9 @@
     },
     "mongodb-raw": {
       "setup_file": "setup",
-      "db_url": "/mongodbdriver",
-      "query_url": "/mongodbdriver?queries=",
-      "update_url": "/update-mongodb?queries=",
+      "db_url": "/mongodb",
+      "query_url": "/mongodb?queries=",
+      "update_url": "/mongodb-update?queries=",
       "port": 8080,
       "approach": "Realistic",
       "classification": "Platform",
@@ -63,6 +64,7 @@
       "setup_file": "setup",
       "db_url": "/mysql-orm",
       "query_url": "/mysql-orm?queries=",
+      "update_url": "/mysql-orm-update?queries=",
       "port": 8080,
       "approach": "Realistic",
       "classification": "Platform",
@@ -82,7 +84,7 @@
       "setup_file": "setup",
       "db_url": "/mysql",
       "query_url": "/mysql?queries=",
-      "update_url": "/update?queries=",
+      "update_url": "/mysql-update?queries=",
       "port": 8080,
       "approach": "Realistic",
       "classification": "Platform",

+ 285 - 213
frameworks/JavaScript/nodejs/hello.js

@@ -1,279 +1,351 @@
+/**
+ * Module dependencies.
+ */
+
 var cluster = require('cluster')
   , numCPUs = require('os').cpus().length
-  , windows = require('os').platform() == 'win32';
-
-if(cluster.isMaster) {
-  // Fork workers.
-  for (var i = 0; i < numCPUs; i++) {
-    cluster.fork();
-  }
-
-  cluster.on('exit', function(worker, code, signal) {
-    console.log('worker ' + worker.pid + ' died');
-  });
-
-  return;
-}
-
-var http = require('http')
+  , http = require('http')
   , url = require('url')
+  , Sequelize = require('sequelize')
+  , mysql = require('mysql')
   , async = require('async')
   , mongoose = require('mongoose')
   , conn = mongoose.connect('mongodb://localhost/hello_world')
-  , MongoClient = require('mongodb').MongoClient
-  , connMap = { user: 'benchmarkdbuser', password: 'benchmarkdbpass', database: 'hello_world', host: 'localhost' };
-
-if (!windows) {
-  var Mapper = require('mapper')  
-    , libmysql = require('mysql-libmysqlclient').createConnectionSync();
-    
-    Mapper.connect(connMap, {verbose: false, strict: false});
-    var World = Mapper.map("World", "id", "randomNumber")
-    libmysql.connectSync('localhost', 'benchmarkdbuser', 'benchmarkdbpass', 'hello_world');
-}
+  , MongoClient = require('mongodb').MongoClient;
 
+// MongoDB Raw Setup
 var collection = null;
-
 MongoClient.connect('mongodb://localhost/hello_world?maxPoolSize=5', function(err, db) {
   collection = db.collection('world');
 });
 
-// define model
-var Schema = mongoose.Schema
-  , ObjectId = Schema.ObjectId;
+// MySQL Raw Setup
+var connection = mysql.createConnection({
+  host     : 'localhost',
+  user     : 'benchmarkdbuser',
+  password : 'benchmarkdbpass',
+  database : 'hello_world'
+});
+connection.connect();
+
+// Mongoose Setup
+var WorldSchema = new mongoose.Schema({
+    id          : Number,
+    randomNumber: Number
+  }, {
+    collection: 'world'
+  }),
+  MWorld = conn.model('World', WorldSchema);
+
+// Sequelize Setup
+var sequelize = new Sequelize('hello_world', 'benchmarkdbuser', 'benchmarkdbpass', {
+  host: 'localhost',
+  dialect: 'mysql',
+  logging: false
+});
 
-var WorldSchema = new Schema({
-    id                           : Number
-  , randomNumber                 : Number
-}, { collection : 'world' });
-var MWorld = conn.model('World', WorldSchema);
+var World = sequelize.define('World', {
+  id: {
+    type: 'Sequelize.INTEGER'
+  },
+  randomNumber: {
+    type: 'Sequelize.INTEGER'
+  }
+}, {
+  timestamps: false,
+  freezeTableName: true
+});
+var Fortune = sequelize.define('Fortune', {
+  id: {
+    type: 'Sequelize.INTEGER'
+  },
+  message: {
+    type: 'Sequelize.STRING'
+  }
+}, {
+  timestamps: false,
+  freezeTableName: true
+});
 
+// Helper functions
 function getRandomNumber() {
   return Math.floor(Math.random() * 10000) + 1;
 }
 
+// Mongoose Query Functions
 function mongooseQuery(callback) {
-  MWorld.findOne({ id: getRandomNumber()}).exec(function (err, world) {
+  MWorld.findOne({
+    id: getRandomNumber()
+  }).exec(function (err, world) {
     callback(err, world);
   });
 }
 
+// MongoDB-Raw Query Functions
 function mongodbDriverQuery(callback) {
-  collection.findOne({ id: getRandomNumber()}, function(err, world) {
+  collection.findOne({
+    id: getRandomNumber()
+  }, function(err, world) {
+    world._id = undefined; // remove _id from query response
     callback(err, world);
   });
 }
 
 function mongodbDriverUpdateQuery(callback) {
-  collection.findAndModify({ id: getRandomNumber()}, [['_id','asc']], {$set: {randomNumber: getRandomNumber()}}, {}, function(err, world) {
-    callback(err, world);
+  collection.findAndModify({
+    id: getRandomNumber()
+  }, [['_id','asc']], {
+    $set: {randomNumber: getRandomNumber()}
+  }, {}, function(err, world) {
+    world.value._id = undefined; // remove _id from query response
+    callback(err, world.value);
   });
 }
 
+// Sequelize Query Functions
 function sequelizeQuery(callback) {
-  World.findById(getRandomNumber(), function (err, world) {
-    callback(null, world);
-  });
+  World.findOne({
+    where: {
+      id: Math.floor(Math.random() * 10000) + 1}
+    }
+  ).complete(callback);
 }
 
-http.createServer(function (req, res) {
-  // JSON response object
-  var hello = {message: "Hello, World!"};
-  var helloStr = "Hello, World!";
-  var path = url.parse(req.url).pathname;
-  
-  // mysql on windows is not supported
-  if (windows && (path.substr(0, 3) == '/my' || path == '/update')) {
-    path = '/doesntexist';
-  }
-
-  switch (path) {
-  case '/json':
-    // JSON Response Test
-    res.writeHead(200, {'Content-Type': 'application/json; charset=UTF-8'});
-    // Write JSON object to response
-    res.end(JSON.stringify(hello));
-    break;
-
-  case '/plaintext':
-    // JSON Response Test
-    res.writeHead(200, {'Content-Type': 'text/plain; charset=UTF-8'});
-    // Write JSON object to response
-    res.end(helloStr);
-    break;
-
-  case '/mongodbdriver':
-    // Database Test
-    var values = url.parse(req.url, true);
-    var queries = values.query.queries || 1;
-    var queryFunctions = new Array(queries);
 
-    for (var i = 0; i < queries; i += 1) {
-      queryFunctions[i] = mongodbDriverQuery;
+// MySQL-Raw Query Functions
+function mysqlQuery(callback) {
+  connection.query("SELECT * FROM world WHERE id = " + getRandomNumber(), function (err, rows, fields) {
+    if (err) {
+      throw err;
     }
+    callback(null, rows[0]);
+  });
+}
 
-    res.writeHead(200, {'Content-Type': 'application/json; charset=UTF-8'});
-
-    async.parallel(queryFunctions, function(err, results) {
-      if (queries == 1) {
-        results = results[0];
+function mysqlUpdateQuery(callback) {
+  connection.query("SELECT * FROM world WHERE id = " + getRandomNumber(), function (err, rows, fields) {
+    if (err) {
+      throw err;
+    }
+    rows[0].randomNumber = getRandomNumber();
+    var updateQuery = "UPDATE world SET randomNumber = " + rows[0].randomNumber + " WHERE id = " + rows[0]['id'];
+    connection.query(updateQuery, function (err, result) {
+      if (err) {
+        throw err;
       }
-      res.end(JSON.stringify(results));
+      callback(null, rows[0]);
     });
-    break;
-
-  case '/mongoose':
-    // Database Test
-    var values = url.parse(req.url, true);
-    var queries = values.query.queries || 1;
-    var queryFunctions = new Array(queries);
+  });
+} 
 
-    for (var i = 0; i < queries; i += 1) {
-      queryFunctions[i] = mongooseQuery;
-    }
+if(cluster.isMaster) {
+  // Fork workers.
+  for (var i = 0; i < numCPUs; i++) {
+    cluster.fork();
+  }
 
-    res.writeHead(200, {'Content-Type': 'application/json; charset=UTF-8'});
+  cluster.on('exit', function(worker, code, signal) {
+    console.log('worker ' + worker.pid + ' died');
+  });
 
-    async.parallel(queryFunctions, function(err, results) {
-      if (queries == 1) {
-        results = results[0];
-      }
-      res.end(JSON.stringify(results));
-    });
-    break;
+  return;
+} else {
+  http.createServer(function (req, res) {
+    // JSON response object
+    var hello = {message: "Hello, World!"};
+    var helloStr = "Hello, World!";
+    var path = url.parse(req.url).pathname;
+
+    switch (req.url) {
+      case '/json':
+        res.writeHead(200, {
+          'Content-Type': 'application/json',
+          'Server': 'Node'
+        });
+        res.end(JSON.stringify(hello));
+        break;
 
-  case '/mysql-orm':
+      case '/plaintext':
+        res.writeHead(200, {
+          'Content-Type': 'text/plain; charset=UTF-8',
+          'Server': 'Node'
+        });
+        res.end(helloStr);
+        break;
+    }
     var values = url.parse(req.url, true);
-    var queries = values.query.queries || 1;
-    var queryFunctions = new Array(queries);
+    var queries = isNaN(values.query.queries) ? 1 : parseInt(values.query.queries, 10);
+    queries = Math.min(Math.max(queries, 1), 500);
+    switch (values.pathname) {
+      // Raw MongoDB Routes
+      case '/mongodb':
+        var queryFunctions = [];
+        for (var i = 0; i < queries; i += 1) {
+          queryFunctions.push(mongodbDriverQuery);
+        }
 
-    for (var i = 0; i < queries; i += 1) {
-      queryFunctions[i] = sequelizeQuery;
-    }
+        async.parallel(queryFunctions, function(err, results) {
+          if (!values.query.queries) {
+            results = results[0];
+          }
+          res.writeHead(200, {
+            'Content-Type': 'application/json',
+            'Server': 'Node'
+          });
+          res.end(JSON.stringify(results));
+        });
+        break;
 
-    res.writeHead(200, {'Content-Type': 'application/json'});
+      case '/mongodb-update':
+        var queryFunctions = [];
+        for (var i = 0; i < queries; i += 1) {
+          queryFunctions.push(mongodbDriverUpdateQuery);
+        }
 
-    async.parallel(queryFunctions, function(err, results) {
-      if (queries == 1) {
-        results = results[0];
-      }
-      res.end(JSON.stringify(results));
-    });
-    break;
-
-  case '/mysql':
-    res.writeHead(200, {'Content-Type': 'application/json'});
-
-    function libmysqlQuery(callback) {
-      libmysql.query("SELECT * FROM world WHERE id = " + getRandomNumber(), function (err, res) {
-        if (err) {
-	        throw err;
-	      }
-	
-	      res.fetchAll(function(err, rows) {
-      	  if (err) {
-      	    throw err;
-      	  }
-
-      	  res.freeSync();
-      	  callback(null, rows[0]);
+        async.parallel(queryFunctions, function(err, results) {
+          res.writeHead(200, {
+            'Content-Type': 'application/json',
+            'Server': 'Node'
+          });
+          res.end(JSON.stringify(results));
         });
-      });
-    } 
+        break;
 
-    var values = url.parse(req.url, true);
-    var queries = values.query.queries || 1;
-    var queryFunctions = new Array(queries);
-
-    for (var i = 0; i < queries; i += 1) {
-      queryFunctions[i] = libmysqlQuery;
-    }
-    async.parallel(queryFunctions, function(err, results) {
-      if (err) {
-        res.writeHead(500);
-        return res.end('MYSQL CONNECTION ERROR.');
-      }
-      if (queries == 1) {
-        results = results[0];
-      }
-      res.end(JSON.stringify(results));
-    });
-    break;
+      // Mongoose ORM Routes
+      case '/mongoose':
+        var queryFunctions = [];
+        for (var i = 0; i < queries; i += 1) {
+          queryFunctions.push(mongooseQuery);
+        }
 
-  case '/update':
-    res.writeHead(200, {'Content-Type': 'application/json'});
+        async.parallel(queryFunctions, function(err, results) {
+          if (!values.query.queries) {
+            results = results[0];
+          }
+          res.writeHead(200, {
+            'Content-Type': 'application/json',
+            'Server': 'Node'
+          });
+          res.end(JSON.stringify(results));
+        });
+        break;
 
-    function libmysqlQuery(callback) {
-      libmysql.query("SELECT * FROM world WHERE id = " + getRandomNumber(), function (err, res) {
-        if (err) {
-          throw err;
+      case '/mongoose-update':
+        var selectFunctions = [];
+        for (var i = 0; i < queries; i += 1) {
+          selectFunctions.push(mongooseQuery);
         }
-  
-        res.fetchAll(function(err, rows) {
-          if (err) {
-            throw err;
+
+        async.parallel(selectFunctions, function(err, worlds) {
+          var updateFunctions = [];
+
+          for (var i = 0; i < queries; i++) {
+            (function(i){
+              updateFunctions.push(function(callback){
+                worlds[i].randomNumber = Math.ceil(Math.random() * 10000);
+                MWorld.update({
+                  id: worlds[i]
+                }, {
+                  randomNumber: worlds[i].randomNumber
+                }, callback);
+              });
+            })(i);
           }
 
-          res.freeSync();
+          async.parallel(updateFunctions, function(err, updates) {
+            res.writeHead(200, {
+              'Content-Type': 'application/json',
+              'Server': 'Node'
+            });
+            res.end(JSON.stringify(worlds));
+          });
+        });
+        break;
+
+      // Sequelize (MySQL ORM) Routes
+      case '/mysql-orm':
+        var queryFunctions = [];
+        for (var i = 0; i < queries; i += 1) {
+          queryFunctions.push(sequelizeQuery);
+        }
 
-          rows[0].randomNumber = getRandomNumber();
-          libmysql.query("UPDATE World SET randomNumber = " + rows[0].randomNumber + " WHERE id = " + rows[0]['id'], function (err, res) {
-            if (err) {
-              throw err;
-            }
-            callback(null, rows[0]);
+        async.parallel(queryFunctions, function(err, results) {
+          if (!values.query.queries) {
+            results = results[0];
+          }
+          res.writeHead(200, {
+            'Content-Type': 'application/json',
+            'Server': 'Node'
           });
+          res.end(JSON.stringify(results));
         });
-      });
-    } 
+        break;
 
-    var values = url.parse(req.url, true);
-    var queries = values.query.queries || 1;
-    if(queries < 1) {
-      queries = 1;
-    } else if(queries > 500) {
-      queries = 500;
-    }
-    var queryFunctions = new Array(queries);
+      case '/mysql-orm-update':
+        var selectFunctions = [];
+        for (var i = 0; i < queries; i += 1) {
+          selectFunctions.push(sequelizeQuery);
+        }
 
-    for (var i = 0; i < queries; i += 1) {
-      queryFunctions[i] = libmysqlQuery;
-    }
-    async.parallel(queryFunctions, function(err, results) {
-      if (err) {
-        res.writeHead(500);
-        return res.end('MYSQL CONNECTION ERROR.');
-      }
-      res.end(JSON.stringify(results));
-    });
-    break;
+        async.parallel(selectFunctions, function(err, worlds) {
+          var updateFunctions = [];
 
-  case '/update-mongodb':
-    // Database Test
-    var values = url.parse(req.url, true);
-    var queries = values.query.queries || 1;
-    if (queries < 1) {
-      queries = 1;
-    } else if (queries > 500) {
-      queries = 500;
-    }
+          for (var i = 0; i < queries; i++) {
+            (function(i){
+              updateFunctions.push(function(callback){
+                worlds[i].randomNumber = Math.ceil(Math.random() * 10000);
+                worlds[i].save().complete(callback);
+              });
+            })(i);
+          }
 
-    var queryFunctions = new Array(queries);
+          async.parallel(updateFunctions, function(err, updates) {
+            res.writeHead(200, {
+              'Content-Type': 'application/json',
+              'Server': 'Node'
+            });
+            res.end(JSON.stringify(worlds));
+          });
+        });
+        break;
 
-    for (var i = 0; i < queries; i += 1) {
-      queryFunctions[i] = mongodbDriverUpdateQuery;
-    }
+      // Raw MongoDB Routes
+      case '/mysql':
+        var queryFunctions = [];
+        for (var i = 0; i < queries; i += 1) {
+          queryFunctions.push(mysqlQuery);
+        }
 
-    res.writeHead(200, {'Content-Type': 'application/json; charset=UTF-8'});
+        async.parallel(queryFunctions, function(err, results) {
+          if (!values.query.queries) {
+            results = results[0];
+          }
+          res.writeHead(200, {
+            'Content-Type': 'application/json',
+            'Server': 'Node'
+          });
+          res.end(JSON.stringify(results));
+        });
+        break;
 
-    async.parallel(queryFunctions, function(err, results) {
-      res.end(JSON.stringify(results));
-    });
-    break;
+      case '/mysql-update':
+        var queryFunctions = [];
+        for (var i = 0; i < queries; i += 1) {
+          queryFunctions.push(mysqlUpdateQuery);
+        }
+        async.parallel(queryFunctions, function(err, results) {
+          res.writeHead(200, {
+            'Content-Type': 'application/json',
+            'Server': 'Node'
+          });
+          res.end(JSON.stringify(results));
+        });
+        break;
 
-  default:
-    // File not found handler
-    res.writeHead(501, {'Content-Type': 'text/plain; charset=UTF-8'});
-    res.end("NOT IMPLEMENTED");
-  }
-}).listen(8080);
+      default:
+        // File not found handler
+        res.writeHead(501, {'Content-Type': 'text/plain; charset=UTF-8'});
+        res.end("NOT IMPLEMENTED");
+      }
+    }).listen(8080);
+}

+ 5 - 5
frameworks/JavaScript/nodejs/package.json

@@ -3,11 +3,11 @@
   , "version": "0.0.1"
   , "private": true
   , "dependencies": {
-      "mongoose": "3.5.5" 
-    , "async": "0.2.5"
-    , "mysql-libmysqlclient": "1.5.2"
-    , "mapper": "0.2.4-pre"
-    , "mongodb": "1.3.0"
+      "mongoose": "4.0.1" 
+    , "async": "0.9.0"
+    , "mongodb": "2.0.27"
+    , "sequelize": "2.0.6"
+    , "mysql": "2.6.2"
   }
   , "main": "hello.js"
 }

+ 2 - 2
frameworks/JavaScript/nodejs/setup.sh

@@ -7,8 +7,8 @@ export NVM_HOME=${IROOT}/nvm
 # Used to avoid nvm's return 2 error.
 # Sourcing this functions if 0 is returned.
 source $NVM_HOME/nvm.sh || 0
-nvm install 0.10.8
-nvm use 0.10.8
+nvm install 0.12.2
+nvm use 0.12.2
 
 # update npm before app init
 npm install -g npm

+ 1 - 1
frameworks/Python/turbogears/app.py

@@ -84,7 +84,7 @@ class RootController(TGController):
         fortunes.sort(key=attrgetter("message"))
         for f in fortunes:
             f.message = bleach.clean(f.message)
-            template = env.get_template("fortunes.html")
+        template = env.get_template("fortunes.html")
         return template.render(fortunes=fortunes)
 
 config = AppConfig(minimal=True, root_controller=RootController())