mysql-queue-pool
Version:
Database connection pooling and query queueing.
180 lines (153 loc) • 3.77 kB
JavaScript
/**
* Database Manager (DBM)
*
* Handles database connection pools.
*
* @api DBM
* @api query([connection], queryconfig)
*/
var Pool = require('./lib/pool').ConnectionPool;
var Queue = require('./lib/queue').QueryQueue;
var _ = require('underscore')._;
var DBM = {
/**
* @const
*/
DEFAULT_POOL_NAME: 'default',
/**
* @const
*/
DEFAULT_POOL_SIZE: 4,
/**
* @private
*/
pools: {},
/**
* @private
*/
adapters: {},
/**
* Default pool name.
*
* @private
* @property {String}
* @see setDefaultPool()
*/
defaultPool: null,
/**
* @public
* @param {String} name
* @param {Function} constructor
*/
registerAdapter: function (name, constructor) {
this.adapters[name] = constructor;
},
/**
* Create new pool with specified connection settings.
*
* @public
* @param {Object} config
*
* @return {Pool}
* Newly created pool.
*/
registerConnection: function (config) {
config.name = config.name || this.defaultPool || this.DEFAULT_POOL_NAME;
config.poolmax = config.poolmax || this.DEFAULT_POOL_SIZE;
// Constructor for new connections (invoked inside pool).
function dbConnect(callback) {
var connection = new (DBM.getAdapter(config.adapter))(config);
connection.onerror(dbErrorHandler);
connection.connect(callback);
return connection;
}
// Callback for error situations.
function dbErrorHandler(err) {
console.log('DBM: ', err);
pool.release(this.connection);
}
var pool = new Pool({
constructor: dbConnect,
maxSize: config.poolmax
});
this.pools[config.name] = pool;
},
/**
* @public
* @param {String} name
* @return {Function}
* @throws ReferenceError
*/
getAdapter: function (name) {
var adapter = this.adapters[name];
if (!adapter) {
var temp = require('./lib/adapter/' + name);
if (temp && temp.Adapter) {
adapter = temp.Adapter;
}
}
if (!adapter) {
throw new ReferenceError('DBM: Undefined adapter.');
}
return adapter;
},
/**
* @public
* @param {String} name
* @return {Pool}
* @throws ReferenceError
*/
getConnectionPool: function (name) {
name = name || this.defaultPool || this.DEFAULT_POOL_NAME;
var pool = this.pools[name];
if (!pool) {
throw new ReferenceError('DBM: Undefined connection.');
}
return pool;
},
/**
* Set default pool to be used if none provided (e.g. to query method).
*
* @public
* @param {String} name
*/
setDefaultPool: function (name) {
this.defaultPool = name;
}
};
// Export DBM's static object.
exports.DBM = DBM;
/**
* Wrapper for query queues with pooled connections. Arguments order doesn't
* matter.
*
* @public
* @param {String} name
* Optional, defaults to DBM.DEFAULT_POOL_NAME or DBM.setDefaultPool().
*
* @param {QueryQueue} query
* Configuration passed to QueryQueue constructor, dbconn property will be
* automatically set.
*/
exports.query = function (name, query) {
if (_.isObject(name)) {
var temp = query;
query = name;
name = temp;
}
var pool = DBM.getConnectionPool(name);
pool.acquire(function (err, connection) {
var queue = new Queue(query);
queue.connection = connection;
if (err) {
console.log('DBM query: ' + err);
queue.failure(err);
}
else {
queue.on('complete', function (status, queue) {
pool.release(queue.connection);
});
queue.go();
}
});
};