-
Notifications
You must be signed in to change notification settings - Fork 97
/
ConnectionManager.js
124 lines (109 loc) · 3.75 KB
/
ConnectionManager.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// Copyright 2013 SAP AG.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http: //www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific
// language governing permissions and limitations under the License.
'use strict';
var util = require('../util');
var common = require('./common');
var debug = util.debuglog('hdb_conn');
module.exports = ConnectionManager;
function ConnectionManager(options) {
this._options = options;
}
ConnectionManager.prototype.openConnection = function openConnection(conn, cb) {
var opts = this._options;
var dbHosts = (Array.isArray(opts.hosts) && opts.hosts.slice()) || [{ host: opts.host, port: opts.port }];
debug('Opening connection. Hosts:', dbHosts);
var errorStats = [];
var self = this;
function tryConnect() {
if (dbHosts.length === 0) {
return cb(couldNotOpenConnectionError(errorStats));
}
var options = util.extend({}, self._options, dbHosts.shift());
self._openConnection(conn, options, function (err) {
if (err) {
debug('Connection to %s:%d failed with:', options.host, options.port, err.message);
errorStats.push({ host: options.host, port: options.port, err: err });
tryConnect();
} else {
debug('Successful connection to %s:%d', options.host, options.port);
return cb(null);
}
});
}
tryConnect();
};
ConnectionManager.prototype._openConnection = function _openConnection(conn, options, cb) {
var dbName = options.databaseName;
if (util.isString(dbName) && dbName.length) {
this._openConnectionMultiDbCase(conn, options, cb);
} else {
conn.open(options, cb);
}
};
ConnectionManager.prototype._openConnectionMultiDbCase = function _openConnectionMultiDbCase(conn, options, cb) {
if (!options.port) {
var instanceNum = extractInstanceNumber(options.instanceNumber);
if (isNaN(instanceNum)) {
return cb(new Error('Instance Number is not valid'));
} else {
options.port = 30013 + (instanceNum * 100);
}
}
function handleError(err) {
conn.close();
cb(err);
}
conn.open(options, function (err) {
if (err) {
return handleError(err);
}
conn.fetchDbConnectInfo({databaseName: options.databaseName}, function (err, info) {
if (err) {
return handleError(err);
}
if (info.isConnected) {
cb(null);
} else {
var initialHost = conn.host;
var initialPort = conn.port;
conn._closeSilently();
options.host = info.host;
options.port = info.port;
conn.setInitialHostAndPort(initialHost, initialPort);
conn.setRedirectHostAndPort(options.host, options.port);
conn.setRedirectType(common.RedirectType.REDIRECTION_DBNAMEBASED);
debug('Connecting to tenant-db %s on %s:%d', options.databaseName, options.host, options.port);
conn.open(options, cb);
}
});
});
};
function extractInstanceNumber(instanceNumber) {
if (util.isNumber(instanceNumber)) {
return instanceNumber;
}
if (util.isString(instanceNumber) && instanceNumber.length) {
return parseInt(instanceNumber, 10);
}
return NaN;
}
function couldNotOpenConnectionError(errorStats) {
var message = 'Could not connect to any host:';
errorStats.forEach(function (stats) {
message += util.format(' [ %s:%d - %s ]', stats.host, stats.port, stats.err.message);
});
var err = new Error(message);
err.code = 'EHDBOPENCONN';
return err;
}