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,1040 @@
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 constants = require("./constants.js");
30
+ const errors = require("../../errors.js");
31
+ const settings = require("../../settings.js");
32
+ const types = require("../../types.js");
33
+
34
+ /**
35
+ * Base buffer class used for managing buffered data without unnecessary
36
+ * copying.
37
+ */
38
+ class BaseBuffer {
39
+
40
+ //---------------------------------------------------------------------------
41
+ // constructor()
42
+ //
43
+ // The initializer is either an integer specifying the size of the buffer, or
44
+ // an existing Buffer, which is used directly.
45
+ //---------------------------------------------------------------------------
46
+ constructor(initializer) {
47
+ if (typeof initializer === 'number') {
48
+ this.buf = Buffer.alloc(initializer);
49
+ this.size = 0;
50
+ this.maxSize = initializer;
51
+ } else {
52
+ this.buf = initializer;
53
+ this.size = this.maxSize = initializer.length;
54
+ }
55
+ this.pos = 0;
56
+ }
57
+
58
+ //---------------------------------------------------------------------------
59
+ // _grow()
60
+ //
61
+ // Called when the buffer needs to grow. The base function simply raises an
62
+ // error.
63
+ //---------------------------------------------------------------------------
64
+ _grow(numBytes) {
65
+ errors.throwErr(errors.ERR_BUFFER_LENGTH_INSUFFICIENT, this.numBytesLeft(),
66
+ numBytes);
67
+ }
68
+
69
+ //---------------------------------------------------------------------------
70
+ // _readBytesWithLength()
71
+ //
72
+ // Helper function that processes the number of bytes (if needed) and then
73
+ // acquires the specified number of bytes from the buffer. The base function
74
+ // simply uses the length as given.
75
+ //---------------------------------------------------------------------------
76
+ _readBytesWithLength(numBytes) {
77
+ return this.readBytes(numBytes);
78
+ }
79
+
80
+ //---------------------------------------------------------------------------
81
+ // _readInteger()
82
+ //
83
+ // Read an integer from the buffer of the specified maximum size and returns
84
+ // it. The signed flag indicates whether the value is allowed to be signed or
85
+ // not and the skip flag indicates whether the data should simply be skipped.
86
+ //---------------------------------------------------------------------------
87
+ _readInteger(maxSize, signed, skip) {
88
+ let isNegative = false;
89
+ let size = this.readUInt8();
90
+ if (size === 0) {
91
+ return 0;
92
+ } else if (size & 0x80) {
93
+ if (!signed) {
94
+ errors.throwErr(errors.ERR_UNEXPECTED_NEGATIVE_INTEGER);
95
+ }
96
+ isNegative = true;
97
+ size = size & 0x7f;
98
+ }
99
+ if (size > maxSize) {
100
+ errors.throwErr(errors.ERR_INTEGER_TOO_LARGE, size, maxSize);
101
+ }
102
+ if (skip) {
103
+ this.skipBytes(size);
104
+ } else {
105
+ const buf = this.readBytes(size);
106
+ const value = buf.readUIntBE(0, size);
107
+ return (isNegative) ? -value : value;
108
+ }
109
+ }
110
+
111
+ //---------------------------------------------------------------------------
112
+ // numBytesLeft()
113
+ //
114
+ // Returns the number of bytes that are remaining in the buffer.
115
+ //---------------------------------------------------------------------------
116
+ numBytesLeft() {
117
+ return this.size - this.pos;
118
+ }
119
+
120
+ //---------------------------------------------------------------------------
121
+ // parseBinaryDouble()
122
+ //
123
+ // Parses a binary double from the supplied buffer and returns a Number.
124
+ // It is assumed at this point that the size of the buffer is 8 bytes. A copy
125
+ // is made of the buffer in order to ensure that the original buffer is not
126
+ // modified. If it is and data spans multiple packets, incorrect data may be
127
+ // returned!
128
+ //---------------------------------------------------------------------------
129
+ parseBinaryDouble(buf) {
130
+ buf = Buffer.from(buf);
131
+ if (buf[0] & 0x80) {
132
+ buf[0] &= 0x7f;
133
+ } else {
134
+ // complement the bits for a negative number
135
+ buf[0] ^= 0xff;
136
+ buf[1] ^= 0xff;
137
+ buf[2] ^= 0xff;
138
+ buf[3] ^= 0xff;
139
+ buf[4] ^= 0xff;
140
+ buf[5] ^= 0xff;
141
+ buf[6] ^= 0xff;
142
+ buf[7] ^= 0xff;
143
+ }
144
+ return buf.readDoubleBE();
145
+ }
146
+
147
+ //---------------------------------------------------------------------------
148
+ // parseBinaryFloat()
149
+ //
150
+ // Parses a binary float from the supplied buffer and returns a Number. It
151
+ // is assumed at this point that the size of the buffer is 4 bytes. A copy is
152
+ // made of the buffer in order to ensure that the original buffer is not
153
+ // modified. If it is and data spans multiple packets, incorrect data may be
154
+ // returned!
155
+ //---------------------------------------------------------------------------
156
+ parseBinaryFloat(buf) {
157
+ buf = Buffer.from(buf);
158
+ if (buf[0] & 0x80) {
159
+ buf[0] &= 0x7f;
160
+ } else {
161
+ // complement the bits for a negative number
162
+ buf[0] ^= 0xff;
163
+ buf[1] ^= 0xff;
164
+ buf[2] ^= 0xff;
165
+ buf[3] ^= 0xff;
166
+ }
167
+ return buf.readFloatBE();
168
+ }
169
+
170
+ //---------------------------------------------------------------------------
171
+ // parseOracleDate()
172
+ //
173
+ // Parses an Oracle date from the supplied buffer and returns a Date. It is
174
+ // assumed at this point that the size of the buffer is either 7 bytes (date
175
+ // or compressed timestamp), 11 bytes (timestamp) or 13 bytes (timestamp with
176
+ // time zone). Time zone information is discarded because Node.js uses UTC
177
+ // timestamps and the server returns the data in that format, too. The Date
178
+ // type in Node.js doesn't support time zone information.
179
+ //---------------------------------------------------------------------------
180
+ parseOracleDate(buf, useLocalTime = true) {
181
+ let fseconds = 0;
182
+ if (buf.length >= 11) {
183
+ fseconds = Math.floor(buf.readUInt32BE(7) / (1000 * 1000));
184
+ }
185
+ const year = (buf[0] - 100) * 100 + buf[1] - 100;
186
+ return settings._makeDate(useLocalTime, year, buf[2], buf[3], buf[4] - 1,
187
+ buf[5] - 1, buf[6] - 1, fseconds, 0);
188
+ }
189
+
190
+ //---------------------------------------------------------------------------
191
+ // parseOracleNumber()
192
+ //
193
+ // Parses an Oracle number from the supplied buffer and returns a Number. It
194
+ // is assumed at this point that the buffer only contains the encoded numeric
195
+ // data.
196
+ //---------------------------------------------------------------------------
197
+ parseOracleNumber(buf) {
198
+
199
+ // the first byte is the exponent; positive numbers have the highest
200
+ // order bit set, whereas negative numbers have the highest order bit
201
+ // cleared and the bits inverted
202
+ let exponent = buf[0];
203
+ const isPositive = Boolean(exponent & 0x80);
204
+ if (!isPositive) {
205
+ exponent = (exponent ^ 0xFF);
206
+ }
207
+ exponent -= 193;
208
+ let decimalPointIndex = exponent * 2 + 2;
209
+
210
+ // a mantissa length of 0 implies a value of 0 (if positive) or a value
211
+ // of -1e126 (if negative)
212
+ if (buf.length === 1) {
213
+ if (isPositive) {
214
+ return "0";
215
+ }
216
+ return "-1e126";
217
+ }
218
+
219
+ // check for the trailing 102 byte for negative numbers and, if present,
220
+ // reduce the number of mantissa digits
221
+ let numBytes = buf.length;
222
+ if (!isPositive && buf[buf.length - 1] === 102) {
223
+ numBytes -= 1;
224
+ }
225
+
226
+ // process the mantissa bytes which are the remaining bytes; each
227
+ // mantissa byte is a base-100 digit
228
+ let base100Digit;
229
+ const digits = [];
230
+ for (let i = 1; i < numBytes; i++) {
231
+
232
+ // positive numbers have 1 added to them; negative numbers are
233
+ // subtracted from the value 101
234
+ if (isPositive) {
235
+ base100Digit = buf[i] - 1;
236
+ } else {
237
+ base100Digit = 101 - buf[i];
238
+ }
239
+
240
+ // process the first digit; leading zeroes are ignored
241
+ let digit = Math.floor(base100Digit / 10);
242
+ if (digit === 0 && i === 1) {
243
+ decimalPointIndex -= 1;
244
+ } else if (digit === 10) {
245
+ digits.push("1");
246
+ digits.push("0");
247
+ decimalPointIndex += 1;
248
+ } else if (digit !== 0 || i > 1) {
249
+ digits.push(digit.toString());
250
+ }
251
+
252
+ // process the second digit; trailing zeroes are ignored
253
+ digit = base100Digit % 10;
254
+ if (digit !== 0 || i < numBytes - 1) {
255
+ digits.push(digit.toString());
256
+ }
257
+ }
258
+
259
+ // create string of digits for transformation to JS value
260
+ const chars = [];
261
+
262
+ // if negative, include the sign
263
+ if (!isPositive) {
264
+ chars.push("-");
265
+ }
266
+
267
+ // if the decimal point index is 0 or less, add the decimal point and
268
+ // any leading zeroes that are needed
269
+ if (decimalPointIndex <= 0) {
270
+ chars.push(".");
271
+ if (decimalPointIndex < 0)
272
+ chars.push("0".repeat(-decimalPointIndex));
273
+ }
274
+
275
+ // add each of the digits
276
+ for (let i = 0; i < digits.length; i++) {
277
+ if (i > 0 && i === decimalPointIndex) {
278
+ chars.push(".");
279
+ }
280
+ chars.push(digits[i]);
281
+ }
282
+
283
+ // if the decimal point index exceeds the number of digits, add any
284
+ // trailing zeroes that are needed
285
+ if (decimalPointIndex > digits.length) {
286
+ for (let i = digits.length; i < decimalPointIndex; i++) {
287
+ chars.push("0");
288
+ }
289
+ }
290
+
291
+ // convert result to a Number
292
+ return chars.join("");
293
+ }
294
+
295
+ //---------------------------------------------------------------------------
296
+ // readBinaryDouble()
297
+ //
298
+ // Reads a binary double value from the buffer and returns a Number or a
299
+ // String, depending on the desired type.
300
+ //---------------------------------------------------------------------------
301
+ readBinaryDouble() {
302
+ const buf = this.readBytesWithLength();
303
+ if (!buf) {
304
+ return null;
305
+ }
306
+ return this.parseBinaryDouble(buf);
307
+ }
308
+
309
+ //---------------------------------------------------------------------------
310
+ // readBinaryFloat()
311
+ //
312
+ // Reads a binary float value from the buffer and returns a Number or a
313
+ // String, depending on the desired type.
314
+ //---------------------------------------------------------------------------
315
+ readBinaryFloat() {
316
+ const buf = this.readBytesWithLength();
317
+ if (!buf) {
318
+ return null;
319
+ }
320
+ return this.parseBinaryFloat(buf);
321
+ }
322
+
323
+ //---------------------------------------------------------------------------
324
+ // readBool()
325
+ //
326
+ // Reads a boolean value from the buffer and returns a Boolean.
327
+ //---------------------------------------------------------------------------
328
+ readBool() {
329
+ const buf = this.readBytesWithLength();
330
+ if (!buf) {
331
+ return null;
332
+ }
333
+ return (buf[buf.length - 1] === 1);
334
+ }
335
+
336
+ //---------------------------------------------------------------------------
337
+ // readBytes()
338
+ //
339
+ // Returns a Buffer containing the specified number of bytes. If an
340
+ // insufficient number of bytes are available an error is thrown.
341
+ //---------------------------------------------------------------------------
342
+ readBytes(numBytes) {
343
+ const numBytesLeft = this.numBytesLeft();
344
+ if (numBytes > numBytesLeft) {
345
+ errors.throwErr(errors.ERR_UNEXPECTED_END_OF_DATA, numBytes,
346
+ numBytesLeft);
347
+ }
348
+ const buf = this.buf.subarray(this.pos, this.pos + numBytes);
349
+ this.pos += numBytes;
350
+ return buf;
351
+ }
352
+
353
+ //---------------------------------------------------------------------------
354
+ // readBytesWithLength()
355
+ //
356
+ // Reads the length from the buffer and then returns a Buffer containing the
357
+ // specified number of bytes. If the length is 0 or the special null length
358
+ // indicator value, null is returned instead.
359
+ //---------------------------------------------------------------------------
360
+ readBytesWithLength() {
361
+ const numBytes = this.readUInt8();
362
+ if (numBytes === 0 || numBytes === constants.TNS_NULL_LENGTH_INDICATOR)
363
+ return null;
364
+ return this._readBytesWithLength(numBytes);
365
+ }
366
+
367
+ //---------------------------------------------------------------------------
368
+ // readDbObject()
369
+ //
370
+ // Reads a database object from the buffer and returns the implementation
371
+ // object (or null, if the object is atomically null).
372
+ //---------------------------------------------------------------------------
373
+ readDbObject() {
374
+ const obj = {};
375
+ let numBytes = this.readUB4();
376
+ if (numBytes > 0)
377
+ obj.toid = this.readBytesWithLength();
378
+ numBytes = this.readUB4();
379
+ if (numBytes > 0)
380
+ obj.oid = this.readBytesWithLength();
381
+ numBytes = this.readUB4();
382
+ if (numBytes > 0)
383
+ obj.snapshot = this.readBytesWithLength();
384
+ this.skipUB2(); // version
385
+ numBytes = this.readUB4();
386
+ this.skipUB2(); // flags
387
+ if (numBytes > 0)
388
+ obj.packedData = this.readBytesWithLength();
389
+ return obj;
390
+ }
391
+
392
+ //---------------------------------------------------------------------------
393
+ // readInt8()
394
+ //
395
+ // Reads a signed 8-bit integer from the buffer.
396
+ //---------------------------------------------------------------------------
397
+ readInt8() {
398
+ const buf = this.readBytes(1);
399
+ return buf.readInt8();
400
+ }
401
+
402
+ //---------------------------------------------------------------------------
403
+ // readOracleDate()
404
+ //
405
+ // Reads an Oracle date from the buffer and returns a Date or a String,
406
+ // depending on the desired type.
407
+ //---------------------------------------------------------------------------
408
+ readOracleDate(useLocalTime) {
409
+ const buf = this.readBytesWithLength();
410
+ if (!buf) {
411
+ return null;
412
+ }
413
+ return this.parseOracleDate(buf, useLocalTime);
414
+ }
415
+
416
+ //---------------------------------------------------------------------------
417
+ // readOracleNumber()
418
+ //
419
+ // Reads an Oracle number from the buffer and returns a Number or a String,
420
+ // depending on the desired type.
421
+ //---------------------------------------------------------------------------
422
+ readOracleNumber() {
423
+ const buf = this.readBytesWithLength();
424
+ if (!buf) {
425
+ return null;
426
+ }
427
+ return this.parseOracleNumber(buf);
428
+ }
429
+
430
+ //---------------------------------------------------------------------------
431
+ // readSB2()
432
+ //
433
+ // Reads a signed, variable length integer of up to 2 bytes in length.
434
+ //---------------------------------------------------------------------------
435
+ readSB2() {
436
+ return this._readInteger(2, true, false);
437
+ }
438
+
439
+ //---------------------------------------------------------------------------
440
+ // readSB4()
441
+ //
442
+ // Reads a signed, variable length integer of up to 4 bytes in length.
443
+ //---------------------------------------------------------------------------
444
+ readSB4() {
445
+ return this._readInteger(4, true, false);
446
+ }
447
+
448
+ //---------------------------------------------------------------------------
449
+ // readSB8()
450
+ //
451
+ // Reads a signed, variable length integer of up to 8 bytes in length.
452
+ //---------------------------------------------------------------------------
453
+ readSB8() {
454
+ return this._readInteger(8, true, false);
455
+ }
456
+
457
+ //---------------------------------------------------------------------------
458
+ // readStr()
459
+ //
460
+ // Reads a string from the buffer in the specified character set form.
461
+ //---------------------------------------------------------------------------
462
+ readStr(csfrm) {
463
+ const buf = this.readBytesWithLength();
464
+ if (!buf) {
465
+ return null;
466
+ }
467
+ if (csfrm === constants.TNS_CS_IMPLICIT)
468
+ return buf.toString();
469
+
470
+ // need a copy of the buffer since swap16() changes the buffer in place and
471
+ // it is possible that the buffer may need to be rescanned (for the case
472
+ // where insufficient packets are available during the initial scan)
473
+ return Buffer.from(buf).swap16().toString('utf16le');
474
+ }
475
+
476
+ //---------------------------------------------------------------------------
477
+ // readUB2()
478
+ //
479
+ // Reads an unsigned, variable length integer of up to 2 bytes in length.
480
+ //---------------------------------------------------------------------------
481
+ readUB2() {
482
+ return this._readInteger(2, false, false);
483
+ }
484
+
485
+ //---------------------------------------------------------------------------
486
+ // readUB4()
487
+ //
488
+ // Reads an unsigned, variable length integer of up to 4 bytes in length.
489
+ //---------------------------------------------------------------------------
490
+ readUB4() {
491
+ return this._readInteger(4, false, false);
492
+ }
493
+
494
+ //---------------------------------------------------------------------------
495
+ // readUB8()
496
+ //
497
+ // Reads an unsigned, variable length integer of up to 8 bytes in length.
498
+ //---------------------------------------------------------------------------
499
+ readUB8() {
500
+ return this._readInteger(8, false, false);
501
+ }
502
+
503
+ //---------------------------------------------------------------------------
504
+ // readUInt8()
505
+ //
506
+ // Reads an unsigned 8-bit integer from the buffer.
507
+ //---------------------------------------------------------------------------
508
+ readUInt8() {
509
+ const buf = this.readBytes(1);
510
+ return buf[0];
511
+ }
512
+
513
+ //---------------------------------------------------------------------------
514
+ // readUInt16BE()
515
+ //
516
+ // Reads an unsigned 16-bit integer from the buffer in big endian order.
517
+ //---------------------------------------------------------------------------
518
+ readUInt16BE() {
519
+ const buf = this.readBytes(2);
520
+ return buf.readUInt16BE();
521
+ }
522
+
523
+ //---------------------------------------------------------------------------
524
+ // readUInt16LE()
525
+ //
526
+ // Reads an unsigned 16-bit integer from the buffer in little endian order.
527
+ //---------------------------------------------------------------------------
528
+ readUInt16LE() {
529
+ const buf = this.readBytes(2);
530
+ return buf.readUInt16LE();
531
+ }
532
+
533
+ //---------------------------------------------------------------------------
534
+ // readUInt32BE()
535
+ //
536
+ // Reads an unsigned 32-bit integer from the buffer in big endian order.
537
+ //---------------------------------------------------------------------------
538
+ readUInt32BE() {
539
+ const buf = this.readBytes(4);
540
+ return buf.readUInt32BE();
541
+ }
542
+
543
+ //---------------------------------------------------------------------------
544
+ // reserveBytes()
545
+ //
546
+ // Reserves the specified number of bytes in the buffer. If not enough bytes
547
+ // remain in the buffer, the buffer is grown.
548
+ //---------------------------------------------------------------------------
549
+ reserveBytes(numBytes) {
550
+ if (numBytes > this.numBytesLeft())
551
+ this._grow(this.pos + numBytes);
552
+ const buf = this.buf.subarray(this.pos, this.pos + numBytes);
553
+ this.pos += numBytes;
554
+ return buf;
555
+ }
556
+
557
+ //---------------------------------------------------------------------------
558
+ // skipBytes()
559
+ //
560
+ // Skips the specified number of bytes in the buffer.
561
+ //---------------------------------------------------------------------------
562
+ skipBytes(numBytes) {
563
+ if (numBytes > this.numBytesLeft())
564
+ errors.throwErr(errors.ERR_UNEXPECTED_END_OF_DATA);
565
+ this.pos += numBytes;
566
+ }
567
+
568
+ //---------------------------------------------------------------------------
569
+ // skipSB4()
570
+ //
571
+ // Skips a signed, variable length integer of up to 4 bytes in length.
572
+ //---------------------------------------------------------------------------
573
+ skipSB4() {
574
+ return this._readInteger(4, true, true);
575
+ }
576
+
577
+ //---------------------------------------------------------------------------
578
+ // skipUB1()
579
+ //
580
+ // Skips a single byte integer in the buffer.
581
+ //---------------------------------------------------------------------------
582
+ skipUB1() {
583
+ this.skipBytes(1);
584
+ }
585
+
586
+ //---------------------------------------------------------------------------
587
+ // skipUB2()
588
+ //
589
+ // Skips an unsigned, variable length integer of up to 2 bytes in length.
590
+ //---------------------------------------------------------------------------
591
+ skipUB2() {
592
+ return this._readInteger(2, false, true);
593
+ }
594
+
595
+ //---------------------------------------------------------------------------
596
+ // skipUB4()
597
+ //
598
+ // Skips an unsigned, variable length integer of up to 4 bytes in length.
599
+ //---------------------------------------------------------------------------
600
+ skipUB4() {
601
+ return this._readInteger(4, false, true);
602
+ }
603
+
604
+ //---------------------------------------------------------------------------
605
+ // skipUB8()
606
+ //
607
+ // Skips an unsigned, variable length integer of up to 8 bytes in length.
608
+ //---------------------------------------------------------------------------
609
+ skipUB8() {
610
+ return this._readInteger(8, false, true);
611
+ }
612
+
613
+ //---------------------------------------------------------------------------
614
+ // writeBinaryDouble()
615
+ //
616
+ // Writes the number in binary double format to the buffer.
617
+ //---------------------------------------------------------------------------
618
+ writeBinaryDouble(n) {
619
+ this.writeUInt8(8);
620
+ const buf = this.reserveBytes(8);
621
+ buf.writeDoubleBE(n);
622
+ if ((buf[0] & 0x80) === 0) {
623
+ buf[0] |= 0x80;
624
+ } else {
625
+ // We complement the bits for a negative number
626
+ buf[0] ^= 0xff;
627
+ buf[1] ^= 0xff;
628
+ buf[2] ^= 0xff;
629
+ buf[3] ^= 0xff;
630
+ buf[4] ^= 0xff;
631
+ buf[5] ^= 0xff;
632
+ buf[6] ^= 0xff;
633
+ buf[7] ^= 0xff;
634
+ }
635
+ }
636
+
637
+ //---------------------------------------------------------------------------
638
+ // writeBinaryFloat()
639
+ //
640
+ // Writes the number in binary float format to the buffer.
641
+ //---------------------------------------------------------------------------
642
+ writeBinaryFloat(n) {
643
+ this.writeUInt8(4);
644
+ const buf = this.reserveBytes(4);
645
+ buf.writeFloatBE(n);
646
+ if ((buf[0] & 0x80) === 0) {
647
+ buf[0] |= 0x80;
648
+ } else {
649
+ // We complement the bits for a negative number
650
+ buf[0] ^= 0xff;
651
+ buf[1] ^= 0xff;
652
+ buf[2] ^= 0xff;
653
+ buf[3] ^= 0xff;
654
+ }
655
+ }
656
+
657
+ //---------------------------------------------------------------------------
658
+ // writeBytes()
659
+ //
660
+ // Writes the bytes in the supplied buffer to the buffer.
661
+ //---------------------------------------------------------------------------
662
+ writeBytes(value) {
663
+ let start = 0;
664
+ let valueLen = value.length;
665
+ while (valueLen > 0) {
666
+ const bytesLeft = this.numBytesLeft();
667
+ if (bytesLeft === 0) {
668
+ this._grow(this.pos + valueLen);
669
+ }
670
+ const bytesToWrite = Math.min(bytesLeft, valueLen);
671
+ value.copy(this.buf, this.pos, start, start + bytesToWrite);
672
+ this.pos += bytesToWrite;
673
+ start += bytesToWrite;
674
+ valueLen -= bytesToWrite;
675
+ }
676
+ }
677
+
678
+ //---------------------------------------------------------------------------
679
+ // writeBytesWithLength()
680
+ //
681
+ // Writes the bytes in the supplied buffer to the buffer, but first writes
682
+ // the length. If the length exceeds a fixed value, the value is written in
683
+ // chunks instead.
684
+ //---------------------------------------------------------------------------
685
+ writeBytesWithLength(value) {
686
+ let numBytes = value.length;
687
+ if (numBytes <= constants.TNS_MAX_SHORT_LENGTH) {
688
+ this.writeUInt8(numBytes);
689
+ this.writeBytes(value);
690
+ } else {
691
+ let start = 0;
692
+ this.writeUInt8(constants.TNS_LONG_LENGTH_INDICATOR);
693
+ while (numBytes > 0) {
694
+ const chunkLen = Math.min(numBytes, constants.BUFFER_CHUNK_SIZE);
695
+ this.writeUB4(chunkLen);
696
+ this.writeBytes(value.subarray(start, start + chunkLen));
697
+ numBytes -= chunkLen;
698
+ start += chunkLen;
699
+ }
700
+ this.writeUB4(0);
701
+ }
702
+ }
703
+
704
+ //---------------------------------------------------------------------------
705
+ // writeDbObject()
706
+ //
707
+ // Writes a database object to the buffer.
708
+ //---------------------------------------------------------------------------
709
+ writeDbObject(obj) {
710
+ this.writeUB4(obj.toid.length);
711
+ this.writeBytesWithLength(obj.toid);
712
+ if (obj.oid) {
713
+ this.writeUB4(obj.oid.length);
714
+ this.writeBytesWithLength(obj.oid);
715
+ } else {
716
+ this.writeUB4(0);
717
+ }
718
+ this.writeUB4(0); // snapshot
719
+ this.writeUB4(0); // version
720
+ const packedData = obj._getPackedData();
721
+ this.writeUB4(packedData.length);
722
+ this.writeUB4(obj.flags);
723
+ this.writeBytesWithLength(packedData);
724
+ }
725
+
726
+ //---------------------------------------------------------------------------
727
+ // writeOracleDate()
728
+ //
729
+ // Writes the date to the buffer using the given Oracle type. Note that if a
730
+ // timestamp with zero milliseconds is written, the type is automatically
731
+ // changed to DB_TYPE_DATE (except for DB_TYPE_TIMESTAMP_TZ which requires
732
+ // the full amount to be written).
733
+ //---------------------------------------------------------------------------
734
+ writeOracleDate(date, type, writeLength = true) {
735
+ let fsec;
736
+ let length = type._bufferSizeFactor;
737
+ if (length > 7) {
738
+ fsec = date.getUTCMilliseconds() * 1000 * 1000;
739
+ if (fsec === 0 && length <= 11)
740
+ length = 7;
741
+ }
742
+ if (writeLength) {
743
+ this.writeUInt8(length);
744
+ }
745
+ const ptr = this.reserveBytes(length);
746
+ if (type === types.DB_TYPE_DATE || type == types.DB_TYPE_TIMESTAMP) {
747
+ const year = date.getFullYear();
748
+ ptr[0] = Math.floor(year / 100) + 100;
749
+ ptr[1] = year % 100 + 100;
750
+ ptr[2] = date.getMonth() + 1;
751
+ ptr[3] = date.getDate();
752
+ ptr[4] = date.getHours() + 1;
753
+ ptr[5] = date.getMinutes() + 1;
754
+ ptr[6] = date.getSeconds() + 1;
755
+ } else {
756
+ const year = date.getUTCFullYear();
757
+ ptr[0] = Math.floor(year / 100) + 100;
758
+ ptr[1] = year % 100 + 100;
759
+ ptr[2] = date.getUTCMonth() + 1;
760
+ ptr[3] = date.getUTCDate();
761
+ ptr[4] = date.getUTCHours() + 1;
762
+ ptr[5] = date.getUTCMinutes() + 1;
763
+ ptr[6] = date.getUTCSeconds() + 1;
764
+ }
765
+ if (length > 7) {
766
+ ptr.writeInt32BE(fsec, 7);
767
+ if (length > 11) {
768
+ ptr[11] = constants.TZ_HOUR_OFFSET;
769
+ ptr[12] = constants.TZ_MINUTE_OFFSET;
770
+ }
771
+ }
772
+ }
773
+
774
+ //---------------------------------------------------------------------------
775
+ // writeOracleNumber()
776
+ //
777
+ // Writes the number (in string form) in Oracle Number format to the buffer.
778
+ //---------------------------------------------------------------------------
779
+ writeOracleNumber(value) {
780
+
781
+ // determine if number is negative
782
+ let isNegative = false;
783
+ if (value[0] === '-') {
784
+ isNegative = true;
785
+ value = value.substring(1);
786
+ }
787
+
788
+ // parse the exponent, if one is present
789
+ let exponent = 0;
790
+ const exponentPos = value.indexOf('e');
791
+ if (exponentPos > 0) {
792
+ exponent = Number(value.substring(exponentPos + 1));
793
+ value = value.substring(0, exponentPos);
794
+ }
795
+
796
+ // adjust the exponent and the value if there is a decimal point
797
+ const decimalPos = value.indexOf('.');
798
+ if (decimalPos > 0) {
799
+ exponent -= (value.length - decimalPos - 1);
800
+ value = value.substring(0, decimalPos) + value.substring(decimalPos + 1);
801
+ }
802
+
803
+ // strip any leading zeroes
804
+ if (value[0] === '0') {
805
+ value = value.replace(/^0+/, "");
806
+ }
807
+
808
+ // strip any trailing zeroes
809
+ if (value.length > 0 && value[value.length - 1] === '0') {
810
+ const trimmedValue = value.replace(/0+$/, "");
811
+ exponent += (value.length - trimmedValue.length);
812
+ value = trimmedValue;
813
+ }
814
+
815
+ // throw exception if number cannot be represented as an Oracle Number
816
+ if (value.length > constants.NUMBER_MAX_DIGITS || exponent > 126 ||
817
+ exponent < -129) {
818
+ errors.throwErr(errors.ERR_ORACLE_NUMBER_NO_REPR);
819
+ }
820
+
821
+ // if the exponent is odd, append a zero
822
+ if ((exponent > 0 && exponent % 2 === 1) ||
823
+ (exponent < 0 && exponent % 2 === -1)) {
824
+ exponent--;
825
+ value += "0";
826
+ }
827
+
828
+ // add a leading zero if the number of digits is odd
829
+ if (value.length % 2 === 1) {
830
+ value = "0" + value;
831
+ }
832
+
833
+ // write the encoded data to the wire
834
+ const appendSentinel =
835
+ (isNegative && value.length < constants.NUMBER_MAX_DIGITS);
836
+ const numPairs = value.length / 2;
837
+ let exponentOnWire = ((exponent + value.length) / 2) + 192;
838
+ if (isNegative) {
839
+ exponentOnWire = (exponentOnWire ^ 0xFF);
840
+ } else if (value.length === 0 && exponent === 0) {
841
+ exponentOnWire = 128;
842
+ }
843
+ const buf = this.reserveBytes(numPairs + 2 + appendSentinel);
844
+ buf[0] = numPairs + 1 + appendSentinel;
845
+ buf[1] = exponentOnWire;
846
+ for (let i = 0, pos = 2; i < value.length; i += 2, pos++) {
847
+ let base100Digit = Number(value.substring(i, i + 2));
848
+ if (isNegative) {
849
+ buf[pos] = 101 - base100Digit;
850
+ } else {
851
+ buf[pos] = base100Digit + 1;
852
+ }
853
+ }
854
+ if (appendSentinel) {
855
+ buf[buf.length - 1] = 102;
856
+ }
857
+
858
+ }
859
+
860
+ //---------------------------------------------------------------------------
861
+ // writeQLocator()
862
+ //
863
+ // Writes a QLocator. QLocators are always 40 bytes in length.
864
+ //---------------------------------------------------------------------------
865
+ writeQLocator(numBytes) {
866
+ this.writeUB4(40); // QLocator length
867
+ this.writeUInt8(40); // repeated length
868
+ this.writeUInt16BE(38); // internal length
869
+ this.writeUInt16BE(constants.TNS_LOB_QLOCATOR_VERSION);
870
+ this.writeUInt8(constants.TNS_LOB_LOC_FLAGS_VALUE_BASED |
871
+ constants.TNS_LOB_LOC_FLAGS_BLOB | constants.TNS_LOB_LOC_FLAGS_ABSTRACT);
872
+ this.writeUInt8(constants.TNS_LOB_LOC_FLAGS_INIT);
873
+ this.writeUInt16BE(0); // additional flags
874
+ this.writeUInt16BE(1); // byt1
875
+ this.writeUInt64BE(numBytes);
876
+ this.writeUInt16BE(0); // unused
877
+ this.writeUInt16BE(0); // csid
878
+ this.writeUInt16BE(0); // unused
879
+ this.writeUInt64BE(0); // unused
880
+ this.writeUInt64BE(0); // unused
881
+ }
882
+
883
+ //---------------------------------------------------------------------------
884
+ // writeStr()
885
+ //
886
+ // Writes the string to the buffer.
887
+ //---------------------------------------------------------------------------
888
+ writeStr(s) {
889
+ this.writeBytes(Buffer.from(s));
890
+ }
891
+
892
+ //---------------------------------------------------------------------------
893
+ // writeInt32BE()
894
+ //
895
+ // Writes a signed 32-bit integer to the buffer in big endian order.
896
+ //---------------------------------------------------------------------------
897
+ writeInt32BE(n) {
898
+ const buf = this.reserveBytes(4);
899
+ buf.writeInt32BE(n);
900
+ }
901
+
902
+ //---------------------------------------------------------------------------
903
+ // writeUB4()
904
+ //
905
+ // Writes an unsigned integer (up to 4 bytes in length) in variable length
906
+ // format to the buffer.
907
+ //---------------------------------------------------------------------------
908
+ writeUB4(value) {
909
+ if (value === 0) {
910
+ this.writeUInt8(0);
911
+ } else if (value <= 0xff) {
912
+ this.writeUInt8(1);
913
+ this.writeUInt8(value);
914
+ } else if (value <= 0xffff) {
915
+ this.writeUInt8(2);
916
+ this.writeUInt16BE(value);
917
+ } else {
918
+ this.writeUInt8(4);
919
+ this.writeUInt32BE(value);
920
+ }
921
+ }
922
+
923
+ //---------------------------------------------------------------------------
924
+ // writeUB8()
925
+ //
926
+ // Writes an unsigned integer (up to 8 bytes in length) in variable length
927
+ // format to the buffer.
928
+ //---------------------------------------------------------------------------
929
+ writeUB8(value) {
930
+ if (value === 0) {
931
+ this.writeUInt8(0);
932
+ } else if (value <= 0xff) {
933
+ this.writeUInt8(1);
934
+ this.writeUInt8(value);
935
+ } else if (value <= 0xffff) {
936
+ this.writeUInt8(2);
937
+ this.writeUInt16BE(value);
938
+ } else if (value <= 0xffffffff) {
939
+ this.writeUInt8(4);
940
+ this.writeUInt32BE(value);
941
+ } else {
942
+ this.writeUInt8(8);
943
+ this.writeUInt64BE(value);
944
+ }
945
+ }
946
+
947
+ //---------------------------------------------------------------------------
948
+ // writeUInt8()
949
+ //
950
+ // Writes an unsigned 8-bit integer to the buffer.
951
+ //---------------------------------------------------------------------------
952
+ writeUInt8(n) {
953
+ const buf = this.reserveBytes(1);
954
+ buf[0] = n;
955
+ }
956
+
957
+ //---------------------------------------------------------------------------
958
+ // writeUInt16BE()
959
+ //
960
+ // Writes an unsigned 16-bit integer to the buffer in big endian order.
961
+ //---------------------------------------------------------------------------
962
+ writeUInt16BE(n) {
963
+ const buf = this.reserveBytes(2);
964
+ buf.writeUInt16BE(n);
965
+ }
966
+
967
+ //---------------------------------------------------------------------------
968
+ // writeUInt32BE()
969
+ //
970
+ // Writes an unsigned 32-bit integer to the buffer in big endian order.
971
+ //---------------------------------------------------------------------------
972
+ writeUInt32BE(n) {
973
+ const buf = this.reserveBytes(4);
974
+ buf.writeUInt32BE(n);
975
+ }
976
+
977
+ //---------------------------------------------------------------------------
978
+ // writeUInt64BE()
979
+ //
980
+ // Writes an unsigned 64-bit integer to the buffer in big endian order. Since
981
+ // Node.js doesn't support anything above 32-bits without using BigInt, the
982
+ // higher order bits are simply written as 0.
983
+ //---------------------------------------------------------------------------
984
+ writeUInt64BE(n) {
985
+ const buf = this.reserveBytes(8);
986
+ buf.writeUInt32BE(0);
987
+ buf.writeUInt32BE(n);
988
+ }
989
+
990
+ //---------------------------------------------------------------------------
991
+ // writeUInt16LE()
992
+ //
993
+ // Writes an unsigned 16-bit integer to the buffer in little endian order.
994
+ //---------------------------------------------------------------------------
995
+ writeUInt16LE(n) {
996
+ const buf = this.reserveBytes(2);
997
+ buf.writeUInt16LE(n);
998
+ }
999
+
1000
+ }
1001
+
1002
+ class GrowableBuffer extends BaseBuffer {
1003
+
1004
+ //---------------------------------------------------------------------------
1005
+ // constructor()
1006
+ //
1007
+ // Initializes the buffer with an initial fixed chunk size.
1008
+ //---------------------------------------------------------------------------
1009
+ constructor(initializer) {
1010
+ if (initializer) {
1011
+ super(initializer);
1012
+ } else {
1013
+ super(constants.BUFFER_CHUNK_SIZE);
1014
+ this.size = this.maxSize;
1015
+ }
1016
+ }
1017
+
1018
+ //---------------------------------------------------------------------------
1019
+ // _grow()
1020
+ //
1021
+ // Called when the buffer needs to grow. Ensures that sufficient space is
1022
+ // allocated to include the requested number of bytes, rounded to the nearest
1023
+ // chunk size.
1024
+ //---------------------------------------------------------------------------
1025
+ _grow(numBytes) {
1026
+ const remainder = numBytes % constants.BUFFER_CHUNK_SIZE;
1027
+ if (remainder > 0) {
1028
+ numBytes += (constants.BUFFER_CHUNK_SIZE - remainder);
1029
+ }
1030
+ const buf = Buffer.alloc(numBytes);
1031
+ this.buf.copy(buf);
1032
+ this.buf = buf;
1033
+ this.maxSize = this.size = numBytes;
1034
+ }
1035
+ }
1036
+
1037
+ module.exports = {
1038
+ BaseBuffer,
1039
+ GrowableBuffer
1040
+ };