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.
Files changed (61) hide show
  1. package/README.md +2 -2
  2. package/build/Release/oracledb-6.7.0-darwin-arm64.node +0 -0
  3. package/build/Release/oracledb-6.7.0-darwin-arm64.node-buildinfo.txt +1 -0
  4. package/build/Release/oracledb-6.7.0-darwin-x64.node +0 -0
  5. package/build/Release/oracledb-6.7.0-darwin-x64.node-buildinfo.txt +1 -0
  6. package/build/Release/oracledb-6.7.0-js-buildinfo.txt +1 -0
  7. package/build/Release/oracledb-6.7.0-linux-arm64.node +0 -0
  8. package/build/Release/oracledb-6.7.0-linux-arm64.node-buildinfo.txt +1 -0
  9. package/build/Release/oracledb-6.7.0-linux-x64.node +0 -0
  10. package/build/Release/oracledb-6.7.0-linux-x64.node-buildinfo.txt +1 -0
  11. package/build/Release/oracledb-6.7.0-win32-x64.node +0 -0
  12. package/build/Release/oracledb-6.7.0-win32-x64.node-buildinfo.txt +1 -0
  13. package/examples/README.md +2 -0
  14. package/lib/configProviders/azure.js +26 -15
  15. package/lib/configProviders/base.js +23 -37
  16. package/lib/configProviders/ociobject.js +53 -45
  17. package/lib/connection.js +70 -3
  18. package/lib/errors.js +13 -6
  19. package/lib/impl/aqQueue.js +2 -1
  20. package/lib/impl/base.js +45 -0
  21. package/lib/impl/connection.js +53 -0
  22. package/lib/impl/lob.js +2 -1
  23. package/lib/impl/pool.js +15 -0
  24. package/lib/impl/resultset.js +2 -1
  25. package/lib/impl/sodaCollection.js +2 -1
  26. package/lib/impl/sodaDatabase.js +2 -1
  27. package/lib/impl/sodaDocCursor.js +2 -1
  28. package/lib/impl/sodaOperation.js +2 -1
  29. package/lib/lob.js +3 -2
  30. package/lib/oracledb.js +220 -35
  31. package/lib/pool.js +14 -5
  32. package/lib/settings.js +1 -0
  33. package/lib/thin/connection.js +150 -91
  34. package/lib/thin/pool.js +3 -0
  35. package/lib/thin/protocol/messages/auth.js +12 -6
  36. package/lib/thin/protocol/messages/base.js +3 -0
  37. package/lib/thin/protocol/messages/sessionRelease.js +1 -0
  38. package/lib/thin/protocol/messages/withData.js +2 -7
  39. package/lib/thin/protocol/protocol.js +23 -0
  40. package/lib/thin/sqlnet/connStrategy.js +9 -1
  41. package/lib/thin/sqlnet/constants.js +2 -0
  42. package/lib/thin/sqlnet/navNodes.js +14 -2
  43. package/lib/thin/sqlnet/networkSession.js +9 -9
  44. package/lib/thin/sqlnet/ntTcp.js +1 -1
  45. package/lib/thin/sqlnet/sessionAtts.js +1 -1
  46. package/lib/thin/util.js +4 -3
  47. package/lib/traceHandler.js +133 -0
  48. package/lib/util.js +179 -33
  49. package/lib/version.js +1 -1
  50. package/package.json +1 -1
  51. package/build/Release/oracledb-6.6.0-darwin-arm64.node +0 -0
  52. package/build/Release/oracledb-6.6.0-darwin-arm64.node-buildinfo.txt +0 -1
  53. package/build/Release/oracledb-6.6.0-darwin-x64.node +0 -0
  54. package/build/Release/oracledb-6.6.0-darwin-x64.node-buildinfo.txt +0 -1
  55. package/build/Release/oracledb-6.6.0-js-buildinfo.txt +0 -1
  56. package/build/Release/oracledb-6.6.0-linux-arm64.node +0 -0
  57. package/build/Release/oracledb-6.6.0-linux-arm64.node-buildinfo.txt +0 -1
  58. package/build/Release/oracledb-6.6.0-linux-x64.node +0 -0
  59. package/build/Release/oracledb-6.6.0-linux-x64.node-buildinfo.txt +0 -1
  60. package/build/Release/oracledb-6.6.0-win32-x64.node +0 -0
  61. package/build/Release/oracledb-6.6.0-win32-x64.node-buildinfo.txt +0 -1
@@ -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 numBinds = statement.bindInfoList.length;
174
- const numVars = binds.length;
175
- if (numBinds !== numVars && (numVars === 0 || !binds[0].name)) {
176
- errors.throwErr(errors.ERR_WRONG_NUMBER_OF_POSITIONAL_BINDS, numBinds, numVars);
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
- // check cache; if already present, nothing more to do!
544
- const info = this._getDbObjectType(result.outBinds.schema,
545
- result.outBinds.name, result.outBinds.package_name, result.outBinds.oid);
546
- if (!info.partial)
547
- return info;
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
- } else {
594
- info.version = result.outBinds.version;
595
- const attrRows = await result.outBinds.attrs_rc._getAllRows();
596
- if (attrRows.length > 0) {
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
- info.attributes = [];
599
- for (const row of attrRows) {
600
- const metaData = {
601
- name: row[1],
602
- dataType: row[3],
603
- dataTypeOwner: row[4],
604
- packageName: row[5],
605
- oid: row[6]
606
- };
607
- this._addAttr(info.attributes, metaData);
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
- await this._parseTDS(result.outBinds.tds, info);
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", constants.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['AUTH_SC_DBUNIQUE_NAME'];
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 (
@@ -45,6 +45,7 @@ class SessionReleaseMessage extends Message {
45
45
  }
46
46
 
47
47
  encode(buf) {
48
+ this.writePiggybacks(buf);
48
49
  this.writeFunctionHeader(buf);
49
50
  buf.writeUInt8(0); // pointer (tag name)
50
51
  buf.writeUInt8(0); // tag name length
@@ -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 === constants.TNS_DATA_TYPE_BFILE) {
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
- const pgmName = "\"'" + cInfo.program + "'\"";
781
- const cid = `(CID=(PROGRAM=${pgmName})(HOST=${cInfo.hostName})(USER=${cInfo.userName}))`;
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, configDir) {
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.configDir);
531
+ addressNode = await resolveAddress(connStr, userConfig);
532
532
  }
533
533
  let address;
534
534
  try {
@@ -234,7 +234,7 @@ class NTTCP {
234
234
  ca: this.atts.wallet,
235
235
  });
236
236
  } catch (err) {
237
- errors.throwErr(errors.ERR_TLS_INIT_FAILURE);
237
+ errors.throwErr(errors.ERR_TLS_INIT_FAILURE, err.message);
238
238
  }
239
239
  await this.tlsConnect(secureContext, this.stream);
240
240
  }
@@ -168,7 +168,7 @@ class SessionAtts {
168
168
  }
169
169
 
170
170
  if (!this.connectTimeout && !this.transportConnectTimeout)
171
- this.transportConnectTimeout = 60 * 1000; /* Default to 60 secs */
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();