oracledb 6.7.0 → 6.7.2

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 (40) hide show
  1. package/README.md +3 -3
  2. package/build/Release/oracledb-6.7.2-darwin-arm64.node +0 -0
  3. package/build/Release/oracledb-6.7.2-darwin-arm64.node-buildinfo.txt +1 -0
  4. package/build/Release/oracledb-6.7.2-darwin-x64.node +0 -0
  5. package/build/Release/oracledb-6.7.2-darwin-x64.node-buildinfo.txt +1 -0
  6. package/build/Release/oracledb-6.7.2-js-buildinfo.txt +1 -0
  7. package/build/Release/oracledb-6.7.2-linux-arm64.node +0 -0
  8. package/build/Release/oracledb-6.7.2-linux-arm64.node-buildinfo.txt +1 -0
  9. package/build/Release/oracledb-6.7.2-linux-x64.node +0 -0
  10. package/build/Release/oracledb-6.7.2-linux-x64.node-buildinfo.txt +1 -0
  11. package/build/Release/oracledb-6.7.2-win32-x64.node +0 -0
  12. package/build/Release/oracledb-6.7.2-win32-x64.node-buildinfo.txt +1 -0
  13. package/examples/example.js +5 -5
  14. package/lib/connection.js +5 -0
  15. package/lib/errors.js +14 -9
  16. package/lib/oracledb.js +2 -2
  17. package/lib/thin/dbObject.js +13 -4
  18. package/lib/thin/protocol/constants.js +1 -1
  19. package/lib/thin/protocol/messages/withData.js +4 -6
  20. package/lib/thin/sqlnet/connStrategy.js +3 -2
  21. package/lib/thin/sqlnet/navNodes.js +16 -21
  22. package/lib/thin/sqlnet/networkSession.js +9 -5
  23. package/lib/thin/sqlnet/ntTcp.js +11 -5
  24. package/lib/thin/sqlnet/nvStrToNvPair.js +23 -26
  25. package/lib/thin/sqlnet/paramParser.js +42 -43
  26. package/lib/util.js +1 -3
  27. package/lib/version.js +2 -2
  28. package/package.json +1 -1
  29. package/build/Release/oracledb-6.7.0-darwin-arm64.node +0 -0
  30. package/build/Release/oracledb-6.7.0-darwin-arm64.node-buildinfo.txt +0 -1
  31. package/build/Release/oracledb-6.7.0-darwin-x64.node +0 -0
  32. package/build/Release/oracledb-6.7.0-darwin-x64.node-buildinfo.txt +0 -1
  33. package/build/Release/oracledb-6.7.0-js-buildinfo.txt +0 -1
  34. package/build/Release/oracledb-6.7.0-linux-arm64.node +0 -0
  35. package/build/Release/oracledb-6.7.0-linux-arm64.node-buildinfo.txt +0 -1
  36. package/build/Release/oracledb-6.7.0-linux-x64.node +0 -0
  37. package/build/Release/oracledb-6.7.0-linux-x64.node-buildinfo.txt +0 -1
  38. package/build/Release/oracledb-6.7.0-win32-x64.node +0 -0
  39. package/build/Release/oracledb-6.7.0-win32-x64.node-buildinfo.txt +0 -1
  40. package/examples/README.md +0 -140
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
- # node-oracledb version 6.7.0
1
+ # node-oracledb version 6.7.2
2
2
 
3
3
  The node-oracledb add-on for Node.js powers high performance Oracle Database
4
4
  applications. Applications can be written in TypeScript, or directly in
5
5
  JavaScript.
6
6
 
7
- Use node-oracledb 6.7.0 to connect Node.js 14.6, or later, to Oracle
7
+ Use node-oracledb 6.7.2 to connect Node.js 14.6, or later, to Oracle
8
8
  Database. Older versions of node-oracledb may work with older versions of
9
9
  Node.js.
10
10
 
@@ -48,7 +48,7 @@ vulnerability disclosure process.
48
48
 
49
49
  ## License
50
50
 
51
- Copyright (c) 2015, 2024, Oracle and/or its affiliates.
51
+ Copyright (c) 2015, 2025, Oracle and/or its affiliates.
52
52
 
53
53
  This software is dual-licensed to you under the Universal Permissive License
54
54
  (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
@@ -0,0 +1 @@
1
+ oracledb-6.7.2-darwin-arm64.node v22.2.0 d813e9fe939a65599afab84c08ad9fcea51718d5 ca4b004c471033328549f8b4d461cb5985fe2230 Fri, 07 Feb 2025 13:55:05 GMT
@@ -0,0 +1 @@
1
+ oracledb-6.7.2-darwin-x64.node v20.11.1 d813e9fe939a65599afab84c08ad9fcea51718d5 ca4b004c471033328549f8b4d461cb5985fe2230 Fri, 07 Feb 2025 14:37:36 GMT
@@ -0,0 +1 @@
1
+ d813e9fe939a65599afab84c08ad9fcea51718d5
@@ -0,0 +1 @@
1
+ oracledb-6.7.2-linux-arm64.node v20.16.0 d813e9fe939a65599afab84c08ad9fcea51718d5 ca4b004c471033328549f8b4d461cb5985fe2230 Fri, 07 Feb 2025 13:48:03 GMT
@@ -0,0 +1 @@
1
+ oracledb-6.7.2-linux-x64.node v20.16.0 d813e9fe939a65599afab84c08ad9fcea51718d5 ca4b004c471033328549f8b4d461cb5985fe2230 Fri, 07 Feb 2025 13:47:00 GMT
@@ -0,0 +1 @@
1
+ oracledb-6.7.2-win32-x64.node v20.0.0 d813e9fe939a65599afab84c08ad9fcea51718d5 ca4b004c471033328549f8b4d461cb5985fe2230 Fri, 07 Feb 2025 13:46:32 GMT
@@ -1,4 +1,4 @@
1
- /* Copyright (c) 2018, 2023, Oracle and/or its affiliates. */
1
+ /* Copyright (c) 2018, 2024, Oracle and/or its affiliates. */
2
2
 
3
3
  /******************************************************************************
4
4
  *
@@ -47,16 +47,16 @@ const dbConfig = require('./dbconfig.js');
47
47
  if (process.env.NODE_ORACLEDB_DRIVER_MODE === 'thick') {
48
48
 
49
49
  // Thick mode requires Oracle Client or Oracle Instant Client libraries.
50
- // On Windows and macOS Intel you can specify the directory containing the
50
+ // On Windows and macOS you can specify the directory containing the
51
51
  // libraries at runtime or before Node.js starts. On other platforms (where
52
52
  // Oracle libraries are available) the system library search path must always
53
53
  // include the Oracle library path before Node.js starts. If the search path
54
54
  // is not correct, you will get a DPI-1047 error. See the node-oracledb
55
55
  // installation documentation.
56
56
  let clientOpts = {};
57
- // On Windows and macOS Intel platforms, set the environment
58
- // variable NODE_ORACLEDB_CLIENT_LIB_DIR to the Oracle Client library path
59
- if (process.platform === 'win32' || (process.platform === 'darwin' && process.arch === 'x64')) {
57
+ // On Windows and macOS platforms, set the environment variable
58
+ // NODE_ORACLEDB_CLIENT_LIB_DIR to the Oracle Client library path
59
+ if (process.platform === 'win32' || process.platform === 'darwin') {
60
60
  clientOpts = { libDir: process.env.NODE_ORACLEDB_CLIENT_LIB_DIR };
61
61
  }
62
62
  oracledb.initOracleClient(clientOpts); // enable node-oracledb Thick mode
package/lib/connection.js CHANGED
@@ -748,6 +748,11 @@ class Connection extends EventEmitter {
748
748
  }
749
749
 
750
750
  delete this._impl;
751
+ if (!this.thin) {
752
+ for (const cls of this._dbObjectClasses.values()) {
753
+ cls._objType.refCleanup();
754
+ }
755
+ }
751
756
  this._dbObjectClasses.clear();
752
757
  this.emit('_afterConnClose');
753
758
  }
package/lib/errors.js CHANGED
@@ -195,6 +195,7 @@ const ERR_OCIOBJECT_CONFIG_PROVIDER_AUTH_FAILED = 526;
195
195
  const ERR_AZURE_VAULT_AUTH_FAILED = 527;
196
196
  const ERR_AZURE_SERVICE_PRINCIPAL_AUTH_FAILED = 528;
197
197
  const ERR_WALLET_TYPE_NOT_SUPPORTED = 529;
198
+ const ERR_HOST_NOT_FOUND = 530;
198
199
 
199
200
  // Oracle SUCCESS_WITH_INFO warning start from 700
200
201
  const WRN_COMPILATION_CREATE = 700;
@@ -511,24 +512,27 @@ messages.set(ERR_TNS_NAMES_FILE_MISSING, // NJS-520
511
512
  'cannot connect to Oracle Database. File tnsnames.ora not found in %s');
512
513
  messages.set(ERR_CONNECTION_EOF, // NJS-521
513
514
  'connection to host %s port %d received end-of-file on communication channel. (CONNECTION_ID=%s)');
514
- messages.set(ERR_AZURE_CONFIG_PROVIDER_AUTH_FAILED, // NJS-522
515
+ messages.set(ERR_AZURE_CONFIG_PROVIDER_AUTH_FAILED, // NJS-522
515
516
  'Azure Authentication Failed: The authentication parameter value %s may be incorrect');
516
- messages.set(ERR_CONFIG_PROVIDER_FAILED_TO_RETRIEVE_CONFIG, // NJS-523
517
+ messages.set(ERR_CONFIG_PROVIDER_FAILED_TO_RETRIEVE_CONFIG, // NJS-523
517
518
  'Failed to retrieve configuration from Centralized Configuration Provider:\n %s');
518
519
  messages.set(ERR_CONFIG_PROVIDER_NOT_SUPPORTED, // NJS-524
519
520
  'Configuration Provider not supported: %s');
520
521
  messages.set(ERR_CONFIG_PROVIDER_LOAD_FAILED, // NJS-525
521
522
  'Centralized Config Provider failed to load required libraries. Please install the required libraries.\n %s');
522
- messages.set(ERR_OCIOBJECT_CONFIG_PROVIDER_AUTH_FAILED, // NJS-526
523
+ messages.set(ERR_OCIOBJECT_CONFIG_PROVIDER_AUTH_FAILED, // NJS-526
523
524
  'OCI authentication failed: The authentication parameter value %s may be incorrect');
524
- messages.set(ERR_AZURE_VAULT_AUTH_FAILED, // NJS-527
525
- 'Azure Vault: Provide correct azure vault authentication details');
526
- messages.set(ERR_AZURE_SERVICE_PRINCIPAL_AUTH_FAILED, // NJS-528
525
+ messages.set(ERR_AZURE_VAULT_AUTH_FAILED, // NJS-527
526
+ 'Azure Vault: Provide correct Azure Vault authentication details');
527
+ messages.set(ERR_AZURE_SERVICE_PRINCIPAL_AUTH_FAILED, // NJS-528
527
528
  'Azure service principal authentication requires either a client certificate path or a client secret string');
528
- messages.set(ERR_WALLET_TYPE_NOT_SUPPORTED, 'Invalid wallet content format. Supported format is PEM');// NJS-529
529
- // Oracle SUCCESS_WITH_INFO warning
529
+ messages.set(ERR_WALLET_TYPE_NOT_SUPPORTED, // NJS-529
530
+ 'Invalid wallet content format. Supported format is PEM');
531
+ messages.set(ERR_HOST_NOT_FOUND, // NJS-530
532
+ 'The host addresses or URLs provided by the connect string are incorrect or unresolvable in your network.');
530
533
 
531
- messages.set(WRN_COMPILATION_CREATE, // NJS-700
534
+ // Oracle SUCCESS_WITH_INFO warning
535
+ messages.set(WRN_COMPILATION_CREATE, // NJS-700
532
536
  'creation succeeded with compilation errors');
533
537
 
534
538
  //-----------------------------------------------------------------------------
@@ -843,6 +847,7 @@ module.exports = {
843
847
  ERR_CONFIG_PROVIDER_NOT_SUPPORTED,
844
848
  ERR_CONFIG_PROVIDER_LOAD_FAILED,
845
849
  ERR_WALLET_TYPE_NOT_SUPPORTED,
850
+ ERR_HOST_NOT_FOUND,
846
851
  ERR_INVALID_BIND_NAME,
847
852
  ERR_WRONG_NUMBER_OF_BINDS,
848
853
  ERR_BUFFER_LENGTH_INSUFFICIENT,
package/lib/oracledb.js CHANGED
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2015, 2023, Oracle and/or its affiliates.
1
+ // Copyright (c) 2015, 2024, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -665,7 +665,7 @@ async function createPool(options) {
665
665
  // If a tnsnames.ora file does not exist, then an exception is raised
666
666
  //-----------------------------------------------------------------------------
667
667
  async function getNetworkServiceNames(configDir) {
668
- const { NLParamParser, tnsnamesFilePath } = require('thin/sqlnet/paramParser.js');
668
+ const { NLParamParser, tnsnamesFilePath } = require('./thin/sqlnet/paramParser.js');
669
669
  const nlParamParser = new NLParamParser;
670
670
  const filePath = tnsnamesFilePath(configDir);
671
671
  const aliasht = await nlParamParser.initializeNlpa(filePath);
@@ -179,7 +179,8 @@ class ThinDbObjectImpl extends DbObjectImpl {
179
179
  //---------------------------------------------------------------------------
180
180
  _ensureAssocKeys() {
181
181
  if (!this.unpackedAssocKeys) {
182
- this.unpackedAssocKeys = [...this.unpackedAssocArray.keys()].sort();
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
- for (const key of this.unpackedAssocKeys.reverse()) {
579
- if (key < index)
580
- return key;
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
  }
@@ -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.SYSBKP,
51
+ SYSBKP: constants.SYSBACKUP,
52
52
  SYSDBA: constants.SYSDBA,
53
53
  SYSDG: constants.SYSDG,
54
54
  SYSKM: constants.SYSKM,
@@ -698,7 +698,7 @@ class MessageWithData extends Message {
698
698
  // conversion requested if maxSize is not multiplied by the
699
699
  // bufferSizeFactor
700
700
  if (variable.type._csfrm === constants.CSFRM_NCHAR) {
701
- maxSize *= variable.type._bufferSizeFactor;
701
+ maxSize = Math.min(maxSize * variable.type._bufferSizeFactor, constants.TNS_MAX_LONG_LENGTH);
702
702
  }
703
703
  if ([constants.TNS_DATA_TYPE_ROWID, constants.TNS_DATA_TYPE_UROWID].includes(oraTypeNum)) {
704
704
  oraTypeNum = constants.TNS_DATA_TYPE_VARCHAR;
@@ -726,11 +726,9 @@ class MessageWithData extends Message {
726
726
  // expects that and complains if any other value is sent!
727
727
  buf.writeUInt8(0);
728
728
  buf.writeUInt8(0);
729
- if (maxSize > buf.caps.maxStringSize) {
730
- buf.writeUB4(constants.TNS_MAX_LONG_LENGTH);
731
- } else {
732
- buf.writeUB4(maxSize);
733
- }
729
+
730
+ // Write the max buffer size
731
+ buf.writeUB4(maxSize);
734
732
 
735
733
  if (variable.isArray) {
736
734
  buf.writeUB4(variable.maxArraySize);
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
1
+ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -90,6 +90,7 @@ class ConnStrategy {
90
90
  this.descriptionList.push(this.currentDescription);
91
91
  this.currentDescription = null;
92
92
  }
93
+
93
94
  /**
94
95
  * Execute the Connection Options from the array. When a refuse packet is received from
95
96
  * server this method is called again and the next connect option is tried.
@@ -148,8 +149,8 @@ class ConnStrategy {
148
149
  }
149
150
  // sleep time expects milliseconds
150
151
 
151
-
152
152
  }
153
+
153
154
  function sleep(time) {
154
155
  return new Promise((resolve) => setTimeout(resolve, time));
155
156
  }
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
1
+ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -315,6 +315,7 @@ class Description {
315
315
  }
316
316
  }
317
317
  }
318
+
318
319
  toString() {
319
320
  let s = new String(""), child ;
320
321
 
@@ -428,9 +429,6 @@ class DescriptionList {
428
429
  }
429
430
 
430
431
 
431
-
432
-
433
-
434
432
  /**
435
433
  * Class that contains information about a possible connection.
436
434
  */
@@ -453,6 +451,7 @@ const NavSchemaObject = {
453
451
  const options = {
454
452
  all: true,
455
453
  };
454
+
456
455
  /**
457
456
  * Class that navigates the address node in the tree.
458
457
  */
@@ -460,16 +459,17 @@ class NavAddress extends Address {
460
459
  constructor() {
461
460
  super();
462
461
  }
462
+
463
463
  /**
464
464
  * Set the connection option to this address.
465
465
  * @param {object} cs
466
466
  */
467
467
  async navigate(cs) {
468
468
  let addresses;
469
- let nullHost = 0;
469
+ let nullHost = false;
470
470
  let needToCloseDescription = false;
471
471
  if (!this.host) {
472
- nullHost = 1;
472
+ nullHost = true;
473
473
  this.host = os.hostname();
474
474
  try {
475
475
  await dnsPromises.lookup(this.host, options);
@@ -495,7 +495,7 @@ class NavAddress extends Address {
495
495
  co.httpsProxyPort = this.httpsProxyPort;
496
496
  co.desc = cs.getcurrentDescription();
497
497
  co.CNdata.push(cs.sBuf.join(""));
498
- if (nullHost == 1)
498
+ if (nullHost)
499
499
  co.CNdata.push('(address=(protocol=' + this.prot + ')(host=' + this.host + ')(port=' + this.port + '))');
500
500
  else
501
501
  co.CNdata.push(this.toString());
@@ -505,6 +505,8 @@ class NavAddress extends Address {
505
505
  }
506
506
  } catch {
507
507
  // do nothing
508
+ // Any error in the try block is ignored, because we want to try
509
+ // the next address
508
510
  }
509
511
  } else {
510
512
  const co = new ConnOption();
@@ -527,8 +529,6 @@ class NavAddress extends Address {
527
529
 
528
530
  }
529
531
 
530
-
531
-
532
532
  /**
533
533
  * AddToString is used to construct a string representation of the TNS
534
534
  * Address. Constructing a string is mainly needed when source route is ON.
@@ -557,10 +557,10 @@ class NavAddressList extends AddressList {
557
557
  }
558
558
 
559
559
  /**
560
- * Method decides how to traverse and sets the active children based on
561
- * the loadbalancing, failover values.
562
- * @param {object} cs
563
- */
560
+ * Method decides how to traverse and sets the active children based on
561
+ * the loadbalancing, failover values.
562
+ * @param {object} cs
563
+ */
564
564
  async navigate(cs) {
565
565
  await this.navigate2(cs, 0);
566
566
  }
@@ -592,6 +592,7 @@ class NavAddressList extends AddressList {
592
592
  cs.sBuf.length = this.sBuflength;
593
593
 
594
594
  }
595
+
595
596
  addToString(cs) {
596
597
  const NVString = this.toString();
597
598
  let cOpts = new Array();
@@ -604,7 +605,6 @@ class NavAddressList extends AddressList {
604
605
  }
605
606
  }
606
607
 
607
-
608
608
  getChildrenSize() {
609
609
  let size = 0;
610
610
  for (let i = 0; i < this.activeChildren.length; i++) {
@@ -762,7 +762,6 @@ class NavDescription extends Description {
762
762
  }
763
763
 
764
764
  closeNVPair(cs) {
765
-
766
765
  if (cs.getcurrentDescription() == null)
767
766
  return;
768
767
  let cOpts = new Array();
@@ -812,11 +811,9 @@ class NavDescription extends Description {
812
811
  }
813
812
 
814
813
  getIntValue(stringInt, defaultValue) {
815
- try {
814
+ if (/^\d+$/.test(stringInt))
816
815
  return parseInt(stringInt);
817
- } catch (exception) {
818
- return defaultValue;
819
- }
816
+ return defaultValue;
820
817
  }
821
818
 
822
819
  }
@@ -884,7 +881,5 @@ class NavDescriptionList extends DescriptionList {
884
881
 
885
882
  }
886
883
 
887
-
888
-
889
884
  }
890
885
  module.exports = {NavAddress, NavAddressList, NavDescription, NavDescriptionList};
@@ -143,6 +143,7 @@ class NetworkSession {
143
143
  async getAddress(addressNode, userConfig) {
144
144
  /* Get the next address */
145
145
  const address = await addressNode.execute(userConfig);
146
+
146
147
  /* Prepare connection attributes */
147
148
  const uuid = this.sAtts ? this.sAtts.uuid : null;
148
149
  this.sAtts = new SessionAtts(uuid);
@@ -196,8 +197,10 @@ class NetworkSession {
196
197
  }
197
198
 
198
199
  /**
199
- * Establish network session .Make transport level connection, send NSPTCN(connect packet) and read the response.
200
- * @returns NetError.(connection successfully established(NetError.CONNECTED) or reason for failure)
200
+ * Establish network session. Make transport level connection, send
201
+ * NSPTCN(connect packet) and read the response. @returns NetError.
202
+ * (connection successfully established(NetError.CONNECTED)
203
+ * or reason for failure)
201
204
  */
202
205
  async connect2(address, userConfig) {
203
206
  /* Sanitise SDU */
@@ -534,8 +537,8 @@ class NetworkSession {
534
537
  try {
535
538
  address = await this.getAddress(addressNode, userConfig);
536
539
  } catch (err) {
537
- if (err.message == "All options tried") /* Not even one valid Address */
538
- errors.throwErr(errors.ERR_INVALID_CONNECT_STRING_PARAMETERS, "Ensure the ADDRESS parameters have been entered correctly, the most likely incorrect parameter is the host name");
540
+ if (err.message == "All options tried") /* Not even one valid address */
541
+ errors.throwErr(errors.ERR_HOST_NOT_FOUND);
539
542
  else
540
543
  errors.throwErr(errors.ERR_INVALID_CONNECT_STRING_PARAMETERS, err.message);
541
544
  }
@@ -617,7 +620,8 @@ class NetworkSession {
617
620
  /**
618
621
  * receive inband notification
619
622
  * @param {Object} obj Return the notification into user provided object
620
- * @returns Error number sent from server, or error on the connection. returns 0 if healthy connection
623
+ * @returns Error number sent from server, or error on the connection.
624
+ * returns 0 if healthy connection
621
625
  */
622
626
  recvInbandNotif() {
623
627
  let error = 0;
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
1
+ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -72,7 +72,7 @@ class NTTCP {
72
72
  }
73
73
 
74
74
  /**
75
- * DN matching funciton(used with TLS)
75
+ * DN matching function(used with TLS)
76
76
  */
77
77
  dnMatch(serverName, cert) {
78
78
  if (this.atts.sslServerDNMatch && this.doDNMatch) {
@@ -211,7 +211,7 @@ class NTTCP {
211
211
 
212
212
  try {
213
213
  await this.ntConnect(address);
214
- if (this.atts.expireTime || this.atts.enableDCD) { /* Set Keep alives */
214
+ if (this.atts.expireTime || this.atts.enableDCD) { /* Set KeepAlives */
215
215
  if (this.atts.expireTime) {
216
216
  this.stream.setKeepAlive(true, this.atts.expireTime);
217
217
  } else {
@@ -248,7 +248,7 @@ class NTTCP {
248
248
  /**
249
249
  * Disconnect Network Transoprt
250
250
  * @param {int} type
251
- * @returns Proimise
251
+ * @returns Promise
252
252
  */
253
253
  disconnect(type) { /* Disconnect function for TCP sockets */
254
254
  if (this.connected && !this.err) {
@@ -470,8 +470,9 @@ class NTTCP {
470
470
  * @returns Promise
471
471
  */
472
472
  async renegTLS() {
473
+ let initTLSDone = false;
474
+ this.checkErr();
473
475
  try {
474
- this.checkErr();
475
476
  this.doDNMatch = true;
476
477
  const secureContext = tls.createSecureContext({
477
478
  cert: this.atts.wallet,
@@ -479,7 +480,12 @@ class NTTCP {
479
480
  passphrase: this.atts.walletPassword,
480
481
  ca: this.atts.wallet,
481
482
  });
483
+ initTLSDone = true;
482
484
  await this.tlsConnect(secureContext, this.connStream);
485
+ } catch (err) {
486
+ if (!initTLSDone)
487
+ errors.throwErr(errors.ERR_TLS_INIT_FAILURE, err.message);
488
+ else throw err;
483
489
  } finally {
484
490
  this.setupEventHandlers();
485
491
  }
@@ -68,6 +68,9 @@ class NVPair {
68
68
  this.listType = LIST_REGULAR;
69
69
  this.rhsType = RHS_NONE;
70
70
  }
71
+ /**
72
+ * @param {string} atom - input atom string literal
73
+ */
71
74
  set setAtom(atom) {
72
75
  if (this._containsComment(atom)) {
73
76
  errors.throwErr(errors.ERR_INVALID_CONNECT_STRING_SYNTAX);
@@ -122,7 +125,7 @@ class NVPair {
122
125
  }
123
126
  /**
124
127
  * adds a nvpair to the existing one.
125
- * @param {nvpair} pair
128
+ * @param {NVPair} pair
126
129
  */
127
130
  addListElement(pair) {
128
131
  if (this.list == null) {
@@ -147,11 +150,11 @@ class NVPair {
147
150
  }
148
151
  }
149
152
  /**
150
- * Returns an empty string with the number specified in the argument. Used for
151
- * indentation of multi-level NVPairs as they are stored
152
- *
153
- * @param count
154
- * Number of spaces required in the blank string.
153
+ * Returns an empty string with the number specified in the argument. Used
154
+ * for indentation of multi-level NVPairs as they are stored
155
+ *
156
+ * @param count
157
+ * Number of spaces required in the blank string.
155
158
  */
156
159
  _space(count) {
157
160
  var blank_str = "";
@@ -274,9 +277,9 @@ const TKN_LF_VALUE = '\n';
274
277
  const TKN_CR_VALUE = '\r';
275
278
 
276
279
  /**
277
- * The NVTokens class is used to help break NVStrings apart into tokens, such as
278
- * TKN_LPAREN or TKN_LITERAL - this helps simplify the task of building NVPairs
279
- * from an NVString.
280
+ * The NVTokens class is used to help break NVStrings apart into tokens, such
281
+ * as TKN_LPAREN or TKN_LITERAL - this helps simplify the task of building
282
+ * NVPairs from an NVString.
280
283
  */
281
284
  class NVTokens {
282
285
 
@@ -435,9 +438,8 @@ class NVTokens {
435
438
  return true;
436
439
  }
437
440
  /**
438
- * Returns current token. Throws Error if no string has
439
- * been parsed, or if there are no tokens left. Does NOT advance
440
- * the token position.
441
+ * Returns current token. Throws Error if no string has been parsed,
442
+ * or if there are no tokens left. Does NOT advance the token position.
441
443
  */
442
444
  getToken() {
443
445
  if (this.tkType == null) { // nothing parsed
@@ -451,9 +453,8 @@ class NVTokens {
451
453
  }
452
454
 
453
455
  /**
454
- * Returns current token. Throws Error if no string has
455
- * been parsed, or if there are no tokens left. DOES advance the
456
- * token position.
456
+ * Returns current token. Throws Error if no string has been parsed,
457
+ * or if there are no tokens left. DOES advance the token position.
457
458
  */
458
459
  popToken() {
459
460
  let token = TKN_NONE;
@@ -470,9 +471,8 @@ class NVTokens {
470
471
  }
471
472
  /**
472
473
  * Returns literal for current token. If current token is NOT a TKN_LITERAL,
473
- * it returns a string representation of the current token. Throws
474
- * Error if no string has been parsed, or
475
- * if there are no tokens left.
474
+ * it returns a string representation of the current token. Throws Error
475
+ * if no string has been parsed, or if there are no tokens left.
476
476
  *
477
477
  * DOES NOT advance the token position.
478
478
  */
@@ -492,9 +492,8 @@ class NVTokens {
492
492
 
493
493
  /**
494
494
  * Returns literal for current token. If current token is NOT a TKN_LITERAL,
495
- * it returns a string representation of the current token. Throws
496
- * Error if no string has been parsed, or
497
- * if there are no tokens left.
495
+ * it returns a string representation of the current token. Throws Error
496
+ * if no string has been parsed, or if there are no tokens left.
498
497
  *
499
498
  * DOES advance the token position.
500
499
  */
@@ -547,8 +546,6 @@ class NVTokens {
547
546
  }
548
547
 
549
548
 
550
-
551
-
552
549
  /**
553
550
  * The NVFactory class is used to help interpret the tokens generated by
554
551
  * NVTokens from an NVString.
@@ -696,7 +693,7 @@ function readNVList(nvt, parent) {
696
693
 
697
694
  /**
698
695
  * Returns a NVPair whose name matches (ignoring case) the specified
699
- * name. This function does search recursively through all descendents
696
+ * name. This function does search recursively through all descendants
700
697
  * of the specified NVPair.
701
698
  * @param nvp NVPair to search through
702
699
  * @param name name to match (ignoring case)
@@ -726,8 +723,8 @@ function findNVPairRecurse(nvp, name) {
726
723
  }
727
724
 
728
725
  /**
729
- * Returns a NVPair whose name matches (ignoring case) the specified
730
- * name. This functions only searches the direct descendants of specified NVPair
726
+ * Returns a NVPair whose name matches (ignoring case) the specified name.
727
+ * This functions only searches the direct descendants of specified NVPair
731
728
  * @param nvp NVPair to search through
732
729
  * @param name name to match (ignoring case)
733
730
  */
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
1
+ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -26,7 +26,7 @@
26
26
 
27
27
  'use strict';
28
28
 
29
- const {createNVPair, findValue} = require("./nvStrToNvPair.js");
29
+ const {createNVPair} = require("./nvStrToNvPair.js");
30
30
  const fs = require('fs');
31
31
  const process = require('process');
32
32
  const readline = require('readline');
@@ -59,12 +59,21 @@ function tnsnamesFilePath(configDir) {
59
59
  return filePathVal;
60
60
  }
61
61
  }
62
+ //Structure for each tnsnames.ora file
63
+ class tnsnamesElement {
62
64
 
65
+ constructor() {
66
+ this.readInProgress = false;
67
+ this.waiters = [];
68
+ this.aliasht = new Map(); // It will have key as alias and value as its aliases value
69
+ this.modTime = new Map(); // It will have tnsnames filename and also all its ifile and its modified time
70
+ }
71
+ }
63
72
  class NLParamParser {
64
73
 
65
74
  constructor() {
66
- this.waiters = [];
67
- this.readInProgress = false;
75
+ // key as tnsnames.ora(file_name) and value will be tnsnamesStruct<ht(alias key and value), modTime>
76
+ this.tnsnamesHT = new Map();
68
77
  }
69
78
  /**
70
79
  * Reads the given file line by line and stores the
@@ -73,29 +82,35 @@ class NLParamParser {
73
82
  * @returns {Promise}
74
83
  */
75
84
  async initializeNlpa(file_path) {
76
- if (this.readInProgress) {
85
+ let tnsFileStruct;
86
+ if (this.tnsnamesHT.has(file_path))
87
+ tnsFileStruct = this.tnsnamesHT.get(file_path);
88
+ else
89
+ tnsFileStruct = new tnsnamesElement();
90
+ if (tnsFileStruct.readInProgress) {
77
91
  await new Promise((resolve) => {
78
- this.waiters.push(resolve);
92
+ tnsFileStruct.waiters.push(resolve);
79
93
  });
80
94
  }
81
- if (!this.checkModfTime()) {
95
+ /* check modification time of all files in the cache
96
+ including the file_path */
97
+ if (!this.checkModfTime(tnsFileStruct)) {
82
98
  /* No File has been modified */
83
- return this.ht;
99
+ return tnsFileStruct.aliasht;
84
100
  }
85
- this.ht = new Map();
86
- this.modTime = new Map(); //stores modified time of each IFile
87
- this.readInProgress = true;
88
- await this.start(file_path, 0); //start with 0 depth (tnsnames.ora)
89
- return this.ht;
101
+ tnsFileStruct.readInProgress = true;
102
+ await this.start(file_path, 0, tnsFileStruct); //start with 0 depth (tnsnames.ora)
103
+ this.tnsnamesHT.set(file_path, tnsFileStruct);
104
+ return tnsFileStruct.aliasht;
90
105
  }
91
106
 
92
- async start(file_path, depth) {
107
+ async start(file_path, depth, tnsFileStruct) {
93
108
 
94
109
  if (depth > MAX_IFILE_DEPTH)
95
110
  return; //ignore after max depth
96
111
  const stat = fs.statSync(file_path);
97
112
  // store file path and its modified time.
98
- this.modTime.set(file_path, stat.mtime);
113
+ tnsFileStruct.modTime.set(file_path, stat.mtime);
99
114
  // Creating a readable stream from file
100
115
  // readline module reads line by line
101
116
  // but from a readable stream only.
@@ -129,7 +144,7 @@ class NLParamParser {
129
144
  nvElem = nvElem + line;
130
145
 
131
146
  } else if (nvElem.length != 0) {
132
- await this.addNLPListElement(nvElem, depth); // Add Parameter to Hashtable
147
+ await this.addNLPListElement(nvElem, depth, tnsFileStruct); // Add Parameter to Hashtable
133
148
  nvElem = ""; // Clear first, before storing current line
134
149
 
135
150
  line = this.checkNLPforComments(line);
@@ -138,12 +153,12 @@ class NLParamParser {
138
153
  }
139
154
  }
140
155
  if (nvElem.length != 0) { // at eof, still one more parameter to read
141
- await this.addNLPListElement(nvElem, depth);
156
+ await this.addNLPListElement(nvElem, depth, tnsFileStruct);
142
157
  nvElem = ""; // clear nvElem buffer after added
143
158
  }
144
- this.readInProgress = false;
159
+ tnsFileStruct.readInProgress = false;
145
160
  let waiter;
146
- while ((waiter = this.waiters.pop())) {
161
+ while ((waiter = tnsFileStruct.waiters.pop())) {
147
162
  waiter();
148
163
  }
149
164
  }
@@ -173,9 +188,11 @@ class NLParamParser {
173
188
  return str1.join('');
174
189
  }
175
190
  // check if any of the IFiles has been changed
176
- checkModfTime() {
177
- if (this.modTime) {
178
- for (const [key, value] of this.modTime) {
191
+ checkModfTime(tnsFileStruct) {
192
+ // There may be multiple tnsnames.ora files. So check if the tnsnames.ora
193
+ // in question is already cached
194
+ if (tnsFileStruct.modTime.size != 0) {
195
+ for (const [key, value] of tnsFileStruct.modTime) {
179
196
  if (fs.existsSync(key)) {
180
197
  const stat = fs.statSync(key);
181
198
  if ((stat.mtime - value > 0)) {
@@ -193,7 +210,7 @@ class NLParamParser {
193
210
  * adds name value pairs from the input buffer into the hash table.
194
211
  * @param {string} ibuf
195
212
  */
196
- async addNLPListElement(ibuf, depth) {
213
+ async addNLPListElement(ibuf, depth, tnsFileStruct) {
197
214
  const res = ibuf.split(/\r?\n/).filter(element => element);
198
215
  for (let i = 0; i < res.length; i++) {
199
216
  if (res[i].charAt(0) != '(') {
@@ -205,33 +222,15 @@ class NLParamParser {
205
222
  nvp.name = uname;
206
223
  // support for ifile
207
224
  if (uname == 'IFILE') {
208
- await this.start(nvp.atom, depth + 1);
225
+ await this.start(nvp.atom, depth + 1, tnsFileStruct);
209
226
  } else {
210
227
  const unames = uname.split(","); //multiple aliases (alias1, alias2, alias3)
211
228
  for (let i = 0; i < unames.length; i++) {
212
- this.ht.set(unames[i], nvp);
229
+ tnsFileStruct.aliasht.set(unames[i], nvp);
213
230
  }
214
231
  }
215
232
  }
216
233
  }
217
- toString() {
218
- let out = "";
219
- this.ht.forEach((value) => {
220
- out = out + value.toString() + "\n";
221
- });
222
- return out;
223
- }
224
- /**
225
- * if key is address/port then it returns the port value from the
226
- * address NVPAIR.
227
- * @param {string} key
228
- * @returns {string}
229
- */
230
- findValueOf(key) {
231
- const myarr = key.split('/');
232
- return (findValue(this.ht.get(myarr[0].toUpperCase()), myarr));
233
- }
234
-
235
234
  }
236
235
 
237
236
  module.exports = {
package/lib/util.js CHANGED
@@ -171,9 +171,7 @@ function traceExitFn(traceContext, result, err) {
171
171
  }
172
172
 
173
173
  // Fill the traceContext.
174
- if (err) {
175
- traceContext.error = Object.assign(({}, err));
176
- }
174
+ traceContext.error = err;
177
175
  traceContext.additionalConfig.result = result;
178
176
  if (this._impl) {
179
177
  // fill function call state.
package/lib/version.js CHANGED
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2023, 2024, Oracle and/or its affiliates.
1
+ // Copyright (c) 2023, 2025, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -31,6 +31,6 @@
31
31
  module.exports = {
32
32
  VERSION_MAJOR: 6,
33
33
  VERSION_MINOR: 7,
34
- VERSION_PATCH: 0,
34
+ VERSION_PATCH: 2,
35
35
  VERSION_SUFFIX: ''
36
36
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oracledb",
3
- "version": "6.7.0",
3
+ "version": "6.7.2",
4
4
  "description": "A Node.js module for Oracle Database access from JavaScript and TypeScript",
5
5
  "license": "(Apache-2.0 OR UPL-1.0)",
6
6
  "homepage": "http://oracle.github.io/node-oracledb/",
@@ -1 +0,0 @@
1
- oracledb-6.7.0-darwin-arm64.node v22.2.0 29e0b9cfc2f22f3df1e6b746323fb5f1f95ba492 3f4e00888d20e313374cfe0fb148de2180eaf93f Thu, 07 Nov 2024 06:28:34 GMT
@@ -1 +0,0 @@
1
- oracledb-6.7.0-darwin-x64.node v20.11.1 29e0b9cfc2f22f3df1e6b746323fb5f1f95ba492 3f4e00888d20e313374cfe0fb148de2180eaf93f Thu, 07 Nov 2024 06:21:29 GMT
@@ -1 +0,0 @@
1
- 29e0b9cfc2f22f3df1e6b746323fb5f1f95ba492
@@ -1 +0,0 @@
1
- oracledb-6.7.0-linux-arm64.node v18.20.4 29e0b9cfc2f22f3df1e6b746323fb5f1f95ba492 3f4e00888d20e313374cfe0fb148de2180eaf93f Thu, 07 Nov 2024 16:48:12 GMT
@@ -1 +0,0 @@
1
- oracledb-6.7.0-linux-x64.node v16.20.2 29e0b9cfc2f22f3df1e6b746323fb5f1f95ba492 3f4e00888d20e313374cfe0fb148de2180eaf93f Thu, 07 Nov 2024 16:47:47 GMT
@@ -1 +0,0 @@
1
- oracledb-6.7.0-win32-x64.node v18.16.0 29e0b9cfc2f22f3df1e6b746323fb5f1f95ba492 3f4e00888d20e313374cfe0fb148de2180eaf93f Thu, 07 Nov 2024 16:23:47 GMT
@@ -1,140 +0,0 @@
1
- # Node-oracledb Examples
2
-
3
- The directory in node-oracledb's [Github repository](https://github.com/oracle/node-oracledb/tree/main/examples) contains a lot of [node-oracledb](https://www.npmjs.com/package/oracledb) examples.
4
- Documentation is [here](https://node-oracledb.readthedocs.io/en/latest/).
5
-
6
- To run the examples:
7
-
8
- - [Install node-oracledb](https://node-oracledb.readthedocs.io/en/latest/user_guide/installation.html#quickstart).
9
-
10
- - Ensure that you navigate to the `examples` directory in your terminal window
11
- or IDE, where you are running the samples.
12
-
13
- - Review `dbconfig.js`.
14
-
15
- In your terminal window or IDE, set the following environment variables to
16
- provide credentials for the `dbconfig.js` file.
17
-
18
- - `NODE_ORACLEDB_USER` must be set to the database user.
19
-
20
- - `NODE_ORACLEDB_PASSWORD` must be set to the database password.
21
-
22
- - `NODE_ORACLEDB_CONNECTIONSTRING` must be set to the connection string that points to your database's location.
23
-
24
- - `NODE_ORACLEDB_EXTERNALAUTH` provides the options for enabling external authentication. Setting this environment variable to "true" will enable external authentication. To ensure external authentication works, firstly make sure the Oracle external authentication service is correctly configured. See [Documentation for External Authentication](https://node-oracledb.readthedocs.io/en/latest/user_guide/connection_handling.html#extauth) for details.
25
-
26
- - `NODE_ORACLEDB_DRIVER_MODE` provides an option to set the 'Thin' or 'Thick' modes of node-oracledb. Setting this environment variable to "thick" will enable Thick mode.
27
- Setting it to "thin" will retain the Thin mode. The default mode is Thin.
28
-
29
- - `NODE_ORACLEDB_WALLET_LOCATION` must be set to the local directory name for the wallets that may be required for mutual TLS (mTLS) connections, especially to Oracle Cloud
30
- Autonomous Databases optionally. The wallet location can also be provided as a part of the database connect string.
31
-
32
- - `NODE_ORACLEDB_WALLET_PASSWORD` must set to the password for the wallets that may be required for mutual TLS (mTLS) connections, especially to Oracle Cloud Autonomous Databases.
33
-
34
- - `NODE_ORACLEDB_CLIENT_LIB_DIR` provides an optional path for the Oracle Client libraries to be used on Windows and macOS platforms, when using Thick mode in node-oracledb.
35
-
36
- Review the examples and then run them individually. For example, to see what
37
- the file `example.js` does, use:
38
-
39
- ```
40
- node example.js
41
- ```
42
-
43
- After running the examples, the demonstration objects can be dropped with
44
- `demodrop.js`:
45
-
46
- ```
47
- node demodrop.js
48
- ```
49
-
50
- Many examples can be run in either node-oracledb Thin (the default) or Thick
51
- modes. Thin mode is a pure JavaScript implementation of node-oracledb.
52
- Setting the environment variable `NODE_ORACLEDB_DRIVER_MODE` to `'thick'` will
53
- make examples use Thick mode.
54
-
55
- ## Example Overview
56
-
57
- If this is your first time with node-oracledb, start with
58
- [`example.js`](example.js).
59
-
60
- File Name | Description
61
- ----------------------------------------------------------|----------------------------------------------------------------------------------
62
- [`aqmulti.js`](aqmulti.js) | Oracle Advanced Queuing (AQ) example passing multiple messages
63
- [`aqobject.js`](aqobject.js) | Oracle Advanced Queuing (AQ) example passing an Oracle Database object
64
- [`aqoptions.js`](aqoptions.js) | Oracle Advanced Queuing (AQ) example setting options and message attributes
65
- [`aqraw.js`](aqraw.js) | Basic Oracle Advanced Queuing (AQ) example passing text messages
66
- [`aqutil.js`](aqutil.js) | Common file to setup the user credentials for all the Advanced Queuing (AQ) examples.
67
- [`blobhttp.js`](blobhttp.js) | Simple web app that streams an image
68
- [`azureConfigProvider.js`](azureConfigProvider.js) | Show how to connect to an Oracle Database using Azure Configuration Providers
69
- [`calltimeout.js`](calltimeout.js) | Shows how to cancel a SQL statement if it doesn't complete in a specified time
70
- [`connect.js`](connect.js) | Basic example for creating a standalone (non-pooled) connection
71
- [`connectionpool.js`](connectionpool.js) | Basic example creating a pool of connections
72
- [`cqn1.js`](cqn1.js) | Basic Continuous Query Notification (CQN) example
73
- [`cqn2.js`](cqn2.js) | Continuous Query Notification with notification grouping
74
- [`date_timestamp1.js`](date_timestamp1.js) | Show some basic DATE and TIMESTAMP behaviors
75
- [`date_timestamp2.js`](date_timestamp2.js) | Show some DATE and TIMESTAMP behaviors with timezones
76
- [`dbconfig.js`](dbconfig.js) | Common file used by examples for setting connection credentials
77
- [`dbmsoutputgetline.js`](dbmsoutputgetline.js) | Show fetching DBMS_OUTPUT by binding buffers
78
- [`dbmsoutputpipe.js`](dbmsoutputpipe.js) | Show fetching DBMS_OUTPUT by using a pipelined table
79
- [`demodrop.js`](demodrop.js) | Drops the schema objects created by the examples
80
- [`demosetup.js`](demosetup.js) | Used to create common schema objects for the examples
81
- [`dmlrupd.js`](dmlrupd.js) | Example of DML RETURNING where multiple rows are matched
82
- [`em_batcherrors.js`](em_batcherrors.js) | `executeMany()` example showing handling data errors
83
- [`em_dmlreturn1.js`](em_dmlreturn1.js) | `executeMany()` example of DML RETURNING that returns single values
84
- [`em_dmlreturn2.js`](em_dmlreturn2.js) | `executeMany()` example of DML RETURNING that returns multiple values
85
- [`em_insert1.js`](em_insert1.js) | Array DML example using `executeMany()` with bind-by-name syntax
86
- [`em_insert2.js`](em_insert2.js) | Array DML example using `executeMany()` with bind by position
87
- [`em_plsql.js`](em_plsql.js) | `executeMany()` example calling PL/SQL multiple times with one call
88
- [`em_rowcounts.js`](em_rowcounts.js) | `executeMany()` example showing how to find the number of rows affected by each input row
89
- [`endtoend.js`](endtoend.js) | Example showing setting tracing attributes
90
- [`example.js`](example.js) | Basic example showing creating a table, inserting multiple rows, and querying rows
91
- [`impres.js`](impres.js) | Shows PL/SQL 'Implict Results' returning multiple query results from PL/SQL code.
92
- [`insert1.js`](insert1.js) | Basic example creating a table and inserting data. Shows DDL and DML
93
- [`insert2.js`](insert2.js) | Basic example showing auto commit behavior
94
- [`lastinsertid.js`](lastinsertid.js) | Shows inserting a row and getting its ROWID.
95
- [`lobbinds.js`](lobbinds.js) | Demonstrates how to bind and query LOBs
96
- [`lobinsert1.js`](lobinsert1.js) | Shows inserting a file into a CLOB column
97
- [`lobinsert2.js`](lobinsert2.js) | Inserts text into a CLOB column using the RETURNING INTO method.
98
- [`lobinserttemp.js`](lobinserttemp.js) | Writes data to a Temporary CLOB and then inserts it into the database
99
- [`lobplsqltemp.js`](lobplsqltemp.js) | Streams data into a Temporary CLOB and then passes it to PL/SQL
100
- [`lobselect.js`](lobselect.js) | Shows basic, non-streaming CLOB and BLOB queries
101
- [`lobstream1.js`](lobstream1.js) | Shows how to stream LOBs to files
102
- [`lobstream2.js`](lobstream2.js) | Shows using Stream data events to fetch a CLOB
103
- [`lowercasecolumns.js`](lowercasecolumns.js) | Shows how a type handler can convert column names to lower case
104
- [`metadata.js`](metadata.js) | Shows the metadata available after executing SELECT statements
105
- [`ociConfigProvider.js`](ociConfigProvider.js) | Show how to connect to an Oracle Database using OCI Configuration Providers
106
- [`plsqlarray.js`](plsqlarray.js) | Examples of binding PL/SQL "INDEX BY" tables
107
- [`plsqlfunc.js`](plsqlfunc.js) | How to call a PL/SQL function
108
- [`plsqlproc.js`](plsqlproc.js) | How to call a PL/SQL procedure
109
- [`plsqlrecord.js`](plsqlrecord.js) | Shows binding of PL/SQL RECORDS
110
- [`plsqlvarrayrecord.js`](plsqlvarrayrecord.js) | Shows binding a VARRAY of RECORD in PL/SQL
111
- [`plsqlrowtype.js`](plsqlrowtype.js) | Shows binding of PL/SQL %ROWTYPE object
112
- [`raw.js`](raw.js) | Shows using a Buffer to insert and select a RAW
113
- [`refcursor.js`](refcursor.js) | Shows using a ResultSet to fetch rows from a REF CURSOR
114
- [`refcursortoquerystream.js`](refcursortoquerystream.js) | Converts a REF CURSOR returned from `execute()` to a query stream.
115
- [`resultset1.js`](resultset1.js) | Executes a query and uses a ResultSet to fetch rows with `getRow()`
116
- [`resultset2.js`](resultset2.js) | Executes a query and uses a ResultSet to fetch batches of rows with `getRows()`
117
- [`resultsettoquerystream.js`](resultsettoquerystream.js) | Converts a ResultSet returned from `execute()` into a Readable Stream.
118
- [`rowlimit.js`](rowlimit.js) | Shows ways to limit the number of records fetched by queries
119
- [`sampleazuretokenauth.js`](sampleazuretokenauth.js) | Shows connection pooling with Azure token based authentication.
120
- [`sampleocitokenauth.js`](sampleocitokenauth.js) | Shows connection pooling with OCI OAuth 2.0 token based authentication.
121
- [`select1.js`](select1.js) | Executes a basic query without using a connection pool or ResultSet
122
- [`select2.js`](select2.js) | Executes queries to show array and object output formats
123
- [`selectgeometry.js`](selectgeometry.js) | Insert and query Oracle Spatial geometries
124
- [`selectjson.js`](selectjson.js) | Shows some JSON features of Oracle Database 21c
125
- [`selectjsonblob.js`](selectjsonblob.js) | Shows how to use a BLOB as a JSON column store
126
- [`selectobject.js`](selectobject.js) | Insert and query a named Oracle database object
127
- [`selectnestedcursor.js`](selectnestedcursor.js) | Shows selecting from a nested cursor
128
- [`selectstream.js`](selectstream.js) | Executes a basic query using a Readable Stream
129
- [`selectvarray.js`](selectvarray.js) | Shows inserting and selecting from a VARRAY column
130
- [`sessionfixup.js`](sessionfixup.js) | Shows a pooled connection callback to efficiently set session state
131
- [`sessiontagging1.js`](sessiontagging1.js) | Simple pooled connection tagging for setting session state
132
- [`sessiontagging2.js`](sessiontagging2.js) | More complex example of pooled connection tagging for setting session state
133
- [`soda1.js`](soda1.js) | Basic Simple Oracle Document Access (SODA) example
134
- [`typehandlerdate.js`](typehandlerdate.js) | Show how a type handler can format a queried date in a locale-specific way
135
- [`typehandlernum.js`](typehandlernum.js) | Show how a type handler can alter queried numbers
136
- [`vectortype1.js`](vectortype1.js) | Insert and query VECTOR columns.
137
- [`vectortype2.js`](vectortype2.js) | Insert data into VECTOR columns and verify vector operations.
138
- [`version.js`](version.js) | Shows the node-oracledb version attributes
139
- [`webapp.js`](webapp.js) | A simple web application using a connection pool
140
- [`xmltypeInDbObject.js`](xmltypeInDbObject.js) | Work with XMLType data in DbObject (Thin mode only)