oracledb 6.3.0 → 6.4.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 (58) hide show
  1. package/LICENSE.txt +1 -1
  2. package/NOTICE.txt +1 -1
  3. package/README.md +3 -3
  4. package/build/Release/oracledb-6.4.0-darwin-x64.node +0 -0
  5. package/build/Release/oracledb-6.4.0-darwin-x64.node-buildinfo.txt +1 -0
  6. package/build/Release/oracledb-6.4.0-js-buildinfo.txt +1 -0
  7. package/build/Release/oracledb-6.4.0-linux-arm64.node +0 -0
  8. package/build/Release/oracledb-6.4.0-linux-arm64.node-buildinfo.txt +1 -0
  9. package/build/Release/oracledb-6.4.0-linux-x64.node +0 -0
  10. package/build/Release/oracledb-6.4.0-linux-x64.node-buildinfo.txt +1 -0
  11. package/build/Release/oracledb-6.4.0-win32-x64.node +0 -0
  12. package/build/Release/oracledb-6.4.0-win32-x64.node-buildinfo.txt +1 -0
  13. package/examples/README.md +3 -0
  14. package/lib/aqQueue.js +8 -8
  15. package/lib/connection.js +55 -9
  16. package/lib/constants.js +7 -1
  17. package/lib/dbObject.js +72 -1
  18. package/lib/errors.js +27 -8
  19. package/lib/{thin/protocol → impl/datahandlers}/buffer.js +36 -32
  20. package/lib/impl/datahandlers/constants.js +105 -0
  21. package/lib/{thin/protocol → impl/datahandlers}/oson.js +19 -1
  22. package/lib/impl/datahandlers/vector.js +156 -0
  23. package/lib/impl/pool.js +9 -0
  24. package/lib/impl/resultset.js +34 -17
  25. package/lib/lob.js +22 -6
  26. package/lib/oracledb.js +24 -0
  27. package/lib/pool.js +10 -1
  28. package/lib/poolStatistics.js +3 -1
  29. package/lib/settings.js +30 -6
  30. package/lib/sodaDocCursor.js +14 -1
  31. package/lib/thin/connection.js +100 -144
  32. package/lib/thin/dbObject.js +4 -2
  33. package/lib/thin/lob.js +6 -6
  34. package/lib/thin/pool.js +22 -4
  35. package/lib/thin/protocol/capabilities.js +3 -1
  36. package/lib/thin/protocol/constants.js +20 -52
  37. package/lib/thin/protocol/messages/auth.js +1 -1
  38. package/lib/thin/protocol/messages/base.js +21 -18
  39. package/lib/thin/protocol/messages/dataType.js +3 -2
  40. package/lib/thin/protocol/messages/withData.js +38 -6
  41. package/lib/thin/protocol/packet.js +58 -4
  42. package/lib/thin/sqlnet/networkSession.js +13 -1
  43. package/lib/thin/statement.js +7 -7
  44. package/lib/thin/statementCache.js +167 -0
  45. package/lib/transformer.js +13 -4
  46. package/lib/types.js +12 -2
  47. package/lib/util.js +29 -0
  48. package/lib/version.js +2 -2
  49. package/package.json +1 -1
  50. package/build/Release/oracledb-6.3.0-darwin-x64.node +0 -0
  51. package/build/Release/oracledb-6.3.0-darwin-x64.node-buildinfo.txt +0 -1
  52. package/build/Release/oracledb-6.3.0-js-buildinfo.txt +0 -1
  53. package/build/Release/oracledb-6.3.0-linux-arm64.node +0 -0
  54. package/build/Release/oracledb-6.3.0-linux-arm64.node-buildinfo.txt +0 -1
  55. package/build/Release/oracledb-6.3.0-linux-x64.node +0 -0
  56. package/build/Release/oracledb-6.3.0-linux-x64.node-buildinfo.txt +0 -1
  57. package/build/Release/oracledb-6.3.0-win32-x64.node +0 -0
  58. package/build/Release/oracledb-6.3.0-win32-x64.node-buildinfo.txt +0 -1
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
1
+ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -31,7 +31,7 @@ const ConnectionImpl = require('../impl/connection.js');
31
31
  const ThinResultSetImpl = require('./resultSet.js');
32
32
  const ThinLobImpl = require("./lob.js");
33
33
  const Protocol = require("./protocol/protocol.js");
34
- const { BaseBuffer } = require('./protocol/buffer.js');
34
+ const { BaseBuffer } = require('../impl/datahandlers/buffer.js');
35
35
  const {NetworkSession: nsi} = require("./sqlnet/networkSession.js");
36
36
  const { Statement } = require("./statement");
37
37
  const thinUtil = require('./util');
@@ -41,6 +41,7 @@ const process = require('process');
41
41
  const types = require('../types.js');
42
42
  const errors = require("../errors.js");
43
43
  const messages = require('./protocol/messages');
44
+ const StatementCache = require('./statementCache.js');
44
45
 
45
46
  const finalizationRegistry = new global.FinalizationRegistry((heldValue) => {
46
47
  heldValue.disconnect();
@@ -63,12 +64,10 @@ class ThinConnectionImpl extends ConnectionImpl {
63
64
  if (this._protocol.txnInProgress) {
64
65
  await this.rollback();
65
66
  }
66
- this._protocol.callTimeout = 0; // not applicable for close
67
67
  if (this._drcpEnabled) {
68
68
  await this._sessRelease();
69
69
  this._drcpEstablishSession = true;
70
70
  }
71
-
72
71
  if (this._pool && !this._dropSess) {
73
72
  await this._pool.release(this);
74
73
  } else {
@@ -94,13 +93,13 @@ class ThinConnectionImpl extends ConnectionImpl {
94
93
  }
95
94
 
96
95
  //---------------------------------------------------------------------------
97
- // _determineElementObjType()
96
+ // _getElementTypeObj()
98
97
  //
99
- // Determine the element type's object type. This is needed when processing
98
+ // Get the element type's object type. This is needed when processing
100
99
  // collections with an object as the element type since this information is
101
100
  // not available in the TDS.
102
101
  //---------------------------------------------------------------------------
103
- async _determineElementObjType(info) {
102
+ async _getElementTypeObj(info) {
104
103
  const binds = [
105
104
  {
106
105
  name: "owner",
@@ -255,60 +254,77 @@ class ThinConnectionImpl extends ConnectionImpl {
255
254
  }
256
255
 
257
256
  //---------------------------------------------------------------------------
258
- // _parseElementType()
257
+ // _parseTDSAttr()
259
258
  //
260
- // Parses the element type from the TDS buffer.
259
+ // Returns the DB type and fills metadata from the TDS buffer.
261
260
  //---------------------------------------------------------------------------
262
- async _parseElementType(buf, info) {
263
- let oraTypeNum, csfrm;
264
- const attrType = buf.readUInt8();
261
+ _parseTDSAttr(buf, metaData) {
262
+ let oraTypeNum, csfrm, attrType;
263
+
264
+ // skip until a type code that is of interest
265
+ for (;;) {
266
+ attrType = buf.readUInt8();
267
+ if (attrType === constants.TNS_OBJ_TDS_TYPE_EMBED_ADT_INFO) {
268
+ buf.skipBytes(1); // flags
269
+ } else if (attrType !== constants.TNS_OBJ_TDS_TYPE_SUBTYPE_MARKER) {
270
+ break;
271
+ }
272
+ }
273
+
274
+ // process the type code.
265
275
  switch (attrType) {
266
276
  case constants.TNS_OBJ_TDS_TYPE_NUMBER:
277
+ metaData.precision = buf.readInt8();
278
+ metaData.scale = buf.readInt8();
279
+ return types.DB_TYPE_NUMBER;
267
280
  case constants.TNS_OBJ_TDS_TYPE_FLOAT:
268
- info.elementType = types.DB_TYPE_NUMBER;
269
- break;
281
+ metaData.precision = buf.readInt8();
282
+ return types.DB_TYPE_NUMBER;
270
283
  case constants.TNS_OBJ_TDS_TYPE_VARCHAR:
271
284
  case constants.TNS_OBJ_TDS_TYPE_CHAR:
272
- info.maxSize = buf.readUInt16BE();
285
+ metaData.maxSize = buf.readUInt16BE(); // maximum length
273
286
  oraTypeNum = (attrType === constants.TNS_OBJ_TDS_TYPE_VARCHAR) ?
274
287
  constants.TNS_DATA_TYPE_VARCHAR : constants.TNS_DATA_TYPE_CHAR;
275
288
  csfrm = buf.readUInt8();
276
- info.elementType = types.getTypeByOraTypeNum(oraTypeNum, csfrm);
277
- break;
289
+ csfrm = csfrm & 0x7f;
290
+ buf.skipBytes(2); // character set
291
+ return types.getTypeByOraTypeNum(oraTypeNum, csfrm);
278
292
  case constants.TNS_OBJ_TDS_TYPE_RAW:
279
- info.elementType = types.DB_TYPE_RAW;
280
- break;
293
+ metaData.maxSize = buf.readUInt16BE(); // maximum length
294
+ return types.DB_TYPE_RAW;
281
295
  case constants.TNS_OBJ_TDS_TYPE_BINARY_FLOAT:
282
- info.elementType = types.DB_TYPE_BINARY_FLOAT;
283
- break;
296
+ return types.DB_TYPE_BINARY_FLOAT;
284
297
  case constants.TNS_OBJ_TDS_TYPE_BINARY_DOUBLE:
285
- info.elementType = types.DB_TYPE_BINARY_DOUBLE;
286
- break;
298
+ return types.DB_TYPE_BINARY_DOUBLE;
287
299
  case constants.TNS_OBJ_TDS_TYPE_DATE:
288
- info.elementType = types.DB_TYPE_DATE;
289
- break;
300
+ return types.DB_TYPE_DATE;
290
301
  case constants.TNS_OBJ_TDS_TYPE_TIMESTAMP:
291
- info.elementType = types.DB_TYPE_TIMESTAMP;
292
- break;
302
+ buf.skipBytes(1); // precision
303
+ return types.DB_TYPE_TIMESTAMP;
293
304
  case constants.TNS_OBJ_TDS_TYPE_TIMESTAMP_LTZ:
294
- info.elementType = types.DB_TYPE_TIMESTAMP_LTZ;
295
- break;
305
+ buf.skipBytes(1); // precision
306
+ return types.DB_TYPE_TIMESTAMP_LTZ;
296
307
  case constants.TNS_OBJ_TDS_TYPE_TIMESTAMP_TZ:
297
- info.elementType = types.DB_TYPE_TIMESTAMP_TZ;
298
- break;
308
+ buf.skipBytes(1); // precision
309
+ return types.DB_TYPE_TIMESTAMP_TZ;
299
310
  case constants.TNS_OBJ_TDS_TYPE_BOOLEAN:
300
- info.elementType = types.DB_TYPE_BOOLEAN;
301
- break;
311
+ return types.DB_TYPE_BOOLEAN;
302
312
  case constants.TNS_OBJ_TDS_TYPE_CLOB:
303
- this._determineElementTypeCharsetForm(info);
304
- break;
313
+ return types.DB_TYPE_CLOB;
305
314
  case constants.TNS_OBJ_TDS_TYPE_BLOB:
306
- info.elementType = types.DB_TYPE_BLOB;
307
- break;
315
+ return types.DB_TYPE_BLOB;
308
316
  case constants.TNS_OBJ_TDS_TYPE_OBJ:
309
- info.elementType = types.DB_TYPE_OBJECT;
310
- await this._determineElementObjType(info);
311
- break;
317
+ buf.skipBytes(5);
318
+ return types.DB_TYPE_OBJECT;
319
+ case constants.TNS_OBJ_TDS_TYPE_START_EMBED_ADT:
320
+ // loop until end type, TNS_OBJ_TDS_TYPE_END_EMBED_ADT
321
+ // is received.
322
+ while (this._parseTDSAttr(buf, {}) !== 0) {
323
+ continue;
324
+ }
325
+ return types.DB_TYPE_OBJECT;
326
+ case constants.TNS_OBJ_TDS_TYPE_END_EMBED_ADT:
327
+ return 0;
312
328
  default:
313
329
  errors.throwErr(errors.ERR_TDS_TYPE_NOT_SUPPORTED, attrType);
314
330
  }
@@ -317,12 +333,9 @@ class ThinConnectionImpl extends ConnectionImpl {
317
333
  //---------------------------------------------------------------------------
318
334
  // _parseTDS()
319
335
  //
320
- // Parses the TDS for the type. This is only needed for collection types, so
321
- // if the TDS is determined to be for an object type, the remaining
322
- // information is ignored.
336
+ // Parses the TDS (type descriptor segment) for the type.
323
337
  //---------------------------------------------------------------------------
324
338
  async _parseTDS(tds, info) {
325
-
326
339
  // parse initial TDS bytes
327
340
  const buf = new TDSBuffer(tds);
328
341
  buf.skipBytes(4); // end offset
@@ -332,10 +345,6 @@ class ThinConnectionImpl extends ConnectionImpl {
332
345
  // if the number of attributes exceeds 1, the type cannot refer to a
333
346
  // collection, so nothing further needs to be done
334
347
  const numAttrs = buf.readUInt16BE();
335
- if (numAttrs > 1) {
336
- info.isCollection = false;
337
- return;
338
- }
339
348
 
340
349
  // continue parsing TDS bytes to discover if type refers to a collection
341
350
  buf.skipBytes(1); // TDS attributes?
@@ -343,23 +352,41 @@ class ThinConnectionImpl extends ConnectionImpl {
343
352
  buf.skipBytes(2); // ADT number (always zero)
344
353
  buf.skipBytes(4); // offset to index table
345
354
 
346
- // if type of first attribute is not a collection, nothing further needs
347
- // to be done
348
- const attrType = buf.readUInt8();
349
- info.isCollection = (attrType === constants.TNS_OBJ_TDS_TYPE_COLL);
350
- if (!info.isCollection)
351
- return;
352
-
353
- // continue parsing TDS to determine element type
354
- const elementPos = buf.readUInt32BE();
355
- info.maxNumElements = buf.readUInt32BE();
356
- info.collectionType = buf.readUInt8();
357
- if (info.collectionType === constants.TNS_OBJ_PLSQL_INDEX_TABLE) {
358
- info.collectionFlags = constants.TNS_OBJ_HAS_INDEXES;
355
+ // check to see if type refers to a collection (only one attribute is
356
+ // present in that case).
357
+ info.isCollection = false;
358
+ if (numAttrs === 1) {
359
+ const pos = buf.pos;
360
+ const attrType = buf.readUInt8();
361
+ if (attrType === constants.TNS_OBJ_TDS_TYPE_COLL) {
362
+ info.isCollection = true;
363
+ } else {
364
+ buf.pos = pos;
365
+ }
359
366
  }
360
- buf.pos = elementPos;
361
367
 
362
- await this._parseElementType(buf, info);
368
+ // Handle collections
369
+ if (info.isCollection) {
370
+ // continue parsing TDS to determine element type
371
+ const elementPos = buf.readUInt32BE();
372
+ info.maxNumElements = buf.readUInt32BE();
373
+ info.collectionType = buf.readUInt8();
374
+ if (info.collectionType === constants.TNS_OBJ_PLSQL_INDEX_TABLE) {
375
+ info.collectionFlags = constants.TNS_OBJ_HAS_INDEXES;
376
+ }
377
+ buf.pos = elementPos;
378
+ info.elementTypeInfo = {};
379
+ info.elementType = this._parseTDSAttr(buf, info.elementTypeInfo);
380
+ if (info.elementType === types.DB_TYPE_OBJECT) {
381
+ await this._getElementTypeObj(info);
382
+ }
383
+ } else {
384
+ if (info.attributes) { // skip for XML type as it has no attributes.
385
+ for (const attr of info.attributes) {
386
+ this._parseTDSAttr(buf, attr);
387
+ }
388
+ }
389
+ }
363
390
  }
364
391
 
365
392
  //---------------------------------------------------------------------------
@@ -485,9 +512,9 @@ class ThinConnectionImpl extends ConnectionImpl {
485
512
 
486
513
  // process TDS and attributes cursor
487
514
  info.version = result.outBinds.version;
488
- await this._parseTDS(result.outBinds.tds, info);
489
515
  const attrRows = await result.outBinds.attrs_rc.getRows(1000, {});
490
516
  if (attrRows.length > 0) {
517
+ // Its an object not a collection.
491
518
  info.attributes = [];
492
519
  for (const row of attrRows) {
493
520
  const attr = { name: row[1] };
@@ -503,8 +530,9 @@ class ThinConnectionImpl extends ConnectionImpl {
503
530
  info.attributes.push(attr);
504
531
  }
505
532
  }
506
- info.partial = false;
507
533
 
534
+ await this._parseTDS(result.outBinds.tds, info);
535
+ info.partial = false;
508
536
  return info;
509
537
 
510
538
  }
@@ -599,11 +627,8 @@ class ThinConnectionImpl extends ConnectionImpl {
599
627
  this.statementCache = null;
600
628
  this.currentSchema = "";
601
629
  this.invokeSessionCallback = true;
602
- this.statementCache = new Map();
603
630
  this.statementCacheSize = params.stmtCacheSize;
604
- this._numCursorsToClose = 0;
605
631
  this._currentSchemaModified = false;
606
- this._cursorsToClose = new Set();
607
632
  this._tempLobsToClose = [];
608
633
  this._tempLobsTotalSize = 0;
609
634
  this._drcpEstablishSession = false;
@@ -707,6 +732,7 @@ class ThinConnectionImpl extends ConnectionImpl {
707
732
  throw err;
708
733
  }
709
734
 
735
+ this.statementCache = new StatementCache(this.statementCacheSize);
710
736
  // maintain a list of partially populated database object types
711
737
  this._partialDbObjectTypes = [];
712
738
 
@@ -719,51 +745,10 @@ class ThinConnectionImpl extends ConnectionImpl {
719
745
  }
720
746
 
721
747
  //---------------------------------------------------------------------------
722
- // Sets that a statement is no longer in use
748
+ // Return the statement to the statement cache, if applicable
723
749
  //---------------------------------------------------------------------------
724
750
  _returnStatement(statement) {
725
- if (statement.bindInfoList) {
726
- statement.bindInfoList.forEach(bindInfo => {
727
- bindInfo.bindVar = null;
728
- });
729
- }
730
- if (statement.queryVars) {
731
- statement.queryVars.forEach(queryVar => {
732
- queryVar.values.fill(null);
733
- });
734
- }
735
- if (statement.returnToCache) {
736
- statement.inUse = false;
737
- } else if (statement.cursorId !== 0) {
738
- this._addCursorToClose(statement.cursorId);
739
- }
740
- }
741
-
742
- //---------------------------------------------------------------------------
743
- // Adds the cursors that needs to be closed to the _cursorsToClose set
744
- //---------------------------------------------------------------------------
745
- _addCursorToClose(cursorId) {
746
- if (this._cursorsToClose.has(cursorId)) {
747
- const reason = `attempt to close cursor ${cursorId} twice`;
748
- errors.throwErr(errors.ERR_INTERNAL, reason);
749
- }
750
- this._cursorsToClose.add(cursorId);
751
- }
752
-
753
- //---------------------------------------------------------------------------
754
- // Adjusts the statement cache to remove least recently used statements
755
- //---------------------------------------------------------------------------
756
- _adjustStatementCache() {
757
- while (this.statementCache.size > this.statementCacheSize) {
758
- const sql = this.statementCache.keys().next().value;
759
- const stmt = this.statementCache.get(sql);
760
- this.statementCache.delete(sql);
761
- if (stmt.inUse) {
762
- stmt.returnToCache = false;
763
- } else if (stmt.cursorId !== 0) {
764
- this._addCursorToClose(stmt.cursorId);
765
- }
766
- }
751
+ this.statementCache.returnStatement(statement);
767
752
  }
768
753
 
769
754
  //---------------------------------------------------------------------------
@@ -873,14 +858,6 @@ class ThinConnectionImpl extends ConnectionImpl {
873
858
  return resultSet;
874
859
  }
875
860
 
876
- //---------------------------------------------------------------------------
877
- // Clears the statement cache for the connection
878
- //---------------------------------------------------------------------------
879
- resetStatementCache() {
880
- this.statementCache.clear();
881
- this._cursorsToClose.clear();
882
- }
883
-
884
861
  //---------------------------------------------------------------------------
885
862
  // getDbObjectClass()
886
863
  //
@@ -945,31 +922,10 @@ class ThinConnectionImpl extends ConnectionImpl {
945
922
  // new session is going to be used.
946
923
  //---------------------------------------------------------------------------
947
924
  _getStatement(sql, cacheStatement = false) {
948
- let statement = this.statementCache.get(sql);
949
- if (!statement) {
950
- statement = new Statement();
951
- statement._prepare(sql);
952
- if (cacheStatement && !this._drcpEstablishSession && !statement.isDdl &&
953
- this.statementCacheSize > 0) {
954
- statement.returnToCache = true;
955
- this.statementCache.set(sql, statement);
956
- this._adjustStatementCache();
957
- }
958
- } else if (statement.inUse || !cacheStatement ||
959
- this._drcpEstablishSession) {
960
- if (!cacheStatement) {
961
- this.statementCache.delete(sql);
962
- statement.returnToCache = false;
963
- }
964
- if (statement.inUse || this._drcpEstablishSession) {
965
- statement = statement._copy();
966
- }
967
- } else {
968
- this.statementCache.delete(sql);
969
- this.statementCache.set(sql, statement);
925
+ if (this._drcpEstablishSession) {
926
+ cacheStatement = false;
970
927
  }
971
- statement.inUse = true;
972
- return statement;
928
+ return this.statementCache.getStatement(sql, cacheStatement);
973
929
  }
974
930
 
975
931
  //---------------------------------------------------------------------------
@@ -1064,7 +1020,7 @@ class ThinConnectionImpl extends ConnectionImpl {
1064
1020
  // the connection object
1065
1021
  //---------------------------------------------------------------------------
1066
1022
  getStmtCacheSize() {
1067
- return this.statementCacheSize;
1023
+ return this.statementCache._maxSize;
1068
1024
  }
1069
1025
 
1070
1026
  setCallTimeout(timeout) {
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2023, Oracle and/or its affiliates.
1
+ // Copyright (c) 2023, 2024, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -31,7 +31,7 @@ const constants = require('./protocol/constants.js');
31
31
  const errors = require('../errors.js');
32
32
  const types = require('../types.js');
33
33
  const DbObjectImpl = require('../impl/dbObject.js');
34
- const { GrowableBuffer } = require('./protocol/buffer.js');
34
+ const { GrowableBuffer } = require('../impl/datahandlers/buffer.js');
35
35
  const ThinLobImpl = require('./lob.js');
36
36
 
37
37
  class DbObjectPickleBuffer extends GrowableBuffer {
@@ -280,9 +280,11 @@ class ThinDbObjectImpl extends DbObjectImpl {
280
280
  buf.writeBytesWithLength(value);
281
281
  break;
282
282
  case types.DB_TYPE_BINARY_DOUBLE:
283
+ buf.writeUInt8(8);
283
284
  buf.writeBinaryDouble(value);
284
285
  break;
285
286
  case types.DB_TYPE_BINARY_FLOAT:
287
+ buf.writeUInt8(4);
286
288
  buf.writeBinaryFloat(value);
287
289
  break;
288
290
  case types.DB_TYPE_DATE:
package/lib/thin/lob.js CHANGED
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
1
+ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -89,11 +89,11 @@ class ThinLobImpl extends LobImpl {
89
89
  return this.dbType;
90
90
  }
91
91
 
92
- async getData() {
93
- if (this._length < 0) {
94
- errors.throwErr(errors.ERR_INVALID_LOB);
92
+ async getData(offset = 1, len = this._length) {
93
+ if (!len) {
94
+ len = this._length;
95
95
  }
96
- return await this.read(1, this._length);
96
+ return await this.read(offset, len);
97
97
  }
98
98
 
99
99
  async read(offset, length) {
@@ -157,7 +157,7 @@ class ThinLobImpl extends LobImpl {
157
157
 
158
158
  checkConn() {
159
159
  if (!this.conn.nscon.connected)
160
- errors.throwErr(errors.ERR_LOB_CLOSED);
160
+ errors.throwErr(errors.ERR_INVALID_CONNECTION);
161
161
  }
162
162
 
163
163
  close() {
package/lib/thin/pool.js CHANGED
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
1
+ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -53,6 +53,7 @@ class ThinPoolImpl extends PoolImpl {
53
53
  this._poolIncrement = params.poolIncrement;
54
54
  this._poolTimeout = params.poolTimeout;
55
55
  this._poolPingInterval = params.poolPingInterval;
56
+ this._poolPingTimeout = params.poolPingTimeout;
56
57
  this._stmtCacheSize = params.stmtCacheSize;
57
58
 
58
59
  // The user Config filterd from common layer is cached except
@@ -318,6 +319,13 @@ class ThinPoolImpl extends PoolImpl {
318
319
  return this._poolPingInterval;
319
320
  }
320
321
 
322
+ //---------------------------------------------------------------------------
323
+ // returns the pool ping Timeout (milliseconds)
324
+ //---------------------------------------------------------------------------
325
+ getPoolPingTimeout() {
326
+ return this._poolPingTimeout;
327
+ }
328
+
321
329
  //---------------------------------------------------------------------------
322
330
  // returns the pool timeout
323
331
  //---------------------------------------------------------------------------
@@ -363,13 +371,13 @@ class ThinPoolImpl extends PoolImpl {
363
371
  _scanIdleConnection() {
364
372
  while ((this._usedConnectionList.size + this._freeConnectionList.length) >
365
373
  this._poolMin && this._freeConnectionList.length > 0) {
366
- const conn = this._freeConnectionList[this._freeConnectionList.length - 1];
374
+ const conn = this._freeConnectionList[0];
367
375
  if (Date.now() - conn._lastTimeUsed < this._poolTimeout * 1000) {
368
376
  break;
369
377
  }
370
378
 
371
379
  this.eventEmitter.emit('_removePoolConnection', conn);
372
- this._freeConnectionList.pop();
380
+ this._freeConnectionList.shift();
373
381
  }
374
382
 
375
383
  this._schedulerJob = null;
@@ -495,11 +503,21 @@ class ThinPoolImpl extends PoolImpl {
495
503
  requiresPing = true;
496
504
  }
497
505
  if (requiresPing) {
506
+ let pingTimer;
498
507
  try {
508
+ if (this._poolPingTimeout) {
509
+ pingTimer = setTimeout(() => {
510
+ // force disconnect causes ping task to unblock
511
+ // and return.
512
+ conn.nscon.forceDisconnect();
513
+ }, this._poolPingTimeout);
514
+ }
499
515
  await conn.ping();
500
516
  } catch {
501
- this.eventEmitter.emit('_removePoolConnection', conn);
517
+ conn.nscon.forceDisconnect();
502
518
  continue;
519
+ } finally {
520
+ clearTimeout(pingTimer);
503
521
  }
504
522
  }
505
523
 
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
1
+ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -104,6 +104,8 @@ class Capabilities {
104
104
  constants.TNS_CCAP_CLIENT_FN_MAX;
105
105
  this.compileCaps[constants.TNS_CCAP_TTC4] =
106
106
  constants.TNS_CCAP_INBAND_NOTIFICATION;
107
+ this.compileCaps[constants.TNS_CCAP_TTC5] =
108
+ constants.TNS_CCAP_VECTOR_SUPPORT;
107
109
  }
108
110
 
109
111
  initRuntimeCaps() {
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
1
+ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -28,6 +28,7 @@
28
28
 
29
29
  const { Buffer } = require('buffer');
30
30
  const constants = require('../../constants.js');
31
+ const dataHandlerConstants = require('../../impl/datahandlers/constants.js');
31
32
 
32
33
  module.exports = {
33
34
 
@@ -198,6 +199,7 @@ module.exports = {
198
199
  TNS_DATA_TYPE_UD12: 124 + 256,
199
200
  TNS_DATA_TYPE_AL8: 125 + 256,
200
201
  TNS_DATA_TYPE_LFOP: 126 + 256,
202
+ TNS_DATA_TYPE_VECTOR: 127,
201
203
  TNS_DATA_TYPE_FCRT: 127 + 256,
202
204
  TNS_DATA_TYPE_DNY: 128 + 256,
203
205
  TNS_DATA_TYPE_OPR: 129 + 256,
@@ -513,42 +515,6 @@ module.exports = {
513
515
 
514
516
  // base JSON constants
515
517
  TNS_JSON_MAX_LENGTH: 32 * 1024 * 1024,
516
- TNS_JSON_MAGIC_BYTE_1: 0xff,
517
- TNS_JSON_MAGIC_BYTE_2: 0x4a, // 'J'
518
- TNS_JSON_MAGIC_BYTE_3: 0x5a, // 'Z'
519
- TNS_JSON_VERSION: 1,
520
- TNS_JSON_FLAG_HASH_ID_UINT8: 0x0100,
521
- TNS_JSON_FLAG_HASH_ID_UINT16: 0x0200,
522
- TNS_JSON_FLAG_NUM_FNAMES_UINT16: 0x0400,
523
- TNS_JSON_FLAG_FNAMES_SEG_UINT32: 0x0800,
524
- TNS_JSON_FLAG_TINY_NODES_STAT: 0x2000,
525
- TNS_JSON_FLAG_TREE_SEG_UINT32: 0x1000,
526
- TNS_JSON_FLAG_REL_OFFSET_MODE: 0x01,
527
- TNS_JSON_FLAG_INLINE_LEAF: 0x02,
528
- TNS_JSON_FLAG_LEN_IN_PCODE: 0x04,
529
- TNS_JSON_FLAG_NUM_FNAMES_UINT32: 0x08,
530
- TNS_JSON_FLAG_IS_SCALAR: 0x10,
531
-
532
- // JSON data types
533
- TNS_JSON_TYPE_NULL: 0x30,
534
- TNS_JSON_TYPE_TRUE: 0x31,
535
- TNS_JSON_TYPE_FALSE: 0x32,
536
- TNS_JSON_TYPE_STRING_LENGTH_UINT8: 0x33,
537
- TNS_JSON_TYPE_NUMBER_LENGTH_UINT8: 0x34,
538
- TNS_JSON_TYPE_BINARY_DOUBLE: 0x36,
539
- TNS_JSON_TYPE_STRING_LENGTH_UINT16: 0x37,
540
- TNS_JSON_TYPE_STRING_LENGTH_UINT32: 0x38,
541
- TNS_JSON_TYPE_TIMESTAMP: 0x39,
542
- TNS_JSON_TYPE_BINARY_LENGTH_UINT16: 0x3a,
543
- TNS_JSON_TYPE_BINARY_LENGTH_UINT32: 0x3b,
544
- TNS_JSON_TYPE_DATE: 0x3c,
545
- TNS_JSON_TYPE_INTERVAL_YM: 0x3d,
546
- TNS_JSON_TYPE_INTERVAL_DS: 0x3e,
547
- TNS_JSON_TYPE_TIMESTAMP_TZ: 0x7c,
548
- TNS_JSON_TYPE_TIMESTAMP7: 0x7d,
549
- TNS_JSON_TYPE_BINARY_FLOAT: 0x7f,
550
- TNS_JSON_TYPE_OBJECT: 0x84,
551
- TNS_JSON_TYPE_ARRAY: 0xc0,
552
518
 
553
519
  // end-to-end metrics
554
520
  TNS_END_TO_END_ACTION: 0x0010,
@@ -608,7 +574,8 @@ module.exports = {
608
574
  TNS_CCAP_TTC3: 37,
609
575
  TNS_CCAP_TTC4: 40,
610
576
  TNS_CCAP_LOB2: 42,
611
- TNS_CCAP_MAX: 45,
577
+ TNS_CCAP_TTC5: 44,
578
+ TNS_CCAP_MAX: 51,
612
579
 
613
580
  // compile time capability values
614
581
  TNS_CCAP_SQL_VERSION_MAX: 6,
@@ -630,7 +597,8 @@ module.exports = {
630
597
  TNS_CCAP_FIELD_VERSION_23_1_EXT_4: 21,
631
598
  TNS_CCAP_FIELD_VERSION_23_1_EXT_5: 22,
632
599
  TNS_CCAP_FIELD_VERSION_23_1_EXT_6: 23,
633
- TNS_CCAP_FIELD_VERSION_MAX: 23,
600
+ TNS_CCAP_FIELD_VERSION_23_4: 24,
601
+ TNS_CCAP_FIELD_VERSION_MAX: 24,
634
602
  TNS_CCAP_O5LOGON: 8,
635
603
  TNS_CCAP_O5LOGON_NP: 2,
636
604
  TNS_CCAP_O7LOGON: 32,
@@ -660,6 +628,7 @@ module.exports = {
660
628
  TNS_CCAP_CLIENT_FN_MAX: 12,
661
629
  TNS_CCAP_LOB2_QUASI: 0x01,
662
630
  TNS_CCAP_LOB2_2GB_PREFETCH: 0x04,
631
+ TNS_CCAP_VECTOR_SUPPORT: 0x08,
663
632
 
664
633
  // runtime capability indices
665
634
  TNS_RCAP_COMPAT: 0,
@@ -680,28 +649,20 @@ module.exports = {
680
649
 
681
650
  // UDS flags
682
651
  TNS_UDS_FLAGS_IS_JSON: 0x00000100,
652
+ TNS_UDS_FLAGS_IS_OSON: 0x00000800,
683
653
 
684
654
  // other constants
685
- TNS_MAX_SHORT_LENGTH: 252,
686
655
  TNS_ESCAPE_CHAR: 253,
687
- TNS_LONG_LENGTH_INDICATOR: 254,
688
- TNS_NULL_LENGTH_INDICATOR: 255,
656
+ TNS_LONG_LENGTH_INDICATOR: dataHandlerConstants.TNS_LONG_LENGTH_INDICATOR,
657
+ TNS_NULL_LENGTH_INDICATOR: dataHandlerConstants.TNS_NULL_LENGTH_INDICATOR,
689
658
  TNS_MAX_ROWID_LENGTH: 18,
690
- TNS_DURATION_MID: 0x80000000,
691
- TNS_DURATION_OFFSET: 60,
692
659
  TNS_DURATION_SESSION: 10,
693
660
  TNS_MAX_LONG_LENGTH: 0x7fffffff,
694
661
  TNS_SDU: 8192,
695
662
  TNS_TDU: 65535,
696
663
  TNS_TXN_IN_PROGRESS: 0x00000002,
697
664
  TNS_MAX_CONNECT_DATA: 230,
698
- TNS_CHUNK_SIZE: 32767,
699
665
  TNS_MAX_UROWID_LENGTH: 3950,
700
- TNS_HAS_REGION_ID: 0x80,
701
-
702
- // timezone offsets
703
- TZ_HOUR_OFFSET: 20,
704
- TZ_MINUTE_OFFSET: 60,
705
666
 
706
667
  // drcp release mode
707
668
  DRCP_DEAUTHENTICATE: 0x00000002,
@@ -742,6 +703,10 @@ module.exports = {
742
703
  TNS_OBJ_TDS_TYPE_BLOB: 30,
743
704
  TNS_OBJ_TDS_TYPE_TIMESTAMP_LTZ: 33,
744
705
  TNS_OBJ_TDS_TYPE_BINARY_FLOAT: 37,
706
+ TNS_OBJ_TDS_TYPE_START_EMBED_ADT: 39,
707
+ TNS_OBJ_TDS_TYPE_END_EMBED_ADT: 40,
708
+ TNS_OBJ_TDS_TYPE_SUBTYPE_MARKER: 43,
709
+ TNS_OBJ_TDS_TYPE_EMBED_ADT_INFO: 44,
745
710
  TNS_OBJ_TDS_TYPE_BINARY_DOUBLE: 45,
746
711
 
747
712
  // xml type constants
@@ -760,11 +725,14 @@ module.exports = {
760
725
  // warnings
761
726
  TNS_WARN_COMPILATION_CREATE: 0x20,
762
727
 
728
+ // vector constants
729
+ TNS_VECTOR_MAX_LENGTH: 1048576,
730
+ VECTOR_FORMAT_FLEX: 0,
731
+ VECTOR_META_FLAG_FLEXIBLE_DIM: 1,
732
+
763
733
  // other constants
764
734
  PACKET_HEADER_SIZE: 8,
765
735
  NUMBER_AS_TEXT_CHARS: 172,
766
- NUMBER_MAX_DIGITS: 40,
767
- BUFFER_CHUNK_SIZE: 65536,
768
736
  CHUNKED_BYTES_CHUNK_SIZE: 65536,
769
737
 
770
738
  TNS_BASE64_ALPHABET_ARRAY: Buffer.from('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'),