oracledb 6.0.3 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/build/Release/oracledb-6.2.0-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.2.0-darwin-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.2.0-js-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.2.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.2.0-linux-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.2.0-linux-x64.node +0 -0
- package/build/Release/oracledb-6.2.0-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.2.0-win32-x64.node +0 -0
- package/build/Release/oracledb-6.2.0-win32-x64.node-buildinfo.txt +1 -0
- package/examples/dbconfig.js +7 -14
- package/examples/example.js +0 -1
- package/lib/aqQueue.js +40 -26
- package/lib/connection.js +16 -4
- package/lib/dbObject.js +9 -0
- package/lib/errors.js +17 -13
- package/lib/impl/connection.js +9 -0
- package/lib/impl/resultset.js +7 -4
- package/lib/oracledb.js +26 -18
- package/lib/pool.js +7 -1
- package/lib/sodaCollection.js +12 -1
- package/lib/sodaOperation.js +16 -0
- package/lib/thin/connection.js +229 -182
- package/lib/thin/dbObject.js +4 -1
- package/lib/thin/pool.js +153 -68
- package/lib/thin/protocol/buffer.js +83 -64
- package/lib/thin/protocol/constants.js +3 -14
- package/lib/thin/protocol/encryptDecrypt.js +17 -17
- package/lib/thin/protocol/messages/auth.js +21 -23
- package/lib/thin/protocol/messages/base.js +29 -45
- package/lib/thin/protocol/messages/connectionCookie.js +76 -0
- package/lib/thin/protocol/messages/dataType.js +13 -9
- package/lib/thin/protocol/messages/execute.js +7 -7
- package/lib/thin/protocol/messages/index.js +2 -0
- package/lib/thin/protocol/messages/protocol.js +31 -20
- package/lib/thin/protocol/messages/withData.js +58 -47
- package/lib/thin/protocol/oson.js +17 -14
- package/lib/thin/protocol/packet.js +36 -14
- package/lib/thin/protocol/utils.js +2 -2
- package/lib/thin/resultSet.js +6 -6
- package/lib/thin/sqlnet/connStrategy.js +130 -5
- package/lib/thin/sqlnet/constants.js +2 -0
- package/lib/thin/sqlnet/ezConnectResolver.js +29 -61
- package/lib/thin/sqlnet/navNodes.js +34 -27
- package/lib/thin/sqlnet/networkSession.js +46 -47
- package/lib/thin/sqlnet/ntTcp.js +30 -14
- package/lib/thin/sqlnet/nvStrToNvPair.js +16 -16
- package/lib/thin/sqlnet/packet.js +10 -3
- package/lib/thin/sqlnet/paramParser.js +9 -9
- package/lib/thin/sqlnet/sessionAtts.js +4 -0
- package/lib/thin/statement.js +345 -113
- package/lib/thin/util.js +23 -86
- package/lib/transformer.js +3 -1
- package/lib/util.js +4 -13
- package/lib/version.js +2 -2
- package/package.json +1 -1
- package/build/Release/oracledb-6.0.3-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.0.3-darwin-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.3-js-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.3-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.0.3-linux-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.3-linux-x64.node +0 -0
- package/build/Release/oracledb-6.0.3-linux-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.3-win32-x64.node +0 -0
- package/build/Release/oracledb-6.0.3-win32-x64.node-buildinfo.txt +0 -1
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# node-oracledb version 6.0
|
|
1
|
+
# node-oracledb version 6.2.0
|
|
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.0
|
|
7
|
+
Use node-oracledb 6.2.0 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
|
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
oracledb-6.2.0-darwin-x64.node v16.20.2 fe16239d5a7ceb588ae0e0766e74da2d20fb7af9 20785f251426f274f4216369b9259908a103384d Wed, 27 Sep 2023 05:56:04 GMT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
fe16239d5a7ceb588ae0e0766e74da2d20fb7af9
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
oracledb-6.2.0-linux-arm64.node v18.15.0 fe16239d5a7ceb588ae0e0766e74da2d20fb7af9 20785f251426f274f4216369b9259908a103384d Wed, 27 Sep 2023 06:02:23 GMT
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
oracledb-6.2.0-linux-x64.node v16.19.1 fe16239d5a7ceb588ae0e0766e74da2d20fb7af9 20785f251426f274f4216369b9259908a103384d Thu, 28 Sep 2023 16:23:40 GMT
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
oracledb-6.2.0-win32-x64.node v16.19.0 fe16239d5a7ceb588ae0e0766e74da2d20fb7af9 20785f251426f274f4216369b9259908a103384d Wed, 27 Sep 2023 10:36:18 GMT
|
package/examples/dbconfig.js
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
* to the database. Production applications should consider using
|
|
31
31
|
* External Authentication to avoid hard coded credentials.
|
|
32
32
|
*
|
|
33
|
-
* To create a database user see
|
|
33
|
+
* To create a database user, see
|
|
34
34
|
* https://blogs.oracle.com/sql/post/how-to-create-users-grant-them-privileges-and-remove-them-in-oracle-database
|
|
35
35
|
*
|
|
36
36
|
* Applications can set the connectString value to an Easy Connect
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
* Commonly just the host_name and service_name are needed
|
|
47
47
|
* e.g. "localhost/orclpdb1" or "example.com/XEPDB1"
|
|
48
48
|
*
|
|
49
|
-
* The Easy Connect syntax
|
|
50
|
-
*
|
|
49
|
+
* The Easy Connect syntax supports lots of options. To know more, please
|
|
50
|
+
* refer to the latest Oracle documentation on Easy Connect syntax:
|
|
51
51
|
* https://www.oracle.com/pls/topic/lookup?ctx=dblatest&id=GUID-B0437826-43C1-49EC-A94D-B650B6A4A6EE
|
|
52
52
|
*
|
|
53
53
|
* If using a tnsnames.ora file, the file can be in a default
|
|
@@ -66,17 +66,10 @@
|
|
|
66
66
|
* creating a pool should not be set when externalAuth is true.
|
|
67
67
|
*
|
|
68
68
|
* TROUBLESHOOTING
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* indicate connectString is invalid.
|
|
74
|
-
*
|
|
75
|
-
* The error:
|
|
76
|
-
* ORA-12514: TNS:listener does not currently know of requested in connect descriptor
|
|
77
|
-
* indicates connectString is invalid. You are reaching a computer
|
|
78
|
-
* with Oracle installed but the service name isn't known.
|
|
79
|
-
* Use 'lsnrctl services' on the database server to find available services
|
|
69
|
+
* Refer to the Error Handling section in node-oracledb documentation
|
|
70
|
+
* to understand the different types of errors in both the Thin and Thick
|
|
71
|
+
* modes of node-oracledb:
|
|
72
|
+
* https://node-oracledb.readthedocs.io/en/latest/user_guide/exception_handling.html#errors-in-thin-and-thick-modes
|
|
80
73
|
*
|
|
81
74
|
*****************************************************************************/
|
|
82
75
|
|
package/examples/example.js
CHANGED
|
@@ -127,7 +127,6 @@ async function run() {
|
|
|
127
127
|
// For a complete list of options see the documentation.
|
|
128
128
|
options = {
|
|
129
129
|
outFormat: oracledb.OUT_FORMAT_OBJECT, // query result format
|
|
130
|
-
// extendedMetaData: true, // get extra metadata
|
|
131
130
|
// fetchArraySize: 100 // internal buffer allocation size for tuning
|
|
132
131
|
};
|
|
133
132
|
|
package/lib/aqQueue.js
CHANGED
|
@@ -27,13 +27,14 @@
|
|
|
27
27
|
'use strict';
|
|
28
28
|
|
|
29
29
|
const { Buffer } = require('buffer');
|
|
30
|
-
const constants = require('./constants.js');
|
|
31
30
|
const errors = require('./errors.js');
|
|
32
31
|
const nodbUtil = require('./util.js');
|
|
33
32
|
const AqDeqOptions = require('./aqDeqOptions.js');
|
|
34
33
|
const AqEnqOptions = require('./aqEnqOptions.js');
|
|
35
34
|
const AqMessage = require('./aqMessage.js');
|
|
36
35
|
const BaseDbObject = require('./dbObject.js');
|
|
36
|
+
const transformer = require('./transformer.js');
|
|
37
|
+
const types = require('./types.js');
|
|
37
38
|
|
|
38
39
|
class AqQueue {
|
|
39
40
|
|
|
@@ -47,6 +48,19 @@ class AqQueue {
|
|
|
47
48
|
value instanceof BaseDbObject);
|
|
48
49
|
}
|
|
49
50
|
|
|
51
|
+
//---------------------------------------------------------------------------
|
|
52
|
+
// _makeMessage()
|
|
53
|
+
//
|
|
54
|
+
// For enqOne()/deqOne()/enqMany()/deqMany(), wrap the return value with JS
|
|
55
|
+
// layer object.
|
|
56
|
+
//---------------------------------------------------------------------------
|
|
57
|
+
_makeMessage(msgImpl) {
|
|
58
|
+
const msg = new AqMessage();
|
|
59
|
+
msg._impl = msgImpl;
|
|
60
|
+
msg._payloadTypeClass = this._payloadTypeClass;
|
|
61
|
+
return msg;
|
|
62
|
+
}
|
|
63
|
+
|
|
50
64
|
//---------------------------------------------------------------------------
|
|
51
65
|
// _verifyMessage()
|
|
52
66
|
//
|
|
@@ -64,7 +78,7 @@ class AqQueue {
|
|
|
64
78
|
message = {};
|
|
65
79
|
} else {
|
|
66
80
|
message = {...message};
|
|
67
|
-
if (this._isPayload(message.payload)) {
|
|
81
|
+
if (this._isJson || this._isPayload(message.payload)) {
|
|
68
82
|
payload = message.payload;
|
|
69
83
|
} else if (this._payloadTypeClass) {
|
|
70
84
|
payload = new this._payloadTypeClass(message.payload);
|
|
@@ -74,7 +88,9 @@ class AqQueue {
|
|
|
74
88
|
}
|
|
75
89
|
|
|
76
90
|
// validate payload
|
|
77
|
-
if (
|
|
91
|
+
if (this._isJson) {
|
|
92
|
+
message.payload = transformer.transformJsonValue(payload);
|
|
93
|
+
} else if (typeof payload === 'string') {
|
|
78
94
|
message.payload = Buffer.from(payload);
|
|
79
95
|
} else if (Buffer.isBuffer(payload)) {
|
|
80
96
|
message.payload = payload;
|
|
@@ -116,8 +132,17 @@ class AqQueue {
|
|
|
116
132
|
// Creates the queue and populates some internal attributes.
|
|
117
133
|
//---------------------------------------------------------------------------
|
|
118
134
|
async create(conn, name, options) {
|
|
119
|
-
if (options.payloadType) {
|
|
120
|
-
|
|
135
|
+
if (options.payloadType === types.DB_TYPE_JSON) {
|
|
136
|
+
this._isJson = true;
|
|
137
|
+
this._payloadType = types.DB_TYPE_JSON;
|
|
138
|
+
this._payloadTypeName = "JSON";
|
|
139
|
+
} else if (options.payloadType === undefined ||
|
|
140
|
+
options.payloadType === types.DB_TYPE_RAW) {
|
|
141
|
+
this._payloadType = types.DB_TYPE_RAW;
|
|
142
|
+
this._payloadTypeName = "RAW";
|
|
143
|
+
} else {
|
|
144
|
+
if (typeof options.payloadType === 'string') {
|
|
145
|
+
// DB Object type
|
|
121
146
|
const cls = await conn._getDbObjectClassForName(options.payloadType);
|
|
122
147
|
this._payloadTypeClass = cls;
|
|
123
148
|
options.payloadType = cls;
|
|
@@ -126,14 +151,12 @@ class AqQueue {
|
|
|
126
151
|
options.payloadType.prototype instanceof BaseDbObject, 2, "payloadType");
|
|
127
152
|
this._payloadTypeClass = options.payloadType;
|
|
128
153
|
}
|
|
129
|
-
this._payloadType =
|
|
154
|
+
this._payloadType = types.DB_TYPE_OBJECT;
|
|
130
155
|
this._payloadTypeName = this._payloadTypeClass.prototype.name;
|
|
131
|
-
} else {
|
|
132
|
-
this._payloadType = constants.DB_TYPE_RAW;
|
|
133
|
-
this._payloadTypeName = "RAW";
|
|
134
156
|
}
|
|
135
157
|
this._name = name;
|
|
136
|
-
this._impl = await conn._impl.getQueue(name,
|
|
158
|
+
this._impl = await conn._impl.getQueue(name, this._payloadTypeClass,
|
|
159
|
+
this._payloadType);
|
|
137
160
|
}
|
|
138
161
|
|
|
139
162
|
//---------------------------------------------------------------------------
|
|
@@ -147,14 +170,7 @@ class AqQueue {
|
|
|
147
170
|
errors.assertParamValue(Number.isInteger(maxMessages) && maxMessages > 0,
|
|
148
171
|
1);
|
|
149
172
|
const msgImpls = await this._impl.deqMany(maxMessages);
|
|
150
|
-
|
|
151
|
-
for (let i = 0; i < msgImpls.length; i++) {
|
|
152
|
-
const msg = new AqMessage();
|
|
153
|
-
msg._impl = msgImpls[i];
|
|
154
|
-
msg._payloadTypeClass = this._payloadTypeClass;
|
|
155
|
-
messages[i] = msg;
|
|
156
|
-
}
|
|
157
|
-
return messages;
|
|
173
|
+
return msgImpls.map(i => this._makeMessage(i));
|
|
158
174
|
}
|
|
159
175
|
|
|
160
176
|
//---------------------------------------------------------------------------
|
|
@@ -165,12 +181,8 @@ class AqQueue {
|
|
|
165
181
|
async deqOne() {
|
|
166
182
|
errors.assertArgCount(arguments, 0, 0);
|
|
167
183
|
const msgImpl = await this._impl.deqOne();
|
|
168
|
-
if (msgImpl)
|
|
169
|
-
|
|
170
|
-
msg._impl = msgImpl;
|
|
171
|
-
msg._payloadTypeClass = this._payloadTypeClass;
|
|
172
|
-
return msg;
|
|
173
|
-
}
|
|
184
|
+
if (msgImpl)
|
|
185
|
+
return this._makeMessage(msgImpl);
|
|
174
186
|
}
|
|
175
187
|
|
|
176
188
|
//---------------------------------------------------------------------------
|
|
@@ -200,7 +212,8 @@ class AqQueue {
|
|
|
200
212
|
for (let i = 0; i < messages.length; i++) {
|
|
201
213
|
verifiedMessages[i] = this._verifyMessage(messages[i]);
|
|
202
214
|
}
|
|
203
|
-
|
|
215
|
+
const msgImpls = await this._impl.enqMany(verifiedMessages);
|
|
216
|
+
return msgImpls.map(i => this._makeMessage(i));
|
|
204
217
|
}
|
|
205
218
|
|
|
206
219
|
//---------------------------------------------------------------------------
|
|
@@ -211,7 +224,8 @@ class AqQueue {
|
|
|
211
224
|
async enqOne(message) {
|
|
212
225
|
errors.assertArgCount(arguments, 1, 1);
|
|
213
226
|
message = this._verifyMessage(message);
|
|
214
|
-
|
|
227
|
+
const msgImpl = await this._impl.enqOne(message);
|
|
228
|
+
return this._makeMessage(msgImpl);
|
|
215
229
|
}
|
|
216
230
|
|
|
217
231
|
//---------------------------------------------------------------------------
|
package/lib/connection.js
CHANGED
|
@@ -1039,6 +1039,19 @@ class Connection extends EventEmitter {
|
|
|
1039
1039
|
return info;
|
|
1040
1040
|
}
|
|
1041
1041
|
|
|
1042
|
+
//---------------------------------------------------------------------------
|
|
1043
|
+
// instanceName
|
|
1044
|
+
//
|
|
1045
|
+
// Returns the Oracle Database instance name associated with the connection.
|
|
1046
|
+
// This is the equivalent of the SQL expression:
|
|
1047
|
+
// sys_context('userenv', 'instance_name')
|
|
1048
|
+
//---------------------------------------------------------------------------
|
|
1049
|
+
get instanceName() {
|
|
1050
|
+
if (this._impl)
|
|
1051
|
+
return this._impl.getInstanceName();
|
|
1052
|
+
return undefined;
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1042
1055
|
//---------------------------------------------------------------------------
|
|
1043
1056
|
// internalName
|
|
1044
1057
|
//
|
|
@@ -1061,7 +1074,7 @@ class Connection extends EventEmitter {
|
|
|
1061
1074
|
//
|
|
1062
1075
|
// Returns the health status of the connection. If this function returns
|
|
1063
1076
|
// false, the caller should close the connection.
|
|
1064
|
-
|
|
1077
|
+
//---------------------------------------------------------------------------
|
|
1065
1078
|
isHealthy() {
|
|
1066
1079
|
return (this._impl !== undefined && !this._closing &&
|
|
1067
1080
|
this._impl.isHealthy());
|
|
@@ -1227,7 +1240,7 @@ class Connection extends EventEmitter {
|
|
|
1227
1240
|
errors.assertArgCount(arguments, 2, 2);
|
|
1228
1241
|
errors.assertParamValue(typeof name === 'string', 1);
|
|
1229
1242
|
errors.assertParamValue(nodbUtil.isObject(options), 2);
|
|
1230
|
-
options = {...options};
|
|
1243
|
+
options = {name: name, ...options};
|
|
1231
1244
|
errors.assertParamPropUnsignedInt(options, 2, "namespace");
|
|
1232
1245
|
if (options.namespace === undefined)
|
|
1233
1246
|
options.namespace = constants.SUBSCR_NAMESPACE_DBCHANGE;
|
|
@@ -1253,14 +1266,13 @@ class Connection extends EventEmitter {
|
|
|
1253
1266
|
errors.assert(this._impl, errors.ERR_INVALID_CONNECTION);
|
|
1254
1267
|
|
|
1255
1268
|
const inSubscr = _subscriptions.get(name);
|
|
1256
|
-
|
|
1269
|
+
const outValue = await this._impl.subscribe(inSubscr, options);
|
|
1257
1270
|
let subscription;
|
|
1258
1271
|
if (options.namespace === constants.SUBSCR_NAMESPACE_DBCHANGE) {
|
|
1259
1272
|
subscription = outValue.subscription;
|
|
1260
1273
|
delete outValue.subscription;
|
|
1261
1274
|
} else {
|
|
1262
1275
|
subscription = outValue;
|
|
1263
|
-
outValue = undefined;
|
|
1264
1276
|
}
|
|
1265
1277
|
_subscriptions.set(name, subscription);
|
|
1266
1278
|
return outValue;
|
package/lib/dbObject.js
CHANGED
|
@@ -319,6 +319,15 @@ class BaseDbObject {
|
|
|
319
319
|
return this._objType.schema;
|
|
320
320
|
}
|
|
321
321
|
|
|
322
|
+
//---------------------------------------------------------------------------
|
|
323
|
+
// packageName
|
|
324
|
+
//
|
|
325
|
+
// Property for the packageName of the database object type.
|
|
326
|
+
//---------------------------------------------------------------------------
|
|
327
|
+
get packageName() {
|
|
328
|
+
return this._objType.packageName;
|
|
329
|
+
}
|
|
330
|
+
|
|
322
331
|
//---------------------------------------------------------------------------
|
|
323
332
|
// setElement()
|
|
324
333
|
//
|
package/lib/errors.js
CHANGED
|
@@ -116,7 +116,6 @@ const ERR_UNEXPECTED_DATA = 113;
|
|
|
116
116
|
const ERR_OSON_FIELD_NAME_LIMITATION = 114;
|
|
117
117
|
const ERR_ORACLE_NUMBER_NO_REPR = 115;
|
|
118
118
|
const ERR_UNSUPPORTED_VERIFIER_TYPE = 116;
|
|
119
|
-
const ERR_INVALID_PRIVATE_KEY = 117;
|
|
120
119
|
const ERR_THIN_CONNECTION_ALREADY_CREATED = 118;
|
|
121
120
|
const ERR_UNSUPPORTED_CONVERSION = 119;
|
|
122
121
|
const ERR_FETCH_TYPE_HANDLER_RETURN_VALUE = 120;
|
|
@@ -178,7 +177,6 @@ adjustErrorXref.set("OCI-22165", [ERR_INVALID_COLL_INDEX_SET, /index \[([0-9]+)\
|
|
|
178
177
|
adjustErrorXref.set("ORA-00028", ERR_CONNECTION_CLOSED);
|
|
179
178
|
adjustErrorXref.set("ORA-00600", ERR_CONNECTION_CLOSED);
|
|
180
179
|
adjustErrorXref.set("ORA-24338", ERR_INVALID_REF_CURSOR);
|
|
181
|
-
adjustErrorXref.set("ORA-24422", ERR_POOL_HAS_BUSY_CONNECTIONS);
|
|
182
180
|
adjustErrorXref.set("ORA-25708", ERR_TOKEN_HAS_EXPIRED);
|
|
183
181
|
|
|
184
182
|
// define mapping for error messages
|
|
@@ -355,8 +353,6 @@ messages.set(ERR_ORACLE_NUMBER_NO_REPR, // NJS-115
|
|
|
355
353
|
'value cannot be represented as an Oracle Database number');
|
|
356
354
|
messages.set(ERR_UNSUPPORTED_VERIFIER_TYPE, // NJS-116
|
|
357
355
|
'password verifier type 0x%s is not supported by node-oracledb in Thin mode');
|
|
358
|
-
messages.set(ERR_INVALID_PRIVATE_KEY, // NJS-117
|
|
359
|
-
'invalid private key. Headers and footers are not allowed');
|
|
360
356
|
messages.set(ERR_THIN_CONNECTION_ALREADY_CREATED, // NJS-118
|
|
361
357
|
'node-oracledb Thick mode cannot be enabled because a Thin mode connection has already been created');
|
|
362
358
|
messages.set(ERR_UNSUPPORTED_CONVERSION, // NJS-119
|
|
@@ -470,7 +466,7 @@ function assertArgCount(args, minArgCount, maxArgCount) {
|
|
|
470
466
|
//-----------------------------------------------------------------------------
|
|
471
467
|
// assertParamPropBool()
|
|
472
468
|
//
|
|
473
|
-
// Asserts that the property value of a
|
|
469
|
+
// Asserts that the property value of a parameter is a boolean value (or
|
|
474
470
|
// undefined).
|
|
475
471
|
//-----------------------------------------------------------------------------
|
|
476
472
|
function assertParamPropBool(obj, parameterNum, propName) {
|
|
@@ -483,7 +479,7 @@ function assertParamPropBool(obj, parameterNum, propName) {
|
|
|
483
479
|
//-----------------------------------------------------------------------------
|
|
484
480
|
// assertParamPropFunction()
|
|
485
481
|
//
|
|
486
|
-
// Asserts that the property value of a
|
|
482
|
+
// Asserts that the property value of a parameter is a function (or undefined).
|
|
487
483
|
//-----------------------------------------------------------------------------
|
|
488
484
|
function assertParamPropFunction(obj, parameterNum, propName) {
|
|
489
485
|
if (obj[propName] !== undefined) {
|
|
@@ -495,7 +491,7 @@ function assertParamPropFunction(obj, parameterNum, propName) {
|
|
|
495
491
|
//-----------------------------------------------------------------------------
|
|
496
492
|
// assertParamPropInt()
|
|
497
493
|
//
|
|
498
|
-
// Asserts that the property value of a
|
|
494
|
+
// Asserts that the property value of a parameter is an integer value (or
|
|
499
495
|
// undefined).
|
|
500
496
|
//-----------------------------------------------------------------------------
|
|
501
497
|
function assertParamPropInt(obj, parameterNum, propName) {
|
|
@@ -508,7 +504,7 @@ function assertParamPropInt(obj, parameterNum, propName) {
|
|
|
508
504
|
//-----------------------------------------------------------------------------
|
|
509
505
|
// assertParamPropUnsignedInt()
|
|
510
506
|
//
|
|
511
|
-
// Asserts that the property value of a
|
|
507
|
+
// Asserts that the property value of a parameter is a positive integer value
|
|
512
508
|
// (or undefined).
|
|
513
509
|
//-----------------------------------------------------------------------------
|
|
514
510
|
function assertParamPropUnsignedInt(obj, parameterNum, propName) {
|
|
@@ -521,7 +517,7 @@ function assertParamPropUnsignedInt(obj, parameterNum, propName) {
|
|
|
521
517
|
//-----------------------------------------------------------------------------
|
|
522
518
|
// assertParamPropString()
|
|
523
519
|
//
|
|
524
|
-
// Asserts that the property value of a
|
|
520
|
+
// Asserts that the property value of a parameter is a string value (or undefined).
|
|
525
521
|
//-----------------------------------------------------------------------------
|
|
526
522
|
function assertParamPropString(obj, parameterNum, propName) {
|
|
527
523
|
if (obj[propName] !== undefined) {
|
|
@@ -533,7 +529,7 @@ function assertParamPropString(obj, parameterNum, propName) {
|
|
|
533
529
|
//-----------------------------------------------------------------------------
|
|
534
530
|
// assertParamPropValue()
|
|
535
531
|
//
|
|
536
|
-
// Asserts that the property value of a
|
|
532
|
+
// Asserts that the property value of a parameter passes the specified
|
|
537
533
|
// condition.
|
|
538
534
|
//-----------------------------------------------------------------------------
|
|
539
535
|
function assertParamPropValue(condition, parameterNum, propName) {
|
|
@@ -544,7 +540,7 @@ function assertParamPropValue(condition, parameterNum, propName) {
|
|
|
544
540
|
//-----------------------------------------------------------------------------
|
|
545
541
|
// assertParamValue()
|
|
546
542
|
//
|
|
547
|
-
// Asserts that the
|
|
543
|
+
// Asserts that the parameter value passes the specified condition.
|
|
548
544
|
//-----------------------------------------------------------------------------
|
|
549
545
|
function assertParamValue(condition, parameterNum) {
|
|
550
546
|
assert(condition, ERR_INVALID_PARAMETER_VALUE, parameterNum);
|
|
@@ -612,10 +608,19 @@ function transformErr(err, fnOpt) {
|
|
|
612
608
|
const pos = err.message.indexOf(":");
|
|
613
609
|
if (pos > 0) {
|
|
614
610
|
err.code = err.message.substr(0, pos);
|
|
611
|
+
/* add Oracle Database Error Help Portal URL for database error
|
|
612
|
+
messages, but only in thin mode since this is done
|
|
613
|
+
automatically in thick mode with Oracle Client 23c and higher
|
|
614
|
+
*/
|
|
615
|
+
const settings = require('./settings.js');
|
|
616
|
+
if (err.errorNum && settings.thin) {
|
|
617
|
+
err.message += '\n' + 'Help: https://docs.oracle.com/error-help/db/ora-' +
|
|
618
|
+
`${err.errorNum.toString().padStart(5, '0')}/`;
|
|
619
|
+
}
|
|
615
620
|
if (adjustErrorXref.has(err.code)) {
|
|
616
621
|
let args = [];
|
|
617
622
|
let driverErrorNum;
|
|
618
|
-
|
|
623
|
+
const driverErrorInfo = adjustErrorXref.get(err.code);
|
|
619
624
|
if (typeof driverErrorInfo === 'number') {
|
|
620
625
|
driverErrorNum = driverErrorInfo;
|
|
621
626
|
} else {
|
|
@@ -748,7 +753,6 @@ module.exports = {
|
|
|
748
753
|
ERR_UNEXPECTED_DATA,
|
|
749
754
|
ERR_OSON_FIELD_NAME_LIMITATION,
|
|
750
755
|
ERR_OSON_VERSION_NOT_SUPPORTED,
|
|
751
|
-
ERR_INVALID_PRIVATE_KEY,
|
|
752
756
|
ERR_THIN_CONNECTION_ALREADY_CREATED,
|
|
753
757
|
ERR_UNSUPPORTED_CONVERSION,
|
|
754
758
|
ERR_FETCH_TYPE_HANDLER_RETURN_VALUE,
|
package/lib/impl/connection.js
CHANGED
|
@@ -226,6 +226,15 @@ class ConnectionImpl {
|
|
|
226
226
|
errors.throwNotImplemented("getting the external name");
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
+
//---------------------------------------------------------------------------
|
|
230
|
+
// getInstanceName()
|
|
231
|
+
//
|
|
232
|
+
// Returns the Oracle Database instance name associated with the connection.
|
|
233
|
+
//---------------------------------------------------------------------------
|
|
234
|
+
getInstanceName() {
|
|
235
|
+
errors.throwNotImplemented("getting the Oracle Database instance name.");
|
|
236
|
+
}
|
|
237
|
+
|
|
229
238
|
//---------------------------------------------------------------------------
|
|
230
239
|
// getInternalName()
|
|
231
240
|
//
|
package/lib/impl/resultset.js
CHANGED
|
@@ -111,14 +111,17 @@ class ResultSetImpl {
|
|
|
111
111
|
if (metadata.dbType === types.DB_TYPE_NUMBER &&
|
|
112
112
|
metadata.fetchType === types.DB_TYPE_NUMBER) {
|
|
113
113
|
converter = (v) => (v === null) ? null : parseFloat(v);
|
|
114
|
-
} else if (metadata.fetchType === types.DB_TYPE_VARCHAR
|
|
115
|
-
|
|
114
|
+
} else if (metadata.fetchType === types.DB_TYPE_VARCHAR) {
|
|
115
|
+
if (metadata.dbType === types.DB_TYPE_BINARY_DOUBLE ||
|
|
116
116
|
metadata.dbType === types.DB_TYPE_BINARY_FLOAT ||
|
|
117
117
|
metadata.dbType === types.DB_TYPE_DATE ||
|
|
118
118
|
metadata.dbType === types.DB_TYPE_TIMESTAMP ||
|
|
119
119
|
metadata.dbType === types.DB_TYPE_TIMESTAMP_LTZ ||
|
|
120
|
-
metadata.dbType === types.DB_TYPE_TIMESTAMP_TZ)
|
|
121
|
-
|
|
120
|
+
metadata.dbType === types.DB_TYPE_TIMESTAMP_TZ) {
|
|
121
|
+
converter = (v) => (v === null) ? null : v.toString();
|
|
122
|
+
} else if (metadata.dbType === types.DB_TYPE_RAW) {
|
|
123
|
+
converter = (v) => (v === null) ? null : v.toString('hex').toUpperCase();
|
|
124
|
+
}
|
|
122
125
|
}
|
|
123
126
|
if (userConverter && converter) {
|
|
124
127
|
const internalConverter = converter;
|
package/lib/oracledb.js
CHANGED
|
@@ -67,25 +67,28 @@ const defaultPoolAlias = 'default';
|
|
|
67
67
|
|
|
68
68
|
// save arguments for call to initOracleClient()
|
|
69
69
|
let _initOracleClientArgs;
|
|
70
|
-
let _thinDriverInitialized = false;
|
|
71
70
|
|
|
72
71
|
// Load the Oracledb binary
|
|
73
|
-
function _initCLib() {
|
|
72
|
+
function _initCLib(options) {
|
|
74
73
|
/*global __non_webpack_require__*/ // quieten eslint
|
|
75
74
|
const requireBinary = (typeof __non_webpack_require__ === 'function') ? __non_webpack_require__ : require; // See Issue 1156
|
|
76
|
-
|
|
77
75
|
const binaryLocations = [
|
|
78
76
|
'../' + nodbUtil.RELEASE_DIR + '/' + nodbUtil.BINARY_FILE, // pre-built binary
|
|
79
|
-
'../' + nodbUtil.RELEASE_DIR + '/' +
|
|
80
|
-
'../build/Debug/
|
|
77
|
+
'../' + nodbUtil.RELEASE_DIR + '/' + nodbUtil.BUILD_FILE, // binary built from source
|
|
78
|
+
'../build/Debug/' + nodbUtil.BUILD_FILE, // debug binary
|
|
81
79
|
// Paths for Webpack.
|
|
82
80
|
// Note: to use node-oracledb Thick mode, you will need a Webpack copy plugin to
|
|
83
81
|
// copy 'node_modules/oracledb/build/' to the output directory,
|
|
84
82
|
// see https://github.com/oracle/node-oracledb/issues/1156
|
|
85
83
|
// If you want to use only node-oracledb Thin mode, a copy plugin is not needed.
|
|
86
84
|
'./node_modules/oracledb/' + nodbUtil.RELEASE_DIR + '/' + nodbUtil.BINARY_FILE,
|
|
87
|
-
'./node_modules/oracledb/' + nodbUtil.RELEASE_DIR + '/' +
|
|
85
|
+
'./node_modules/oracledb/' + nodbUtil.RELEASE_DIR + '/' + nodbUtil.BUILD_FILE
|
|
88
86
|
];
|
|
87
|
+
|
|
88
|
+
if (options.binaryDir !== undefined) {
|
|
89
|
+
binaryLocations.splice(0, 0, options.binaryDir + '/' + nodbUtil.BINARY_FILE,
|
|
90
|
+
options.binaryDir + '/' + nodbUtil.BUILD_FILE);
|
|
91
|
+
}
|
|
89
92
|
let oracledbCLib;
|
|
90
93
|
for (let i = 0; i < binaryLocations.length; i++) {
|
|
91
94
|
try {
|
|
@@ -248,6 +251,12 @@ async function _verifyOptions(options, inCreatePool) {
|
|
|
248
251
|
outOptions.sslServerDNMatch = options.sslServerDNMatch;
|
|
249
252
|
}
|
|
250
253
|
|
|
254
|
+
// sslAllowWeakDNMatch must be a boolean
|
|
255
|
+
if (options.sslAllowWeakDNMatch !== undefined) {
|
|
256
|
+
errors.assertParamPropValue(typeof options.sslAllowWeakDNMatch === 'boolean',
|
|
257
|
+
1, "sslAllowWeakDNMatch");
|
|
258
|
+
outOptions.sslAllowWeakDNMatch = options.sslAllowWeakDNMatch;
|
|
259
|
+
}
|
|
251
260
|
// httpsProxy must be a string
|
|
252
261
|
if (options.httpsProxy !== undefined) {
|
|
253
262
|
errors.assertParamPropValue(typeof options.httpsProxy === 'string',
|
|
@@ -472,8 +481,10 @@ async function _verifyOptions(options, inCreatePool) {
|
|
|
472
481
|
errors.assert(nodbUtil.isTokenValid(accessToken),
|
|
473
482
|
errors.ERR_TOKEN_HAS_EXPIRED);
|
|
474
483
|
if (accessToken.privateKey !== undefined) {
|
|
475
|
-
errors.assert(
|
|
476
|
-
|
|
484
|
+
errors.assert(typeof accessToken.privateKey === 'string', errors.ERR_TOKEN_BASED_AUTH);
|
|
485
|
+
accessToken.privateKey = accessToken.privateKey.replace(/\n/g, '');
|
|
486
|
+
accessToken.privateKey = accessToken.privateKey.replace('-----BEGIN PRIVATE KEY-----', '');
|
|
487
|
+
accessToken.privateKey = accessToken.privateKey.replace('-----END PRIVATE KEY-----', '');
|
|
477
488
|
}
|
|
478
489
|
|
|
479
490
|
// store token and privatekey
|
|
@@ -546,7 +557,7 @@ async function createPool(options) {
|
|
|
546
557
|
}
|
|
547
558
|
|
|
548
559
|
// initialize the Oracle client, if necessary
|
|
549
|
-
if (_initOracleClientArgs === undefined && !
|
|
560
|
+
if (_initOracleClientArgs === undefined && !settings.thinDriverInitialized) {
|
|
550
561
|
_initializeThinDriver();
|
|
551
562
|
}
|
|
552
563
|
|
|
@@ -579,6 +590,9 @@ async function createPool(options) {
|
|
|
579
590
|
delete poolCache[pool.poolAlias];
|
|
580
591
|
}
|
|
581
592
|
});
|
|
593
|
+
if (_initOracleClientArgs === undefined) {
|
|
594
|
+
settings.thinDriverInitialized = true;
|
|
595
|
+
}
|
|
582
596
|
|
|
583
597
|
return pool;
|
|
584
598
|
}
|
|
@@ -638,7 +652,6 @@ async function getConnection(a1) {
|
|
|
638
652
|
// Returns a pool for the given alias.
|
|
639
653
|
//-----------------------------------------------------------------------------
|
|
640
654
|
function getPool(poolAlias) {
|
|
641
|
-
let pool;
|
|
642
655
|
|
|
643
656
|
errors.assertArgCount(arguments, 0, 1);
|
|
644
657
|
|
|
@@ -649,7 +662,7 @@ function getPool(poolAlias) {
|
|
|
649
662
|
|
|
650
663
|
poolAlias = poolAlias || defaultPoolAlias;
|
|
651
664
|
|
|
652
|
-
pool = poolCache[poolAlias];
|
|
665
|
+
const pool = poolCache[poolAlias];
|
|
653
666
|
|
|
654
667
|
if (!pool) {
|
|
655
668
|
errors.throwErr(errors.ERR_POOL_WITH_ALIAS_NOT_FOUND, poolAlias);
|
|
@@ -673,12 +686,13 @@ function initOracleClient(arg1) {
|
|
|
673
686
|
errors.assertParamPropString(options, 1, "configDir");
|
|
674
687
|
errors.assertParamPropString(options, 1, "errorUrl");
|
|
675
688
|
errors.assertParamPropString(options, 1, "driverName");
|
|
689
|
+
errors.assertParamPropString(options, 1, "binaryDir");
|
|
676
690
|
}
|
|
677
691
|
if (settings.thinDriverInitialized) {
|
|
678
692
|
errors.throwErr(errors.ERR_THIN_CONNECTION_ALREADY_CREATED);
|
|
679
693
|
}
|
|
680
694
|
if (_initOracleClientArgs === undefined) {
|
|
681
|
-
const oracledbCLib = _initCLib();
|
|
695
|
+
const oracledbCLib = _initCLib(options);
|
|
682
696
|
if (options.driverName === undefined)
|
|
683
697
|
options.driverName = constants.DEFAULT_DRIVER_NAME + " thk";
|
|
684
698
|
if (options.errorUrl === undefined)
|
|
@@ -1053,16 +1067,10 @@ module.exports = {
|
|
|
1053
1067
|
},
|
|
1054
1068
|
|
|
1055
1069
|
get oracleClientVersion() {
|
|
1056
|
-
if (_initOracleClientArgs === undefined) {
|
|
1057
|
-
errors.throwNotImplemented("getting the Oracle Client version");
|
|
1058
|
-
}
|
|
1059
1070
|
return settings.oracleClientVersion;
|
|
1060
1071
|
},
|
|
1061
1072
|
|
|
1062
1073
|
get oracleClientVersionString() {
|
|
1063
|
-
if (_initOracleClientArgs === undefined) {
|
|
1064
|
-
errors.throwNotImplemented("getting the Oracle Client version");
|
|
1065
|
-
}
|
|
1066
1074
|
return settings.oracleClientVersionString;
|
|
1067
1075
|
},
|
|
1068
1076
|
|
package/lib/pool.js
CHANGED
|
@@ -279,8 +279,14 @@ class Pool extends EventEmitter {
|
|
|
279
279
|
});
|
|
280
280
|
}
|
|
281
281
|
|
|
282
|
+
// if any connections are still out and the pool is not being force closed,
|
|
283
|
+
// throw an exception
|
|
284
|
+
if (!forceClose && this._connectionsOut > 0) {
|
|
285
|
+
errors.throwErr(errors.ERR_POOL_HAS_BUSY_CONNECTIONS);
|
|
286
|
+
}
|
|
287
|
+
|
|
282
288
|
// close the pool
|
|
283
|
-
await this._impl.close(
|
|
289
|
+
await this._impl.close();
|
|
284
290
|
this._status = constants.POOL_STATUS_CLOSED;
|
|
285
291
|
this.emit('_afterPoolClose');
|
|
286
292
|
|
package/lib/sodaCollection.js
CHANGED
|
@@ -109,7 +109,7 @@ class SodaCollection {
|
|
|
109
109
|
errors.assertArgCount(arguments, 1, 1);
|
|
110
110
|
errors.assertParamValue(Array.isArray(docs) && docs.length > 0, 1);
|
|
111
111
|
|
|
112
|
-
|
|
112
|
+
const actualDocs = Array(docs.length);
|
|
113
113
|
for (let i = 0; i < docs.length; i++) {
|
|
114
114
|
actualDocs[i] = nodbUtil.verifySodaDoc(docs[i]);
|
|
115
115
|
}
|
|
@@ -188,6 +188,16 @@ class SodaCollection {
|
|
|
188
188
|
return doc;
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
+
//---------------------------------------------------------------------------
|
|
192
|
+
// listIndexes()
|
|
193
|
+
//
|
|
194
|
+
// To obtain all indices from the collection
|
|
195
|
+
//---------------------------------------------------------------------------
|
|
196
|
+
async listIndexes() {
|
|
197
|
+
const arr = await this._impl.listIndexes();
|
|
198
|
+
return arr.map(i => JSON.parse(i));
|
|
199
|
+
}
|
|
200
|
+
|
|
191
201
|
//---------------------------------------------------------------------------
|
|
192
202
|
// metaData()
|
|
193
203
|
//
|
|
@@ -262,6 +272,7 @@ nodbUtil.wrapFns(SodaCollection.prototype,
|
|
|
262
272
|
"insertManyAndGet",
|
|
263
273
|
"insertOne",
|
|
264
274
|
"insertOneAndGet",
|
|
275
|
+
"listIndexes",
|
|
265
276
|
"save",
|
|
266
277
|
"saveAndGet",
|
|
267
278
|
"truncate");
|
package/lib/sodaOperation.js
CHANGED
|
@@ -94,6 +94,22 @@ class SodaOperation {
|
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
|
|
98
|
+
//---------------------------------------------------------------------------
|
|
99
|
+
// lock()
|
|
100
|
+
//
|
|
101
|
+
// Pessimistic locking - similar to SELECT FOR UPDATE, these documents
|
|
102
|
+
// cannot be updated by other threads until an explicit commit/rollback is
|
|
103
|
+
// called. With autoCommit set to true is applicable only for one immediate
|
|
104
|
+
// operation and is not recommended in this context
|
|
105
|
+
//---------------------------------------------------------------------------
|
|
106
|
+
lock() {
|
|
107
|
+
errors.assertArgCount(arguments, 0, 0);
|
|
108
|
+
this._options.lock = true;
|
|
109
|
+
return this;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
|
|
97
113
|
//---------------------------------------------------------------------------
|
|
98
114
|
// replaceOne()
|
|
99
115
|
//
|