UNPKG

3.36 kBJavaScriptView Raw
1var Connection = require('./Connection');
2var PoolSelector = require('./PoolSelector');
3
4module.exports = PoolNamespace;
5
6/**
7 * PoolNamespace
8 * @constructor
9 * @param {PoolCluster} cluster The parent cluster for the namespace
10 * @param {string} pattern The selection pattern to use
11 * @param {string} selector The selector name to use
12 * @public
13 */
14function PoolNamespace(cluster, pattern, selector) {
15 this._cluster = cluster;
16 this._pattern = pattern;
17 this._selector = new PoolSelector[selector]();
18}
19
20PoolNamespace.prototype.getConnection = function(cb) {
21 var clusterNode = this._getClusterNode();
22 var cluster = this._cluster;
23 var namespace = this;
24
25 if (clusterNode === null) {
26 var err = null;
27
28 if (this._cluster._findNodeIds(this._pattern, true).length !== 0) {
29 err = new Error('Pool does not have online node.');
30 err.code = 'POOL_NONEONLINE';
31 } else {
32 err = new Error('Pool does not exist.');
33 err.code = 'POOL_NOEXIST';
34 }
35
36 cb(err);
37 return;
38 }
39
40 cluster._getConnection(clusterNode, function(err, connection) {
41 var retry = err && cluster._canRetry
42 && cluster._findNodeIds(namespace._pattern).length !== 0;
43
44 if (retry) {
45 namespace.getConnection(cb);
46 return;
47 }
48
49 if (err) {
50 cb(err);
51 return;
52 }
53
54 cb(null, connection);
55 });
56};
57
58PoolNamespace.prototype.query = function (sql, values, cb) {
59 var cluster = this._cluster;
60 var clusterNode = this._getClusterNode();
61 var query = Connection.createQuery(sql, values, cb);
62 var namespace = this;
63
64 if (clusterNode === null) {
65 var err = null;
66
67 if (this._cluster._findNodeIds(this._pattern, true).length !== 0) {
68 err = new Error('Pool does not have online node.');
69 err.code = 'POOL_NONEONLINE';
70 } else {
71 err = new Error('Pool does not exist.');
72 err.code = 'POOL_NOEXIST';
73 }
74
75 process.nextTick(function () {
76 query.on('error', function () {});
77 query.end(err);
78 });
79 return query;
80 }
81
82 if (!(typeof sql === 'object' && 'typeCast' in sql)) {
83 query.typeCast = clusterNode.pool.config.connectionConfig.typeCast;
84 }
85
86 if (clusterNode.pool.config.connectionConfig.trace) {
87 // Long stack trace support
88 query._callSite = new Error();
89 }
90
91 cluster._getConnection(clusterNode, function (err, conn) {
92 var retry = err && cluster._canRetry
93 && cluster._findNodeIds(namespace._pattern).length !== 0;
94
95 if (retry) {
96 namespace.query(query);
97 return;
98 }
99
100 if (err) {
101 query.on('error', function () {});
102 query.end(err);
103 return;
104 }
105
106 // Release connection based off event
107 query.once('end', function() {
108 conn.release();
109 });
110
111 conn.query(query);
112 });
113
114 return query;
115};
116
117PoolNamespace.prototype._getClusterNode = function _getClusterNode() {
118 var foundNodeIds = this._cluster._findNodeIds(this._pattern);
119 var nodeId;
120
121 switch (foundNodeIds.length) {
122 case 0:
123 nodeId = null;
124 break;
125 case 1:
126 nodeId = foundNodeIds[0];
127 break;
128 default:
129 nodeId = this._selector(foundNodeIds);
130 break;
131 }
132
133 return nodeId !== null
134 ? this._cluster._getNode(nodeId)
135 : null;
136};