oracledb 6.6.0 → 6.7.1
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/README.md +2 -2
- package/build/Release/Linux_cmds.txt +972 -0
- package/build/Release/oracledb-6.7.1-darwin-arm64.node +0 -0
- package/build/Release/oracledb-6.7.1-darwin-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.7.1-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.7.1-darwin-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.7.1-js-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.7.1-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.7.1-linux-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.7.1-linux-x64.node +0 -0
- package/build/Release/oracledb-6.7.1-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.7.1-win32-x64.node +0 -0
- package/build/Release/oracledb-6.7.1-win32-x64.node-buildinfo.txt +1 -0
- package/examples/example.js +5 -5
- package/lib/configProviders/azure.js +26 -15
- package/lib/configProviders/base.js +23 -37
- package/lib/configProviders/ociobject.js +53 -45
- package/lib/connection.js +75 -3
- package/lib/errors.js +26 -14
- package/lib/impl/aqQueue.js +2 -1
- package/lib/impl/base.js +45 -0
- package/lib/impl/connection.js +53 -0
- package/lib/impl/lob.js +2 -1
- package/lib/impl/pool.js +15 -0
- package/lib/impl/resultset.js +2 -1
- package/lib/impl/sodaCollection.js +2 -1
- package/lib/impl/sodaDatabase.js +2 -1
- package/lib/impl/sodaDocCursor.js +2 -1
- package/lib/impl/sodaOperation.js +2 -1
- package/lib/lob.js +3 -2
- package/lib/oracledb.js +221 -36
- package/lib/pool.js +14 -5
- package/lib/settings.js +1 -0
- package/lib/thin/connection.js +150 -91
- package/lib/thin/dbObject.js +13 -4
- package/lib/thin/pool.js +3 -0
- package/lib/thin/protocol/constants.js +1 -1
- package/lib/thin/protocol/messages/auth.js +12 -6
- package/lib/thin/protocol/messages/base.js +3 -0
- package/lib/thin/protocol/messages/sessionRelease.js +1 -0
- package/lib/thin/protocol/messages/withData.js +6 -13
- package/lib/thin/protocol/protocol.js +23 -0
- package/lib/thin/sqlnet/connStrategy.js +12 -3
- package/lib/thin/sqlnet/constants.js +2 -0
- package/lib/thin/sqlnet/navNodes.js +30 -23
- package/lib/thin/sqlnet/networkSession.js +18 -14
- package/lib/thin/sqlnet/ntTcp.js +12 -6
- package/lib/thin/sqlnet/nvStrToNvPair.js +23 -26
- package/lib/thin/sqlnet/paramParser.js +42 -43
- package/lib/thin/sqlnet/sessionAtts.js +1 -1
- package/lib/thin/util.js +4 -3
- package/lib/traceHandler.js +133 -0
- package/lib/util.js +177 -33
- package/lib/version.js +2 -2
- package/package.json +1 -1
- package/build/Release/oracledb-6.6.0-darwin-arm64.node +0 -0
- package/build/Release/oracledb-6.6.0-darwin-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.6.0-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.6.0-darwin-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.6.0-js-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.6.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.6.0-linux-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.6.0-linux-x64.node +0 -0
- package/build/Release/oracledb-6.6.0-linux-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.6.0-win32-x64.node +0 -0
- package/build/Release/oracledb-6.6.0-win32-x64.node-buildinfo.txt +0 -1
- package/examples/README.md +0 -138
package/lib/thin/connection.js
CHANGED
|
@@ -169,12 +169,27 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
169
169
|
//---------------------------------------------------------------------------
|
|
170
170
|
async _execute(statement, numIters, binds, options, executeManyFlag) {
|
|
171
171
|
|
|
172
|
+
// Throw error if executeMany is not called on a DML statement or PL/SQL
|
|
173
|
+
if (executeManyFlag && statement.isQuery) {
|
|
174
|
+
errors.throwErr(errors.ERR_EXECMANY_NOT_ALLOWED_ON_QUERIES);
|
|
175
|
+
}
|
|
172
176
|
// perform binds
|
|
173
|
-
const
|
|
174
|
-
const
|
|
175
|
-
if (
|
|
176
|
-
|
|
177
|
+
const numStmtBinds = statement.bindInfoList.length;
|
|
178
|
+
const numUserBinds = binds.length;
|
|
179
|
+
if (numStmtBinds !== numUserBinds) {
|
|
180
|
+
if (!binds[0]?.name) {
|
|
181
|
+
// positional bind mismatch or zero binds
|
|
182
|
+
errors.throwErr(errors.ERR_WRONG_NUMBER_OF_BINDS, numStmtBinds, numUserBinds);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// named bind mismatch
|
|
186
|
+
// Find the number of distinct named bind placeholders and see
|
|
187
|
+
// if they match the bind values
|
|
188
|
+
const numDistinctStmtBinds = statement.bindInfoDict.size;
|
|
189
|
+
if (numDistinctStmtBinds !== numUserBinds)
|
|
190
|
+
errors.throwErr(errors.ERR_WRONG_NUMBER_OF_BINDS, numStmtBinds, numUserBinds);
|
|
177
191
|
}
|
|
192
|
+
|
|
178
193
|
for (let i = 0; i < binds.length; i++) {
|
|
179
194
|
await this._bind(statement, binds[i], i + 1);
|
|
180
195
|
}
|
|
@@ -404,6 +419,79 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
404
419
|
}
|
|
405
420
|
}
|
|
406
421
|
|
|
422
|
+
//---------------------------------------------------------------------------
|
|
423
|
+
// _populateRowTypeInfo()
|
|
424
|
+
//
|
|
425
|
+
// Get column and datatype information in case of %ROWTYPE handling.
|
|
426
|
+
//---------------------------------------------------------------------------
|
|
427
|
+
async _populateRowTypeInfo(info, options, result) {
|
|
428
|
+
const getColumnsSQL = `
|
|
429
|
+
SELECT
|
|
430
|
+
column_name,
|
|
431
|
+
data_type,
|
|
432
|
+
data_type_owner,
|
|
433
|
+
case
|
|
434
|
+
when data_type in
|
|
435
|
+
('CHAR', 'NCHAR', 'VARCHAR2', 'NVARCHAR2', 'RAW')
|
|
436
|
+
then data_length
|
|
437
|
+
else 0
|
|
438
|
+
end,
|
|
439
|
+
nvl(data_precision, 0),
|
|
440
|
+
nvl(data_scale, 0)
|
|
441
|
+
from all_tab_cols
|
|
442
|
+
where owner = :owner
|
|
443
|
+
and table_name = :name
|
|
444
|
+
and hidden_column != 'YES'
|
|
445
|
+
order by column_id`;
|
|
446
|
+
|
|
447
|
+
const bindVal = [
|
|
448
|
+
{
|
|
449
|
+
name: "owner",
|
|
450
|
+
type: types.DB_TYPE_VARCHAR,
|
|
451
|
+
maxSize: 128,
|
|
452
|
+
dir: constants.BIND_IN,
|
|
453
|
+
values: [result.outBinds.schema],
|
|
454
|
+
},
|
|
455
|
+
{
|
|
456
|
+
name: "name",
|
|
457
|
+
type: types.DB_TYPE_VARCHAR,
|
|
458
|
+
maxSize: 128,
|
|
459
|
+
dir: constants.BIND_IN,
|
|
460
|
+
values: [info.name.substring(0, info.name.length - 8)]
|
|
461
|
+
}
|
|
462
|
+
];
|
|
463
|
+
const val = await this.execute(
|
|
464
|
+
getColumnsSQL, 1, bindVal, options, false
|
|
465
|
+
);
|
|
466
|
+
try {
|
|
467
|
+
const attrRows = await val.resultSet._getAllRows();
|
|
468
|
+
info.attributes = [];
|
|
469
|
+
for (const row of attrRows) {
|
|
470
|
+
const metaData = {
|
|
471
|
+
name: row[0],
|
|
472
|
+
dataType: row[1],
|
|
473
|
+
dataTypeOwner: row[2],
|
|
474
|
+
maxSize: row[3],
|
|
475
|
+
dataPrecision: row[4],
|
|
476
|
+
dataScale: row[5],
|
|
477
|
+
};
|
|
478
|
+
if (!metaData.dataTypeOwner) {
|
|
479
|
+
const startPos = row[1].indexOf('(');
|
|
480
|
+
const endPos = row[1].indexOf(')');
|
|
481
|
+
if (endPos > startPos) {
|
|
482
|
+
metaData.dataType = metaData.dataType.substring(0, startPos) +
|
|
483
|
+
metaData.dataType.substring(
|
|
484
|
+
endPos + 1, metaData.dataType.length
|
|
485
|
+
);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
this._addAttr(info.attributes, metaData);
|
|
489
|
+
}
|
|
490
|
+
} finally {
|
|
491
|
+
val.resultSet.close();
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
407
495
|
//---------------------------------------------------------------------------
|
|
408
496
|
// _populateDbObjectTypeInfo()
|
|
409
497
|
//
|
|
@@ -449,26 +537,6 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
449
537
|
end if;
|
|
450
538
|
end;`;
|
|
451
539
|
|
|
452
|
-
// get column and datatype information in case of %ROWTYPE handling.
|
|
453
|
-
const getColumnsSQL = `
|
|
454
|
-
SELECT
|
|
455
|
-
column_name,
|
|
456
|
-
data_type,
|
|
457
|
-
data_type_owner,
|
|
458
|
-
case
|
|
459
|
-
when data_type in
|
|
460
|
-
('CHAR', 'NCHAR', 'VARCHAR2', 'NVARCHAR2', 'RAW')
|
|
461
|
-
then data_length
|
|
462
|
-
else 0
|
|
463
|
-
end,
|
|
464
|
-
nvl(data_precision, 0),
|
|
465
|
-
nvl(data_scale, 0)
|
|
466
|
-
from all_tab_cols
|
|
467
|
-
where owner = :owner
|
|
468
|
-
and table_name = :name
|
|
469
|
-
and hidden_column != 'YES'
|
|
470
|
-
order by column_id`;
|
|
471
|
-
|
|
472
540
|
const binds = [
|
|
473
541
|
{
|
|
474
542
|
name: "full_name",
|
|
@@ -540,78 +608,42 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
540
608
|
errors.throwErr(errors.ERR_INVALID_OBJECT_TYPE_NAME, name);
|
|
541
609
|
}
|
|
542
610
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
// process TDS and attributes cursor
|
|
550
|
-
if (info.name.endsWith('%ROWTYPE')) {
|
|
551
|
-
const bindVal = [
|
|
552
|
-
{
|
|
553
|
-
name: "owner",
|
|
554
|
-
type: types.DB_TYPE_VARCHAR,
|
|
555
|
-
maxSize: 128,
|
|
556
|
-
dir: constants.BIND_IN,
|
|
557
|
-
values: [result.outBinds.schema],
|
|
558
|
-
},
|
|
559
|
-
{
|
|
560
|
-
name: "name",
|
|
561
|
-
type: types.DB_TYPE_VARCHAR,
|
|
562
|
-
maxSize: 128,
|
|
563
|
-
dir: constants.BIND_IN,
|
|
564
|
-
values: [info.name.substring(0, info.name.length - 8)]
|
|
565
|
-
}
|
|
566
|
-
];
|
|
567
|
-
const val = await this.execute(
|
|
568
|
-
getColumnsSQL, 1, bindVal, options, false
|
|
569
|
-
);
|
|
570
|
-
const attrRows = await val.resultSet._getAllRows();
|
|
571
|
-
info.attributes = [];
|
|
572
|
-
for (const row of attrRows) {
|
|
573
|
-
const metaData = {
|
|
574
|
-
name: row[0],
|
|
575
|
-
dataType: row[1],
|
|
576
|
-
dataTypeOwner: row[2],
|
|
577
|
-
maxSize: row[3],
|
|
578
|
-
dataPrecision: row[4],
|
|
579
|
-
dataScale: row[5],
|
|
580
|
-
};
|
|
581
|
-
if (!metaData.dataTypeOwner) {
|
|
582
|
-
const startPos = row[1].indexOf('(');
|
|
583
|
-
const endPos = row[1].indexOf(')');
|
|
584
|
-
if (endPos > startPos) {
|
|
585
|
-
metaData.dataType = metaData.dataType.substring(0, startPos) +
|
|
586
|
-
metaData.dataType.substring(
|
|
587
|
-
endPos + 1, metaData.dataType.length
|
|
588
|
-
);
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
this._addAttr(info.attributes, metaData);
|
|
611
|
+
try {
|
|
612
|
+
// check cache; if already present, nothing more to do!
|
|
613
|
+
const info = this._getDbObjectType(result.outBinds.schema,
|
|
614
|
+
result.outBinds.name, result.outBinds.package_name, result.outBinds.oid);
|
|
615
|
+
if (!info.partial) {
|
|
616
|
+
return info;
|
|
592
617
|
}
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
618
|
+
|
|
619
|
+
// process TDS and attributes cursor
|
|
620
|
+
if (info.name.endsWith('%ROWTYPE')) {
|
|
621
|
+
await this._populateRowTypeInfo(info, options, result);
|
|
622
|
+
} else {
|
|
623
|
+
info.version = result.outBinds.version;
|
|
624
|
+
const attrRows = await result.outBinds.attrs_rc._getAllRows();
|
|
625
|
+
if (attrRows.length > 0) {
|
|
597
626
|
// Its an object not a collection.
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
627
|
+
info.attributes = [];
|
|
628
|
+
for (const row of attrRows) {
|
|
629
|
+
const metaData = {
|
|
630
|
+
name: row[1],
|
|
631
|
+
dataType: row[3],
|
|
632
|
+
dataTypeOwner: row[4],
|
|
633
|
+
packageName: row[5],
|
|
634
|
+
oid: row[6]
|
|
635
|
+
};
|
|
636
|
+
this._addAttr(info.attributes, metaData);
|
|
637
|
+
}
|
|
609
638
|
|
|
639
|
+
}
|
|
640
|
+
await this._parseTDS(result.outBinds.tds, info);
|
|
610
641
|
}
|
|
611
|
-
|
|
642
|
+
info.partial = false;
|
|
643
|
+
return info;
|
|
644
|
+
} finally {
|
|
645
|
+
result.outBinds.attrs_rc.close();
|
|
612
646
|
}
|
|
613
|
-
info.partial = false;
|
|
614
|
-
return info;
|
|
615
647
|
|
|
616
648
|
}
|
|
617
649
|
|
|
@@ -797,8 +829,14 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
797
829
|
await this._protocol._processMessage(authMessage);
|
|
798
830
|
}
|
|
799
831
|
} else {
|
|
832
|
+
// When Fast Auth is explicitly disabled on servers > 23ai,
|
|
833
|
+
// we dont rely on message type TNS_MSG_TYPE_END_OF_REQUEST too
|
|
834
|
+
// for protocolMessage and dataTypeMessage.
|
|
835
|
+
const endOfRequestSupport = this.nscon.endOfRequestSupport;
|
|
836
|
+
this.nscon.endOfRequestSupport = false;
|
|
800
837
|
await this._protocol._processMessage(protocolMessage);
|
|
801
838
|
await this._protocol._processMessage(dataTypeMessage);
|
|
839
|
+
this.nscon.endOfRequestSupport = endOfRequestSupport;
|
|
802
840
|
await this._protocol._processMessage(authMessage);
|
|
803
841
|
}
|
|
804
842
|
if (!params.token) { // non-token Authentication
|
|
@@ -1239,6 +1277,27 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
1239
1277
|
return this.dbDomain;
|
|
1240
1278
|
}
|
|
1241
1279
|
|
|
1280
|
+
//---------------------------------------------------------------------------
|
|
1281
|
+
// Returns the Oracle Database host name associated with the connection.
|
|
1282
|
+
//---------------------------------------------------------------------------
|
|
1283
|
+
getHostName() {
|
|
1284
|
+
return this.nscon.ntAdapter.hostName;
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
//---------------------------------------------------------------------------
|
|
1288
|
+
// Returns the Oracle Database port number associated with the connection.
|
|
1289
|
+
//---------------------------------------------------------------------------
|
|
1290
|
+
getPort() {
|
|
1291
|
+
return this.nscon.ntAdapter.port;
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
//---------------------------------------------------------------------------
|
|
1295
|
+
// Returns the protocol associated with the connection.
|
|
1296
|
+
//---------------------------------------------------------------------------
|
|
1297
|
+
getProtocol() {
|
|
1298
|
+
return (this.nscon.ntAdapter.secure) ? 'TCPS' : 'TCP';
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1242
1301
|
//---------------------------------------------------------------------------
|
|
1243
1302
|
// Returns the Oracle Database name associated with the connection.
|
|
1244
1303
|
//---------------------------------------------------------------------------
|
package/lib/thin/dbObject.js
CHANGED
|
@@ -179,7 +179,8 @@ class ThinDbObjectImpl extends DbObjectImpl {
|
|
|
179
179
|
//---------------------------------------------------------------------------
|
|
180
180
|
_ensureAssocKeys() {
|
|
181
181
|
if (!this.unpackedAssocKeys) {
|
|
182
|
-
|
|
182
|
+
// Associative arrays indexed by integer are only supported now
|
|
183
|
+
this.unpackedAssocKeys = [...this.unpackedAssocArray.keys()].sort((x, y) => x - y);
|
|
183
184
|
}
|
|
184
185
|
}
|
|
185
186
|
|
|
@@ -546,6 +547,9 @@ class ThinDbObjectImpl extends DbObjectImpl {
|
|
|
546
547
|
// getNextIndex()
|
|
547
548
|
//
|
|
548
549
|
// Returns the next index in a collection.
|
|
550
|
+
// For associative arrays indexed by integers, if the passed-in index
|
|
551
|
+
// parameter is not present, it will return the next higher index found
|
|
552
|
+
// in the associative array.
|
|
549
553
|
//---------------------------------------------------------------------------
|
|
550
554
|
getNextIndex(index) {
|
|
551
555
|
this._ensureUnpacked();
|
|
@@ -566,6 +570,9 @@ class ThinDbObjectImpl extends DbObjectImpl {
|
|
|
566
570
|
// getPrevIndex()
|
|
567
571
|
//
|
|
568
572
|
// Returns the previous index in a collection.
|
|
573
|
+
// For associative arrays indexed by integers, if the passed-in index
|
|
574
|
+
// parameter is not present, it will return the next lower index found
|
|
575
|
+
// in the associative array.
|
|
569
576
|
//---------------------------------------------------------------------------
|
|
570
577
|
getPrevIndex(index) {
|
|
571
578
|
this._ensureUnpacked();
|
|
@@ -575,9 +582,11 @@ class ThinDbObjectImpl extends DbObjectImpl {
|
|
|
575
582
|
}
|
|
576
583
|
} else if (this.unpackedAssocArray) {
|
|
577
584
|
this._ensureAssocKeys();
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
585
|
+
let prev;
|
|
586
|
+
for (const key of this.unpackedAssocKeys) {
|
|
587
|
+
if (key >= index)
|
|
588
|
+
return prev;
|
|
589
|
+
prev = key;
|
|
581
590
|
}
|
|
582
591
|
}
|
|
583
592
|
}
|
package/lib/thin/pool.js
CHANGED
|
@@ -44,6 +44,9 @@ class ThinPoolImpl extends PoolImpl {
|
|
|
44
44
|
if (!params.homogeneous) {
|
|
45
45
|
errors.throwErr(errors.ERR_NOT_IMPLEMENTED, 'Heterogeneous Pooling');
|
|
46
46
|
}
|
|
47
|
+
if (!params.connectString) {
|
|
48
|
+
errors.throwErr(errors.ERR_EMPTY_CONNECT_STRING);
|
|
49
|
+
}
|
|
47
50
|
thinUtil.checkCredentials(params);
|
|
48
51
|
|
|
49
52
|
this._availableObjects = [];
|
|
@@ -48,7 +48,7 @@ module.exports = {
|
|
|
48
48
|
PURITY_NEW: constants.PURITY_NEW,
|
|
49
49
|
PURITY_SELF: constants.PURITY_SELF,
|
|
50
50
|
SYSASM: constants.SYSASM,
|
|
51
|
-
SYSBKP: constants.
|
|
51
|
+
SYSBKP: constants.SYSBACKUP,
|
|
52
52
|
SYSDBA: constants.SYSDBA,
|
|
53
53
|
SYSDG: constants.SYSDG,
|
|
54
54
|
SYSKM: constants.SYSKM,
|
|
@@ -102,6 +102,11 @@ class AuthMessage extends Message {
|
|
|
102
102
|
}
|
|
103
103
|
this.serviceName = this.conn.serviceName;
|
|
104
104
|
this.remoteAddress = this.conn.remoteAddress;
|
|
105
|
+
this.driverName = config.driverName;
|
|
106
|
+
this.machine = config.machine;
|
|
107
|
+
this.osUser = config.osUser;
|
|
108
|
+
this.program = config.program;
|
|
109
|
+
this.terminal = config.terminal;
|
|
105
110
|
this.setAuthMode(config);
|
|
106
111
|
}
|
|
107
112
|
|
|
@@ -181,11 +186,11 @@ class AuthMessage extends Message {
|
|
|
181
186
|
if (this.userByteLen > 0) {
|
|
182
187
|
buf.writeBytesWithLength(Buffer.from(this.username));
|
|
183
188
|
}
|
|
184
|
-
buf.writeKeyValue("AUTH_TERMINAL", cInfo.terminal);
|
|
185
|
-
buf.writeKeyValue("AUTH_PROGRAM_NM", cInfo.program);
|
|
186
|
-
buf.writeKeyValue("AUTH_MACHINE", cInfo.hostName);
|
|
189
|
+
buf.writeKeyValue("AUTH_TERMINAL", this.terminal ?? cInfo.terminal);
|
|
190
|
+
buf.writeKeyValue("AUTH_PROGRAM_NM", this.program ?? cInfo.program);
|
|
191
|
+
buf.writeKeyValue("AUTH_MACHINE", this.machine ?? cInfo.hostName);
|
|
187
192
|
buf.writeKeyValue("AUTH_PID", cInfo.pid);
|
|
188
|
-
buf.writeKeyValue("AUTH_SID", cInfo.userName);
|
|
193
|
+
buf.writeKeyValue("AUTH_SID", this.osUser ?? cInfo.userName);
|
|
189
194
|
} else {
|
|
190
195
|
let numPairs = 0;
|
|
191
196
|
|
|
@@ -253,7 +258,8 @@ class AuthMessage extends Message {
|
|
|
253
258
|
}
|
|
254
259
|
if (!this.changePassword) {
|
|
255
260
|
buf.writeKeyValue("SESSION_CLIENT_CHARSET", "873");
|
|
256
|
-
buf.writeKeyValue("SESSION_CLIENT_DRIVER_NAME",
|
|
261
|
+
buf.writeKeyValue("SESSION_CLIENT_DRIVER_NAME",
|
|
262
|
+
this.driverName ?? constants.DRIVER_NAME);
|
|
257
263
|
buf.writeKeyValue("SESSION_CLIENT_VERSION",
|
|
258
264
|
constants.CLIENT_VERSION.toString());
|
|
259
265
|
buf.writeKeyValue("AUTH_ALTER_SESSION", this.getAlterTimezoneStatement(), 1);
|
|
@@ -321,7 +327,7 @@ class AuthMessage extends Message {
|
|
|
321
327
|
let portUpdateNum;
|
|
322
328
|
|
|
323
329
|
this.conn.dbDomain = this.sessionData['AUTH_SC_DB_DOMAIN'];
|
|
324
|
-
this.conn.dbName = this.sessionData['
|
|
330
|
+
this.conn.dbName = this.sessionData['AUTH_DBNAME'];
|
|
325
331
|
this.conn.maxOpenCursors = Number(this.sessionData['AUTH_MAX_OPEN_CURSORS'] || 0);
|
|
326
332
|
this.conn.serviceName = this.sessionData['AUTH_SC_SERVICE_NAME'];
|
|
327
333
|
this.conn.instanceName = this.sessionData['AUTH_INSTANCENAME'];
|
|
@@ -296,6 +296,9 @@ class Message {
|
|
|
296
296
|
this._writeCurrentSchemaPiggyback(buf);
|
|
297
297
|
}
|
|
298
298
|
if (this.connection.statementCache._cursorsToClose.size > 0 && !this.connection._drcpEstablishSession) {
|
|
299
|
+
// skip closing cursors when '_drcpEstablishSession = true' Since we don't know whether the same session
|
|
300
|
+
// is in use. We can not send the information across until after the session information has been returned
|
|
301
|
+
// (on the first round trip).
|
|
299
302
|
this.writeCloseCursorsPiggyBack(buf);
|
|
300
303
|
}
|
|
301
304
|
if (
|
|
@@ -67,7 +67,6 @@ class MessageWithData extends Message {
|
|
|
67
67
|
if (messageType === constants.TNS_MSG_TYPE_DESCRIBE_INFO) {
|
|
68
68
|
buf.skipBytesChunked();
|
|
69
69
|
const prevQueryVars = this.statement.queryVars;
|
|
70
|
-
this.statement.queryVars = [];
|
|
71
70
|
this.statement.numQueryVars = 0;
|
|
72
71
|
this.statement.bufferRowCount = 0;
|
|
73
72
|
this.statement.bufferRowIndex = 0;
|
|
@@ -512,9 +511,7 @@ class MessageWithData extends Message {
|
|
|
512
511
|
const bvalue = buf.readUB4();
|
|
513
512
|
if (bvalue > 0) { // Non Null data in column
|
|
514
513
|
colValue = new ThinLobImpl();
|
|
515
|
-
if (oraTypeNum
|
|
516
|
-
buf.skipUB4();
|
|
517
|
-
} else {
|
|
514
|
+
if (oraTypeNum !== constants.TNS_DATA_TYPE_BFILE) {
|
|
518
515
|
length = buf.readUB8();
|
|
519
516
|
chunkSize = buf.readUB4();
|
|
520
517
|
}
|
|
@@ -633,7 +630,6 @@ class MessageWithData extends Message {
|
|
|
633
630
|
if (variable.type === types.DB_TYPE_CLOB ||
|
|
634
631
|
variable.type === types.DB_TYPE_NCLOB ||
|
|
635
632
|
variable.type === types.DB_TYPE_BLOB ||
|
|
636
|
-
variable.type === types.DB_TYPE_BFILE ||
|
|
637
633
|
variable.type === types.DB_TYPE_JSON ||
|
|
638
634
|
variable.type === types.DB_TYPE_VECTOR) {
|
|
639
635
|
if (variable.type !== variable.fetchInfo.fetchType) {
|
|
@@ -702,7 +698,7 @@ class MessageWithData extends Message {
|
|
|
702
698
|
// conversion requested if maxSize is not multiplied by the
|
|
703
699
|
// bufferSizeFactor
|
|
704
700
|
if (variable.type._csfrm === constants.CSFRM_NCHAR) {
|
|
705
|
-
maxSize
|
|
701
|
+
maxSize = Math.min(maxSize * variable.type._bufferSizeFactor, constants.TNS_MAX_LONG_LENGTH);
|
|
706
702
|
}
|
|
707
703
|
if ([constants.TNS_DATA_TYPE_ROWID, constants.TNS_DATA_TYPE_UROWID].includes(oraTypeNum)) {
|
|
708
704
|
oraTypeNum = constants.TNS_DATA_TYPE_VARCHAR;
|
|
@@ -715,8 +711,7 @@ class MessageWithData extends Message {
|
|
|
715
711
|
let contFlag = 0;
|
|
716
712
|
if (variable.type === types.DB_TYPE_BLOB ||
|
|
717
713
|
variable.type === types.DB_TYPE_CLOB ||
|
|
718
|
-
variable.type === types.DB_TYPE_NCLOB
|
|
719
|
-
variable.type === types.DB_TYPE_BFILE) {
|
|
714
|
+
variable.type === types.DB_TYPE_NCLOB) {
|
|
720
715
|
contFlag = constants.TNS_LOB_PREFETCH_FLAG;
|
|
721
716
|
} else if (variable.type === types.DB_TYPE_JSON) {
|
|
722
717
|
contFlag = constants.TNS_LOB_PREFETCH_FLAG;
|
|
@@ -731,11 +726,9 @@ class MessageWithData extends Message {
|
|
|
731
726
|
// expects that and complains if any other value is sent!
|
|
732
727
|
buf.writeUInt8(0);
|
|
733
728
|
buf.writeUInt8(0);
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
buf.writeUB4(maxSize);
|
|
738
|
-
}
|
|
729
|
+
|
|
730
|
+
// Write the max buffer size
|
|
731
|
+
buf.writeUB4(maxSize);
|
|
739
732
|
|
|
740
733
|
if (variable.isArray) {
|
|
741
734
|
buf.writeUB4(variable.maxArraySize);
|
|
@@ -31,6 +31,7 @@ const Capabilities = require("./capabilities.js");
|
|
|
31
31
|
const {WritePacket, ReadPacket} = require("./packet.js");
|
|
32
32
|
const errors = require("../../errors");
|
|
33
33
|
const utils = require("./utils.js");
|
|
34
|
+
const traceHandler = require('../../traceHandler.js');
|
|
34
35
|
|
|
35
36
|
/**
|
|
36
37
|
* Handles protocol details.
|
|
@@ -141,6 +142,13 @@ class Protocol {
|
|
|
141
142
|
async _processMessage(message) {
|
|
142
143
|
let callTimer;
|
|
143
144
|
let callTimeoutExpired = false;
|
|
145
|
+
let traceInstance, traceContext;
|
|
146
|
+
const traceEnabled = traceHandler.isEnabled();
|
|
147
|
+
|
|
148
|
+
if (traceEnabled) {
|
|
149
|
+
traceContext = { additionalConfig: {} };
|
|
150
|
+
traceInstance = traceHandler.getTraceInstance();
|
|
151
|
+
}
|
|
144
152
|
try {
|
|
145
153
|
if (this.callTimeout > 0) {
|
|
146
154
|
callTimer = setTimeout(() => {
|
|
@@ -148,6 +156,10 @@ class Protocol {
|
|
|
148
156
|
this.breakMessage();
|
|
149
157
|
}, this.callTimeout);
|
|
150
158
|
}
|
|
159
|
+
if (traceEnabled) {
|
|
160
|
+
traceContext.operation = `oracledb.${message.constructor.name}`;
|
|
161
|
+
traceInstance.onBeginRoundTrip(traceContext);
|
|
162
|
+
}
|
|
151
163
|
await this._encodeMessage(message);
|
|
152
164
|
if (message.messageType !== constants.TNS_MSG_TYPE_ONEWAY_FN) {
|
|
153
165
|
await this._decodeMessage(message);
|
|
@@ -157,9 +169,20 @@ class Protocol {
|
|
|
157
169
|
err.code !== errors.ERR_CONNECTION_CLOSED_CODE) {
|
|
158
170
|
await this._recoverFromError(err, message);
|
|
159
171
|
}
|
|
172
|
+
if (traceEnabled) {
|
|
173
|
+
traceContext.error = err;
|
|
174
|
+
}
|
|
160
175
|
throw err;
|
|
161
176
|
} finally {
|
|
162
177
|
clearTimeout(callTimer);
|
|
178
|
+
if (traceEnabled) {
|
|
179
|
+
traceContext.callLevelConfig = message.connection._callLevelTraceData;
|
|
180
|
+
traceContext.connectLevelConfig = message.connection._getConnectTraceConfig();
|
|
181
|
+
if (message.callStatus & constants.TNS_EOCS_FLAGS_SESS_RELEASE) {
|
|
182
|
+
traceContext.additionalConfig.implicitRelease = true;
|
|
183
|
+
}
|
|
184
|
+
traceInstance.onEndRoundTrip(traceContext);
|
|
185
|
+
}
|
|
163
186
|
}
|
|
164
187
|
if (message.flushOutBinds) {
|
|
165
188
|
await this.flushOutBindMessage(message);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2022,
|
|
1
|
+
// Copyright (c) 2022, 2024, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
const { NavAddress, NavAddressList, NavDescription, NavDescriptionList } = require("./navNodes.js");
|
|
30
30
|
const { createNVPair } = require("./nvStrToNvPair.js");
|
|
31
31
|
const errors = require("../../errors.js");
|
|
32
|
+
const constants = require("./constants.js");
|
|
32
33
|
|
|
33
34
|
/**
|
|
34
35
|
* Class that holds all possible attributes under Description
|
|
@@ -89,6 +90,7 @@ class ConnStrategy {
|
|
|
89
90
|
this.descriptionList.push(this.currentDescription);
|
|
90
91
|
this.currentDescription = null;
|
|
91
92
|
}
|
|
93
|
+
|
|
92
94
|
/**
|
|
93
95
|
* Execute the Connection Options from the array. When a refuse packet is received from
|
|
94
96
|
* server this method is called again and the next connect option is tried.
|
|
@@ -114,6 +116,8 @@ class ConnStrategy {
|
|
|
114
116
|
if (config != null) {
|
|
115
117
|
if ((delay == 0 || delay == undefined) && config.retryDelay > 0) {
|
|
116
118
|
delay = config.retryDelay * 1000;
|
|
119
|
+
} else if (!delay) {
|
|
120
|
+
delay = constants.DEFAULT_RETRY_DELAY; // 1 sec default
|
|
117
121
|
}
|
|
118
122
|
}
|
|
119
123
|
for (let i = this.lastRetryCounter; i <= this.retryCount; ++i) {
|
|
@@ -145,8 +149,8 @@ class ConnStrategy {
|
|
|
145
149
|
}
|
|
146
150
|
// sleep time expects milliseconds
|
|
147
151
|
|
|
148
|
-
|
|
149
152
|
}
|
|
153
|
+
|
|
150
154
|
function sleep(time) {
|
|
151
155
|
return new Promise((resolve) => setTimeout(resolve, time));
|
|
152
156
|
}
|
|
@@ -157,7 +161,7 @@ function sleep(time) {
|
|
|
157
161
|
* @param {string} str - input description string
|
|
158
162
|
* @returns {object} - returns a connection strategy object.
|
|
159
163
|
*/
|
|
160
|
-
async function createNode(str) {
|
|
164
|
+
async function createNode(str, userConfig) {
|
|
161
165
|
let nvpair;
|
|
162
166
|
if (typeof str === 'string')
|
|
163
167
|
nvpair = createNVPair(str);
|
|
@@ -185,6 +189,11 @@ async function createNode(str) {
|
|
|
185
189
|
}
|
|
186
190
|
navobj.initFromNVPair(nvpair);
|
|
187
191
|
const cs = new ConnStrategy();
|
|
192
|
+
cs.driverName = userConfig.driverName;
|
|
193
|
+
cs.machine = userConfig.machine;
|
|
194
|
+
cs.terminal = userConfig.terminal;
|
|
195
|
+
cs.osUser = userConfig.osUser;
|
|
196
|
+
cs.program = userConfig.program;
|
|
188
197
|
await navobj.navigate(cs);
|
|
189
198
|
return cs;
|
|
190
199
|
}
|
|
@@ -187,6 +187,8 @@ module.exports = {
|
|
|
187
187
|
DISABLE_OOB_STR: 'DISABLE_OOB', // disable OOB parameter
|
|
188
188
|
EXPIRE_TIME: 'EXPIRE_TIME', // expire Time
|
|
189
189
|
PEM_WALLET_FILE_NAME: 'ewallet.pem',
|
|
190
|
+
DEFAULT_TRANSPORT_CONNECT_TIMEOUT: 20000, //default transport connect timeout
|
|
191
|
+
DEFAULT_RETRY_DELAY: 1000, //default retry delay
|
|
190
192
|
|
|
191
193
|
/* Get/Set options */
|
|
192
194
|
NT_MOREDATA: 1, // More Data in Transport available
|