oracledb 6.0.3 → 6.2.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 (65) hide show
  1. package/README.md +2 -2
  2. package/build/Release/oracledb-6.2.0-darwin-x64.node +0 -0
  3. package/build/Release/oracledb-6.2.0-darwin-x64.node-buildinfo.txt +1 -0
  4. package/build/Release/oracledb-6.2.0-js-buildinfo.txt +1 -0
  5. package/build/Release/oracledb-6.2.0-linux-arm64.node +0 -0
  6. package/build/Release/oracledb-6.2.0-linux-arm64.node-buildinfo.txt +1 -0
  7. package/build/Release/oracledb-6.2.0-linux-x64.node +0 -0
  8. package/build/Release/oracledb-6.2.0-linux-x64.node-buildinfo.txt +1 -0
  9. package/build/Release/oracledb-6.2.0-win32-x64.node +0 -0
  10. package/build/Release/oracledb-6.2.0-win32-x64.node-buildinfo.txt +1 -0
  11. package/examples/dbconfig.js +7 -14
  12. package/examples/example.js +0 -1
  13. package/lib/aqQueue.js +40 -26
  14. package/lib/connection.js +16 -4
  15. package/lib/dbObject.js +9 -0
  16. package/lib/errors.js +17 -13
  17. package/lib/impl/connection.js +9 -0
  18. package/lib/impl/resultset.js +7 -4
  19. package/lib/oracledb.js +26 -18
  20. package/lib/pool.js +7 -1
  21. package/lib/sodaCollection.js +12 -1
  22. package/lib/sodaOperation.js +16 -0
  23. package/lib/thin/connection.js +229 -182
  24. package/lib/thin/dbObject.js +4 -1
  25. package/lib/thin/pool.js +153 -68
  26. package/lib/thin/protocol/buffer.js +83 -64
  27. package/lib/thin/protocol/constants.js +3 -14
  28. package/lib/thin/protocol/encryptDecrypt.js +17 -17
  29. package/lib/thin/protocol/messages/auth.js +21 -23
  30. package/lib/thin/protocol/messages/base.js +29 -45
  31. package/lib/thin/protocol/messages/connectionCookie.js +76 -0
  32. package/lib/thin/protocol/messages/dataType.js +13 -9
  33. package/lib/thin/protocol/messages/execute.js +7 -7
  34. package/lib/thin/protocol/messages/index.js +2 -0
  35. package/lib/thin/protocol/messages/protocol.js +31 -20
  36. package/lib/thin/protocol/messages/withData.js +58 -47
  37. package/lib/thin/protocol/oson.js +17 -14
  38. package/lib/thin/protocol/packet.js +36 -14
  39. package/lib/thin/protocol/utils.js +2 -2
  40. package/lib/thin/resultSet.js +6 -6
  41. package/lib/thin/sqlnet/connStrategy.js +130 -5
  42. package/lib/thin/sqlnet/constants.js +2 -0
  43. package/lib/thin/sqlnet/ezConnectResolver.js +29 -61
  44. package/lib/thin/sqlnet/navNodes.js +34 -27
  45. package/lib/thin/sqlnet/networkSession.js +46 -47
  46. package/lib/thin/sqlnet/ntTcp.js +30 -14
  47. package/lib/thin/sqlnet/nvStrToNvPair.js +16 -16
  48. package/lib/thin/sqlnet/packet.js +10 -3
  49. package/lib/thin/sqlnet/paramParser.js +9 -9
  50. package/lib/thin/sqlnet/sessionAtts.js +4 -0
  51. package/lib/thin/statement.js +345 -113
  52. package/lib/thin/util.js +23 -86
  53. package/lib/transformer.js +3 -1
  54. package/lib/util.js +4 -13
  55. package/lib/version.js +2 -2
  56. package/package.json +1 -1
  57. package/build/Release/oracledb-6.0.3-darwin-x64.node +0 -0
  58. package/build/Release/oracledb-6.0.3-darwin-x64.node-buildinfo.txt +0 -1
  59. package/build/Release/oracledb-6.0.3-js-buildinfo.txt +0 -1
  60. package/build/Release/oracledb-6.0.3-linux-arm64.node +0 -0
  61. package/build/Release/oracledb-6.0.3-linux-arm64.node-buildinfo.txt +0 -1
  62. package/build/Release/oracledb-6.0.3-linux-x64.node +0 -0
  63. package/build/Release/oracledb-6.0.3-linux-x64.node-buildinfo.txt +0 -1
  64. package/build/Release/oracledb-6.0.3-win32-x64.node +0 -0
  65. package/build/Release/oracledb-6.0.3-win32-x64.node-buildinfo.txt +0 -1
package/lib/thin/pool.js CHANGED
@@ -36,6 +36,7 @@ const thinUtil = require('./util.js');
36
36
  const {getConnectionInfo} = require('./sqlnet/networkSession.js');
37
37
  const crypto = require('crypto');
38
38
  const EventEmitter = require('events');
39
+ const Timers = require('timers');
39
40
 
40
41
  class ThinPoolImpl extends PoolImpl {
41
42
 
@@ -69,30 +70,33 @@ class ThinPoolImpl extends PoolImpl {
69
70
  this._privateKey = params.privateKey;
70
71
  this._obfuscatedPrivateKey = [];
71
72
  this._schedulerJob = null;
73
+ this._poolCloseWaiter = null;
74
+ this._pendingRequests = [];
75
+
72
76
  // password obfuscation
73
77
  if (this._password !== undefined) {
74
- let obj = protocolUtil.setObfuscatedValue(this._password);
78
+ const obj = protocolUtil.setObfuscatedValue(this._password);
75
79
  this._password = obj.value;
76
80
  this._obfuscatedPassword = obj.obfuscatedValue;
77
81
  this._userConfig.password = null;
78
82
  }
79
83
  // wallet password obfuscation
80
84
  if (this._walletPassword !== undefined) {
81
- let obj = protocolUtil.setObfuscatedValue(this._walletPassword);
85
+ const obj = protocolUtil.setObfuscatedValue(this._walletPassword);
82
86
  this._walletPassword = obj.value;
83
87
  this._obfuscatedWalletPassword = obj.obfuscatedValue;
84
88
  this._userConfig.walletPassword = null;
85
89
  }
86
90
  // token obfuscation
87
91
  if (this._token !== undefined) {
88
- let obj = protocolUtil.setObfuscatedValue(this._token);
92
+ const obj = protocolUtil.setObfuscatedValue(this._token);
89
93
  this._token = obj.value;
90
94
  this._obfuscatedToken = obj.obfuscatedValue;
91
95
  this._userConfig.token = null;
92
96
  }
93
97
  // privateKey obfuscation
94
98
  if (this._privateKey !== undefined) {
95
- let obj = protocolUtil.setObfuscatedValue(this._privateKey);
99
+ const obj = protocolUtil.setObfuscatedValue(this._privateKey);
96
100
  this._privateKey = obj.value;
97
101
  this._obfuscatedPrivateKey = obj.obfuscatedValue;
98
102
  this._userConfig.privateKey = null;
@@ -121,8 +125,9 @@ class ThinPoolImpl extends PoolImpl {
121
125
  this._generateConnectionClass();
122
126
  }
123
127
 
124
- // create minimum connections
125
- await this._growPool(this._poolMin);
128
+ // create a background task. It will create minimum connections in the pool
129
+ // and expand the pool as required.
130
+ this.bgThreadFunc();
126
131
  }
127
132
 
128
133
  //---------------------------------------------------------------------------
@@ -131,13 +136,13 @@ class ThinPoolImpl extends PoolImpl {
131
136
  setAccessToken(params) {
132
137
  if (params.token) {
133
138
  this._token = params.token;
134
- let objToken = protocolUtil.setObfuscatedValue(this._token);
139
+ const objToken = protocolUtil.setObfuscatedValue(this._token);
135
140
  this._token = objToken.value;
136
141
  this._obfuscatedToken = objToken.obfuscatedValue;
137
142
  }
138
143
  if (params.privateKey) {
139
144
  this._privateKey = params.privateKey;
140
- let objKey = protocolUtil.setObfuscatedValue(this._privateKey);
145
+ const objKey = protocolUtil.setObfuscatedValue(this._privateKey);
141
146
  this._privateKey = objKey.value;
142
147
  this._obfuscatedPrivateKey = objKey.obfuscatedValue;
143
148
  }
@@ -151,15 +156,21 @@ class ThinPoolImpl extends PoolImpl {
151
156
  async _getConnAttrs() {
152
157
  let accessToken;
153
158
  const clonedAttrs = Object.assign({}, this._userConfig);
159
+ // deobfuscate password
154
160
  if (clonedAttrs.password === null) {
155
161
  clonedAttrs.password = protocolUtil.getDeobfuscatedValue(this._password,
156
162
  this._obfuscatedPassword);
157
163
  }
164
+
165
+ // deobfuscate wallet password
158
166
  if (clonedAttrs.walletPassword === null) {
159
167
  clonedAttrs.walletPassword =
160
168
  protocolUtil.getDeobfuscatedValue(this._walletPassword,
161
169
  this._obfuscatedWalletPassword);
162
170
  }
171
+
172
+ // deobfuscate token and private key
173
+ // check for token expiry
163
174
  if (clonedAttrs.token === null) {
164
175
  clonedAttrs.token =
165
176
  protocolUtil.getDeobfuscatedValue(this._token, this._obfuscatedToken);
@@ -173,7 +184,7 @@ class ThinPoolImpl extends PoolImpl {
173
184
  errors.throwErr(errors.ERR_TOKEN_HAS_EXPIRED);
174
185
  } else {
175
186
  // update pool with OAuth2 token
176
- let obj = protocolUtil.setObfuscatedValue(clonedAttrs.token);
187
+ const obj = protocolUtil.setObfuscatedValue(clonedAttrs.token);
177
188
  this._token = obj.value;
178
189
  this._obfuscatedToken = obj.obfuscatedValue;
179
190
  }
@@ -185,11 +196,11 @@ class ThinPoolImpl extends PoolImpl {
185
196
  errors.throwErr(errors.ERR_TOKEN_HAS_EXPIRED);
186
197
  } else {
187
198
  // update pool with IAM token and private key
188
- let objToken = protocolUtil.setObfuscatedValue(clonedAttrs.token);
199
+ const objToken = protocolUtil.setObfuscatedValue(clonedAttrs.token);
189
200
  this._token = objToken.value;
190
201
  this._obfuscatedToken = objToken.obfuscatedValue;
191
202
 
192
- let objKey = protocolUtil.setObfuscatedValue(clonedAttrs.privateKey);
203
+ const objKey = protocolUtil.setObfuscatedValue(clonedAttrs.privateKey);
193
204
  this._privateKey = objKey.value;
194
205
  this._obfuscatedPrivateKey = objKey.obfuscatedValue;
195
206
  }
@@ -228,13 +239,34 @@ class ThinPoolImpl extends PoolImpl {
228
239
  //---------------------------------------------------------------------------
229
240
  // close pool by destroying available connections
230
241
  //---------------------------------------------------------------------------
231
- async close(obj) {
242
+ async close() {
243
+
244
+ // wait till background task for pool expansion is finished; if it is not
245
+ // currently running, wake it up!
246
+ await new Promise((resolve) => {
247
+ this._poolCloseWaiter = resolve;
248
+ if (this.bgWaiter) {
249
+ this.bgWaiter();
250
+ }
251
+ });
252
+
232
253
  // clear scheduled job
233
254
  if (this._schedulerJob) {
234
255
  clearTimeout(this._schedulerJob);
235
256
  this._schedulerJob = null;
236
257
  }
237
- return await this.destroyAllNow(obj);
258
+
259
+ // destroy all free connections
260
+ for (const conn of this._freeConnectionList) {
261
+ await this._destroy(conn);
262
+ }
263
+
264
+ // destroy all used connections
265
+ for (const conn of this._usedConnectionList) {
266
+ await this._destroy(conn);
267
+ }
268
+
269
+ this.eventEmitter.removeAllListeners();
238
270
  }
239
271
 
240
272
  //---------------------------------------------------------------------------
@@ -307,25 +339,6 @@ class ThinPoolImpl extends PoolImpl {
307
339
  return this._stmtCacheSize;
308
340
  }
309
341
 
310
- //---------------------------------------------------------------------------
311
- // _growPool()
312
- //
313
- // Grows the pool to include the specified number of connections.
314
- //---------------------------------------------------------------------------
315
- async _growPool(numConns) {
316
- const clonedAttrs = await this._getConnAttrs();
317
- while (numConns > 0) {
318
- const conn = new ThinConnectionImpl();
319
- conn._pool = this;
320
- await conn.connect(clonedAttrs);
321
- conn._newSession = true;
322
- conn._dropSess = false;
323
- conn._lastTimeUsed = Date.now();
324
- this._freeConnectionList.push(conn);
325
- numConns--;
326
- }
327
- }
328
-
329
342
  //---------------------------------------------------------------------------
330
343
  // _setScheduler()
331
344
  //
@@ -363,6 +376,94 @@ class ThinPoolImpl extends PoolImpl {
363
376
  this._setScheduler();
364
377
  }
365
378
 
379
+ //---------------------------------------------------------------------------
380
+ // _getNumConns()
381
+ //
382
+ // get number of connections need to be created
383
+ //---------------------------------------------------------------------------
384
+ _getNumConns() {
385
+ const usedConns = this._freeConnectionList.length + this._usedConnectionList.size;
386
+ // less connections in the pool than poolMin? restore to poolMin
387
+ if (usedConns < this._poolMin) {
388
+ return this._poolMin - usedConns;
389
+ // connections need to be created? create up to poolIncrement without exceeding poolMax
390
+ } else if (this._pendingRequests.length > 0) {
391
+ return Math.min(this._poolIncrement, this._poolMax - usedConns);
392
+ // no pending requests and we are already at poolMin so nothing to do!
393
+ } else {
394
+ return 0;
395
+ }
396
+ }
397
+
398
+ //---------------------------------------------------------------------------
399
+ // bgThreadFunc()
400
+ //
401
+ // method which runs in a background thread and is used to create connections.
402
+ // When first started, it creates poolMin connections. After that, it creates
403
+ // poolIncrement connections up to the value of poolMax when needed.
404
+ // The thread terminates automatically when the pool is closed.
405
+ //---------------------------------------------------------------------------
406
+ async bgThreadFunc() {
407
+
408
+ // continue until a close request is received
409
+ while (!this._poolCloseWaiter) {
410
+ // get count for connections to be created
411
+ const numConns = this._getNumConns();
412
+
413
+ // connection creation is going on serially and not concurrently
414
+ for (let i = 0; i < numConns; i++) {
415
+ try {
416
+ // get deobfuscated value
417
+ const config = await this._getConnAttrs();
418
+ const conn = new ThinConnectionImpl();
419
+ conn._pool = this;
420
+ await conn.connect(config);
421
+ conn._newSession = true;
422
+ conn._dropSess = false;
423
+ conn._lastTimeUsed = Date.now();
424
+ this._freeConnectionList.push(conn);
425
+ } catch (err) {
426
+ this._bgErr = err;
427
+ }
428
+
429
+ if (this._poolIncrement > 1 && (this._poolMax - this._usedConnectionList.size
430
+ - this._freeConnectionList.length) > 1) {
431
+ this._setScheduler();
432
+ }
433
+
434
+ // resolve pending request
435
+ if (this._pendingRequests.length > 0) {
436
+ const payload = this._pendingRequests.shift();
437
+ payload.resolve();
438
+ }
439
+
440
+ // give an opportunity for other "threads" to do their work.
441
+ await new Promise((resolve) => Timers.setImmediate(resolve));
442
+
443
+ // break loop when pool is closing
444
+ if (this._poolCloseWaiter) {
445
+ break;
446
+ }
447
+ }
448
+
449
+ // when pool is closing, break from while loop
450
+ if (this._poolCloseWaiter) {
451
+ break;
452
+ }
453
+
454
+ // if no pending requests, wait for pending requests to appear!
455
+ if (this._pendingRequests.length == 0 || this._bgErr) {
456
+ await new Promise((resolve) => {
457
+ this.bgWaiter = resolve;
458
+ });
459
+ this.bgWaiter = null;
460
+ }
461
+ }
462
+
463
+ // notify the closer that the close can actually take place
464
+ this._poolCloseWaiter();
465
+ }
466
+
366
467
  //---------------------------------------------------------------------------
367
468
  // acquire()
368
469
  //
@@ -410,17 +511,28 @@ class ThinPoolImpl extends PoolImpl {
410
511
 
411
512
  // no free connections exist at this point; if less than poolMin
412
513
  // connections exist, grow the pool to poolMin again; otherwise, increase
413
- // the pool by poolIncrement up to poolMax
414
- if (this._usedConnectionList.size < this._poolMin) {
415
- await this._growPool(this._poolMin - this._usedConnectionList.size);
416
- } else {
417
- const sizeAvailable = this._poolMax - this._usedConnectionList.size;
418
- await this._growPool(Math.min(this._poolIncrement, sizeAvailable));
419
- if (this._poolIncrement > 1 && sizeAvailable > 1) {
420
- this._setScheduler();
514
+ // the pool by poolIncrement up to poolMax. We are deferring this
515
+ // to the background thread function!
516
+ await new Promise((resolve) => {
517
+ this._pendingRequests.push({resolve: resolve});
518
+ if (this.bgWaiter) {
519
+ // this wakes up the function to do some more work
520
+ this.bgWaiter();
421
521
  }
422
- }
522
+ });
523
+
524
+ if (this._bgErr) {
525
+ const err = this._bgErr;
526
+ this._bgErr = null;
423
527
 
528
+ // if an error has occurred in the background thread we clear it and then,
529
+ // if there are more pending requests we request the background thread
530
+ // function to try again.
531
+ if (this._pendingRequests.length > 0 && this.bgWaiter) {
532
+ this.bgWaiter();
533
+ }
534
+ throw err;
535
+ }
424
536
  // return a connection from the ones that were just built
425
537
  const conn = this._freeConnectionList.pop();
426
538
  this._usedConnectionList.add(conn);
@@ -438,33 +550,6 @@ class ThinPoolImpl extends PoolImpl {
438
550
  this._setScheduler();
439
551
  }
440
552
 
441
- //---------------------------------------------------------------------------
442
- // destroyAllNow()
443
- //
444
- // called during pool close operation and close any available connection
445
- // available in connection pool
446
- //---------------------------------------------------------------------------
447
- async destroyAllNow(obj) {
448
- let conn;
449
- while (this._freeConnectionList.length !== 0) {
450
- conn = this._freeConnectionList.pop();
451
- await this._destroy(conn);
452
- }
453
-
454
- if (obj.forceClose) {
455
- for (const item of this._usedConnectionList) {
456
- await this._destroy(item);
457
- this._usedConnectionList.delete(item);
458
- }
459
- }
460
-
461
- if (this._usedConnectionList.size !== 0) {
462
- errors.throwErr(errors.ERR_POOL_HAS_BUSY_CONNECTIONS);
463
- }
464
-
465
- this.eventEmitter.removeAllListeners();
466
- }
467
-
468
553
  //---------------------------------------------------------------------------
469
554
  // _generateConnectionClass()
470
555
  //
@@ -49,7 +49,7 @@ class BaseBuffer {
49
49
  this.buf = Buffer.alloc(initializer);
50
50
  this.size = 0;
51
51
  this.maxSize = initializer;
52
- } else {
52
+ } else if (initializer) {
53
53
  this.buf = initializer;
54
54
  this.size = this.maxSize = initializer.length;
55
55
  }
@@ -548,11 +548,12 @@ class BaseBuffer {
548
548
  // remain in the buffer, the buffer is grown.
549
549
  //---------------------------------------------------------------------------
550
550
  reserveBytes(numBytes) {
551
- if (numBytes > this.numBytesLeft())
551
+ if (numBytes > this.numBytesLeft()) {
552
552
  this._grow(this.pos + numBytes);
553
- const buf = this.buf.subarray(this.pos, this.pos + numBytes);
553
+ }
554
+ const pos = this.pos;
554
555
  this.pos += numBytes;
555
- return buf;
556
+ return pos;
556
557
  }
557
558
 
558
559
  //---------------------------------------------------------------------------
@@ -618,20 +619,20 @@ class BaseBuffer {
618
619
  //---------------------------------------------------------------------------
619
620
  writeBinaryDouble(n) {
620
621
  this.writeUInt8(8);
621
- const buf = this.reserveBytes(8);
622
- buf.writeDoubleBE(n);
623
- if ((buf[0] & 0x80) === 0) {
624
- buf[0] |= 0x80;
622
+ const pos = this.reserveBytes(8);
623
+ this.buf.writeDoubleBE(n, pos);
624
+ if ((this.buf[pos] & 0x80) === 0) {
625
+ this.buf[pos] |= 0x80;
625
626
  } else {
626
627
  // We complement the bits for a negative number
627
- buf[0] ^= 0xff;
628
- buf[1] ^= 0xff;
629
- buf[2] ^= 0xff;
630
- buf[3] ^= 0xff;
631
- buf[4] ^= 0xff;
632
- buf[5] ^= 0xff;
633
- buf[6] ^= 0xff;
634
- buf[7] ^= 0xff;
628
+ this.buf[pos] ^= 0xff;
629
+ this.buf[pos + 1] ^= 0xff;
630
+ this.buf[pos + 2] ^= 0xff;
631
+ this.buf[pos + 3] ^= 0xff;
632
+ this.buf[pos + 4] ^= 0xff;
633
+ this.buf[pos + 5] ^= 0xff;
634
+ this.buf[pos + 6] ^= 0xff;
635
+ this.buf[pos + 7] ^= 0xff;
635
636
  }
636
637
  }
637
638
 
@@ -642,16 +643,16 @@ class BaseBuffer {
642
643
  //---------------------------------------------------------------------------
643
644
  writeBinaryFloat(n) {
644
645
  this.writeUInt8(4);
645
- const buf = this.reserveBytes(4);
646
- buf.writeFloatBE(n);
647
- if ((buf[0] & 0x80) === 0) {
648
- buf[0] |= 0x80;
646
+ const pos = this.reserveBytes(4);
647
+ this.buf.writeFloatBE(n, pos);
648
+ if ((this.buf[pos] & 0x80) === 0) {
649
+ this.buf[pos] |= 0x80;
649
650
  } else {
650
651
  // We complement the bits for a negative number
651
- buf[0] ^= 0xff;
652
- buf[1] ^= 0xff;
653
- buf[2] ^= 0xff;
654
- buf[3] ^= 0xff;
652
+ this.buf[pos] ^= 0xff;
653
+ this.buf[pos + 1] ^= 0xff;
654
+ this.buf[pos + 2] ^= 0xff;
655
+ this.buf[pos + 3] ^= 0xff;
655
656
  }
656
657
  }
657
658
 
@@ -745,31 +746,31 @@ class BaseBuffer {
745
746
  if (writeLength) {
746
747
  this.writeUInt8(length);
747
748
  }
748
- const ptr = this.reserveBytes(length);
749
+ const pos = this.reserveBytes(length);
749
750
  if (type === types.DB_TYPE_DATE || type == types.DB_TYPE_TIMESTAMP) {
750
751
  const year = date.getFullYear();
751
- ptr[0] = Math.trunc(year / 100) + 100;
752
- ptr[1] = year % 100 + 100;
753
- ptr[2] = date.getMonth() + 1;
754
- ptr[3] = date.getDate();
755
- ptr[4] = date.getHours() + 1;
756
- ptr[5] = date.getMinutes() + 1;
757
- ptr[6] = date.getSeconds() + 1;
752
+ this.buf[pos] = Math.trunc(year / 100) + 100;
753
+ this.buf[pos + 1] = year % 100 + 100;
754
+ this.buf[pos + 2] = date.getMonth() + 1;
755
+ this.buf[pos + 3] = date.getDate();
756
+ this.buf[pos + 4] = date.getHours() + 1;
757
+ this.buf[pos + 5] = date.getMinutes() + 1;
758
+ this.buf[pos + 6] = date.getSeconds() + 1;
758
759
  } else {
759
760
  const year = date.getUTCFullYear();
760
- ptr[0] = Math.trunc(year / 100) + 100;
761
- ptr[1] = year % 100 + 100;
762
- ptr[2] = date.getUTCMonth() + 1;
763
- ptr[3] = date.getUTCDate();
764
- ptr[4] = date.getUTCHours() + 1;
765
- ptr[5] = date.getUTCMinutes() + 1;
766
- ptr[6] = date.getUTCSeconds() + 1;
761
+ this.buf[pos] = Math.trunc(year / 100) + 100;
762
+ this.buf[pos + 1] = year % 100 + 100;
763
+ this.buf[pos + 2] = date.getUTCMonth() + 1;
764
+ this.buf[pos + 3] = date.getUTCDate();
765
+ this.buf[pos + 4] = date.getUTCHours() + 1;
766
+ this.buf[pos + 5] = date.getUTCMinutes() + 1;
767
+ this.buf[pos + 6] = date.getUTCSeconds() + 1;
767
768
  }
768
769
  if (length > 7) {
769
- ptr.writeInt32BE(fsec, 7);
770
+ this.buf.writeInt32BE(fsec, pos + 7);
770
771
  if (length > 11) {
771
- ptr[11] = constants.TZ_HOUR_OFFSET;
772
- ptr[12] = constants.TZ_MINUTE_OFFSET;
772
+ this.buf[pos + 11] = constants.TZ_HOUR_OFFSET;
773
+ this.buf[pos + 12] = constants.TZ_MINUTE_OFFSET;
773
774
  }
774
775
  }
775
776
  }
@@ -843,19 +844,19 @@ class BaseBuffer {
843
844
  } else if (value.length === 0 && exponent === 0) {
844
845
  exponentOnWire = 128;
845
846
  }
846
- const buf = this.reserveBytes(numPairs + 2 + appendSentinel);
847
- buf[0] = numPairs + 1 + appendSentinel;
848
- buf[1] = exponentOnWire;
849
- for (let i = 0, pos = 2; i < value.length; i += 2, pos++) {
850
- let base100Digit = Number(value.substring(i, i + 2));
847
+ let pos = this.reserveBytes(numPairs + 2 + appendSentinel);
848
+ this.buf[pos++] = numPairs + 1 + appendSentinel;
849
+ this.buf[pos++] = exponentOnWire;
850
+ for (let i = 0; i < value.length; i += 2) {
851
+ const base100Digit = Number(value.substring(i, i + 2));
851
852
  if (isNegative) {
852
- buf[pos] = 101 - base100Digit;
853
+ this.buf[pos++] = 101 - base100Digit;
853
854
  } else {
854
- buf[pos] = base100Digit + 1;
855
+ this.buf[pos++] = base100Digit + 1;
855
856
  }
856
857
  }
857
858
  if (appendSentinel) {
858
- buf[buf.length - 1] = 102;
859
+ this.buf[pos] = 102;
859
860
  }
860
861
 
861
862
  }
@@ -898,8 +899,8 @@ class BaseBuffer {
898
899
  // Writes a signed 32-bit integer to the buffer in big endian order.
899
900
  //---------------------------------------------------------------------------
900
901
  writeInt32BE(n) {
901
- const buf = this.reserveBytes(4);
902
- buf.writeInt32BE(n);
902
+ const pos = this.reserveBytes(4);
903
+ this.buf.writeInt32BE(n, pos);
903
904
  }
904
905
 
905
906
  //---------------------------------------------------------------------------
@@ -923,6 +924,24 @@ class BaseBuffer {
923
924
  }
924
925
  }
925
926
 
927
+ //---------------------------------------------------------------------------
928
+ // writeUB2()
929
+ //
930
+ // Writes an unsigned integer (up to 2 bytes in length) in variable length
931
+ // format to the buffer.
932
+ //---------------------------------------------------------------------------
933
+ writeUB2(value) {
934
+ if (value === 0) {
935
+ this.writeUInt8(0);
936
+ } else if (value <= 0xff) {
937
+ this.writeUInt8(1);
938
+ this.writeUInt8(value);
939
+ } else {
940
+ this.writeUInt8(2);
941
+ this.writeUInt16BE(value);
942
+ }
943
+ }
944
+
926
945
  //---------------------------------------------------------------------------
927
946
  // writeUB8()
928
947
  //
@@ -953,8 +972,8 @@ class BaseBuffer {
953
972
  // Writes an unsigned 8-bit integer to the buffer.
954
973
  //---------------------------------------------------------------------------
955
974
  writeUInt8(n) {
956
- const buf = this.reserveBytes(1);
957
- buf[0] = n;
975
+ const pos = this.reserveBytes(1);
976
+ this.buf[pos] = n;
958
977
  }
959
978
 
960
979
  //---------------------------------------------------------------------------
@@ -963,8 +982,8 @@ class BaseBuffer {
963
982
  // Writes an unsigned 16-bit integer to the buffer in big endian order.
964
983
  //---------------------------------------------------------------------------
965
984
  writeUInt16BE(n) {
966
- const buf = this.reserveBytes(2);
967
- buf.writeUInt16BE(n);
985
+ const pos = this.reserveBytes(2);
986
+ this.buf.writeUInt16BE(n, pos);
968
987
  }
969
988
 
970
989
  //---------------------------------------------------------------------------
@@ -973,8 +992,8 @@ class BaseBuffer {
973
992
  // Writes an unsigned 32-bit integer to the buffer in big endian order.
974
993
  //---------------------------------------------------------------------------
975
994
  writeUInt32BE(n) {
976
- const buf = this.reserveBytes(4);
977
- buf.writeUInt32BE(n);
995
+ const pos = this.reserveBytes(4);
996
+ this.buf.writeUInt32BE(n, pos);
978
997
  }
979
998
 
980
999
  //---------------------------------------------------------------------------
@@ -985,9 +1004,9 @@ class BaseBuffer {
985
1004
  // higher order bits are simply written as 0.
986
1005
  //---------------------------------------------------------------------------
987
1006
  writeUInt64BE(n) {
988
- const buf = this.reserveBytes(8);
989
- buf.writeUInt32BE(0);
990
- buf.writeUInt32BE(n, 4);
1007
+ const pos = this.reserveBytes(8);
1008
+ this.buf.writeUInt32BE(0, pos);
1009
+ this.buf.writeUInt32BE(n, pos + 4);
991
1010
  }
992
1011
 
993
1012
  //---------------------------------------------------------------------------
@@ -996,8 +1015,8 @@ class BaseBuffer {
996
1015
  // Writes an unsigned 16-bit integer to the buffer in little endian order.
997
1016
  //---------------------------------------------------------------------------
998
1017
  writeUInt16LE(n) {
999
- const buf = this.reserveBytes(2);
1000
- buf.writeUInt16LE(n);
1018
+ const pos = this.reserveBytes(2);
1019
+ this.buf.writeUInt16LE(n, pos);
1001
1020
  }
1002
1021
 
1003
1022
  }
@@ -1030,7 +1049,7 @@ class GrowableBuffer extends BaseBuffer {
1030
1049
  if (remainder > 0) {
1031
1050
  numBytes += (constants.BUFFER_CHUNK_SIZE - remainder);
1032
1051
  }
1033
- const buf = Buffer.alloc(numBytes);
1052
+ const buf = Buffer.allocUnsafe(numBytes);
1034
1053
  this.buf.copy(buf);
1035
1054
  this.buf = buf;
1036
1055
  this.maxSize = this.size = numBytes;
@@ -89,10 +89,6 @@ module.exports = {
89
89
  TNS_PACKET_TYPE_MARKER: 12,
90
90
  TNS_PACKET_TYPE_CONTROL: 14,
91
91
 
92
- // marker types
93
- TNS_MARKER_TYPE_BREAK: 1,
94
- TNS_MARKER_TYPE_RESET: 2,
95
-
96
92
  // data types
97
93
  TNS_DATA_TYPE_DEFAULT: 0,
98
94
  TNS_DATA_TYPE_VARCHAR: 1,
@@ -429,8 +425,10 @@ module.exports = {
429
425
  TNS_MSG_TYPE_FLUSH_OUT_BINDS: 19,
430
426
  TNS_MSG_TYPE_BIT_VECTOR: 21,
431
427
  TNS_MSG_TYPE_SERVER_SIDE_PIGGYBACK: 23,
432
- TNS_MSG_TYPE_IMPLICIT_RESULTSET: 27,
433
428
  TNS_MSG_TYPE_ONEWAY_FN: 26,
429
+ TNS_MSG_TYPE_IMPLICIT_RESULTSET: 27,
430
+ TNS_MSG_TYPE_RENEGOTIATE: 28,
431
+ TNS_MSG_TYPE_COOKIE: 30,
434
432
 
435
433
  // parameter keyword numbers,
436
434
  TNS_KEYWORD_NUM_CURRENT_SCHEMA: 168,
@@ -557,18 +555,9 @@ module.exports = {
557
555
  TNS_END_TO_END_MODULE: 0x0008,
558
556
 
559
557
  // versions
560
- TNS_VERSION_DESIRED: 316,
561
- TNS_VERSION_MINIMUM: 300,
562
558
  TNS_VERSION_MIN_ACCEPTED: 315,
563
559
  TNS_VERSION_MIN_LARGE_SDU: 315,
564
560
 
565
- // other connection constants
566
- TNS_SERVICE_OPTIONS: 0xc01,
567
- TNS_PROTOCOL_CHARACTERISTICS: 0x4f98,
568
- TNS_CONNECT_FLAGS: 0x8080,
569
- TNS_CAN_RECV_ATTENTION: 0x0400,
570
- TNS_CHECK_OOB: 0x01,
571
-
572
561
  // TTC functions
573
562
  TNS_FUNC_AUTH_PHASE_ONE: 118,
574
563
  TNS_FUNC_AUTH_PHASE_TWO: 115,