oracledb 5.1.0 → 5.4.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 (40) hide show
  1. package/CHANGELOG.md +164 -2
  2. package/LICENSE.txt +443 -0
  3. package/NOTICE.txt +1 -0
  4. package/README.md +15 -13
  5. package/THIRD_PARTY_LICENSES.txt +52 -0
  6. package/build/Release/oracledb-5.4.0-darwin-x64.node +0 -0
  7. package/build/Release/oracledb-5.4.0-darwin-x64.node-buildinfo.txt +1 -0
  8. package/build/Release/oracledb-5.4.0-linux-x64.node +0 -0
  9. package/build/Release/oracledb-5.4.0-linux-x64.node-buildinfo.txt +1 -0
  10. package/build/Release/oracledb-5.4.0-win32-x64.node +0 -0
  11. package/build/Release/oracledb-5.4.0-win32-x64.node-buildinfo.txt +1 -0
  12. package/lib/aqDeqOptions.js +1 -1
  13. package/lib/aqEnqOptions.js +1 -1
  14. package/lib/aqMessage.js +1 -1
  15. package/lib/aqQueue.js +9 -5
  16. package/lib/connection.js +233 -33
  17. package/lib/dbObject.js +17 -17
  18. package/lib/lob.js +17 -5
  19. package/lib/oracledb.js +74 -11
  20. package/lib/pool.js +271 -163
  21. package/lib/poolStatistics.js +124 -0
  22. package/lib/queryStream.js +8 -6
  23. package/lib/resultset.js +37 -9
  24. package/lib/sodaCollection.js +46 -21
  25. package/lib/sodaDatabase.js +8 -4
  26. package/lib/sodaDocCursor.js +7 -3
  27. package/lib/sodaDocument.js +1 -1
  28. package/lib/sodaOperation.js +21 -9
  29. package/lib/util.js +80 -20
  30. package/package/README.md +8 -8
  31. package/package/install.js +8 -7
  32. package/package/prunebinaries.js +4 -5
  33. package/package.json +2 -2
  34. package/LICENSE.md +0 -2685
  35. package/build/Release/oracledb-5.1.0-darwin-x64.node +0 -0
  36. package/build/Release/oracledb-5.1.0-darwin-x64.node-buildinfo.txt +0 -1
  37. package/build/Release/oracledb-5.1.0-linux-x64.node +0 -0
  38. package/build/Release/oracledb-5.1.0-linux-x64.node-buildinfo.txt +0 -1
  39. package/build/Release/oracledb-5.1.0-win32-x64.node +0 -0
  40. package/build/Release/oracledb-5.1.0-win32-x64.node-buildinfo.txt +0 -1
@@ -0,0 +1,124 @@
1
+ // Copyright (c) 2021, 2022, Oracle and/or its affiliates.
2
+ //-----------------------------------------------------------------------------
3
+ //
4
+ // You may not use the identified files except in compliance with the Apache
5
+ // License, Version 2.0 (the "License.")
6
+ //
7
+ // You may obtain a copy of the License at
8
+ // http://www.apache.org/licenses/LICENSE-2.0.
9
+ //
10
+ // Unless required by applicable law or agreed to in writing, software
11
+ // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ //
14
+ // See the License for the specific language governing permissions and
15
+ // limitations under the License.
16
+ //
17
+ //-----------------------------------------------------------------------------
18
+
19
+ 'use strict';
20
+
21
+ //-----------------------------------------------------------------------------
22
+ // class PoolStatistics
23
+ // collection of statistics metrics for Pool object
24
+ //-----------------------------------------------------------------------------
25
+
26
+ class PoolStatistics {
27
+
28
+ constructor(pool) {
29
+ let averageTimeInQueue = 0;
30
+
31
+ if (pool._totalRequestsEnqueued !== 0) {
32
+ averageTimeInQueue = Math.round(pool._totalTimeInQueue /
33
+ pool._totalRequestsEnqueued);
34
+ }
35
+
36
+ this.gatheredDate = Date.now ();
37
+ this.upTime = this.gatheredDate - pool._createdDate;
38
+ this.upTimeSinceReset = this.gatheredDate - pool._timeOfReset;
39
+ this.connectionRequests = pool._totalConnectionRequests;
40
+ this.requestsEnqueued = pool._totalRequestsEnqueued;
41
+ this.requestsDequeued = pool._totalRequestsDequeued;
42
+ this.failedRequests = pool._totalFailedRequests;
43
+ this.rejectedRequests = pool._totalRequestsRejected;
44
+ this.requestTimeouts = pool._totalRequestTimeouts;
45
+ this.maximumQueueLength = pool._maximumQueueLength;
46
+ this.currentQueueLength = pool._connRequestQueue.length;
47
+ this.timeInQueue = pool._totalTimeInQueue;
48
+ this.minimumTimeInQueue = pool._minTimeInQueue;
49
+ this.maximumTimeInQueue = pool._maxTimeInQueue;
50
+ this.averageTimeInQueue = averageTimeInQueue;
51
+ this.connectionsInUse = pool.connectionsInUse;
52
+ this.connectionsOpen = pool.connectionsOpen;
53
+ this.connectString = pool.connectString;
54
+ this.edition = pool.edition;
55
+ this.events = pool.events;
56
+ this.externalAuth = pool.externalAuth;
57
+ this.homogeneous = pool.homogeneous;
58
+ this.poolAlias = pool.poolAlias;
59
+ this.poolIncrement = pool.poolIncrement;
60
+ this.poolMax = pool.poolMax;
61
+ this.poolMaxPerShard = pool.poolMaxPerShard;
62
+ this.poolMin = pool.poolMin;
63
+ this.poolPingInterval = pool.poolPingInterval;
64
+ this.poolTimeout = pool.poolTimeout;
65
+ this.queueMax = pool.queueMax;
66
+ this.queueTimeout = pool.queueTimeout;
67
+ this.sodaMetaDataCache = pool.sodaMetaDataCache;
68
+ this.stmtCacheSize = pool.stmtCacheSize;
69
+ this.user = pool.user;
70
+ this.threadPoolSize = process.env.UV_THREADPOOL_SIZE;
71
+ }
72
+
73
+ //---------------------------------------------------------------------------
74
+ // logStatistics()
75
+ // To print the statistics metrics of the pool
76
+ //---------------------------------------------------------------------------
77
+ logStatistics() {
78
+ console.log('\nPool statistics:');
79
+ console.log('...gathered at:', new Date(this.gatheredDate).toISOString());
80
+ console.log('...up time (milliseconds):', this.upTime);
81
+ console.log('...up time from last reset (milliseconds)',
82
+ this.upTimeSinceReset);
83
+ console.log('...connection requests:', this.connectionRequests);
84
+ console.log('...requests enqueued:', this.requestsEnqueued);
85
+ console.log('...requests dequeued:', this.requestsDequeued);
86
+ console.log('...requests failed:', this.failedRequests);
87
+ console.log('...requests exceeding queueMax:', this.rejectedRequests);
88
+ console.log('...requests exceeding queueTimeout:', this.requestTimeouts);
89
+ console.log('...current queue length:', this.currentQueueLength);
90
+ console.log('...maximum queue length:', this.maximumQueueLength);
91
+ console.log('...sum of time in queue (milliseconds):', this.timeInQueue);
92
+ console.log('...minimum time in queue (milliseconds):',
93
+ this.minimumTimeInQueue);
94
+ console.log('...maximum time in queue (milliseconds):',
95
+ this.maximumTimeInQueue);
96
+ console.log('...average time in queue (milliseconds):',
97
+ this.averageTimeInQueue);
98
+ console.log('...pool connections in use:', this.connectionsInUse);
99
+ console.log('...pool connections open:', this.connectionsOpen);
100
+ console.log('Pool attributes:');
101
+ console.log('...connectString:', this.connectString);
102
+ console.log('...edition:', this.edition);
103
+ console.log('...events:', this.events);
104
+ console.log('...externalAuth:', this.externalAuth);
105
+ console.log('...homogeneous:', this.homogeneous);
106
+ console.log('...poolAlias:', this.poolAlias);
107
+ console.log('...poolIncrement:', this.poolIncrement);
108
+ console.log('...poolMax:', this.poolMax);
109
+ console.log('...poolMaxPerShard:', this.poolMaxPerShard);
110
+ console.log('...poolMin:', this.poolMin);
111
+ console.log('...poolPingInterval (seconds):', this.poolPingInterval);
112
+ console.log('...poolTimeout (seconds):', this.poolTimeout);
113
+ console.log('...queueMax:', this.queueMax);
114
+ console.log('...queueTimeout (milliseconds):', this.queueTimeout);
115
+ console.log('...sessionCallback:', this.sessionCallback);
116
+ console.log('...sodaMetaDataCache:', this.sodaMetaDataCache);
117
+ console.log('...stmtCacheSize:', this.stmtCacheSize);
118
+ console.log('...user:', this.user);
119
+ console.log('Related environment variables:');
120
+ console.log('...UV_THREADPOOL_SIZE:', this.threadPoolSize);
121
+ }
122
+ }
123
+
124
+ module.exports = PoolStatistics;
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved
1
+ // Copyright (c) 2015, 2022, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -89,11 +89,6 @@ class QueryStream extends Readable {
89
89
  this._fetching = true;
90
90
  this._resultSet._allowGetRowCall = true;
91
91
  const row = await this._resultSet.getRow();
92
- this._fetching = false;
93
- if (!this._resultSet) {
94
- this.emit('_doneFetching');
95
- return;
96
- }
97
92
  if (row) {
98
93
  this.push(row);
99
94
  } else {
@@ -101,6 +96,13 @@ class QueryStream extends Readable {
101
96
  }
102
97
  } catch (err) {
103
98
  this.destroy(err);
99
+ } finally {
100
+ this._fetching = false;
101
+ if (this._resultSet) {
102
+ this._resultSet._allowGetRowCall = false;
103
+ } else {
104
+ this.emit('_doneFetching');
105
+ }
104
106
  }
105
107
  }
106
108
 
package/lib/resultset.js CHANGED
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved
1
+ // Copyright (c) 2016, 2022, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -72,9 +72,14 @@ async function getRow() {
72
72
  async function getRows(numRows) {
73
73
  let rowsNeeded;
74
74
 
75
- nodbUtil.checkArgCount(arguments, 1, 1);
76
- nodbUtil.assert(Number.isInteger(numRows), 'NJS-005', 2);
77
- nodbUtil.assert(numRows > 0, 'NJS-005', 2);
75
+ nodbUtil.checkArgCount(arguments, 0, 1);
76
+
77
+ if (arguments.length == 0) {
78
+ numRows = 0;
79
+ } else {
80
+ nodbUtil.assert(Number.isInteger(numRows), 'NJS-005', 1);
81
+ nodbUtil.assert(numRows >= 0, 'NJS-005', 1);
82
+ }
78
83
 
79
84
  if (this._convertedToStream) {
80
85
  throw new Error(nodbUtil.getErrorMessage('NJS-042'));
@@ -82,6 +87,20 @@ async function getRows(numRows) {
82
87
 
83
88
  this._processingStarted = true;
84
89
 
90
+ if (numRows == 0) {
91
+ let requestedRows = this._rowCache;
92
+
93
+ const fetchArraySize = this._fetchArraySize;
94
+ while (true) { // eslint-disable-line
95
+ let rows = await this._getRows(fetchArraySize, false, false);
96
+ if (rows)
97
+ requestedRows = requestedRows.concat(rows);
98
+ if (rows.length < fetchArraySize)
99
+ break;
100
+ }
101
+ return requestedRows;
102
+ }
103
+
85
104
  if (this._rowCache.length === 0) {
86
105
  return await this._getRows(numRows, false, false);
87
106
  }
@@ -105,13 +124,21 @@ class ResultSet {
105
124
  this._processingStarted = false;
106
125
  this._convertedToStream = false;
107
126
  this._allowGetRowCall = false;
127
+ this._isActive = false;
108
128
  }
109
129
 
110
130
  _extend(oracledb) {
111
131
  this._oracledb = oracledb;
112
- this.close = nodbUtil.callbackify(close);
113
- this.getRow = nodbUtil.callbackify(getRow);
114
- this.getRows = nodbUtil.callbackify(getRows);
132
+ this.close = nodbUtil.callbackify(nodbUtil.preventConcurrent(nodbUtil.serialize(close), 'NJS-017'));
133
+ this.getRow = nodbUtil.callbackify(nodbUtil.preventConcurrent(nodbUtil.serialize(getRow), 'NJS-017'));
134
+ this.getRows = nodbUtil.callbackify(nodbUtil.preventConcurrent(nodbUtil.serialize(getRows), 'NJS-017'));
135
+ }
136
+
137
+ _getConnection() {
138
+ let connection = this._parentObj;
139
+ while (!(connection instanceof this._oracledb.Connection))
140
+ connection = connection._parentObj;
141
+ return connection;
115
142
  }
116
143
 
117
144
  async _getAllRows(executeOpts, metaDataObj, isNested) {
@@ -167,8 +194,9 @@ class ResultSet {
167
194
  for (let j = 0; j < nestedCursorIndices.length; j++) {
168
195
  const val = row[nestedCursorIndices[j]];
169
196
  if (val) {
170
- row[nestedCursorIndices[j]] = await val._getAllRows(executeOpts,
171
- nestedCursorMetaDataObjs[j], true);
197
+ row[nestedCursorIndices[j]] =
198
+ await val._getAllRows(executeOpts,
199
+ nestedCursorMetaDataObjs[j], true);
172
200
  }
173
201
  }
174
202
  }
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved
1
+ // Copyright (c) 2018, 2022, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -61,10 +61,17 @@ async function insertMany(docs) {
61
61
  // Insert an array of documents into the collection in a single round-trip
62
62
  // and return a set of result documents containing metadata.
63
63
  //-----------------------------------------------------------------------------
64
- async function insertManyAndGet(docs) {
65
- nodbUtil.checkArgCount(arguments, 1, 1);
64
+ async function insertManyAndGet(docs, a2) {
65
+ let options = {};
66
+
67
+ nodbUtil.checkArgCount(arguments, 1, 2);
66
68
  nodbUtil.assert(Array.isArray(docs), 'NJS-005', 1);
67
69
 
70
+ if (arguments.length == 2) {
71
+ nodbUtil.assert(nodbUtil.isObject(a2), 'NJS-005', 2);
72
+ options = a2;
73
+ }
74
+
68
75
  if (docs.length == 0) {
69
76
  throw new Error(nodbUtil.getErrorMessage('NJS-005', 1));
70
77
  }
@@ -78,7 +85,7 @@ async function insertManyAndGet(docs) {
78
85
  actualDocs[i] = content;
79
86
  }
80
87
 
81
- return await this._insertManyAndGet(actualDocs);
88
+ return await this._insertManyAndGet(actualDocs, options);
82
89
  }
83
90
 
84
91
 
@@ -104,16 +111,23 @@ async function insertOne(content) {
104
111
  // Inserts a single document into the collection and returns a result
105
112
  // document containing metadata.
106
113
  //-----------------------------------------------------------------------------
107
- async function insertOneAndGet(content) {
108
- nodbUtil.checkArgCount(arguments, 1, 1);
114
+ async function insertOneAndGet(content, a2) {
115
+ let options = {};
116
+
117
+ nodbUtil.checkArgCount(arguments, 1, 2);
109
118
  nodbUtil.assert(nodbUtil.isObject(content) ||
110
119
  nodbUtil.isSodaDocument(content), 'NJS-005', 1);
111
120
 
121
+ if (arguments.length == 2) {
122
+ nodbUtil.assert(nodbUtil.isObject(a2), 'NJS-005', 2);
123
+ options = a2;
124
+ }
125
+
112
126
  if (!nodbUtil.isSodaDocument(content)) {
113
127
  content = Buffer.from(JSON.stringify(content));
114
128
  }
115
129
 
116
- return await this._insertOneAndGet(content);
130
+ return await this._insertOneAndGet(content, options);
117
131
  }
118
132
 
119
133
 
@@ -178,16 +192,23 @@ async function save(content) {
178
192
  // Saves a single document into the collection and returns a result
179
193
  // document containing metadata.
180
194
  //-----------------------------------------------------------------------------
181
- async function saveAndGet(content) {
182
- nodbUtil.checkArgCount(arguments, 1, 1);
195
+ async function saveAndGet(content, a2) {
196
+ let options = {};
197
+
198
+ nodbUtil.checkArgCount(arguments, 1, 2);
183
199
  nodbUtil.assert(nodbUtil.isObject(content) ||
184
200
  nodbUtil.isSodaDocument(content), 'NJS-005', 1);
185
201
 
202
+ if (arguments.length == 2) {
203
+ nodbUtil.assert(nodbUtil.isObject(a2), 'NJS-005', 2);
204
+ options = a2;
205
+ }
206
+
186
207
  if (!nodbUtil.isSodaDocument(content)) {
187
208
  content = Buffer.from(JSON.stringify(content));
188
209
  }
189
210
 
190
- return await this._saveAndGet(content);
211
+ return await this._saveAndGet(content, options);
191
212
  }
192
213
 
193
214
 
@@ -204,17 +225,21 @@ async function truncate() {
204
225
  class SodaCollection {
205
226
 
206
227
  _extend() {
207
- this.createIndex = nodbUtil.callbackify(createIndex);
208
- this.drop = nodbUtil.callbackify(drop);
209
- this.dropIndex = nodbUtil.callbackify(dropIndex);
210
- this.getDataGuide = nodbUtil.callbackify(getDataGuide);
211
- this.insertMany = nodbUtil.callbackify(insertMany);
212
- this.insertManyAndGet = nodbUtil.callbackify(insertManyAndGet);
213
- this.insertOne = nodbUtil.callbackify(insertOne);
214
- this.insertOneAndGet = nodbUtil.callbackify(insertOneAndGet);
215
- this.save = nodbUtil.callbackify(save);
216
- this.saveAndGet = nodbUtil.callbackify(saveAndGet);
217
- this.truncate = nodbUtil.callbackify(truncate);
228
+ this.createIndex = nodbUtil.callbackify(nodbUtil.serialize(createIndex));
229
+ this.drop = nodbUtil.callbackify(nodbUtil.serialize(drop));
230
+ this.dropIndex = nodbUtil.callbackify(nodbUtil.serialize(dropIndex));
231
+ this.getDataGuide = nodbUtil.callbackify(nodbUtil.serialize(getDataGuide));
232
+ this.insertMany = nodbUtil.callbackify(nodbUtil.serialize(insertMany));
233
+ this.insertManyAndGet = nodbUtil.callbackify(nodbUtil.serialize(insertManyAndGet));
234
+ this.insertOne = nodbUtil.callbackify(nodbUtil.serialize(insertOne));
235
+ this.insertOneAndGet = nodbUtil.callbackify(nodbUtil.serialize(insertOneAndGet));
236
+ this.save = nodbUtil.callbackify(nodbUtil.serialize(save));
237
+ this.saveAndGet = nodbUtil.callbackify(nodbUtil.serialize(saveAndGet));
238
+ this.truncate = nodbUtil.callbackify(nodbUtil.serialize(truncate));
239
+ }
240
+
241
+ _getConnection() {
242
+ return this._database._connection;
218
243
  }
219
244
 
220
245
  find() {
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved
1
+ // Copyright (c) 2018, 2022, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -76,9 +76,13 @@ async function getCollectionNames(a1) {
76
76
  class SodaDatabase {
77
77
 
78
78
  _extend() {
79
- this.createCollection = nodbUtil.callbackify(createCollection);
80
- this.getCollectionNames = nodbUtil.callbackify(getCollectionNames);
81
- this.openCollection = nodbUtil.callbackify(openCollection);
79
+ this.createCollection = nodbUtil.callbackify(nodbUtil.serialize(createCollection));
80
+ this.getCollectionNames = nodbUtil.callbackify(nodbUtil.serialize(getCollectionNames));
81
+ this.openCollection = nodbUtil.callbackify(nodbUtil.serialize(openCollection));
82
+ }
83
+
84
+ _getConnection() {
85
+ return this._connection;
82
86
  }
83
87
 
84
88
  // To create a SODA document object based content and (optional) other fields
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved
1
+ // Copyright (c) 2018, 2022, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -44,8 +44,12 @@ async function close() {
44
44
  class SodaDocCursor {
45
45
 
46
46
  _extend() {
47
- this.close = nodbUtil.callbackify(close);
48
- this.getNext = nodbUtil.callbackify(getNext);
47
+ this.close = nodbUtil.callbackify(nodbUtil.serialize(close));
48
+ this.getNext = nodbUtil.callbackify(nodbUtil.serialize(getNext));
49
+ }
50
+
51
+ _getConnection() {
52
+ return this._operation._getConnection();
49
53
  }
50
54
 
51
55
  }
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved
1
+ // Copyright (c) 2018, 2022, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved
1
+ // Copyright (c) 2018, 2022, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -116,13 +116,17 @@ class SodaOperation {
116
116
  }
117
117
 
118
118
  _extend() {
119
- this.count = nodbUtil.callbackify(count);
120
- this.getCursor = nodbUtil.callbackify(getCursor);
121
- this.getDocuments = nodbUtil.callbackify(getDocuments);
122
- this.getOne = nodbUtil.callbackify(getOne);
123
- this.remove = nodbUtil.callbackify(remove);
124
- this.replaceOne = nodbUtil.callbackify(replaceOne);
125
- this.replaceOneAndGet = nodbUtil.callbackify(replaceOneAndGet);
119
+ this.count = nodbUtil.callbackify(nodbUtil.serialize(count));
120
+ this.getCursor = nodbUtil.callbackify(nodbUtil.serialize(getCursor));
121
+ this.getDocuments = nodbUtil.callbackify(nodbUtil.serialize(getDocuments));
122
+ this.getOne = nodbUtil.callbackify(nodbUtil.serialize(getOne));
123
+ this.remove = nodbUtil.callbackify(nodbUtil.serialize(remove));
124
+ this.replaceOne = nodbUtil.callbackify(nodbUtil.serialize(replaceOne));
125
+ this.replaceOneAndGet = nodbUtil.callbackify(nodbUtil.serialize(replaceOneAndGet));
126
+ }
127
+
128
+ _getConnection() {
129
+ return this._collection._database._connection;
126
130
  }
127
131
 
128
132
  // fetchArraySize - a non-terminal function that can chain further
@@ -141,6 +145,14 @@ class SodaOperation {
141
145
  return this;
142
146
  }
143
147
 
148
+ // hint - a non-terminal function and can chain further
149
+ hint(val) {
150
+ nodbUtil.checkArgCount(arguments, 1, 1);
151
+ nodbUtil.assert(typeof val === 'string', 'NJS-005', 1);
152
+ this._options.hint = val;
153
+ return this;
154
+ }
155
+
144
156
  // key - a non-terminal function and can chain further
145
157
  key(k) {
146
158
  nodbUtil.checkArgCount(arguments, 1, 1);
@@ -165,7 +177,7 @@ class SodaOperation {
165
177
  }
166
178
 
167
179
  // limit property - a non-terminal function and can chain further
168
- limit (n) {
180
+ limit(n) {
169
181
  nodbUtil.checkArgCount(arguments, 1, 1);
170
182
  nodbUtil.assert(typeof n === 'number', 'NJS-005', 1);
171
183
  this._options.limit = n;
package/lib/util.js CHANGED
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved
1
+ // Copyright (c) 2016, 2022, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -25,7 +25,7 @@ const util = require('util');
25
25
  let packageJSON;
26
26
  try {
27
27
  packageJSON = require('../package.json');
28
- } catch(err) {
28
+ } catch (err) {
29
29
  throw new Error('package.json is missing');
30
30
  }
31
31
  const PACKAGE_JSON_VERSION = packageJSON.version;
@@ -49,6 +49,8 @@ const errorMessages = {
49
49
  'NJS-004': 'NJS-004: invalid value for property %s',
50
50
  'NJS-005': 'NJS-005: invalid value for parameter %d',
51
51
  'NJS-009': 'NJS-009: invalid number of parameters',
52
+ 'NJS-017': 'NJS-017: concurrent operations on ResultSet are not allowed',
53
+ 'NJS-023': 'NJS-023: concurrent operations on LOB are not allowed',
52
54
  'NJS-037': 'NJS-037: incompatible type of value provided',
53
55
  'NJS-040': 'NJS-040: connection request timeout. Request exceeded queueTimeout of %d',
54
56
  'NJS-041': 'NJS-041: cannot convert ResultSet to QueryStream after invoking methods',
@@ -62,11 +64,17 @@ const errorMessages = {
62
64
  'NJS-067': 'NJS-067: a pre-built node-oracledb binary was not found for %s',
63
65
  'NJS-069': 'NJS-069: node-oracledb %s requires Node.js %s or later',
64
66
  'NJS-076': 'NJS-076: connection request rejected. Pool queue length queueMax %d reached',
67
+ 'NJS-081': 'NJS-081: concurrent operations on a connection are disabled',
68
+ 'NJS-082': 'NJS-082: connection pool is being reconfigured',
69
+ 'NJS-083': 'NJS-083: pool statistics not enabled',
70
+ 'NJS-084': 'NJS-084: invalid or missing parameter with token based authentication. The token and privateKey attributes must contain values. Other credentials cannot be specified',
71
+ 'NJS-085': 'NJS-085: invalid connection pool configuration with token based authentication. The homogeneous and externalAuth attributes must be set to true',
72
+ 'NJS-086': 'NJS-086: invalid standalone configuration with token based authentication. The externalAuth attribute must be set to true'
65
73
  };
66
74
 
67
75
  // getInstallURL returns a string with installation URL
68
76
  function getInstallURL() {
69
- return('Node-oracledb installation instructions: https://oracle.github.io/node-oracledb/INSTALL.html');
77
+ return ('Node-oracledb installation instructions: https://oracle.github.io/node-oracledb/INSTALL.html');
70
78
  }
71
79
 
72
80
  module.exports.getInstallURL = getInstallURL;
@@ -77,27 +85,24 @@ function getInstallHelp() {
77
85
  let mesg = getInstallURL() + '\n';
78
86
  if (process.platform === 'linux') {
79
87
  if (process.arch === 'x64') {
80
- url = 'http://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html\n';
88
+ url = 'https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html\n';
81
89
  arch = '64-bit';
82
90
  } else if (process.arch === 'x32') {
83
- url = 'http://www.oracle.com/technetwork/topics/linuxsoft-082809.html\n';
91
+ url = 'https://www.oracle.com/database/technologies/instant-client/linux-x86-32-downloads.html\n';
84
92
  arch = '32-bit';
85
93
  } else {
86
- url = 'http://www.oracle.com/technetwork/database/database-technologies/instant-client/overview/index.html\n';
94
+ url = 'https://www.oracle.com/database/technologies/instant-client.html\n';
87
95
  arch = process.arch;
88
96
  }
89
- mesg += 'You must have ' + arch + ' Oracle client libraries in LD_LIBRARY_PATH, or configured with ldconfig.\n';
97
+ mesg += 'You must have ' + arch + ' Oracle Client libraries configured with ldconfig, or in LD_LIBRARY_PATH.\n';
90
98
  mesg += 'If you do not have Oracle Database on this computer, then install the Instant Client Basic or Basic Light package from \n';
91
99
  mesg += url;
92
100
  } else if (process.platform === 'darwin') {
93
101
  if (process.arch === 'x64') {
94
- url = 'http://www.oracle.com/technetwork/topics/intel-macsoft-096467.html';
102
+ url = 'https://www.oracle.com/database/technologies/instant-client/macos-intel-x86-downloads.html\n';
95
103
  arch = '64-bit';
96
- } else if (process.arch === 'x32') {
97
- url = 'http://www.oracle.com/technetwork/topics/intel-macsoft-096467.html';
98
- arch = '32-bit';
99
104
  } else {
100
- url = 'http://www.oracle.com/technetwork/database/database-technologies/instant-client/overview/index.html\n';
105
+ url = 'https://www.oracle.com/database/technologies/instant-client.html\n';
101
106
  arch = process.arch;
102
107
  }
103
108
  mesg += 'You must have the ' + arch + ' Oracle Instant Client Basic or Basic Light package libraries in\n';
@@ -105,22 +110,22 @@ function getInstallHelp() {
105
110
  mesg += 'Oracle Instant Client can be downloaded from ' + url;
106
111
  } else if (process.platform === 'win32') {
107
112
  if (process.arch === 'x64') {
108
- url = 'http://www.oracle.com/technetwork/topics/winx64soft-089540.html\n';
113
+ url = 'https://www.oracle.com/database/technologies/instant-client/winx64-64-downloads.html\n';
109
114
  arch = '64-bit';
110
115
  } else if (process.arch === 'x32') {
111
- url = 'http://www.oracle.com/technetwork/topics/winsoft-085727.html\n';
116
+ url = 'https://www.oracle.com/database/technologies/instant-client/microsoft-windows-32-downloads.html\n';
112
117
  arch = '32-bit';
113
118
  } else {
114
- url = 'http://www.oracle.com/technetwork/database/database-technologies/instant-client/overview/index.html\n';
119
+ url = 'https://www.oracle.com/database/technologies/instant-client.html\n';
115
120
  arch = process.arch;
116
121
  }
117
- mesg += 'You must have ' + arch + ' Oracle client libraries in your PATH environment variable.\n';
122
+ mesg += 'You must have ' + arch + ' Oracle Client libraries in your PATH environment variable.\n';
118
123
  mesg += 'If you do not have Oracle Database on this computer, then install the Instant Client Basic or Basic Light package from\n';
119
124
  mesg += url;
120
125
  mesg += 'A Microsoft Visual Studio Redistributable suitable for your Oracle client library version must be available.\n';
121
126
  } else {
122
- url = 'http://www.oracle.com/technetwork/database/database-technologies/instant-client/overview/index.html\n';
123
- mesg += 'You must have ' + process.arch + ' Oracle client libraries in your operating system library search path.\n';
127
+ url = 'https://www.oracle.com/database/technologies/instant-client.html\n';
128
+ mesg += 'You must have ' + process.arch + ' Oracle Client libraries in your operating system library search path.\n';
124
129
  mesg += 'If you do not have Oracle Database on this computer, then install an Instant Client Basic or Basic Light package from: \n';
125
130
  mesg += url;
126
131
  }
@@ -168,12 +173,15 @@ module.exports.checkArgCount = checkArgCount;
168
173
  // is resolved or rejected and the callback invoked; otherwise, the function is
169
174
  // called unchanged and a promise is returned
170
175
  function callbackify(func) {
171
- return function() {
176
+ const wrapper = function() {
172
177
 
173
178
  // if last argument is not a function, simply invoke the function as usual
174
179
  // and a promise will be returned
175
180
  if (typeof arguments[arguments.length - 1] !== 'function') {
176
- return func.apply(this, arguments);
181
+ return func.apply(this, arguments).catch(function stackCapture(e) {
182
+ Error.captureStackTrace(e, stackCapture);
183
+ throw e;
184
+ });
177
185
  }
178
186
 
179
187
  // otherwise, resolve or reject the promise and invoke the callback
@@ -184,10 +192,53 @@ function callbackify(func) {
184
192
  }, cb);
185
193
 
186
194
  };
195
+ if (func.name) {
196
+ Object.defineProperty(wrapper, 'name', { value: func.name });
197
+ }
198
+ return wrapper;
187
199
  }
188
200
 
189
201
  module.exports.callbackify = callbackify;
190
202
 
203
+ // The serialize function is used to wrap methods to ensure that the connection
204
+ // is not used concurrently by multiple threads
205
+ function serialize(func) {
206
+ return async function() {
207
+
208
+ // determine the connection associated with the object
209
+ const connection = this._getConnection();
210
+
211
+ // acquire the "lock"; this simply checks to see if another operation is in
212
+ // progress, and if so, waits for it to complete
213
+ await connection._acquireLock();
214
+
215
+ // call the function and ensure that the lock is "released" once the
216
+ // function has completed -- either successfully or in failure
217
+ try {
218
+ return await func.apply(this, arguments);
219
+ } finally {
220
+ connection._releaseLock();
221
+ }
222
+ };
223
+ }
224
+
225
+ module.exports.serialize = serialize;
226
+
227
+ function preventConcurrent(func, errorCode) {
228
+ return async function() {
229
+ if (this._isActive)
230
+ throw new Error(getErrorMessage(errorCode));
231
+ this._isActive = true;
232
+ try {
233
+ return await func.apply(this, arguments);
234
+ } finally {
235
+ this._isActive = false;
236
+ }
237
+ };
238
+ }
239
+
240
+ module.exports.preventConcurrent = preventConcurrent;
241
+
191
242
  function isObject(value) {
192
243
  return value !== null && typeof value === 'object';
193
244
  }
@@ -204,4 +255,13 @@ function isSodaDocument(value) {
204
255
  return (value != null && value._sodaDocumentMarker);
205
256
  }
206
257
 
258
+ function isXid(value) {
259
+ return (isObject(value) &&
260
+ (value.formatId !== undefined) &&
261
+ (value.globalTransactionId !== undefined) &&
262
+ (value.branchQualifier !== undefined));
263
+ }
264
+
265
+ module.exports.isXid = isXid;
266
+
207
267
  module.exports.isSodaDocument = isSodaDocument;