oracledb 5.5.0 → 6.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/CHANGELOG.md +1 -1875
  2. package/LICENSE.txt +8 -222
  3. package/NOTICE.txt +1 -1
  4. package/README.md +38 -30
  5. package/SECURITY.md +38 -0
  6. package/build/Release/oracledb-6.0.1-darwin-x64.node +0 -0
  7. package/build/Release/oracledb-6.0.1-darwin-x64.node-buildinfo.txt +1 -0
  8. package/build/Release/oracledb-6.0.1-js-buildinfo.txt +1 -0
  9. package/build/Release/oracledb-6.0.1-linux-arm64.node +0 -0
  10. package/build/Release/oracledb-6.0.1-linux-arm64.node-buildinfo.txt +1 -0
  11. package/build/Release/oracledb-6.0.1-linux-x64.node +0 -0
  12. package/build/Release/oracledb-6.0.1-linux-x64.node-buildinfo.txt +1 -0
  13. package/build/Release/oracledb-6.0.1-win32-x64.node +0 -0
  14. package/build/Release/oracledb-6.0.1-win32-x64.node-buildinfo.txt +1 -0
  15. package/examples/README.md +113 -0
  16. package/examples/dbconfig.js +100 -0
  17. package/examples/example.js +156 -0
  18. package/index.js +26 -0
  19. package/lib/aqDeqOptions.js +148 -8
  20. package/lib/aqEnqOptions.js +59 -7
  21. package/lib/aqMessage.js +118 -7
  22. package/lib/aqQueue.js +243 -53
  23. package/lib/connection.js +1326 -465
  24. package/lib/constants.js +203 -0
  25. package/lib/dbObject.js +346 -32
  26. package/lib/errors.js +785 -0
  27. package/lib/impl/aqDeqOptions.js +197 -0
  28. package/lib/impl/aqEnqOptions.js +89 -0
  29. package/lib/impl/aqMessage.js +134 -0
  30. package/lib/impl/aqQueue.js +81 -0
  31. package/lib/impl/connection.js +529 -0
  32. package/lib/impl/dbObject.js +159 -0
  33. package/lib/impl/index.js +59 -0
  34. package/lib/impl/lob.js +85 -0
  35. package/lib/impl/pool.js +195 -0
  36. package/lib/impl/resultset.js +223 -0
  37. package/lib/impl/sodaCollection.js +174 -0
  38. package/lib/impl/sodaDatabase.js +81 -0
  39. package/lib/impl/sodaDocCursor.js +63 -0
  40. package/lib/impl/sodaDocument.js +98 -0
  41. package/lib/impl/sodaOperation.js +109 -0
  42. package/lib/lob.js +157 -68
  43. package/lib/oracledb.js +1047 -345
  44. package/lib/pool.js +654 -465
  45. package/lib/poolStatistics.js +24 -9
  46. package/lib/queryStream.js +16 -8
  47. package/lib/resultset.js +291 -183
  48. package/lib/settings.js +191 -0
  49. package/lib/sodaCollection.js +214 -201
  50. package/lib/sodaDatabase.js +108 -71
  51. package/lib/sodaDocCursor.js +44 -32
  52. package/lib/sodaDocument.js +76 -14
  53. package/lib/sodaOperation.js +131 -118
  54. package/lib/thin/connection.js +1043 -0
  55. package/lib/thin/dbObject.js +630 -0
  56. package/lib/thin/index.js +40 -0
  57. package/lib/thin/lob.js +189 -0
  58. package/lib/thin/pool.js +481 -0
  59. package/lib/thin/protocol/buffer.js +1043 -0
  60. package/lib/thin/protocol/capabilities.js +121 -0
  61. package/lib/thin/protocol/constants.js +765 -0
  62. package/lib/thin/protocol/encryptDecrypt.js +185 -0
  63. package/lib/thin/protocol/messages/auth.js +349 -0
  64. package/lib/thin/protocol/messages/base.js +476 -0
  65. package/lib/thin/protocol/messages/commit.js +56 -0
  66. package/lib/thin/protocol/messages/dataType.js +391 -0
  67. package/lib/thin/protocol/messages/execute.js +312 -0
  68. package/lib/thin/protocol/messages/fetch.js +60 -0
  69. package/lib/thin/protocol/messages/index.js +53 -0
  70. package/lib/thin/protocol/messages/lobOp.js +201 -0
  71. package/lib/thin/protocol/messages/logOff.js +53 -0
  72. package/lib/thin/protocol/messages/ping.js +56 -0
  73. package/lib/thin/protocol/messages/protocol.js +78 -0
  74. package/lib/thin/protocol/messages/rollback.js +56 -0
  75. package/lib/thin/protocol/messages/sessionRelease.js +60 -0
  76. package/lib/thin/protocol/messages/withData.js +812 -0
  77. package/lib/thin/protocol/oson.js +661 -0
  78. package/lib/thin/protocol/packet.js +519 -0
  79. package/lib/thin/protocol/protocol.js +202 -0
  80. package/lib/thin/protocol/utils.js +89 -0
  81. package/lib/thin/resultSet.js +122 -0
  82. package/lib/thin/sqlnet/connStrategy.js +175 -0
  83. package/lib/thin/sqlnet/constants.js +199 -0
  84. package/lib/thin/sqlnet/ezConnectResolver.js +488 -0
  85. package/lib/thin/sqlnet/navNodes.js +870 -0
  86. package/lib/thin/sqlnet/networkSession.js +621 -0
  87. package/lib/thin/sqlnet/ntTcp.js +527 -0
  88. package/lib/thin/sqlnet/nvStrToNvPair.js +783 -0
  89. package/lib/thin/sqlnet/packet.js +405 -0
  90. package/lib/thin/sqlnet/paramParser.js +206 -0
  91. package/lib/thin/sqlnet/sessionAtts.js +160 -0
  92. package/lib/thin/statement.js +300 -0
  93. package/lib/thin/util.js +289 -0
  94. package/lib/transformer.js +252 -0
  95. package/lib/types.js +357 -0
  96. package/lib/util.js +196 -110
  97. package/lib/version.js +36 -0
  98. package/package/README.md +33 -30
  99. package/package/install.js +89 -64
  100. package/package/prunebinaries.js +60 -12
  101. package/package.json +3 -3
  102. package/build/Release/oracledb-5.5.0-darwin-x64.node +0 -0
  103. package/build/Release/oracledb-5.5.0-darwin-x64.node-buildinfo.txt +0 -1
  104. package/build/Release/oracledb-5.5.0-linux-x64.node +0 -0
  105. package/build/Release/oracledb-5.5.0-linux-x64.node-buildinfo.txt +0 -1
  106. package/build/Release/oracledb-5.5.0-win32-x64.node +0 -0
  107. package/build/Release/oracledb-5.5.0-win32-x64.node-buildinfo.txt +0 -1
@@ -0,0 +1,488 @@
1
+ // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
2
+
3
+ //-----------------------------------------------------------------------------
4
+ //
5
+ // This software is dual-licensed to you under the Universal Permissive License
6
+ // (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
7
+ // 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
8
+ // either license.
9
+ //
10
+ // If you elect to accept the software under the Apache License, Version 2.0,
11
+ // the following applies:
12
+ //
13
+ // Licensed under the Apache License, Version 2.0 (the "License");
14
+ // you may not use this file except in compliance with the License.
15
+ // You may obtain a copy of the License at
16
+ //
17
+ // https://www.apache.org/licenses/LICENSE-2.0
18
+ //
19
+ // Unless required by applicable law or agreed to in writing, software
20
+ // distributed under the License is distributed on an "AS IS" BASIS,
21
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22
+ // See the License for the specific language governing permissions and
23
+ // limitations under the License.
24
+ //
25
+ //-----------------------------------------------------------------------------
26
+
27
+ 'use strict';
28
+
29
+ const {lookup} = require('dns').promises;
30
+ const errors = require("../../errors.js");
31
+
32
+ // The host information pattern of the EZConnect URL format.
33
+ /*
34
+ Used (?=) for lookahead and \\k<hostnames> for the backreference.Lookahead
35
+ and backreference together prevents catastrophic backtracking.
36
+ Test Case in oracle_private/ezconnectTest.js
37
+ */
38
+
39
+ const HOSTNAMES_PATTERN = new RegExp("((?=(?<hostnames>(((\\[[A-z0-9:]+\\])|([A-z0-9][A-z0-9._-]+))[,]?)+)))\\k<hostnames>(:(?<port>\\d+)?)?", 'g');
40
+
41
+ // The EZConnect pattern without the extended settings part.
42
+ const EZ_URL_PATTERN = new RegExp("^((?<protocol>tcp|tcps):)?"
43
+ + "(//)?"
44
+ + "(?<hostinfo>(" + HOSTNAMES_PATTERN.source + "(?=([,]|[;]|[/]|[:]|$))([,]|[;])?)+)"
45
+ + "(/(?<servicename>[A-z0-9][A-z0-9,-.]+)?)"
46
+ + "?(:(?<servermode>dedicated|shared|pooled))"
47
+ + "?(/(?<instance>[A-z0-9][A-z0-9]+))?$", 'ig');
48
+
49
+ //'=' separates the connection property name and value.
50
+ const EXT_DOUBLE_QT = '"';
51
+
52
+ // '=' separates the connection property name and value.
53
+ const EXT_KEY_VAL_SEP = '=';
54
+
55
+ // '&' separates the connection properties.
56
+ const EXT_PARAM_SEP = '&';
57
+
58
+ // The parameters which will be part of the DESCRIPTION node.
59
+ const DESCRIPTION_PARAMS = ["ENABLE", "FAILOVER", "LOAD_BALANCE",
60
+ "RECV_BUF_SIZE", "SEND_BUF_SIZE", "SDU",
61
+ "SOURCE_ROUTE", "RETRY_COUNT", "RETRY_DELAY",
62
+ "CONNECT_TIMEOUT", "TRANSPORT_CONNECT_TIMEOUT", "RECV_TIMEOUT"];
63
+ /*
64
+ DESCRIPTION
65
+ This class takes care resolving the EZConnect format to Long TNS URL format.
66
+ It also takes care of parsing the connection and url properties set in the url.
67
+ The format of the EZConnect URL is :
68
+ [[protocol:]//]host1[,host12;host13][:port1][,host2:port2][/service_name]
69
+ [:server][/instance_name][?[key1=value1][&key2=value2]...
70
+
71
+ */
72
+ class EZConnectResolver {
73
+ constructor(url) {
74
+ this.URL_PROPS_ALIAS = this.initializeUrlAlias();
75
+ let jdbcUrlPrefix = url.indexOf('@');
76
+ if (jdbcUrlPrefix != -1) {
77
+ this.url = url.substring(jdbcUrlPrefix + 1);
78
+ this.urlPrefix = url.substring(0, jdbcUrlPrefix + 1);
79
+ } else {
80
+ this.url = url;
81
+ this.urlPrefix = "";
82
+ }
83
+ this.resolvedUrl = '';
84
+ this.connectionProps = new Map();
85
+ this.urlProps = new Map();
86
+ this.lb = false;
87
+ }
88
+
89
+ /**
90
+ * Returns the resolved long TNS String.
91
+ * @return Resolved TNS URL.
92
+ */
93
+ async getResolvedUrl() {
94
+ await this.parse();
95
+ return this.resolvedUrl;
96
+ }
97
+
98
+ /**
99
+ * First parse the extended settings part of the given url.
100
+ * After parsing the extended settings if the remaining part of the URL is in
101
+ * EZConnectURL format then resolve it to long TNS url format.
102
+ */
103
+ async parse() {
104
+ // First try to parse the extended settings part of the URL.
105
+ let parsedUrl = this.parseExtendedSettings(this.url);
106
+ if (this.connectionProps.size === 0 && this.urlProps.size === 0) {
107
+ // If we have not parsed anything then use the received url as is.
108
+ parsedUrl = this.url;
109
+ }
110
+
111
+ if (parsedUrl.startsWith("(")) {
112
+ // Skip resolve the URL if it is in TNS format,
113
+ // TNS format starts with '('
114
+ this.resolvedUrl = this.urlPrefix + parsedUrl;
115
+ } else {
116
+ // Try to resolve the EZConnectURL to Long TNS URL.
117
+ this.resolvedUrl = this.urlPrefix + await this.resolveToLongURLFormat(parsedUrl);
118
+ }
119
+ }
120
+ /**
121
+ * Translate the given ezconnect url format to Long TNS format.
122
+ * @param url EZConnect URL
123
+ * @return Returns resolved TNS url.
124
+ */
125
+ async resolveToLongURLFormat(url) {
126
+ // URL is in the following format
127
+ // [protocol://]host1[,host13][:port1][,host2:port2][/service_name][:server][/instance_name]
128
+
129
+ let urlWithoutWhiteSpaces = url.replace(/\s/g, "");
130
+ let bool = 0;
131
+ let protocol = null, hostInfo = null, serviceName = null, serverMode = null, instanceName = null;
132
+ for (const match of urlWithoutWhiteSpaces.matchAll(EZ_URL_PATTERN)) {
133
+ bool = 1;
134
+ protocol = match.groups.protocol;
135
+ hostInfo = match.groups.hostinfo;
136
+ serviceName = match.groups.servicename;
137
+ serverMode = match.groups.servermode;
138
+ instanceName = match.groups.instance;
139
+ }
140
+ if (!bool) {
141
+ // No Processing required as the URL is not in ezconnect format.
142
+ errors.throwErr(errors.ERR_INVALID_EZCONNECT_SYNTAX, 'input string not in easy connect format', urlWithoutWhiteSpaces);
143
+ }
144
+
145
+ if (protocol == null) {
146
+ if (!(url.includes("//")))
147
+ protocol = 'TCP';
148
+ }
149
+
150
+ // Try to get the proxy information from URL properties
151
+ const proxyHost = this.urlProps.get("HTTPS_PROXY");
152
+ const proxyPort = this.urlProps.get("HTTPS_PROXY_PORT");
153
+ const addressInfo =
154
+ await this.buildAddressList(hostInfo, protocol, proxyHost, proxyPort);
155
+
156
+ let connectionIdPrefix =
157
+ this.urlProps.get("CONNECTION_ID_PREFIX");
158
+ // Build the available information in TNS format.
159
+ const parts = [];
160
+ if (this.lb)
161
+ parts.push("(LOAD_BALANCE=ON)");
162
+ parts.push(this.buildDescriptionParams());
163
+ parts.push(addressInfo);
164
+ parts.push(this.buildConnectData(serviceName, serverMode, instanceName,
165
+ connectionIdPrefix));
166
+ parts.push(this.buildSecurityInfo(protocol));
167
+ return `(DESCRIPTION=${parts.join('')})`;
168
+ }
169
+
170
+ /**
171
+ * Returns the CONNECT_DATA part of DESCRIPTION node of the TNS URL.
172
+ * @param serviceName the database service name [optional].
173
+ * @param serverMode dedicated or shared or pooled [optional].
174
+ * @param instanceName the database instance name [optional].
175
+ * @param connectionIdPrefix prefix which will be appended to the connection id [optional].
176
+ * @return CONNECT_DATA as string
177
+ */
178
+ buildConnectData(serviceName, serverMode, instanceName, connectionIdPrefix) {
179
+ const poolConnectionClass = this.urlProps.get("POOL_CONNECTION_CLASS");
180
+ const poolPurity = this.urlProps.get("POOL_PURITY");
181
+ const serviceTag = this.urlProps.get("SERVICE_TAG");
182
+
183
+ const parts = [];
184
+ if (serviceName)
185
+ parts.push(`(SERVICE_NAME=${serviceName})`);
186
+ else
187
+ parts.push('(SERVICE_NAME=)');
188
+ if (serverMode)
189
+ parts.push(`(SERVER=${serverMode})`);
190
+ if (instanceName)
191
+ parts.push(`(INSTANCE_NAME=${instanceName})`);
192
+ if (poolConnectionClass)
193
+ parts.push(`(POOL_CONNECTION_CLASS=${poolConnectionClass})`);
194
+ if (poolPurity)
195
+ parts.push(`(POOL_PURITY=${poolPurity})`);
196
+ if (serviceTag)
197
+ parts.push(`(SERVICE_TAG=${serviceTag})`);
198
+ if (connectionIdPrefix)
199
+ parts.push(`(CONNECTION_ID_PREFIX=${connectionIdPrefix})`);
200
+ return `(CONNECT_DATA=${parts.join("")})`;
201
+ }
202
+
203
+ /**
204
+ * Builds the address information of the DESCRIPTION node with the given
205
+ * information.
206
+ * @param hostInfo host and port information separated by comma.
207
+ hosts can be grouped into a ADDRESS_LIST using semi-colon ';'
208
+ * @param protocol either tcp or tcps [optional].
209
+ * @param proxyHost host name of the proxy server [optional].
210
+ * @param proxyPort proxy server port [optional].
211
+ * @return address information of the DESCRIPTION node.
212
+ */
213
+ async buildAddressList(hostInfo, protocol,
214
+ proxyHost, proxyPort) {
215
+ let shost = '';
216
+ let ipcnt = 0;
217
+ let builder = new Array();
218
+ let proxyInfo = '';
219
+ if (proxyHost != null && proxyPort != null) {
220
+ proxyInfo = `(HTTPS_PROXY=${proxyHost})(HTTPS_PROXY_PORT=${proxyPort})`;
221
+ }
222
+
223
+ if (protocol == null) protocol = 'TCP';
224
+ let naddr = 0;
225
+ // ; groups the user into a ADDRESS_LIST
226
+ let addressLists = hostInfo.split(";");
227
+ for (let addressList in addressLists) {
228
+ let addressNodeCount = 0;
229
+ let addressListBuilder = new Array();
230
+ for (const match of addressLists[addressList].matchAll(HOSTNAMES_PATTERN)) {
231
+ let hostnames = (match.groups.hostnames).split(',');
232
+ let port = match.groups.port;
233
+ if (port == null) {
234
+ port = '1521' + '';
235
+ }
236
+ for (let hname in hostnames) {
237
+ addressListBuilder.push(this.getAddrStr(hostnames[hname], port, protocol, proxyInfo));
238
+ shost = hostnames[hname];
239
+ addressNodeCount++;
240
+ }
241
+ }
242
+ naddr += addressNodeCount;
243
+ const parts = [];
244
+ if (addressLists.length > 1 && addressNodeCount > 1)
245
+ parts.push('(LOAD_BALANCE=ON)');
246
+ parts.push(addressListBuilder.join(''));
247
+ if (addressLists.length > 1)
248
+ builder.push(`(ADDRESS_LIST=${parts.join('')})`);
249
+ else
250
+ builder.push(parts.join(''));
251
+ }
252
+ if (naddr == 1) {
253
+ shost = shost.trim();
254
+ // If it is IPV6 format address then remove the enclosing '[' and ']'
255
+ if (shost.startsWith("[") && shost.endsWith("]"))
256
+ shost = shost.substring(1, shost.length - 1);
257
+ try {
258
+ await lookup(shost);
259
+ ipcnt++;
260
+ } catch {
261
+ // nothing
262
+ }
263
+ if (ipcnt == 0) {
264
+ errors.throwErr(errors.ERR_INVALID_EZCONNECT_SYNTAX, 'could not resolve hostname', shost);
265
+ }
266
+ }
267
+
268
+ if (addressLists.length < 2 && naddr > 1) {
269
+ this.lb = true;
270
+ }
271
+
272
+ return builder.join('');
273
+
274
+ }
275
+ /**
276
+ * Builds address information using the given hostname, port, protocol and
277
+ * proxyinfo.
278
+ * @param hostName
279
+ * @param port
280
+ * @param protocol
281
+ * @param proxyInfo
282
+ * @return addressInfo
283
+ */
284
+ getAddrStr(hostName, port, protocol, proxyInfo) {
285
+ let host = hostName.trim();
286
+ // If it is IPV6 format address then remove the enclosing '[' and ']'
287
+ if (host.startsWith("[") && host.endsWith("]"))
288
+ host = host.substring(1, host.length - 1);
289
+ return `(ADDRESS=(PROTOCOL=${protocol})(HOST=${host})(PORT=${port})${proxyInfo})`;
290
+ }
291
+ /**
292
+ * Builds the parameters for the DESCRIPTION node using the parsed properties
293
+ * from the URL.
294
+ * @return Description Parameters String.
295
+ */
296
+ buildDescriptionParams() {
297
+ if (this.urlProps.size === 0)
298
+ return '';
299
+ let builder = new Array();
300
+ this.urlProps.forEach(function(v, k) {
301
+ if (DESCRIPTION_PARAMS.includes(k)) // Add only if it is a DESCRIPTION node parameter
302
+ builder.push(`(${k}=${v})`);
303
+ });
304
+ return builder.join('');
305
+ }
306
+
307
+ /**
308
+ * Builds the security section of the DESCRIPTION node, which contains the information
309
+ * about wallet location, server DN, encryption and checksum options.
310
+ * @return security node of the description as string.
311
+ */
312
+ buildSecurityInfo(protocol) {
313
+ const securityInfo = new Array();
314
+ if (protocol != null && protocol.toLowerCase() == "tcps") {
315
+ // In EZConnect format if the DN match is not specified the enable it
316
+ // by default for TCPS protocol.
317
+ const serverDNMatch = this.urlProps.get("SSL_SERVER_DN_MATCH") || 'TRUE';
318
+ const serverCertDN = this.urlProps.get("SSL_SERVER_CERT_DN");
319
+ const walletDir = this.urlProps.get("MY_WALLET_DIRECTORY");
320
+ securityInfo.push(`(SSL_SERVER_DN_MATCH=${serverDNMatch})`);
321
+ if (serverCertDN != null)
322
+ securityInfo.push(`(SSL_SERVER_CERT_DN=${serverCertDN}})`);
323
+ if (walletDir != null)
324
+ securityInfo.push(`(MY_WALLET_DIRECTORY=${walletDir})`);
325
+ }
326
+ if (securityInfo.length === 0)
327
+ return '';
328
+ return `(SECURITY=${securityInfo.join('')})`;
329
+ }
330
+
331
+ /**
332
+ * If the URL has extended settings part appended to it, this method takes
333
+ * care of parsing it.
334
+ * Parses the Extended Settings and takes appropriate action based on the
335
+ * settings type.
336
+ * <URL>?<propertyName1>=<propertyValue1>&<propertyName2>=<propertyValue2>.
337
+ * @param urlStr Database URL supplied by the application.
338
+ * @return the parsed URL which does not contain the extended settings part.
339
+ */
340
+ parseExtendedSettings(urlStr) {
341
+ let urlBytes = Array.from(urlStr.trim());
342
+ let extendedSettingsIndex = this.findExtendedSettingPosition(urlBytes);
343
+
344
+ if (extendedSettingsIndex == -1) {
345
+ return urlStr; // No extended settings configuration found
346
+ }
347
+ this.parseExtendedProperties(urlBytes, (extendedSettingsIndex + 1));
348
+ return urlStr.substring(0, extendedSettingsIndex);
349
+ }
350
+ /**
351
+ * Loops through the chars of the extended settings part of the URL and
352
+ * parses the connection properties.
353
+ * @param urlChars URL in char[]
354
+ * @param extIndex the begin index of the extended settings
355
+ */
356
+ parseExtendedProperties(urlChars, extIndex) {
357
+ let key = null;
358
+ let value = null;
359
+ let token = new Array(urlChars.length);
360
+ let tokenIndx = 0;
361
+ let indices = '';
362
+ for (let i = extIndex; i < urlChars.length; i++) {
363
+ if (urlChars[i].trim() == '') {
364
+ continue; //if whitespace char, then ignore it
365
+ }
366
+
367
+ switch (urlChars[i]) {
368
+ case EXT_DOUBLE_QT:
369
+ indices = this.parseQuotedString(i, urlChars, tokenIndx, token);
370
+ tokenIndx = indices[1];
371
+ i = indices[0];
372
+ break;
373
+
374
+ // Hit a '=' assign the value up to this to param key and
375
+ // reset the startIndex
376
+ case EXT_KEY_VAL_SEP:
377
+ if (key != null) {
378
+ errors.throwErr(errors.ERR_INVALID_EZCONNECT_SYNTAX, 'unable to parse, invalid syntax', this.url);
379
+ }
380
+ key = token.join("").substring(0, tokenIndx).trim();
381
+ tokenIndx = 0;
382
+ break;
383
+
384
+ // Hit a '&' assign the value up to this to param key and
385
+ // reset the startIndex
386
+ case EXT_PARAM_SEP:
387
+ if (key == null) {
388
+ errors.throwErr(errors.ERR_INVALID_EZCONNECT_SYNTAX, 'unable to parse, invalid syntax', this.url);
389
+ }
390
+ value = token.join("").substring(0, tokenIndx).trim();
391
+ this.addParam(key, value);
392
+ key = null;
393
+ value = null;
394
+ tokenIndx = 0;
395
+ break;
396
+
397
+ default:
398
+ token[tokenIndx++] = urlChars[i];
399
+ }
400
+ }
401
+ // We don't have any unassigned key, ignore the read chars.
402
+ if (key != null) {
403
+ value = token.join("").substring(0, tokenIndx).trim();
404
+ this.addParam(key, value);
405
+ }
406
+ }
407
+
408
+ /**
409
+ * Parses the quoted string from the given startIndex of the urlChars and
410
+ * return the length of the parsed quoted string.
411
+ * @param startIndex index of the starting '"' in the urlChars
412
+ * @param urlChars char[] of the url string.
413
+ * @param tokenIndex starting index in the token char[] to store the result
414
+ * @param token char[] to store the result
415
+ * @return int[] int[0] - new index for urlChars, int[1] new index for token
416
+ */
417
+ parseQuotedString(startIndex, urlChars, tokenIndex, token) {
418
+ let i = startIndex + 1; // look for closing '"' from the next index
419
+ while (i < urlChars.length) {
420
+ let curChar = urlChars[i];
421
+ if (curChar == EXT_DOUBLE_QT) {
422
+ // Got the " which ends the quoted block, so break the loop
423
+ // Return the new indices, caller would resume from this new indices.
424
+ return [i, tokenIndex];
425
+ } else {
426
+ token[tokenIndex++] = curChar;
427
+ }
428
+ i++;
429
+ }
430
+ }
431
+
432
+ /**
433
+ * Adds the given key and value to the connection properties.
434
+ * @param key
435
+ * @param value
436
+ */
437
+ addParam(key, value) {
438
+ let aliasKeyName = key.toLowerCase();
439
+ let propertyName = this.URL_PROPS_ALIAS.get(aliasKeyName);
440
+ if (propertyName != null) {
441
+ // if it is an URL alias then add to URL props
442
+ this.urlProps.set(propertyName, value);
443
+ } else {
444
+ this.connectionProps.set(propertyName, value);
445
+ }
446
+ }
447
+
448
+ findExtendedSettingPosition(urlBytes) {
449
+ let urlNodeDepth = 0;
450
+ for (let i = 0; i < urlBytes.length; i++) {
451
+ if (urlBytes[i] == '(') urlNodeDepth++;
452
+ else if (urlBytes[i] == ')') urlNodeDepth--;
453
+ else if (urlBytes[i] == '?' && urlNodeDepth == 0) return i;
454
+ }
455
+ return -1;
456
+ }
457
+
458
+ /**
459
+ * Initialize a Map with URL parameter alias. key is what we get from the
460
+ * URL and the value is what we use while creating the TNS URL.
461
+ * @return url alias map
462
+ */
463
+ initializeUrlAlias() {
464
+ let aliasMap = new Map();
465
+ aliasMap.set("enable", "ENABLE");
466
+ aliasMap.set("failover", "FAILOVER");
467
+ aliasMap.set("load_balance", "LOAD_BALANCE");
468
+ aliasMap.set("recv_buf_size", "RECV_BUF_SIZE");
469
+ aliasMap.set("send_buf_size", "SEND_BUF_SIZE");
470
+ aliasMap.set("sdu", "SDU");
471
+ aliasMap.set("source_route", "SOURCE_ROUTE");
472
+ aliasMap.set("retry_count", "RETRY_COUNT");
473
+ aliasMap.set("retry_delay", "RETRY_DELAY");
474
+ aliasMap.set("https_proxy", "HTTPS_PROXY");
475
+ aliasMap.set("https_proxy_port", "HTTPS_PROXY_PORT");
476
+ aliasMap.set("connect_timeout", "CONNECT_TIMEOUT");
477
+ aliasMap.set("transport_connect_timeout", "TRANSPORT_CONNECT_TIMEOUT");
478
+ aliasMap.set("recv_timeout", "RECV_TIMEOUT");
479
+ aliasMap.set("ssl_server_cert_dn", "SSL_SERVER_CERT_DN");
480
+ aliasMap.set("ssl_server_dn_match", "SSL_SERVER_DN_MATCH");
481
+ aliasMap.set("wallet_location", "MY_WALLET_DIRECTORY");
482
+ aliasMap.set("pool_connection_class", "POOL_CONNECTION_CLASS");
483
+ aliasMap.set("pool_purity", "POOL_PURITY");
484
+ aliasMap.set("service_tag", "SERVICE_TAG");
485
+ aliasMap.set("connection_id_prefix", "CONNECTION_ID_PREFIX");
486
+ return aliasMap;
487
+ }
488
+ }module.exports = EZConnectResolver;