oracledb 6.8.0 → 6.10.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 (85) hide show
  1. package/README.md +39 -3
  2. package/build/Release/oracledb-6.10.0-darwin-arm64.node +0 -0
  3. package/build/Release/oracledb-6.10.0-darwin-arm64.node-buildinfo.txt +1 -0
  4. package/build/Release/oracledb-6.10.0-darwin-x64.node +0 -0
  5. package/build/Release/oracledb-6.10.0-darwin-x64.node-buildinfo.txt +1 -0
  6. package/build/Release/oracledb-6.10.0-js-buildinfo.txt +1 -0
  7. package/build/Release/oracledb-6.10.0-linux-arm64.node +0 -0
  8. package/build/Release/oracledb-6.10.0-linux-arm64.node-buildinfo.txt +1 -0
  9. package/build/Release/oracledb-6.10.0-linux-x64.node +0 -0
  10. package/build/Release/oracledb-6.10.0-linux-x64.node-buildinfo.txt +1 -0
  11. package/build/Release/oracledb-6.10.0-win32-x64.node +0 -0
  12. package/build/Release/oracledb-6.10.0-win32-x64.node-buildinfo.txt +1 -0
  13. package/lib/aqDeqOptions.js +18 -1
  14. package/lib/aqMessage.js +10 -1
  15. package/lib/aqQueue.js +10 -6
  16. package/lib/configProviders/file.js +72 -0
  17. package/lib/connection.js +93 -4
  18. package/lib/dbObject.js +34 -4
  19. package/lib/errors.js +70 -35
  20. package/lib/impl/aqDeqOptions.js +10 -1
  21. package/lib/impl/connection.js +9 -0
  22. package/lib/impl/datahandlers/buffer.js +49 -0
  23. package/lib/impl/datahandlers/oson.js +7 -2
  24. package/lib/impl/pool.js +10 -1
  25. package/lib/impl/resultset.js +5 -4
  26. package/lib/impl/sodaDocument.js +5 -14
  27. package/lib/lob.js +9 -1
  28. package/lib/oracledb.js +152 -30
  29. package/lib/pool.js +199 -147
  30. package/lib/poolStatistics.js +4 -2
  31. package/lib/sodaCollection.js +12 -8
  32. package/lib/sodaDatabase.js +35 -8
  33. package/lib/sodaDocument.js +24 -6
  34. package/lib/sodaOperation.js +7 -6
  35. package/lib/thin/aq.js +475 -0
  36. package/lib/thin/connection.js +171 -14
  37. package/lib/thin/dbObject.js +8 -6
  38. package/lib/thin/lob.js +2 -3
  39. package/lib/thin/pool.js +105 -28
  40. package/lib/thin/protocol/capabilities.js +10 -4
  41. package/lib/thin/protocol/constants.js +90 -1
  42. package/lib/thin/protocol/encryptDecrypt.js +2 -2
  43. package/lib/thin/protocol/messages/aqArray.js +238 -0
  44. package/lib/thin/protocol/messages/aqBase.js +305 -0
  45. package/lib/thin/protocol/messages/aqDeq.js +164 -0
  46. package/lib/thin/protocol/messages/aqEnq.js +135 -0
  47. package/lib/thin/protocol/messages/auth.js +25 -27
  48. package/lib/thin/protocol/messages/base.js +98 -9
  49. package/lib/thin/protocol/messages/dataType.js +2 -1
  50. package/lib/thin/protocol/messages/execute.js +46 -4
  51. package/lib/thin/protocol/messages/lobOp.js +5 -22
  52. package/lib/thin/protocol/messages/logOff.js +0 -1
  53. package/lib/thin/protocol/messages/sessionRelease.js +0 -1
  54. package/lib/thin/protocol/messages/transactionSwitch.js +12 -4
  55. package/lib/thin/protocol/messages/withData.js +3 -3
  56. package/lib/thin/protocol/packet.js +6 -5
  57. package/lib/thin/protocol/protocol.js +2 -1
  58. package/lib/thin/sqlnet/connStrategy.js +2 -1
  59. package/lib/thin/sqlnet/navNodes.js +1 -1
  60. package/lib/thin/sqlnet/networkSession.js +10 -4
  61. package/lib/thin/sqlnet/packet.js +2 -1
  62. package/lib/thin/sqlnet/sessionAtts.js +2 -3
  63. package/lib/types.js +6 -11
  64. package/lib/util.js +72 -11
  65. package/lib/version.js +1 -1
  66. package/package/install.js +3 -3
  67. package/package/prunebinaries.js +6 -12
  68. package/package.json +2 -2
  69. package/{lib/configProviders/azure.js → plugins/configProviders/azure/index.js} +73 -63
  70. package/plugins/configProviders/azurevault/index.js +84 -0
  71. package/{lib → plugins}/configProviders/base.js +13 -3
  72. package/{lib/configProviders/ociobject.js → plugins/configProviders/ociobject/index.js} +43 -78
  73. package/plugins/configProviders/ocivault/index.js +100 -0
  74. package/plugins/token/extensionOci/index.js +71 -35
  75. package/build/Release/oracledb-6.8.0-darwin-arm64.node +0 -0
  76. package/build/Release/oracledb-6.8.0-darwin-arm64.node-buildinfo.txt +0 -1
  77. package/build/Release/oracledb-6.8.0-darwin-x64.node +0 -0
  78. package/build/Release/oracledb-6.8.0-darwin-x64.node-buildinfo.txt +0 -1
  79. package/build/Release/oracledb-6.8.0-js-buildinfo.txt +0 -1
  80. package/build/Release/oracledb-6.8.0-linux-arm64.node +0 -0
  81. package/build/Release/oracledb-6.8.0-linux-arm64.node-buildinfo.txt +0 -1
  82. package/build/Release/oracledb-6.8.0-linux-x64.node +0 -0
  83. package/build/Release/oracledb-6.8.0-linux-x64.node-buildinfo.txt +0 -1
  84. package/build/Release/oracledb-6.8.0-win32-x64.node +0 -0
  85. package/build/Release/oracledb-6.8.0-win32-x64.node-buildinfo.txt +0 -1
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
- # node-oracledb version 6.8.0
1
+ # node-oracledb version 6.10.0 <img src="https://img.shields.io/npm/v/oracledb.svg" alt="oracledb"/> <img src="https://img.shields.io/npm/dm/oracledb.svg" alt="oracledb"/>
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.8.0 to connect Node.js 14.6, or later, to Oracle
7
+ Use node-oracledb 6.10.0 to connect Node.js 14.17, or later, to Oracle
8
8
  Database. Older versions of node-oracledb may work with older versions of
9
9
  Node.js.
10
10
 
@@ -16,8 +16,42 @@ It is stable, well documented, and has a comprehensive test suite.
16
16
 
17
17
  ## Installation
18
18
 
19
+ Run `npm install oracledb`
20
+
19
21
  See [Getting Started with Node-oracledb][1] and [Quick Start Node-oracledb Installation][2].
20
22
 
23
+ ## Dependencies and Interoperability
24
+
25
+ - Node.js versions 14.17 and later.
26
+
27
+ Pre-built packages are available on [npm][14] and other mirror repositories.
28
+
29
+ Source code is also available.
30
+
31
+ Previous versions of node-oracledb supported older Node.js versions.
32
+
33
+ - Oracle Client libraries are *optional* starting from node-oracledb 6.0.
34
+ Older versions of node-oracledb require Oracle Client libraries.
35
+
36
+ **Thin mode**: By default node-oracledb (from version 6.0 onwards) runs in a
37
+ 'Thin' mode which connects directly to Oracle Database.
38
+
39
+ **Thick mode**: Some advanced Oracle Database functionality is currently only
40
+ available when optional Oracle Client libraries are loaded by
41
+ node-oracledb. Libraries are available in the free [Oracle Instant
42
+ Client][15] packages. Node-oracledb can use Oracle Client
43
+ libraries 11.2 through 23ai.
44
+
45
+ - Oracle Database
46
+
47
+ **Thin mode**: Oracle Database 12.1 (or later) is required.
48
+
49
+ **Thick mode**: Oracle Database 9.2 (or later) is required, depending on the
50
+ Oracle Client library version. Oracle Database's standard client-server
51
+ version interoperability allows connection to both older and newer
52
+ databases. For example when node-oracledb uses Oracle Client 19c libraries,
53
+ then it can connect to Oracle Database 11.2 or later.
54
+
21
55
  ## Documentation
22
56
 
23
57
  See [Documentation for the Oracle Database Node.js Add-on][9] and the [release
@@ -34,7 +68,7 @@ to join Slack][6]).
34
68
 
35
69
  ## <a name="testing"></a> Tests
36
70
 
37
- To run the test suite see [test/README][11].
71
+ To run the test suite, see [test/README][11].
38
72
 
39
73
  ## Contributing
40
74
 
@@ -83,3 +117,5 @@ limitations under the License.
83
117
  [11]: https://github.com/oracle/node-oracledb/blob/main/test/README.md
84
118
  [12]: https://github.com/oracle/node-oracledb/blob/main/CONTRIBUTING.md
85
119
  [13]: https://github.com/oracle/node-oracledb/blob/main/SECURITY.md
120
+ [14]: https://www.npmjs.com/package/oracledb
121
+ [15]: https://www.oracle.com/database/technologies/instant-client.html
@@ -0,0 +1 @@
1
+ oracledb-6.10.0-darwin-arm64.node v22.17.1 71ba4e79b3fb8ffe6191e84eb0422c9bdfbb6c9d 8b14d5980d7d6116abb8865c7baed9e458698dbf Thu, 09 Oct 2025 15:26:22 GMT
@@ -0,0 +1 @@
1
+ oracledb-6.10.0-darwin-x64.node v20.11.1 71ba4e79b3fb8ffe6191e84eb0422c9bdfbb6c9d 8b14d5980d7d6116abb8865c7baed9e458698dbf Thu, 09 Oct 2025 15:33:20 GMT
@@ -0,0 +1 @@
1
+ 71ba4e79b3fb8ffe6191e84eb0422c9bdfbb6c9d
@@ -0,0 +1 @@
1
+ oracledb-6.10.0-linux-arm64.node v20.19.2 71ba4e79b3fb8ffe6191e84eb0422c9bdfbb6c9d 8b14d5980d7d6116abb8865c7baed9e458698dbf Thu, 09 Oct 2025 13:43:20 GMT
@@ -0,0 +1 @@
1
+ oracledb-6.10.0-linux-x64.node v22.16.0 71ba4e79b3fb8ffe6191e84eb0422c9bdfbb6c9d 8b14d5980d7d6116abb8865c7baed9e458698dbf Thu, 09 Oct 2025 13:31:19 GMT
@@ -0,0 +1 @@
1
+ oracledb-6.10.0-win32-x64.node v22.17.1 71ba4e79b3fb8ffe6191e84eb0422c9bdfbb6c9d 8b14d5980d7d6116abb8865c7baed9e458698dbf Thu, 09 Oct 2025 13:31:10 GMT
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2019, 2023, Oracle and/or its affiliates.
1
+ // Copyright (c) 2019, 2025, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -74,6 +74,23 @@ class AqDeqOptions {
74
74
  this._impl.setCorrelation(value);
75
75
  }
76
76
 
77
+ //---------------------------------------------------------------------------
78
+ // deliveryMode
79
+ //
80
+ // Property for the delivery mode to use for dequeuing messages.
81
+ //---------------------------------------------------------------------------
82
+ get deliveryMode() {
83
+ return null;
84
+ }
85
+
86
+ set deliveryMode(value) {
87
+ errors.assertPropValue(value === constants.AQ_MSG_DELIV_MODE_PERSISTENT ||
88
+ value === constants.AQ_MSG_DELIV_MODE_BUFFERED ||
89
+ value === constants.AQ_MSG_DELIV_MODE_PERSISTENT_OR_BUFFERED,
90
+ "deliveryMode");
91
+ this._impl.setDeliveryMode(value);
92
+ }
93
+
77
94
  //---------------------------------------------------------------------------
78
95
  // mode
79
96
  //
package/lib/aqMessage.js CHANGED
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2019, 2022, Oracle and/or its affiliates.
1
+ // Copyright (c) 2019, 2025, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -48,6 +48,15 @@ class AqMessage {
48
48
  return this._impl.getDelay();
49
49
  }
50
50
 
51
+ //---------------------------------------------------------------------------
52
+ // enqTime
53
+ //
54
+ // Property to indicate the enqueue time for the message.
55
+ //---------------------------------------------------------------------------
56
+ get enqTime() {
57
+ return this._impl.getEnqTime();
58
+ }
59
+
51
60
  //---------------------------------------------------------------------------
52
61
  // deliveryMode
53
62
  //
package/lib/aqQueue.js CHANGED
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2019, 2024, Oracle and/or its affiliates.
1
+ // Copyright (c) 2019, 2025, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -87,17 +87,21 @@ class AqQueue {
87
87
  }
88
88
  }
89
89
 
90
- // validate payload
90
+ // validate payload/queue type compatibility
91
91
  if (this._isJson) {
92
92
  message.payload = transformer.transformJsonValue(payload);
93
- } else if (typeof payload === 'string') {
93
+ } else if (typeof payload === 'string' || Buffer.isBuffer(payload)) {
94
94
  message.payload = Buffer.from(payload);
95
- } else if (Buffer.isBuffer(payload)) {
96
- message.payload = payload;
97
- } else {
95
+ } else if (this._payloadType == types.DB_TYPE_OBJECT) {
96
+ if (!(payload instanceof BaseDbObject) ||
97
+ (this._payloadTypeName !== payload._impl._objType.name))
98
+ errors.throwErr(errors.ERR_PAYLOAD_CANNOT_BE_ENQUEUED);
98
99
  message.payload = payload._impl;
100
+ } else {
101
+ errors.throwErr(errors.ERR_PAYLOAD_CANNOT_BE_ENQUEUED);
99
102
  }
100
103
 
104
+
101
105
  // validate options, if applicable
102
106
  if (message.correlation !== undefined) {
103
107
  errors.assertParamPropValue(typeof message.correlation === 'string', 1,
@@ -0,0 +1,72 @@
1
+ // Copyright (c) 2025, Oracle and/or its affiliates.
2
+
3
+ //-----------------------------------------------------------------------------
4
+ //
5
+ // This software is dual-licensed to you under the Universal Permissive License
6
+ // (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
7
+ // 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
8
+ // either license.
9
+ //
10
+ // If you elect to accept the software under the Apache License, Version 2.0,
11
+ // the following applies:
12
+ //
13
+ // Licensed under the Apache License, Version 2.0 (the "License");
14
+ // you may not use this file except in compliance with the License.
15
+ // You may obtain a copy of the License at
16
+ //
17
+ // https://www.apache.org/licenses/LICENSE-2.0
18
+ //
19
+ // Unless required by applicable law or agreed to in writing, software
20
+ // distributed under the License is distributed on an "AS IS" BASIS,
21
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22
+ // See the License for the specific language governing permissions and
23
+ // limitations under the License.
24
+ //
25
+ //-----------------------------------------------------------------------------
26
+ const fs = require('fs').promises;
27
+ const util = require('node:util');
28
+ const oracledb = require('oracledb');
29
+ class locaJson {
30
+
31
+ constructor(provider_arg, urlExtendedPart) {
32
+ const params = new URLSearchParams(urlExtendedPart);
33
+ this.paramMap = new URLSearchParams([...params].map(([key, value]) => [key.toLowerCase(), value])); //parse the extended part and store parameters in Map
34
+ this.paramMap.set('filepath', provider_arg);
35
+ }
36
+ //---------------------------------------------------------------------------
37
+ // init()
38
+ //
39
+ // Require/import modules from ociobject
40
+ //---------------------------------------------------------------------------
41
+ init() {
42
+ // nothing to require
43
+ }
44
+ async returnConfig() {
45
+ const alias = this.paramMap.get('alias');
46
+ // Read input file
47
+ const data = Buffer.from(await fs.readFile(this.paramMap.get("filepath"), { encoding: 'utf8', flag: 'r' }));
48
+ // Converting to JSON
49
+ const listofAliases = JSON.parse(data);
50
+ if (alias) {
51
+ this.obj = listofAliases[alias];
52
+ } else {
53
+ this.obj = listofAliases;
54
+ }
55
+ return this.obj;
56
+ }
57
+ }
58
+ //---------------------------------------------------------------------------
59
+ // hookFn()
60
+ // hookFn will get registered to the driver while loading the plugins
61
+ //---------------------------------------------------------------------------
62
+ async function hookFn(args) {
63
+ const configProvider = new locaJson(args.provider_arg, args.urlExtendedPart);
64
+ try {
65
+ configProvider.init();
66
+ } catch (err) {
67
+ const errmsg = util.format('Centralized Config Provider failed to load required libraries. Please install the required libraries.\n %s', err.message);
68
+ throw new Error(errmsg);
69
+ }
70
+ return [await configProvider.returnConfig(), configProvider.credential];
71
+ }
72
+ oracledb.registerConfigurationProviderHook('file', hookFn);
package/lib/connection.js CHANGED
@@ -110,6 +110,8 @@ class Connection extends EventEmitter {
110
110
  options.connection = this;
111
111
  if (options.keepInStmtCache === undefined)
112
112
  options.keepInStmtCache = true;
113
+ if (options.suspendOnSuccess === undefined)
114
+ options.suspendOnSuccess = false;
113
115
  settings.addToOptions(options,
114
116
  "autoCommit",
115
117
  "dbObjectAsPojo",
@@ -138,7 +140,12 @@ class Connection extends EventEmitter {
138
140
  }
139
141
  return (proxy);
140
142
  } else if (initialValue !== undefined) {
141
- Object.assign(this, initialValue);
143
+ for (const attr of objType.attributes) {
144
+ const value = initialValue[attr.name];
145
+ if (value !== undefined) {
146
+ this._setAttrValue(attr, value);
147
+ }
148
+ }
142
149
  }
143
150
  };
144
151
  DbObject.prototype = Object.create(BaseDbObject.prototype);
@@ -591,6 +598,11 @@ class Connection extends EventEmitter {
591
598
  outOptions.keepInStmtCache = options.keepInStmtCache;
592
599
  }
593
600
 
601
+ if (options.suspendOnSuccess !== undefined) {
602
+ errors.assertParamPropBool(options, 2, "suspendOnSucess");
603
+ outOptions.suspendOnSuccess = options.suspendOnSuccess;
604
+ }
605
+
594
606
  // handle options specific to executeMany()
595
607
  if (inExecuteMany) {
596
608
 
@@ -701,6 +713,29 @@ class Connection extends EventEmitter {
701
713
  this._impl.setAction(value);
702
714
  }
703
715
 
716
+ //---------------------------------------------------------------------------
717
+ // beginSessionlessTransaction()
718
+ //
719
+ // Begin a new sessionless transaction with provided transactionId.
720
+ // If transactionId wasn't provided a random-generated transactionId will be
721
+ // used and returned.
722
+ //---------------------------------------------------------------------------
723
+ async beginSessionlessTransaction(options = {}) {
724
+ errors.assertArgCount(arguments, 0, 1);
725
+ errors.assertParamValue(nodbUtil.isObject(options), 1);
726
+ if (options.transactionId !== undefined)
727
+ errors.assertParamPropValue(
728
+ nodbUtil.isTransactionId(options.transactionId), 1, 'transactionId');
729
+ errors.assertParamPropUnsignedIntNonZero(options, 1, 'timeout');
730
+ errors.assertParamPropBool(options, 1, 'deferRoundTrip');
731
+ const normalizedTransactionId =
732
+ nodbUtil.normalizeTransactionId(options.transactionId);
733
+ const {timeout = 60, deferRoundTrip = false} = options;
734
+ await this._impl.startSessionlessTransaction(normalizedTransactionId,
735
+ timeout, constants.TPC_BEGIN_NEW, deferRoundTrip);
736
+ return normalizedTransactionId;
737
+ }
738
+
704
739
  //---------------------------------------------------------------------------
705
740
  // breakExecution()
706
741
  //
@@ -792,7 +827,12 @@ class Connection extends EventEmitter {
792
827
 
793
828
  this._closing = true;
794
829
  try {
795
- await this._impl.close(options);
830
+ // If connection is part of a pool, notify the pool of its availability
831
+ if (this._pool) {
832
+ await this._pool._release(this._impl, options);
833
+ } else {
834
+ await this._impl.close(options);
835
+ }
796
836
  } finally {
797
837
  this._closing = false;
798
838
  }
@@ -804,7 +844,6 @@ class Connection extends EventEmitter {
804
844
  }
805
845
  }
806
846
  this._dbObjectClasses.clear();
807
- this.emit('_afterConnClose');
808
847
  }
809
848
 
810
849
  //---------------------------------------------------------------------------
@@ -1255,6 +1294,18 @@ class Connection extends EventEmitter {
1255
1294
  this._impl.setInternalName(value);
1256
1295
  }
1257
1296
 
1297
+ //---------------------------------------------------------------------------
1298
+ // ltxid
1299
+ //
1300
+ // Property for identifying the logical transaction ID to avoid duplicate
1301
+ // transactions. Used with Oracle Transaction Guard.
1302
+ //---------------------------------------------------------------------------
1303
+ get ltxid() {
1304
+ if (this._impl)
1305
+ return this._impl.getLTXID();
1306
+ return undefined;
1307
+ }
1308
+
1258
1309
  //--------------------------------------------------------------------------
1259
1310
  // isHealthy()
1260
1311
  //
@@ -1407,6 +1458,25 @@ class Connection extends EventEmitter {
1407
1458
  return (stream);
1408
1459
  }
1409
1460
 
1461
+ //---------------------------------------------------------------------------
1462
+ // resumeSessionlessTransaction()
1463
+ //
1464
+ // Resume an existing sessionlesss transaction using given transactionId
1465
+ //---------------------------------------------------------------------------
1466
+ async resumeSessionlessTransaction(transactionId, options = {}) {
1467
+ errors.assertArgCount(arguments, 1, 2);
1468
+ errors.assertParamValue(nodbUtil.isTransactionId(transactionId), 1);
1469
+ errors.assertParamValue(nodbUtil.isObject(options), 2);
1470
+ errors.assertParamPropUnsignedInt(options, 2, 'timeout');
1471
+ errors.assertParamPropBool(options, 2, 'deferRoundTrip');
1472
+ const normalizedTransactionId =
1473
+ nodbUtil.normalizeTransactionId(transactionId);
1474
+ const {timeout = 60, deferRoundTrip = false} = options;
1475
+ await this._impl.startSessionlessTransaction(normalizedTransactionId,
1476
+ timeout, constants.TPC_BEGIN_RESUME, deferRoundTrip);
1477
+ return normalizedTransactionId;
1478
+ }
1479
+
1410
1480
  //---------------------------------------------------------------------------
1411
1481
  // rollback()
1412
1482
  //
@@ -1521,6 +1591,17 @@ class Connection extends EventEmitter {
1521
1591
  return outValue;
1522
1592
  }
1523
1593
 
1594
+ //---------------------------------------------------------------------------
1595
+ // suspendSessionlessTransaction()
1596
+ //
1597
+ // Suspend any active sessionless transaction immediately
1598
+ //---------------------------------------------------------------------------
1599
+ async suspendSessionlessTransaction() {
1600
+ errors.assertArgCount(arguments, 0, 0);
1601
+ errors.assert(this._impl, errors.ERR_INVALID_CONNECTION);
1602
+ await this._impl.suspendSessionlessTransaction();
1603
+ }
1604
+
1524
1605
  //---------------------------------------------------------------------------
1525
1606
  // tag
1526
1607
  //
@@ -1711,7 +1792,12 @@ class Connection extends EventEmitter {
1711
1792
  errors.assert(this._impl, errors.ERR_INVALID_CONNECTION);
1712
1793
  errors.assert(_subscriptions.has(name), errors.ERR_INVALID_SUBSCR);
1713
1794
  await this._impl.unsubscribe(_subscriptions.get(name));
1714
- _subscriptions.delete(name);
1795
+
1796
+ // Delay decreasing the reference count
1797
+ // as NJS layer starts cleanup (uv_close) of async handle asynchronously.
1798
+ setTimeout(() => {
1799
+ _subscriptions.delete(name);
1800
+ }, 0);
1715
1801
  }
1716
1802
 
1717
1803
  }
@@ -1724,6 +1810,7 @@ Connection.prototype.break =
1724
1810
  Connection.prototype.tpcRecover =
1725
1811
  nodbUtil.callbackify(nodbUtil.wrapFn(Connection.prototype.tpcRecover));
1726
1812
  nodbUtil.wrapFns(Connection.prototype,
1813
+ "beginSessionlessTransaction",
1727
1814
  "changePassword",
1728
1815
  "close",
1729
1816
  "commit",
@@ -1734,10 +1821,12 @@ nodbUtil.wrapFns(Connection.prototype,
1734
1821
  "getQueue",
1735
1822
  "getStatementInfo",
1736
1823
  "ping",
1824
+ "resumeSessionlessTransaction",
1737
1825
  "rollback",
1738
1826
  "shutdown",
1739
1827
  "startup",
1740
1828
  "subscribe",
1829
+ "suspendSessionlessTransaction",
1741
1830
  "tpcBegin",
1742
1831
  "tpcCommit",
1743
1832
  "tpcEnd",
package/lib/dbObject.js CHANGED
@@ -79,6 +79,18 @@ function validatePropertyValue(objType, metaData, value, index) {
79
79
  // instantiated; a cache of these classes are maintained on each connection
80
80
  class BaseDbObject {
81
81
 
82
+ //---------------------------------------------------------------------------
83
+ // _ensureCollection()
84
+ //
85
+ // Ensures that the object is a collection.
86
+ //---------------------------------------------------------------------------
87
+ _ensureCollection() {
88
+ if (!this.isCollection) {
89
+ errors.throwErr(errors.ERR_OBJECT_IS_NOT_A_COLLECTION,
90
+ this.name);
91
+ }
92
+ }
93
+
82
94
  //---------------------------------------------------------------------------
83
95
  // _getAttrValue()
84
96
  //
@@ -165,6 +177,7 @@ class BaseDbObject {
165
177
  //---------------------------------------------------------------------------
166
178
  append(value) {
167
179
  errors.assertArgCount(arguments, 1, 1);
180
+ this._ensureCollection();
168
181
  const info = {
169
182
  fqn: this._objType.fqn,
170
183
  type: this._objType.elementType,
@@ -200,6 +213,15 @@ class BaseDbObject {
200
213
  if (implAttr.typeClass) {
201
214
  attr.typeClass = implAttr.typeClass;
202
215
  }
216
+ if (implAttr.precision != null) {
217
+ attr.precision = implAttr.precision;
218
+ }
219
+ if (implAttr.scale != null) {
220
+ attr.scale = implAttr.scale;
221
+ }
222
+ if (implAttr.maxSize != null) {
223
+ attr.maxSize = implAttr.maxSize;
224
+ }
203
225
  attrs[implAttr.name] = attr;
204
226
  }
205
227
  this._attributes = attrs;
@@ -229,6 +251,7 @@ class BaseDbObject {
229
251
  //---------------------------------------------------------------------------
230
252
  deleteElement(index) {
231
253
  errors.assertArgCount(arguments, 1, 1);
254
+ this._ensureCollection();
232
255
  errors.assertParamValue(Number.isInteger(index), 1);
233
256
  return this._impl.deleteElement(index);
234
257
  }
@@ -291,6 +314,7 @@ class BaseDbObject {
291
314
  //---------------------------------------------------------------------------
292
315
  getElement(index) {
293
316
  errors.assertArgCount(arguments, 1, 1);
317
+ this._ensureCollection();
294
318
  errors.assertParamValue(Number.isInteger(index), 1);
295
319
  const value = this._impl.getElement(index);
296
320
  return this._transformValueOut(value, this.elementTypeClass, this._objType.elementTypeInfo);
@@ -303,6 +327,7 @@ class BaseDbObject {
303
327
  //---------------------------------------------------------------------------
304
328
  getKeys() {
305
329
  errors.assertArgCount(arguments, 0, 0);
330
+ this._ensureCollection();
306
331
  return this._impl.getKeys();
307
332
  }
308
333
 
@@ -313,6 +338,7 @@ class BaseDbObject {
313
338
  //---------------------------------------------------------------------------
314
339
  getFirstIndex() {
315
340
  errors.assertArgCount(arguments, 0, 0);
341
+ this._ensureCollection();
316
342
  return this._impl.getFirstIndex();
317
343
  }
318
344
 
@@ -323,6 +349,7 @@ class BaseDbObject {
323
349
  //---------------------------------------------------------------------------
324
350
  getLastIndex() {
325
351
  errors.assertArgCount(arguments, 0, 0);
352
+ this._ensureCollection();
326
353
  return this._impl.getLastIndex();
327
354
  }
328
355
 
@@ -333,6 +360,7 @@ class BaseDbObject {
333
360
  //---------------------------------------------------------------------------
334
361
  getNextIndex(index) {
335
362
  errors.assertArgCount(arguments, 1, 1);
363
+ this._ensureCollection();
336
364
  errors.assertParamValue(Number.isInteger(index), 1);
337
365
  return this._impl.getNextIndex(index);
338
366
  }
@@ -344,6 +372,7 @@ class BaseDbObject {
344
372
  //---------------------------------------------------------------------------
345
373
  getPrevIndex(index) {
346
374
  errors.assertArgCount(arguments, 1, 1);
375
+ this._ensureCollection();
347
376
  errors.assertParamValue(Number.isInteger(index), 1);
348
377
  return this._impl.getPrevIndex(index);
349
378
  }
@@ -355,6 +384,7 @@ class BaseDbObject {
355
384
  //---------------------------------------------------------------------------
356
385
  getValues() {
357
386
  errors.assertArgCount(arguments, 0, 0);
387
+ this._ensureCollection();
358
388
  const values = this._impl.getValues();
359
389
  for (let i = 0; i < values.length; i++) {
360
390
  values[i] = this._transformValueOut(values[i], this.elementTypeClass, this._objType.elementTypeInfo);
@@ -369,6 +399,7 @@ class BaseDbObject {
369
399
  //---------------------------------------------------------------------------
370
400
  hasElement(index) {
371
401
  errors.assertArgCount(arguments, 1, 1);
402
+ this._ensureCollection();
372
403
  errors.assertParamValue(Number.isInteger(index), 1);
373
404
  return this._impl.hasElement(index);
374
405
  }
@@ -417,6 +448,7 @@ class BaseDbObject {
417
448
  //---------------------------------------------------------------------------
418
449
  setElement(index, value) {
419
450
  errors.assertArgCount(arguments, 2, 2);
451
+ this._ensureCollection();
420
452
  errors.assertParamValue(Number.isInteger(index), 1);
421
453
  const info = {
422
454
  fqn: this._objType.fqn,
@@ -436,6 +468,7 @@ class BaseDbObject {
436
468
  //---------------------------------------------------------------------------
437
469
  trim(numToTrim) {
438
470
  errors.assertArgCount(arguments, 1, 1);
471
+ this._ensureCollection();
439
472
  errors.assertParamValue(Number.isInteger(numToTrim) && numToTrim >= 0, 1);
440
473
  this._impl.trim(numToTrim);
441
474
  }
@@ -478,10 +511,7 @@ class BaseDbObject {
478
511
  //---------------------------------------------------------------------------
479
512
  toMap() {
480
513
  errors.assertArgCount(arguments, 0, 0);
481
- if (!this.isCollection) {
482
- errors.throwErr(errors.ERR_OBJECT_IS_NOT_A_COLLECTION,
483
- this.name);
484
- }
514
+ this._ensureCollection();
485
515
  const result = new Map();
486
516
  this.getKeys().forEach(element => {
487
517
  result.set(element, this.getElement(element));