Use connection pool for MySQL

This commit is contained in:
Raymond Feng 2013-11-26 17:40:31 -08:00
parent 348ec4eafe
commit 999825abea
2 changed files with 191 additions and 134 deletions

View File

@ -31,12 +31,13 @@ exports.initialize = function initializeDataSource(dataSource, callback) {
s.supportBigNumbers = (s.supportBigNumbers || false); s.supportBigNumbers = (s.supportBigNumbers || false);
s.timezone = (s.timezone || 'local'); s.timezone = (s.timezone || 'local');
dataSource.client = mysql.createConnection({ dataSource.client = mysql.createPool({
host: s.host || s.hostname || 'localhost', host: s.host || s.hostname || 'localhost',
port: s.port || 3306, port: s.port || 3306,
user: s.username || s.user, user: s.username || s.user,
password: s.password, password: s.password,
timezone: s.timezone, timezone: s.timezone,
// database: s.database,
debug: s.debug, debug: s.debug,
socketPath: s.socketPath, socketPath: s.socketPath,
charset: s.collation.toUpperCase(), // Correct by docs despite seeming odd. charset: s.collation.toUpperCase(), // Correct by docs despite seeming odd.
@ -54,30 +55,50 @@ exports.initialize = function initializeDataSource(dataSource, callback) {
dataSource.connector = new MySQL(dataSource.client, s); dataSource.connector = new MySQL(dataSource.client, s);
dataSource.connector.dataSource = dataSource; dataSource.connector.dataSource = dataSource;
dataSource.client.query('USE `' + s.database + '`', function (err) { callback && callback();
/*
dataSource.client.getConnection(function (err, connection) {
if (err) {
callback && callback(err);
return;
}
connection.query('USE `' + s.database + '`', function (err) {
if (err) { if (err) {
if (err.message.match(/(^|: )unknown database/i)) { if (err.message.match(/(^|: )unknown database/i)) {
var dbName = s.database; var dbName = s.database;
var charset = s.charset; var charset = s.charset;
var collation = s.collation; var collation = s.collation;
var q = 'CREATE DATABASE ' + dbName + ' CHARACTER SET ' + charset + ' COLLATE ' + collation; var q = 'CREATE DATABASE ' + dbName + ' CHARACTER SET ' + charset + ' COLLATE ' + collation;
dataSource.client.query(q, function (error) { connection.query(q, function (error) {
if (!error) { if (!error) {
dataSource.client.query('USE ' + s.database, callback); connection.query('USE ' + s.database, function (err, result) {
connection.release();
callback && callback(err, result);
});
} else { } else {
throw error; connection.release();
callback && callback(err);
} }
}); });
} else throw err; } else {
} else callback(); connection.release();
callback && callback(err);
}
} else {
connection.release();
callback && callback();
}
}); });
});
*/
// MySQL specific column types // MySQL specific column types
juggler.ModelBuilder.registerType(function Point() {}); juggler.ModelBuilder.registerType(function Point() {
});
dataSource.EnumFactory = EnumFactory; // factory for Enums. Note that currently Enums can not be registered. dataSource.EnumFactory = EnumFactory; // factory for Enums. Note that currently Enums can not be registered.
}; };
exports.MySQL = MySQL; exports.MySQL = MySQL;
@ -103,6 +124,7 @@ require('util').inherits(MySQL, juggler.BaseSQL);
* @param {Function} [callback] The callback after the SQL statement is executed * @param {Function} [callback] The callback after the SQL statement is executed
*/ */
MySQL.prototype.query = function (sql, callback) { MySQL.prototype.query = function (sql, callback) {
var self = this;
if (!this.dataSource.connected) { if (!this.dataSource.connected) {
return this.dataSource.on('connected', function () { return this.dataSource.on('connected', function () {
this.query(sql, callback); this.query(sql, callback);
@ -111,36 +133,59 @@ MySQL.prototype.query = function (sql, callback) {
var client = this.client; var client = this.client;
var time = Date.now(); var time = Date.now();
var debug = this.settings.debug; var debug = this.settings.debug;
var db = this.settings.database;
var log = this.log; var log = this.log;
if (typeof callback !== 'function') throw new Error('callback should be a function'); if (typeof callback !== 'function') throw new Error('callback should be a function');
if (debug) { if (debug) {
console.log('SQL:', sql); console.log('SQL:', sql);
} }
this.client.query(sql, function (err, data) { client.getConnection(function (err, connection) {
if (err) { if (err) {
if(debug) { callback && callback(err);
console.error('Error:', err); return;
}
} }
connection.query('USE `' + db + '`', function (err) {
if (err) {
if (err && err.message.match(/(^|: )unknown database/i)) { if (err && err.message.match(/(^|: )unknown database/i)) {
var dbName = err.message.match(/(^|: )unknown database '(.*?)'/i)[1]; var charset = self.settings.charset;
client.query('CREATE DATABASE ' + dbName, function (error) { var collation = self.settings.collation;
var q = 'CREATE DATABASE ' + db + ' CHARACTER SET ' + charset + ' COLLATE ' + collation;
connection.query(q, function (error) {
if (!error) { if (!error) {
client.query(sql, callback); connection.query('USE `' + db + '`', function (err) {
connection.query(sql, function (err, result) {
connection.release();
callback && callback(err, result);
});
});
} else { } else {
callback(err); connection.release();
callback && callback(err);
} }
}); });
return; return;
} else {
connection.release();
callback && callback(err);
return;
} }
}
connection.query(sql, function (err, data) {
if (debug) { if (debug) {
if(err) {
console.error('Error:', err);
}
console.log('Data:', data); console.log('Data:', data);
} }
if (log) log(sql, time); if (log) log(sql, time);
callback(err, data); connection.release();
callback && callback(err, data);
});
});
}); });
}; };
/** /**
* Create the data model in MySQL * Create the data model in MySQL
* *
@ -1045,5 +1090,17 @@ function unsigned(p, dt){
return dt; return dt;
} }
/**
* Disconnect from MongoDB
*/
MySQL.prototype.disconnect = function () {
if(this.debug) {
console.log('disconnect');
}
if(this.client) {
this.client.end();
}
};
require('./discovery')(MySQL); require('./discovery')(MySQL);

View File

@ -41,7 +41,7 @@ describe('migrations', function() {
}); });
it('should drop db and disconnect all', function(done) { it('should drop db and disconnect all', function(done) {
db.adapter.query('DROP DATABASE IF EXISTS ' + db.settings.database, function(err) { db.connector.query('DROP DATABASE IF EXISTS ' + db.settings.database, function(err) {
db.client.end(function(){ db.client.end(function(){
done(); done();
}); });
@ -61,10 +61,10 @@ function charsetTest(test_set, test_collo, test_set_str, test_set_collo, done){
DummyModel = db.define('DummyModel', {string: String}); DummyModel = db.define('DummyModel', {string: String});
db.automigrate(function(){ db.automigrate(function(){
var q = 'SELECT DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = ' + db.client.escape(db.settings.database) + ' LIMIT 1'; var q = 'SELECT DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = ' + db.client.escape(db.settings.database) + ' LIMIT 1';
db.client.query(q, function(err, r) { db.connector.query(q, function(err, r) {
assert.ok(!err); assert.ok(!err);
assert.ok(r[0].DEFAULT_COLLATION_NAME.match(test_collo)); assert.ok(r[0].DEFAULT_COLLATION_NAME.match(test_collo));
db.client.query('SHOW VARIABLES LIKE "character_set%"', function(err, r){ db.connector.query('SHOW VARIABLES LIKE "character_set%"', function(err, r){
assert.ok(!err); assert.ok(!err);
var hit_all = 0; var hit_all = 0;
for (var result in r) { for (var result in r) {
@ -75,7 +75,7 @@ function charsetTest(test_set, test_collo, test_set_str, test_set_collo, done){
} }
assert.equal(hit_all, 4); assert.equal(hit_all, 4);
}); });
db.client.query('SHOW VARIABLES LIKE "collation%"', function(err, r){ db.connector.query('SHOW VARIABLES LIKE "collation%"', function(err, r){
assert.ok(!err); assert.ok(!err);
var hit_all = 0; var hit_all = 0;
for (var result in r) { for (var result in r) {
@ -101,7 +101,7 @@ function matchResult(result, variable_name, match) {
} }
var query = function (sql, cb) { var query = function (sql, cb) {
odb.adapter.query(sql, cb); odb.connector.query(sql, cb);
}; };