oracledb 6.6.0 → 6.7.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/README.md +2 -2
- package/build/Release/oracledb-6.7.0-darwin-arm64.node +0 -0
- package/build/Release/oracledb-6.7.0-darwin-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.7.0-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.7.0-darwin-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.7.0-js-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.7.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.7.0-linux-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.7.0-linux-x64.node +0 -0
- package/build/Release/oracledb-6.7.0-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.7.0-win32-x64.node +0 -0
- package/build/Release/oracledb-6.7.0-win32-x64.node-buildinfo.txt +1 -0
- package/examples/README.md +2 -0
- 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 +70 -3
- package/lib/errors.js +13 -6
- 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 +220 -35
- package/lib/pool.js +14 -5
- package/lib/settings.js +1 -0
- package/lib/thin/connection.js +150 -91
- package/lib/thin/pool.js +3 -0
- 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 +2 -7
- package/lib/thin/protocol/protocol.js +23 -0
- package/lib/thin/sqlnet/connStrategy.js +9 -1
- package/lib/thin/sqlnet/constants.js +2 -0
- package/lib/thin/sqlnet/navNodes.js +14 -2
- package/lib/thin/sqlnet/networkSession.js +9 -9
- package/lib/thin/sqlnet/ntTcp.js +1 -1
- 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 +179 -33
- package/lib/version.js +1 -1
- 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/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/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 = [];
|
|
@@ -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) {
|
|
@@ -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;
|
|
@@ -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);
|
|
@@ -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
|
|
@@ -114,6 +115,8 @@ class ConnStrategy {
|
|
|
114
115
|
if (config != null) {
|
|
115
116
|
if ((delay == 0 || delay == undefined) && config.retryDelay > 0) {
|
|
116
117
|
delay = config.retryDelay * 1000;
|
|
118
|
+
} else if (!delay) {
|
|
119
|
+
delay = constants.DEFAULT_RETRY_DELAY; // 1 sec default
|
|
117
120
|
}
|
|
118
121
|
}
|
|
119
122
|
for (let i = this.lastRetryCounter; i <= this.retryCount; ++i) {
|
|
@@ -157,7 +160,7 @@ function sleep(time) {
|
|
|
157
160
|
* @param {string} str - input description string
|
|
158
161
|
* @returns {object} - returns a connection strategy object.
|
|
159
162
|
*/
|
|
160
|
-
async function createNode(str) {
|
|
163
|
+
async function createNode(str, userConfig) {
|
|
161
164
|
let nvpair;
|
|
162
165
|
if (typeof str === 'string')
|
|
163
166
|
nvpair = createNVPair(str);
|
|
@@ -185,6 +188,11 @@ async function createNode(str) {
|
|
|
185
188
|
}
|
|
186
189
|
navobj.initFromNVPair(nvpair);
|
|
187
190
|
const cs = new ConnStrategy();
|
|
191
|
+
cs.driverName = userConfig.driverName;
|
|
192
|
+
cs.machine = userConfig.machine;
|
|
193
|
+
cs.terminal = userConfig.terminal;
|
|
194
|
+
cs.osUser = userConfig.osUser;
|
|
195
|
+
cs.program = userConfig.program;
|
|
188
196
|
await navobj.navigate(cs);
|
|
189
197
|
return cs;
|
|
190
198
|
}
|
|
@@ -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
|
|
@@ -777,8 +777,20 @@ class NavDescription extends Description {
|
|
|
777
777
|
if (this.connectData == null) {
|
|
778
778
|
this.connectData = "(SERVICE_NAME=)";
|
|
779
779
|
}
|
|
780
|
-
|
|
781
|
-
|
|
780
|
+
|
|
781
|
+
let pgmName = cInfo.program;
|
|
782
|
+
if (cs.program) {
|
|
783
|
+
pgmName = cs.program;
|
|
784
|
+
}
|
|
785
|
+
let hostName = cInfo.hostName;
|
|
786
|
+
if (cs.machine) {
|
|
787
|
+
hostName = cs.machine;
|
|
788
|
+
}
|
|
789
|
+
let userName = cInfo.userName;
|
|
790
|
+
if (cs.osUser) {
|
|
791
|
+
userName = cs.osUser;
|
|
792
|
+
}
|
|
793
|
+
const cid = `(CID=(PROGRAM=${pgmName})(HOST=${hostName})(USER=${userName}))`;
|
|
782
794
|
cOpts[i].CNdata.push(NavSchemaObject.CD);
|
|
783
795
|
cOpts[i].CNdata.push(this.connectData);
|
|
784
796
|
cOpts[i].CNdata.push(cid);
|
|
@@ -46,7 +46,7 @@ const downHostInstance = require("./connStrategy.js").SOLE_INST_DHCACHE;
|
|
|
46
46
|
|
|
47
47
|
async function getConnectionInfo(userConfig) {
|
|
48
48
|
const connStr = await resolveConnectStr(userConfig.connectString, userConfig.configDir);
|
|
49
|
-
const addressNode = await createNode(connStr);
|
|
49
|
+
const addressNode = await createNode(connStr, userConfig);
|
|
50
50
|
let nvpair;
|
|
51
51
|
if (typeof connStr === 'string')
|
|
52
52
|
nvpair = createNVPair(connStr);
|
|
@@ -97,9 +97,9 @@ async function resolveConnectStr(connectString, configDir) {
|
|
|
97
97
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
async function resolveAddress(connStr,
|
|
101
|
-
const connstr = await resolveConnectStr(connStr, configDir);
|
|
102
|
-
return createNode(connstr);
|
|
100
|
+
async function resolveAddress(connStr, userConfig) {
|
|
101
|
+
const connstr = await resolveConnectStr(connStr, userConfig.configDir);
|
|
102
|
+
return createNode(connstr, userConfig);
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
/**
|
|
@@ -199,7 +199,7 @@ class NetworkSession {
|
|
|
199
199
|
* Establish network session .Make transport level connection, send NSPTCN(connect packet) and read the response.
|
|
200
200
|
* @returns NetError.(connection successfully established(NetError.CONNECTED) or reason for failure)
|
|
201
201
|
*/
|
|
202
|
-
async connect2(address) {
|
|
202
|
+
async connect2(address, userConfig) {
|
|
203
203
|
/* Sanitise SDU */
|
|
204
204
|
if (this.sAtts.sdu) {
|
|
205
205
|
if (this.sAtts.sdu > constants.NSPABSSDULN) {
|
|
@@ -269,7 +269,7 @@ class NetworkSession {
|
|
|
269
269
|
redirConnData = this.cData;
|
|
270
270
|
}
|
|
271
271
|
|
|
272
|
-
const redirAddressNode = await resolveAddress(adrStr);
|
|
272
|
+
const redirAddressNode = await resolveAddress(adrStr, userConfig);
|
|
273
273
|
const host = address.hostname;
|
|
274
274
|
address = await redirAddressNode.execute();
|
|
275
275
|
if (address.desc)
|
|
@@ -314,10 +314,10 @@ class NetworkSession {
|
|
|
314
314
|
do {
|
|
315
315
|
try {
|
|
316
316
|
if (this.sAtts.connectTimeout) {
|
|
317
|
-
const asyncPromise = this.connect2(address);
|
|
317
|
+
const asyncPromise = this.connect2(address, userConfig);
|
|
318
318
|
connected = await timeout(asyncPromise, this.sAtts.connectTimeout, "connectTimeout", address, this.sAtts.connectionId);
|
|
319
319
|
} else {
|
|
320
|
-
connected = await this.connect2(address);
|
|
320
|
+
connected = await this.connect2(address, userConfig);
|
|
321
321
|
}
|
|
322
322
|
} catch (err) {
|
|
323
323
|
if (err.message.startsWith('NJS-510') && !this.ntAdapter.connected) {
|
|
@@ -528,7 +528,7 @@ class NetworkSession {
|
|
|
528
528
|
addressNode = userConfig._connInfo[5];
|
|
529
529
|
addressNode.reset();
|
|
530
530
|
} else {
|
|
531
|
-
addressNode = await resolveAddress(connStr, userConfig
|
|
531
|
+
addressNode = await resolveAddress(connStr, userConfig);
|
|
532
532
|
}
|
|
533
533
|
let address;
|
|
534
534
|
try {
|
package/lib/thin/sqlnet/ntTcp.js
CHANGED
|
@@ -168,7 +168,7 @@ class SessionAtts {
|
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
if (!this.connectTimeout && !this.transportConnectTimeout)
|
|
171
|
-
this.transportConnectTimeout =
|
|
171
|
+
this.transportConnectTimeout = constants.DEFAULT_TRANSPORT_CONNECT_TIMEOUT; /* Default to 20 secs */
|
|
172
172
|
}
|
|
173
173
|
|
|
174
174
|
}
|
package/lib/thin/util.js
CHANGED
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
const constants = require('../constants');
|
|
30
30
|
const errors = require('../errors.js');
|
|
31
31
|
const os = require('os');
|
|
32
|
+
const nodbUtil = require('../util.js');
|
|
32
33
|
|
|
33
34
|
//---------------------------------------------------------------------------
|
|
34
35
|
// populateClientInfo()
|
|
@@ -36,15 +37,15 @@ const os = require('os');
|
|
|
36
37
|
// Populates client process information
|
|
37
38
|
//---------------------------------------------------------------------------
|
|
38
39
|
function populateClientInfo() {
|
|
39
|
-
this.program = process.argv0;
|
|
40
|
+
this.program = nodbUtil.sanitize(process.argv0);
|
|
40
41
|
this.terminal = "unknown";
|
|
41
42
|
this.pid = process.pid.toString();
|
|
42
43
|
try {
|
|
43
|
-
this.userName = os.userInfo().username;
|
|
44
|
+
this.userName = nodbUtil.sanitize(os.userInfo().username);
|
|
44
45
|
} catch {
|
|
45
46
|
this.userName = "unknown";
|
|
46
47
|
}
|
|
47
|
-
this.hostName = os.hostname();
|
|
48
|
+
this.hostName = nodbUtil.sanitize(os.hostname());
|
|
48
49
|
}
|
|
49
50
|
// Initialize client data on startup.
|
|
50
51
|
const CLIENT_INFO = new populateClientInfo();
|