oracledb 5.4.0 → 6.0.0

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 (108) hide show
  1. package/CHANGELOG.md +1 -1849
  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/THIRD_PARTY_LICENSES.txt +1 -1
  7. package/build/Release/oracledb-6.0.0-darwin-x64.node +0 -0
  8. package/build/Release/oracledb-6.0.0-darwin-x64.node-buildinfo.txt +1 -0
  9. package/build/Release/oracledb-6.0.0-js-buildinfo.txt +1 -0
  10. package/build/Release/oracledb-6.0.0-linux-arm64.node +0 -0
  11. package/build/Release/oracledb-6.0.0-linux-arm64.node-buildinfo.txt +1 -0
  12. package/build/Release/oracledb-6.0.0-linux-x64.node +0 -0
  13. package/build/Release/oracledb-6.0.0-linux-x64.node-buildinfo.txt +1 -0
  14. package/build/Release/oracledb-6.0.0-win32-x64.node +0 -0
  15. package/build/Release/oracledb-6.0.0-win32-x64.node-buildinfo.txt +1 -0
  16. package/examples/README.md +113 -0
  17. package/examples/dbconfig.js +100 -0
  18. package/examples/example.js +156 -0
  19. package/index.js +26 -0
  20. package/lib/aqDeqOptions.js +146 -7
  21. package/lib/aqEnqOptions.js +59 -7
  22. package/lib/aqMessage.js +118 -7
  23. package/lib/aqQueue.js +242 -53
  24. package/lib/connection.js +1324 -465
  25. package/lib/constants.js +203 -0
  26. package/lib/dbObject.js +346 -32
  27. package/lib/errors.js +781 -0
  28. package/lib/impl/aqDeqOptions.js +197 -0
  29. package/lib/impl/aqEnqOptions.js +89 -0
  30. package/lib/impl/aqMessage.js +134 -0
  31. package/lib/impl/aqQueue.js +81 -0
  32. package/lib/impl/connection.js +529 -0
  33. package/lib/impl/dbObject.js +159 -0
  34. package/lib/impl/index.js +59 -0
  35. package/lib/impl/lob.js +85 -0
  36. package/lib/impl/pool.js +195 -0
  37. package/lib/impl/resultset.js +223 -0
  38. package/lib/impl/sodaCollection.js +174 -0
  39. package/lib/impl/sodaDatabase.js +81 -0
  40. package/lib/impl/sodaDocCursor.js +63 -0
  41. package/lib/impl/sodaDocument.js +98 -0
  42. package/lib/impl/sodaOperation.js +109 -0
  43. package/lib/lob.js +156 -68
  44. package/lib/oracledb.js +1051 -257
  45. package/lib/pool.js +654 -465
  46. package/lib/poolStatistics.js +23 -9
  47. package/lib/queryStream.js +14 -7
  48. package/lib/resultset.js +292 -171
  49. package/lib/settings.js +191 -0
  50. package/lib/sodaCollection.js +214 -201
  51. package/lib/sodaDatabase.js +107 -71
  52. package/lib/sodaDocCursor.js +44 -32
  53. package/lib/sodaDocument.js +76 -14
  54. package/lib/sodaOperation.js +131 -118
  55. package/lib/thin/connection.js +1038 -0
  56. package/lib/thin/dbObject.js +629 -0
  57. package/lib/thin/index.js +40 -0
  58. package/lib/thin/lob.js +188 -0
  59. package/lib/thin/pool.js +481 -0
  60. package/lib/thin/protocol/buffer.js +1040 -0
  61. package/lib/thin/protocol/capabilities.js +116 -0
  62. package/lib/thin/protocol/constants.js +764 -0
  63. package/lib/thin/protocol/encryptDecrypt.js +185 -0
  64. package/lib/thin/protocol/messages/auth.js +348 -0
  65. package/lib/thin/protocol/messages/base.js +475 -0
  66. package/lib/thin/protocol/messages/commit.js +56 -0
  67. package/lib/thin/protocol/messages/dataType.js +382 -0
  68. package/lib/thin/protocol/messages/execute.js +312 -0
  69. package/lib/thin/protocol/messages/fetch.js +60 -0
  70. package/lib/thin/protocol/messages/index.js +53 -0
  71. package/lib/thin/protocol/messages/lobOp.js +200 -0
  72. package/lib/thin/protocol/messages/logOff.js +53 -0
  73. package/lib/thin/protocol/messages/ping.js +56 -0
  74. package/lib/thin/protocol/messages/protocol.js +78 -0
  75. package/lib/thin/protocol/messages/rollback.js +56 -0
  76. package/lib/thin/protocol/messages/sessionRelease.js +60 -0
  77. package/lib/thin/protocol/messages/withData.js +811 -0
  78. package/lib/thin/protocol/oson.js +660 -0
  79. package/lib/thin/protocol/packet.js +520 -0
  80. package/lib/thin/protocol/protocol.js +202 -0
  81. package/lib/thin/protocol/utils.js +88 -0
  82. package/lib/thin/resultSet.js +122 -0
  83. package/lib/thin/sqlnet/connStrategy.js +175 -0
  84. package/lib/thin/sqlnet/constants.js +199 -0
  85. package/lib/thin/sqlnet/ezConnectResolver.js +488 -0
  86. package/lib/thin/sqlnet/navNodes.js +870 -0
  87. package/lib/thin/sqlnet/networkSession.js +620 -0
  88. package/lib/thin/sqlnet/ntTcp.js +525 -0
  89. package/lib/thin/sqlnet/nvStrToNvPair.js +783 -0
  90. package/lib/thin/sqlnet/packet.js +405 -0
  91. package/lib/thin/sqlnet/paramParser.js +205 -0
  92. package/lib/thin/sqlnet/sessionAtts.js +160 -0
  93. package/lib/thin/statement.js +301 -0
  94. package/lib/thin/util.js +289 -0
  95. package/lib/transformer.js +250 -0
  96. package/lib/types.js +357 -0
  97. package/lib/util.js +194 -108
  98. package/lib/version.js +36 -0
  99. package/package/README.md +33 -30
  100. package/package/install.js +89 -64
  101. package/package/prunebinaries.js +60 -12
  102. package/package.json +3 -3
  103. package/build/Release/oracledb-5.4.0-darwin-x64.node +0 -0
  104. package/build/Release/oracledb-5.4.0-darwin-x64.node-buildinfo.txt +0 -1
  105. package/build/Release/oracledb-5.4.0-linux-x64.node +0 -0
  106. package/build/Release/oracledb-5.4.0-linux-x64.node-buildinfo.txt +0 -1
  107. package/build/Release/oracledb-5.4.0-win32-x64.node +0 -0
  108. package/build/Release/oracledb-5.4.0-win32-x64.node-buildinfo.txt +0 -1
@@ -0,0 +1,405 @@
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 Buffer = require("buffer").Buffer;
30
+ const constants = require("./constants.js");
31
+ const errors = require("../../errors.js");
32
+ const MAX_CDATA_LEN = 230;
33
+ const NSPCNL = 74;
34
+
35
+ /**
36
+ * Connect Packet (NSPTCN)
37
+ * @param {Buffer} connectData Outgoing Connect Data
38
+ * @param {Object} sAtts Session Attributes
39
+ */
40
+ function ConnectPacket(connectData, sAtts, flags = 0) {
41
+ this.connectData = connectData;
42
+ this.connectDataLen = connectData.length;
43
+ this.overflow = false;
44
+
45
+ let size, options;
46
+
47
+ if (this.connectDataLen <= MAX_CDATA_LEN) {
48
+ size = NSPCNL + this.connectDataLen;
49
+ } else {
50
+ size = NSPCNL;
51
+ this.overflow = true;
52
+ }
53
+
54
+ /* Building Connect Packet */
55
+ this.buf = Buffer.alloc(size);
56
+ this.buf.writeUInt16BE(size, constants.NSPHDLEN);
57
+ this.buf.writeUInt8(flags, constants.NSPHDFLGS);
58
+ this.buf.writeUInt8(constants.NSPTCN, constants.NSPHDTYP);
59
+
60
+ this.buf.writeUInt16BE(
61
+ constants.TNS_VERSION_DESIRED,
62
+ constants.NSPCNVSN
63
+ ); /* My version */
64
+ this.buf.writeUInt16BE(
65
+ constants.TNS_VERSION_MINIMUM,
66
+ constants.NSPCNLOV
67
+ ); /* Lowest version*/
68
+
69
+ /* Options:
70
+ Note : Node JS does not support TCP Out-of-band so not setting NSGSENDATTN or NSGRECVATTN
71
+ */
72
+ options = constants.NSGDONTCARE;
73
+ //options = options | constants.NSGUSEVIO /* Vectored I/O support.Uncomment when support is added */
74
+ this.buf.writeUInt16BE(options, constants.NSPCNOPT);
75
+
76
+ /* SDU */
77
+ if (sAtts.sdu > constants.NSPMXSDULN) {
78
+ this.buf.writeUInt16BE(constants.NSPMXSDULN, constants.NSPCNSDU);
79
+ } else {
80
+ this.buf.writeUInt16BE(sAtts.sdu, constants.NSPCNSDU);
81
+ }
82
+
83
+ /* TDU */
84
+ if (sAtts.tdu > constants.NSPMXSDULN) {
85
+ this.buf.writeUInt16BE(constants.NSPMXSDULN, constants.NSPCNTDU);
86
+ } else {
87
+ this.buf.writeUInt16BE(sAtts.tdu, constants.NSPCNTDU);
88
+ }
89
+
90
+ this.buf.writeUInt16BE(
91
+ sAtts.ntCha,
92
+ constants.NSPCNNTC
93
+ ); /* Protocol characteristics */
94
+
95
+ this.buf.writeUInt16BE(
96
+ 1,
97
+ constants.NSPCNONE
98
+ ); /* Endianness does not matter for Node */
99
+
100
+ this.buf.writeUInt16BE(
101
+ this.connectDataLen,
102
+ constants.NSPCNLEN
103
+ ); /* Connect data Length */
104
+
105
+ this.buf.writeUInt16BE(
106
+ constants.NSPCNDAT,
107
+ constants.NSPCNOFF
108
+ ); /* Connect data offset */
109
+
110
+ this.buf.writeUInt8(
111
+ constants.NSISUPSECRENEG | constants.NSINADISABLEDFORCONNECTION,
112
+ constants.NSPCNFL0
113
+ ); /* NA disabled */
114
+
115
+ this.buf.writeUInt8(
116
+ constants.NSISUPSECRENEG | constants.NSINADISABLEDFORCONNECTION,
117
+ constants.NSPCNFL1
118
+ ); /* NA disabled *
119
+
120
+ /* Connection Pool is not supported */
121
+ this.buf.writeUInt16BE(0, constants.NSPCNTMO);
122
+ this.buf.writeUInt16BE(0, constants.NSPCNTCK);
123
+ this.buf.writeUInt16BE(0, constants.NSPCNADL);
124
+ this.buf.writeUInt16BE(0, constants.NSPCNAOF);
125
+
126
+ this.buf.writeUInt32BE(sAtts.sdu, constants.NSPCNLSD); /* SDU */
127
+ this.buf.writeUInt32BE(sAtts.tdu, constants.NSPCNLTD); /* TDU */
128
+ this.buf.writeUInt32BE(0, constants.NSPCNCFL); /* Compression not supported */
129
+
130
+ this.buf.writeUInt32BE(
131
+ 0,
132
+ constants.NSPCNCFL2
133
+ ); /* No OOB path check support */
134
+
135
+ if (!this.overflow && this.connectDataLen) {
136
+ this.buf.write(connectData.toString('ascii'), constants.NSPCNDAT, this.connectDataLen, "ascii");
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Data Pakcet (NSPTDA)
142
+ * @param {int} size of Data Packet
143
+ * @param {boolean} isLargeSDU Large SDU
144
+ */
145
+ function DataPacket(size, isLargeSDU) {
146
+ this.dataPtr = 0; /* data offset start */
147
+ this.dataLen = 0; /* data offset end */
148
+ this.bufLen = size; /* Length of buffer */
149
+ this.offset = 0; /* Offset for buffer read/write (fastpath) */
150
+ this.len = 0; /* Length of buffer read/write (fastpath) */
151
+
152
+ /**
153
+ * Create the Data Packet(Internal)
154
+ */
155
+ this.createPacket = function() {
156
+ /* Building Data Packet */
157
+ this.dataPtr = constants.NSPDADAT;
158
+ this.dataLen = constants.NSPDADAT;
159
+
160
+ this.buf = Buffer.alloc(size);
161
+ this.buf.writeUInt8(0, constants.NSPHDFLGS);
162
+ this.buf.writeUInt8(constants.NSPTDA, constants.NSPHDTYP);
163
+ };
164
+
165
+ /**
166
+ * Populate the Data Packet
167
+ * @param {Buffer} userbuf User Buffer
168
+ * @param {int} offset from which to fill data
169
+ * @param {int} len length of data
170
+ * @returns number of bytes copied
171
+ */
172
+ this.fillBuf = function(userbuf, offset, len, flags = 0) {
173
+ let bytes2Copy;
174
+
175
+ if (!this.buf) {
176
+ this.createPacket();
177
+ }
178
+
179
+ if (len > this.bufLen - this.dataLen) {
180
+ bytes2Copy = this.bufLen - this.dataLen;
181
+ } else {
182
+ bytes2Copy = len;
183
+ }
184
+ if (bytes2Copy) {
185
+ userbuf.copy(this.buf, this.dataLen, offset, offset + bytes2Copy);
186
+ }
187
+ this.dataLen += bytes2Copy;
188
+
189
+ this.prepare2Send(flags);
190
+
191
+ return bytes2Copy;
192
+ };
193
+
194
+ /**
195
+ * Prepare Data Packet for send
196
+ * @param {int} flags Data flags
197
+ */
198
+ this.prepare2Send = function(flags = 0) {
199
+ if (isLargeSDU) {
200
+ this.buf.writeUInt32BE(this.dataLen, constants.NSPHDLEN);
201
+ } else {
202
+ this.buf.writeUInt16BE(this.dataLen, constants.NSPHDLEN);
203
+ }
204
+
205
+ this.buf.writeUInt16BE(flags, constants.NSPDAFLG);
206
+ this.dataBuf = this.buf.subarray(0, this.dataLen);
207
+ };
208
+
209
+ /**
210
+ * Construct Data Packet from receive data
211
+ * @param {Packet} packet NS packet
212
+ */
213
+ this.fromPacket = function(packet) {
214
+ this.buf = packet.buf;
215
+ this.dataLen = packet.buf.length;
216
+ this.dataPtr = constants.NSPDADAT;
217
+ this.offset = this.dataPtr;
218
+ this.len = this.dataLen;
219
+ packet.dataOffset = this.dataPtr;
220
+ };
221
+ }
222
+
223
+ /**
224
+ * Accept Packet (NSPTAC)
225
+ * @param {Packet} packet NS packet
226
+ * @param {*} sAtts session Attributes
227
+ */
228
+ function AcceptPacket(packet, sAtts) {
229
+ this.buf = packet.buf;
230
+ this.len = packet.buf.length;
231
+
232
+ /* Set negotiated values */
233
+ sAtts.version = packet.buf.readUInt16BE(constants.NSPACVSN);
234
+ sAtts.options = packet.buf.readUInt16BE(constants.NSPACOPT);
235
+ sAtts.sdu = packet.buf.readUInt16BE(constants.NSPACSDU);
236
+ sAtts.tdu = packet.buf.readUInt16BE(constants.NSPACTDU);
237
+
238
+ if (sAtts.version >= 315) {
239
+ /* Large SDU Support */
240
+ sAtts.sdu = packet.buf.readUInt32BE(constants.NSPACLSD);
241
+ sAtts.tdu = packet.buf.readUInt32BE(constants.NSPACLTD);
242
+ sAtts.largeSDU = true;
243
+ }
244
+
245
+ /* Accept flags */
246
+ this.flag0 = packet.buf.readUInt8(constants.NSPACFL0);
247
+ this.flag1 = packet.buf.readUInt8(constants.NSPACFL1);
248
+ }
249
+
250
+ /**
251
+ * Refuse Packet
252
+ * @param {*} packet NS packet
253
+ */
254
+ function RefusePacket(packet) {
255
+ this.buf = packet.buf;
256
+ this.len = packet.buf.length;
257
+ this.userReason = packet.buf.readUInt8(constants.NSPRFURS);
258
+ this.systemReason = packet.buf.readUInt8(constants.NSPRFURS);
259
+ this.dataLen = packet.buf.readUInt16BE(constants.NSPRFLEN);
260
+ this.dataOff = constants.NSPRFDAT;
261
+
262
+ if (this.len > this.dataOff) {
263
+ this.dataBuf = this.buf.toString('ascii', this.dataOff, this.len);
264
+ this.overflow = false;
265
+ } else {
266
+ this.overflow = true;
267
+ }
268
+ }
269
+
270
+ /**
271
+ * Redirect Packet (NSPTRD)
272
+ * @param {*} packet NS packet
273
+ */
274
+ function RedirectPacket(packet) {
275
+ this.buf = packet.buf;
276
+ this.len = packet.buf.length;
277
+ this.flags = packet.flags;
278
+ this.dataLen = packet.buf.readUInt16BE(constants.NSPRDLEN);
279
+ this.dataOff = constants.NSPRDDAT;
280
+
281
+ if (this.len > this.dataOff) {
282
+ this.dataBuf = this.buf.subarray(this.dataOff, this.len);
283
+ this.overflow = false;
284
+ } else {
285
+ this.overflow = true;
286
+ }
287
+ }
288
+
289
+ /**
290
+ * Marker Packet (NSPTMK)
291
+ * @param {int} isLargeSDU Large SDU
292
+ */
293
+ function MarkerPacket(isLargeSDU) {
294
+ this.len = constants.NSPMKDAT + 1; /* Packet length */
295
+ this.buf = Buffer.alloc(constants.NSPMKDAT + 1); /* Packet Buffer */
296
+
297
+ if (isLargeSDU) {
298
+ this.buf.writeUInt32BE(this.len, constants.NSPHDLEN);
299
+ } else {
300
+ this.buf.writeUInt16BE(this.len, constants.NSPHDLEN);
301
+ }
302
+ this.buf.writeUInt8(0, constants.NSPHDFLGS);
303
+ this.buf.writeUInt8(constants.NSPTMK, constants.NSPHDTYP);
304
+
305
+ /**
306
+ * Prepare Marker packet for write
307
+ * @param {Uint8} type of Marker
308
+ * @param {Uint8} data Marker byte
309
+ */
310
+ this.prepare = function(type, data) {
311
+ this.buf.writeUInt8(type, constants.NSPMKTYP);
312
+ this.buf.writeUInt8(data, constants.NSPMKDAT);
313
+ };
314
+
315
+ /**
316
+ * Marker Packet receive
317
+ * @param {Packet} packet NS packet
318
+ * @param {NetworkSession} nsi Network Session
319
+ */
320
+ this.fromPacket = function(packet, nsi) {
321
+ this.type = packet.buf.readUInt8(constants.NSPMKTYP);
322
+
323
+ switch (this.type) {
324
+ case constants.NSPMKTD0:
325
+ nsi.isBreak = true;
326
+ break;
327
+ case constants.NSPMKTD1:
328
+ this.data = packet.buf.readUInt8(constants.NSPMKDAT);
329
+ nsi.isBreak = true;
330
+ if (this.data == constants.NIQRMARK) {
331
+ nsi.isReset = true;
332
+ nsi.isBreak = true;
333
+ }
334
+ break;
335
+ default:
336
+ errors.throwErr(errors.ERR_INVALID_PACKET);
337
+ }
338
+ };
339
+ }
340
+
341
+ /**
342
+ * Control Packet NSPTCTL
343
+ */
344
+
345
+ function ControlPacket() {
346
+ /**
347
+ * Clear(reset) the packet
348
+ */
349
+ this.clear = function() {
350
+ this.errno = 0;
351
+ this.notif = null;
352
+ this.notifLen = 0;
353
+ this.cmd = 0;
354
+ };
355
+
356
+ /**
357
+ * Control Packet receive
358
+ * @param {*} packet NS packet
359
+ */
360
+ this.fromPacket = function(packet) {
361
+ const NSECMANSHUT = 12572; // CMAN SHUTDOWN
362
+ const NSESENDMESG = 12573; // SEND MESSAGE
363
+ const ORA_ERROR_EMFI_NUMBER = 22; //ORA -error
364
+ let emfi;
365
+ let err1;
366
+ let err2;
367
+
368
+ this.cmd = packet.buf.readUInt16BE(constants.NSPCTLCMD);
369
+ switch (this.cmd) {
370
+ case constants.NSPCTL_SERR:
371
+ emfi = packet.buf.readUInt32BE(constants.NSPCTLDAT);
372
+ err1 = packet.buf.readUInt32BE(constants.NSPCTLDAT + 4);
373
+ err2 = packet.buf.readUInt32BE(constants.NSPCTLDAT + 8);
374
+
375
+ if (err1 == NSECMANSHUT) {
376
+ this.errno = err1;
377
+ } else if (err1 == NSESENDMESG) {
378
+ this.errno = err1;
379
+ this.notifLen = err2;
380
+ this.notif = Buffer.alloc(err2 + 1);
381
+ this.buf.copy(this.notif, 0, constants.NSPCTLDAT + 12, constants.NSPCTLDAT + 12 + err2);
382
+ } else {
383
+ this.errno = err1;
384
+ if (emfi == ORA_ERROR_EMFI_NUMBER) {
385
+ errors.throwErr(errors.ERR_CONNECTION_INBAND, "ORA" + "-" + err1);
386
+ } else {
387
+ errors.throwErr(errors.ERR_CONNECTION_INBAND, "TNS" + "-" + err1);
388
+ }
389
+ }
390
+ break;
391
+ default:
392
+ errors.throwErr(errors.ERR_INVALID_PACKET);
393
+ }
394
+ };
395
+ }
396
+
397
+ module.exports = {
398
+ ConnectPacket,
399
+ DataPacket,
400
+ AcceptPacket,
401
+ RefusePacket,
402
+ RedirectPacket,
403
+ MarkerPacket,
404
+ ControlPacket
405
+ };
@@ -0,0 +1,205 @@
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 {createNVPair, findValue} = require("./nvStrToNvPair.js");
30
+ const fs = require('fs');
31
+ const readline = require('readline');
32
+ const errors = require("../../errors.js");
33
+
34
+ /**
35
+ * Returns File path of the tnsnames.ora if it exists.
36
+ */
37
+ function tnsnamesFilePath(configDir) {
38
+ let filePathVal = null;
39
+ let tnsAdminVal = process.env.TNS_ADMIN;
40
+ if (configDir) {
41
+ filePathVal = configDir + '/tnsnames.ora';
42
+ if (fs.existsSync(filePathVal)) {
43
+ return filePathVal;
44
+ } else {
45
+ errors.throwErr(errors.ERR_TNS_NAMES_FILE_MISSING, configDir);
46
+ }
47
+ } else {
48
+ if (!tnsAdminVal) {
49
+ errors.throwErr(errors.ERR_NO_CONFIG_DIR);
50
+ } else {
51
+ filePathVal = tnsAdminVal;
52
+ filePathVal += '/tnsnames.ora';
53
+ if (!fs.existsSync(filePathVal)) {
54
+ errors.throwErr(errors.ERR_TNS_NAMES_FILE_MISSING, tnsAdminVal);
55
+ }
56
+ }
57
+ return filePathVal;
58
+ }
59
+ }
60
+
61
+ let prevmtime = 0;
62
+
63
+ class NLParamParser {
64
+ /**
65
+ * Reads the given file line by line and stores the
66
+ * network service names mapped to connect descriptors in the hashtable.
67
+ * @param {string} file_path
68
+ * @returns {Promise}
69
+ */
70
+ async initializeNlpa(file_path) {
71
+ let stat = fs.statSync(file_path);
72
+
73
+ if (!(stat.mtime - prevmtime)) {
74
+ /* File has been read */
75
+ return this.ht;
76
+ }
77
+
78
+ // Creating a readable stream from file
79
+ // readline module reads line by line
80
+ // but from a readable stream only.
81
+ const file = readline.createInterface({
82
+ input: fs.createReadStream(file_path),
83
+ output: process.stdout,
84
+ terminal: false
85
+ });
86
+ this.ht = new Map();
87
+
88
+ const start = async () =>{
89
+ let nvElem = "";
90
+ for await (let line of file) {
91
+ if (line.length == 0) { // ignore empty lines
92
+ continue;
93
+ } else if (line[0] == '#') { // comment line
94
+ continue;
95
+ } else if ((line[0] == ' ') || // continued input on new line
96
+ (line[0] == '\t') ||
97
+ (line[0] == ')') ||
98
+ (line[0] == '(')) {
99
+ line = line.replace(/\s+/g, '');
100
+ line = this.checkNLPforComments(line);
101
+ if (line.length == 0)
102
+ continue;
103
+ else {
104
+ nvElem = nvElem + line;
105
+ }
106
+
107
+ } else { // new NV Element starting here
108
+ if (nvElem.length == 0) {
109
+
110
+ line = this.checkNLPforComments(line);
111
+ nvElem = nvElem + line;
112
+
113
+ } else if (nvElem.length != 0) {
114
+ this.addNLPListElement(nvElem); // Add Parameter to Hashtable
115
+ nvElem = ""; // Clear first, before storing current line
116
+
117
+ line = this.checkNLPforComments(line);
118
+ nvElem = nvElem + line;
119
+ }
120
+ }
121
+ }
122
+ if (nvElem.length != 0) { // at eof, still one more parameter to read
123
+ this.addNLPListElement(nvElem);
124
+ nvElem = ""; // clear nvElem buffer after added
125
+ }
126
+ prevmtime = stat.mtime;
127
+ return this.ht;
128
+ };
129
+ return await start();
130
+ }
131
+
132
+ /**
133
+ * Given a string, this method looks if the '#' character is present.
134
+ * If true, the line is truncated from that point onwards until the end
135
+ * of the line; else, the original line is returned unchanged.
136
+ *
137
+ * @param str The String that is going to be tested for inline comments
138
+ * @return String The modified String returned
139
+ */
140
+ checkNLPforComments(str) {
141
+ let str1 = new Array(str.length);
142
+
143
+ for (let i = 0; i < str.length; i++) {
144
+ let current_char = str[i];
145
+ if (current_char == '#') {
146
+ if (i != 0) {
147
+ break; // No need to continue. Return the line
148
+ } else {
149
+ // Entire line is a comment
150
+ return "";
151
+ }
152
+ } else
153
+ str1.push(current_char);
154
+ }
155
+ return str1.join('');
156
+ }
157
+ /**
158
+ * adds name value pairs from the input buffer into the hash table.
159
+ * @param {string} ibuf
160
+ */
161
+ addNLPListElement(ibuf) {
162
+ let res = ibuf.split(/\r?\n/).filter(element => element);
163
+ for (let i = 0; i < res.length; i++) {
164
+ if (res[i].charAt(0) != '(') {
165
+ res[i] = '(' + res[i];
166
+ }
167
+ if (res[i].charAt(res[i].length - 1 != ')')) {
168
+ res[i] = res[i] + ')';
169
+ }
170
+ let nvp = createNVPair(res[i]);
171
+ let name = nvp.name;
172
+ let uname = name.toUpperCase();
173
+ nvp.name = uname;
174
+ this.add_NLPListElement(uname, nvp);
175
+ }
176
+ }
177
+
178
+ add_NLPListElement(name, value) {
179
+ this.ht.set(name, value);
180
+ }
181
+
182
+ toString() {
183
+ let out = "";
184
+ this.ht.forEach((value) => {
185
+ out = out + value.toString() + "\n";
186
+ });
187
+ return out;
188
+ }
189
+ /**
190
+ * if key is address/port then it returns the port value from the
191
+ * address NVPAIR.
192
+ * @param {string} key
193
+ * @returns {string}
194
+ */
195
+ findValueOf(key) {
196
+ let myarr = key.split('/');
197
+ return (findValue(this.ht.get(myarr[0].toUpperCase()), myarr));
198
+ }
199
+
200
+ }
201
+
202
+ module.exports = {
203
+ NLParamParser,
204
+ tnsnamesFilePath
205
+ };