137 lines
3.1 KiB
JavaScript
137 lines
3.1 KiB
JavaScript
|
var Connection = require('./Connection');
|
||
|
var PoolSelector = require('./PoolSelector');
|
||
|
|
||
|
module.exports = PoolNamespace;
|
||
|
|
||
|
/**
|
||
|
* PoolNamespace
|
||
|
* @constructor
|
||
|
* @param {PoolCluster} cluster The parent cluster for the namespace
|
||
|
* @param {string} pattern The selection pattern to use
|
||
|
* @param {string} selector The selector name to use
|
||
|
* @public
|
||
|
*/
|
||
|
function PoolNamespace(cluster, pattern, selector) {
|
||
|
this._cluster = cluster;
|
||
|
this._pattern = pattern;
|
||
|
this._selector = new PoolSelector[selector]();
|
||
|
}
|
||
|
|
||
|
PoolNamespace.prototype.getConnection = function(cb) {
|
||
|
var clusterNode = this._getClusterNode();
|
||
|
var cluster = this._cluster;
|
||
|
var namespace = this;
|
||
|
|
||
|
if (clusterNode === null) {
|
||
|
var err = null;
|
||
|
|
||
|
if (this._cluster._findNodeIds(this._pattern, true).length !== 0) {
|
||
|
err = new Error('Pool does not have online node.');
|
||
|
err.code = 'POOL_NONEONLINE';
|
||
|
} else {
|
||
|
err = new Error('Pool does not exist.');
|
||
|
err.code = 'POOL_NOEXIST';
|
||
|
}
|
||
|
|
||
|
cb(err);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
cluster._getConnection(clusterNode, function(err, connection) {
|
||
|
var retry = err && cluster._canRetry
|
||
|
&& cluster._findNodeIds(namespace._pattern).length !== 0;
|
||
|
|
||
|
if (retry) {
|
||
|
namespace.getConnection(cb);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (err) {
|
||
|
cb(err);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
cb(null, connection);
|
||
|
});
|
||
|
};
|
||
|
|
||
|
PoolNamespace.prototype.query = function (sql, values, cb) {
|
||
|
var cluster = this._cluster;
|
||
|
var clusterNode = this._getClusterNode();
|
||
|
var query = Connection.createQuery(sql, values, cb);
|
||
|
var namespace = this;
|
||
|
|
||
|
if (clusterNode === null) {
|
||
|
var err = null;
|
||
|
|
||
|
if (this._cluster._findNodeIds(this._pattern, true).length !== 0) {
|
||
|
err = new Error('Pool does not have online node.');
|
||
|
err.code = 'POOL_NONEONLINE';
|
||
|
} else {
|
||
|
err = new Error('Pool does not exist.');
|
||
|
err.code = 'POOL_NOEXIST';
|
||
|
}
|
||
|
|
||
|
process.nextTick(function () {
|
||
|
query.on('error', function () {});
|
||
|
query.end(err);
|
||
|
});
|
||
|
return query;
|
||
|
}
|
||
|
|
||
|
if (!(typeof sql === 'object' && 'typeCast' in sql)) {
|
||
|
query.typeCast = clusterNode.pool.config.connectionConfig.typeCast;
|
||
|
}
|
||
|
|
||
|
if (clusterNode.pool.config.connectionConfig.trace) {
|
||
|
// Long stack trace support
|
||
|
query._callSite = new Error();
|
||
|
}
|
||
|
|
||
|
cluster._getConnection(clusterNode, function (err, conn) {
|
||
|
var retry = err && cluster._canRetry
|
||
|
&& cluster._findNodeIds(namespace._pattern).length !== 0;
|
||
|
|
||
|
if (retry) {
|
||
|
namespace.query(query);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (err) {
|
||
|
query.on('error', function () {});
|
||
|
query.end(err);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Release connection based off event
|
||
|
query.once('end', function() {
|
||
|
conn.release();
|
||
|
});
|
||
|
|
||
|
conn.query(query);
|
||
|
});
|
||
|
|
||
|
return query;
|
||
|
};
|
||
|
|
||
|
PoolNamespace.prototype._getClusterNode = function _getClusterNode() {
|
||
|
var foundNodeIds = this._cluster._findNodeIds(this._pattern);
|
||
|
var nodeId;
|
||
|
|
||
|
switch (foundNodeIds.length) {
|
||
|
case 0:
|
||
|
nodeId = null;
|
||
|
break;
|
||
|
case 1:
|
||
|
nodeId = foundNodeIds[0];
|
||
|
break;
|
||
|
default:
|
||
|
nodeId = this._selector(foundNodeIds);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return nodeId !== null
|
||
|
? this._cluster._getNode(nodeId)
|
||
|
: null;
|
||
|
};
|