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.
- package/LICENSE.txt +1 -1
- package/NOTICE.txt +1 -1
- package/README.md +3 -3
- package/build/Release/oracledb-6.4.0-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.4.0-darwin-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.4.0-js-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.4.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.4.0-linux-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.4.0-linux-x64.node +0 -0
- package/build/Release/oracledb-6.4.0-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.4.0-win32-x64.node +0 -0
- package/build/Release/oracledb-6.4.0-win32-x64.node-buildinfo.txt +1 -0
- package/examples/README.md +3 -0
- package/lib/aqQueue.js +8 -8
- package/lib/connection.js +55 -9
- package/lib/constants.js +7 -1
- package/lib/dbObject.js +72 -1
- package/lib/errors.js +27 -8
- package/lib/{thin/protocol → impl/datahandlers}/buffer.js +36 -32
- package/lib/impl/datahandlers/constants.js +105 -0
- package/lib/{thin/protocol → impl/datahandlers}/oson.js +19 -1
- package/lib/impl/datahandlers/vector.js +156 -0
- package/lib/impl/pool.js +9 -0
- package/lib/impl/resultset.js +34 -17
- package/lib/lob.js +22 -6
- package/lib/oracledb.js +24 -0
- package/lib/pool.js +10 -1
- package/lib/poolStatistics.js +3 -1
- package/lib/settings.js +30 -6
- package/lib/sodaDocCursor.js +14 -1
- package/lib/thin/connection.js +100 -144
- package/lib/thin/dbObject.js +4 -2
- package/lib/thin/lob.js +6 -6
- package/lib/thin/pool.js +22 -4
- package/lib/thin/protocol/capabilities.js +3 -1
- package/lib/thin/protocol/constants.js +20 -52
- package/lib/thin/protocol/messages/auth.js +1 -1
- package/lib/thin/protocol/messages/base.js +21 -18
- package/lib/thin/protocol/messages/dataType.js +3 -2
- package/lib/thin/protocol/messages/withData.js +38 -6
- package/lib/thin/protocol/packet.js +58 -4
- package/lib/thin/sqlnet/networkSession.js +13 -1
- package/lib/thin/statement.js +7 -7
- package/lib/thin/statementCache.js +167 -0
- package/lib/transformer.js +13 -4
- package/lib/types.js +12 -2
- package/lib/util.js +29 -0
- package/lib/version.js +2 -2
- package/package.json +1 -1
- package/build/Release/oracledb-6.3.0-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.3.0-darwin-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.3.0-js-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.3.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.3.0-linux-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.3.0-linux-x64.node +0 -0
- package/build/Release/oracledb-6.3.0-linux-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.3.0-win32-x64.node +0 -0
- package/build/Release/oracledb-6.3.0-win32-x64.node-buildinfo.txt +0 -1
package/lib/thin/connection.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2022,
|
|
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('
|
|
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
|
-
//
|
|
96
|
+
// _getElementTypeObj()
|
|
98
97
|
//
|
|
99
|
-
//
|
|
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
|
|
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
|
-
//
|
|
257
|
+
// _parseTDSAttr()
|
|
259
258
|
//
|
|
260
|
-
//
|
|
259
|
+
// Returns the DB type and fills metadata from the TDS buffer.
|
|
261
260
|
//---------------------------------------------------------------------------
|
|
262
|
-
|
|
263
|
-
let oraTypeNum, csfrm;
|
|
264
|
-
|
|
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
|
-
|
|
269
|
-
|
|
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
|
-
|
|
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
|
-
|
|
277
|
-
|
|
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
|
-
|
|
280
|
-
|
|
293
|
+
metaData.maxSize = buf.readUInt16BE(); // maximum length
|
|
294
|
+
return types.DB_TYPE_RAW;
|
|
281
295
|
case constants.TNS_OBJ_TDS_TYPE_BINARY_FLOAT:
|
|
282
|
-
|
|
283
|
-
break;
|
|
296
|
+
return types.DB_TYPE_BINARY_FLOAT;
|
|
284
297
|
case constants.TNS_OBJ_TDS_TYPE_BINARY_DOUBLE:
|
|
285
|
-
|
|
286
|
-
break;
|
|
298
|
+
return types.DB_TYPE_BINARY_DOUBLE;
|
|
287
299
|
case constants.TNS_OBJ_TDS_TYPE_DATE:
|
|
288
|
-
|
|
289
|
-
break;
|
|
300
|
+
return types.DB_TYPE_DATE;
|
|
290
301
|
case constants.TNS_OBJ_TDS_TYPE_TIMESTAMP:
|
|
291
|
-
|
|
292
|
-
|
|
302
|
+
buf.skipBytes(1); // precision
|
|
303
|
+
return types.DB_TYPE_TIMESTAMP;
|
|
293
304
|
case constants.TNS_OBJ_TDS_TYPE_TIMESTAMP_LTZ:
|
|
294
|
-
|
|
295
|
-
|
|
305
|
+
buf.skipBytes(1); // precision
|
|
306
|
+
return types.DB_TYPE_TIMESTAMP_LTZ;
|
|
296
307
|
case constants.TNS_OBJ_TDS_TYPE_TIMESTAMP_TZ:
|
|
297
|
-
|
|
298
|
-
|
|
308
|
+
buf.skipBytes(1); // precision
|
|
309
|
+
return types.DB_TYPE_TIMESTAMP_TZ;
|
|
299
310
|
case constants.TNS_OBJ_TDS_TYPE_BOOLEAN:
|
|
300
|
-
|
|
301
|
-
break;
|
|
311
|
+
return types.DB_TYPE_BOOLEAN;
|
|
302
312
|
case constants.TNS_OBJ_TDS_TYPE_CLOB:
|
|
303
|
-
|
|
304
|
-
break;
|
|
313
|
+
return types.DB_TYPE_CLOB;
|
|
305
314
|
case constants.TNS_OBJ_TDS_TYPE_BLOB:
|
|
306
|
-
|
|
307
|
-
break;
|
|
315
|
+
return types.DB_TYPE_BLOB;
|
|
308
316
|
case constants.TNS_OBJ_TDS_TYPE_OBJ:
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
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
|
|
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
|
-
//
|
|
347
|
-
//
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
748
|
+
// Return the statement to the statement cache, if applicable
|
|
723
749
|
//---------------------------------------------------------------------------
|
|
724
750
|
_returnStatement(statement) {
|
|
725
|
-
|
|
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
|
-
|
|
949
|
-
|
|
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
|
-
|
|
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.
|
|
1023
|
+
return this.statementCache._maxSize;
|
|
1068
1024
|
}
|
|
1069
1025
|
|
|
1070
1026
|
setCallTimeout(timeout) {
|
package/lib/thin/dbObject.js
CHANGED
|
@@ -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('
|
|
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,
|
|
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 (
|
|
94
|
-
|
|
92
|
+
async getData(offset = 1, len = this._length) {
|
|
93
|
+
if (!len) {
|
|
94
|
+
len = this._length;
|
|
95
95
|
}
|
|
96
|
-
return await this.read(
|
|
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.
|
|
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,
|
|
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[
|
|
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.
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
688
|
-
TNS_NULL_LENGTH_INDICATOR:
|
|
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+/'),
|