1 | var Connection = require('./Connection');
|
2 | var PoolSelector = require('./PoolSelector');
|
3 |
|
4 | module.exports = PoolNamespace;
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 | function PoolNamespace(cluster, pattern, selector) {
|
15 | this._cluster = cluster;
|
16 | this._pattern = pattern;
|
17 | this._selector = new PoolSelector[selector]();
|
18 | }
|
19 |
|
20 | PoolNamespace.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 |
|
58 | PoolNamespace.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 |
|
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 |
|
107 | query.once('end', function() {
|
108 | conn.release();
|
109 | });
|
110 |
|
111 | conn.query(query);
|
112 | });
|
113 |
|
114 | return query;
|
115 | };
|
116 |
|
117 | PoolNamespace.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 | };
|