mysql-queue-pool
Version:
Database connection pooling and query queueing.
118 lines (92 loc) • 2.47 kB
JavaScript
/**
* QueryQueue - sequential SQL query processing.
*
* @todo support transactions
*/
var EXTEND = require('util').inherits
, Emitter = require("events").EventEmitter;
/**
* Create SQL query queue.
*
* @param {Object} config
*/
function QueryQueue(config) {
this.config = config;
this.atomic = config.atomic;
this.connection = config.connection;
this.failure = config.failure || function (e) {throw e;};
this.success = config.success || null;
this.failed = false;
this.paused = false;
this.cptr = 0;
this.steps = config.steps;
this.lastStatement = null;
this.nextArgs = null;
QueryQueue.super_.call(this);
}
EXTEND(QueryQueue, Emitter);
QueryQueue.prototype.QUERY_FAIL = 0;
QueryQueue.prototype.QUERY_SUCCESS = 1;
/**
*/
QueryQueue.prototype.silentErrorHandler = function () {
};
/**
* Execute failure callback for this queue step and exit.
* @public
*/
QueryQueue.prototype.fail = function (error) {
this.failed = true;
(this.lastStatement.failure || this.failure).call(this, error);
this.emit('complete', this.QUERY_FAIL, this);
};
/**
* Execute next statement and loop until queue is processed or paused.
*/
QueryQueue.prototype.go = function () {
var stat = this.lastStatement = this.steps[this.cptr++];
this.paused = false;
if (this.cptr <= this.steps.length) {
var q = this;
if (this.nextArgs) {
stat.args = this.nextArgs;
this.nextArgs = null;
}
this.connection.query(stat.query, stat.args, function (err, rows) {
if (err) {
q.fail(err);
}
// Empty SELECT is bad.
else if (!rows[0] && stat.query.toUpperCase().indexOf('SELECT') === 0) {
q.fail('Error: no result');
}
else {
(stat.success || q.success).call(q, rows);
(q.failed === false || q.paused === true) && q.go();
}
});
}
else {
this.emit('complete', this.QUERY_SUCCESS, this);
}
};
/**
* Stop processing (.go method will start it again).
*
* @public
*/
QueryQueue.prototype.halt = function () {
this.paused = true;
};
/**
* Set arguments for next query.
*
* @public
* @param ...
* Variable number of arguments passed to next query.
*/
QueryQueue.prototype.setNextArgs = function () {
this.nextArgs = Array.prototype.slice.call(arguments, 0);
};
//
exports.QueryQueue = QueryQueue;