oracledb 7.0.1 → 26.0.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 +16 -6
- package/build/Release/oracledb-26.0.0-darwin-arm64.node +0 -0
- package/build/Release/oracledb-26.0.0-darwin-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-26.0.0-js-buildinfo.txt +1 -0
- package/build/Release/oracledb-26.0.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-26.0.0-linux-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-26.0.0-linux-x64.node +0 -0
- package/build/Release/oracledb-26.0.0-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-26.0.0-win32-x64.node +0 -0
- package/build/Release/oracledb-26.0.0-win32-x64.node-buildinfo.txt +1 -0
- package/lib/connection.js +71 -8
- package/lib/constants.js +4 -0
- package/lib/endUserSecurityContext.js +20 -8
- package/lib/errors.js +70 -5
- package/lib/impl/connection.js +36 -0
- package/lib/impl/datahandlers/buffer.js +91 -18
- package/lib/impl/datahandlers/oson.js +3 -2
- package/lib/impl/resultset.js +32 -11
- package/lib/oracledb.js +34 -0
- package/lib/pool.js +6 -2
- package/lib/queryStream.js +13 -5
- package/lib/resultset.js +10 -3
- package/lib/securityContextProvider.js +206 -0
- package/lib/thin/aq.js +2 -3
- package/lib/thin/connection.js +381 -19
- package/lib/thin/dbObject.js +17 -8
- package/lib/thin/pool.js +3 -2
- package/lib/thin/protocol/capabilities.js +37 -4
- package/lib/thin/protocol/constants.js +49 -1
- package/lib/thin/protocol/messages/auth.js +17 -6
- package/lib/thin/protocol/messages/base.js +74 -16
- package/lib/thin/protocol/messages/dataType.js +46 -0
- package/lib/thin/protocol/messages/directPathLoadStream.js +3 -2
- package/lib/thin/protocol/messages/execute.js +10 -4
- package/lib/thin/protocol/messages/index.js +4 -0
- package/lib/thin/protocol/messages/notification.js +281 -0
- package/lib/thin/protocol/messages/subscribe.js +181 -0
- package/lib/thin/protocol/messages/withData.js +21 -7
- package/lib/thin/protocol/packet.js +2 -4
- package/lib/thin/protocol/protocol.js +7 -4
- package/lib/thin/resultSet.js +40 -20
- package/lib/thin/sqlnet/ezConnectResolver.js +7 -0
- package/lib/thin/sqlnet/navNodes.js +3 -3
- package/lib/thin/sqlnet/ntTcp.js +24 -8
- package/lib/thin/statement.js +6 -1
- package/lib/thin/statementCache.js +34 -6
- package/lib/thin/subscr.js +363 -0
- package/lib/transformer.js +60 -17
- package/lib/util.js +46 -8
- package/lib/version.js +2 -2
- package/package.json +1 -1
- package/plugins/configProviders/gcpstorage/index.js +121 -0
- package/plugins/configProviders/ociobject/index.js +1 -1
- package/plugins/token/cache.js +154 -0
- package/plugins/token/endUserSecurityProvider/index.js +377 -0
- package/plugins/token/extensionAzure/index.js +160 -28
- package/plugins/token/extensionOci/index.js +221 -16
- package/plugins/vectorsdk/OracleVecDB.js +346 -0
- package/plugins/vectorsdk/index.js +49 -0
- package/plugins/vectorsdk/utils.js +370 -0
- package/plugins/vectorsdk/vectorEmbedding.js +223 -0
- package/plugins/vectorsdk/vectorIndex.js +177 -0
- package/plugins/vectorsdk/vectorRecords.js +406 -0
- package/plugins/vectorsdk/vectorSchema.js +408 -0
- package/plugins/vectorsdk/vectorSearch.js +538 -0
- package/build/Release/oracledb-7.0.1-darwin-arm64.node +0 -0
- package/build/Release/oracledb-7.0.1-darwin-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-7.0.1-js-buildinfo.txt +0 -1
- package/build/Release/oracledb-7.0.1-linux-arm64.node +0 -0
- package/build/Release/oracledb-7.0.1-linux-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-7.0.1-linux-x64.node +0 -0
- package/build/Release/oracledb-7.0.1-linux-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-7.0.1-win32-x64.node +0 -0
- package/build/Release/oracledb-7.0.1-win32-x64.node-buildinfo.txt +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2022,
|
|
1
|
+
// Copyright (c) 2022, 2026, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -44,7 +44,7 @@ class BaseBuffer {
|
|
|
44
44
|
// The initializer is either an integer specifying the size of the buffer, or
|
|
45
45
|
// an existing Buffer, which is used directly.
|
|
46
46
|
//---------------------------------------------------------------------------
|
|
47
|
-
constructor(initializer) {
|
|
47
|
+
constructor(initializer, caps) {
|
|
48
48
|
if (typeof initializer === 'number') {
|
|
49
49
|
this.buf = Buffer.alloc(initializer);
|
|
50
50
|
this.size = 0;
|
|
@@ -54,6 +54,7 @@ class BaseBuffer {
|
|
|
54
54
|
this.size = this.maxSize = initializer.length;
|
|
55
55
|
}
|
|
56
56
|
this.pos = 0;
|
|
57
|
+
this.caps = caps;
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
//---------------------------------------------------------------------------
|
|
@@ -84,29 +85,42 @@ class BaseBuffer {
|
|
|
84
85
|
// Read an integer from the buffer of the specified maximum size and returns
|
|
85
86
|
// it. The signed flag indicates whether the value is allowed to be signed or
|
|
86
87
|
// not and the skip flag indicates whether the data should simply be skipped.
|
|
88
|
+
// The asBigInt flag indicates whether the value should be returned as a
|
|
89
|
+
// BigInt instead of a Number.
|
|
87
90
|
//---------------------------------------------------------------------------
|
|
88
|
-
_readInteger(maxSize, signed, skip) {
|
|
91
|
+
_readInteger(maxSize, signed, skip, asBigInt = false) {
|
|
89
92
|
let isNegative = false;
|
|
90
93
|
let size = this.readUInt8();
|
|
91
94
|
if (size === 0) {
|
|
92
|
-
return 0;
|
|
95
|
+
return asBigInt ? 0n : 0;
|
|
93
96
|
} else if (size & 0x80) {
|
|
94
97
|
if (!signed) {
|
|
95
|
-
errors.throwErr(errors.ERR_UNEXPECTED_NEGATIVE_INTEGER, this.pos,
|
|
98
|
+
errors.throwErr(errors.ERR_UNEXPECTED_NEGATIVE_INTEGER, this.pos,
|
|
99
|
+
this.packetNum);
|
|
96
100
|
}
|
|
97
101
|
isNegative = true;
|
|
98
102
|
size = size & 0x7f;
|
|
99
103
|
}
|
|
100
104
|
if (size > maxSize) {
|
|
101
|
-
errors.throwErr(errors.ERR_INTEGER_TOO_LARGE, size, maxSize, this.pos,
|
|
105
|
+
errors.throwErr(errors.ERR_INTEGER_TOO_LARGE, size, maxSize, this.pos,
|
|
106
|
+
this.packetNum);
|
|
102
107
|
}
|
|
103
108
|
if (skip) {
|
|
104
109
|
this.skipBytes(size);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const buf = this.readBytes(size);
|
|
114
|
+
let value;
|
|
115
|
+
if (asBigInt) {
|
|
116
|
+
value = 0n;
|
|
117
|
+
for (const byte of buf) {
|
|
118
|
+
value = (value << 8n) | BigInt(byte);
|
|
119
|
+
}
|
|
105
120
|
} else {
|
|
106
|
-
|
|
107
|
-
const value = buf.readUIntBE(0, size);
|
|
108
|
-
return (isNegative) ? -value : value;
|
|
121
|
+
value = buf.readUIntBE(0, size);
|
|
109
122
|
}
|
|
123
|
+
return isNegative ? -value : value;
|
|
110
124
|
}
|
|
111
125
|
|
|
112
126
|
//---------------------------------------------------------------------------
|
|
@@ -175,17 +189,22 @@ class BaseBuffer {
|
|
|
175
189
|
// assumed at this point that the size of the buffer is either 7 bytes (date
|
|
176
190
|
// or compressed timestamp), 11 bytes (timestamp) or 13 bytes (timestamp with
|
|
177
191
|
// time zone). Time zone information is discarded because Node.js uses UTC
|
|
178
|
-
// timestamps
|
|
179
|
-
//
|
|
192
|
+
// timestamps. TIMESTAMP WITH LOCAL TIME ZONE is returned in the database
|
|
193
|
+
// time zone and needs its offset to produce the original UTC instant.
|
|
180
194
|
//---------------------------------------------------------------------------
|
|
181
|
-
parseOracleDate(buf, useLocalTime = true) {
|
|
195
|
+
parseOracleDate(buf, useLocalTime = true, useDbTz = false) {
|
|
182
196
|
let fseconds = 0;
|
|
183
197
|
if (buf.length >= 11) {
|
|
184
198
|
fseconds = Math.floor(buf.readUInt32BE(7) / (1000 * 1000));
|
|
185
199
|
}
|
|
186
200
|
const year = (buf[0] - 100) * 100 + buf[1] - 100;
|
|
201
|
+
if (useDbTz && this.caps?.dbTzRegion) {
|
|
202
|
+
errors.throwErr(errors.ERR_TIMESTAMP_LTZ_REGION_NOT_SUPPORTED,
|
|
203
|
+
this.caps.dbTzRegion);
|
|
204
|
+
}
|
|
205
|
+
const offset = useDbTz ? this.caps?.dbTzOffset ?? 0 : 0;
|
|
187
206
|
return nodbUtil.makeDate(useLocalTime, year, buf[2], buf[3], buf[4] - 1,
|
|
188
|
-
buf[5] - 1, buf[6] - 1, fseconds,
|
|
207
|
+
buf[5] - 1, buf[6] - 1, fseconds, offset);
|
|
189
208
|
}
|
|
190
209
|
|
|
191
210
|
//---------------------------------------------------------------------------
|
|
@@ -475,12 +494,12 @@ class BaseBuffer {
|
|
|
475
494
|
// Reads an Oracle date from the buffer and returns a Date or a String,
|
|
476
495
|
// depending on the desired type.
|
|
477
496
|
//---------------------------------------------------------------------------
|
|
478
|
-
readOracleDate(useLocalTime) {
|
|
497
|
+
readOracleDate(useLocalTime, useDbTz = false) {
|
|
479
498
|
const buf = this.readBytesWithLength();
|
|
480
499
|
if (!buf) {
|
|
481
500
|
return null;
|
|
482
501
|
}
|
|
483
|
-
return this.parseOracleDate(buf, useLocalTime);
|
|
502
|
+
return this.parseOracleDate(buf, useLocalTime, useDbTz);
|
|
484
503
|
}
|
|
485
504
|
|
|
486
505
|
//---------------------------------------------------------------------------
|
|
@@ -609,6 +628,17 @@ class BaseBuffer {
|
|
|
609
628
|
return this._readInteger(8, false, false);
|
|
610
629
|
}
|
|
611
630
|
|
|
631
|
+
//---------------------------------------------------------------------------
|
|
632
|
+
// readUB8BigInt()
|
|
633
|
+
//
|
|
634
|
+
// Reads an unsigned, variable length integer of up to 8 bytes in length as
|
|
635
|
+
// a BigInt. This preserves values that cannot safely be represented by a
|
|
636
|
+
// JavaScript Number.
|
|
637
|
+
//---------------------------------------------------------------------------
|
|
638
|
+
readUB8BigInt() {
|
|
639
|
+
return this._readInteger(8, false, false, true);
|
|
640
|
+
}
|
|
641
|
+
|
|
612
642
|
//---------------------------------------------------------------------------
|
|
613
643
|
// readUInt8()
|
|
614
644
|
//
|
|
@@ -856,6 +886,16 @@ class BaseBuffer {
|
|
|
856
886
|
writeOracleDate(date, type, writeLength = true) {
|
|
857
887
|
let fsec;
|
|
858
888
|
let length = type._bufferSizeFactor;
|
|
889
|
+
if (type === types.DB_TYPE_TIMESTAMP_LTZ) {
|
|
890
|
+
if (this.caps?.dbTzRegion) {
|
|
891
|
+
errors.throwErr(errors.ERR_TIMESTAMP_LTZ_REGION_NOT_SUPPORTED,
|
|
892
|
+
this.caps.dbTzRegion);
|
|
893
|
+
}
|
|
894
|
+
const offset = this.caps?.dbTzOffset;
|
|
895
|
+
if (offset !== null && offset !== undefined) {
|
|
896
|
+
date = new Date(date.getTime() + offset * 60000);
|
|
897
|
+
}
|
|
898
|
+
}
|
|
859
899
|
if (length > 7) {
|
|
860
900
|
fsec = date.getUTCMilliseconds() * 1000 * 1000;
|
|
861
901
|
if (fsec === 0 && length <= 11)
|
|
@@ -1123,6 +1163,29 @@ class BaseBuffer {
|
|
|
1123
1163
|
}
|
|
1124
1164
|
}
|
|
1125
1165
|
|
|
1166
|
+
//---------------------------------------------------------------------------
|
|
1167
|
+
// writeUB8BigInt()
|
|
1168
|
+
//
|
|
1169
|
+
// Writes an unsigned BigInt in variable length format, up to eight bytes.
|
|
1170
|
+
//---------------------------------------------------------------------------
|
|
1171
|
+
writeUB8BigInt(value) {
|
|
1172
|
+
if (value === 0n) {
|
|
1173
|
+
this.writeUInt8(0);
|
|
1174
|
+
} else if (value <= 0xffn) {
|
|
1175
|
+
this.writeUInt8(1);
|
|
1176
|
+
this.writeUInt8(Number(value));
|
|
1177
|
+
} else if (value <= 0xffffn) {
|
|
1178
|
+
this.writeUInt8(2);
|
|
1179
|
+
this.writeUInt16BE(Number(value));
|
|
1180
|
+
} else if (value <= 0xffffffffn) {
|
|
1181
|
+
this.writeUInt8(4);
|
|
1182
|
+
this.writeUInt32BE(Number(value));
|
|
1183
|
+
} else {
|
|
1184
|
+
this.writeUInt8(8);
|
|
1185
|
+
this.writeBigUInt64BE(value);
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1126
1189
|
//---------------------------------------------------------------------------
|
|
1127
1190
|
// writeUInt8()
|
|
1128
1191
|
//
|
|
@@ -1175,6 +1238,16 @@ class BaseBuffer {
|
|
|
1175
1238
|
this.buf.writeUInt32BE(n, pos + 4);
|
|
1176
1239
|
}
|
|
1177
1240
|
|
|
1241
|
+
//---------------------------------------------------------------------------
|
|
1242
|
+
// writeBigUInt64BE()
|
|
1243
|
+
//
|
|
1244
|
+
// Writes an unsigned BigInt value up to 64 bits in big endian order.
|
|
1245
|
+
//---------------------------------------------------------------------------
|
|
1246
|
+
writeBigUInt64BE(n) {
|
|
1247
|
+
const pos = this.reserveBytes(8);
|
|
1248
|
+
this.buf.writeBigUInt64BE(n, pos);
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1178
1251
|
//---------------------------------------------------------------------------
|
|
1179
1252
|
// writeUInt16LE()
|
|
1180
1253
|
//
|
|
@@ -1194,11 +1267,11 @@ class GrowableBuffer extends BaseBuffer {
|
|
|
1194
1267
|
//
|
|
1195
1268
|
// Initializes the buffer with an initial fixed chunk size.
|
|
1196
1269
|
//---------------------------------------------------------------------------
|
|
1197
|
-
constructor(initializer) {
|
|
1270
|
+
constructor(initializer, caps) {
|
|
1198
1271
|
if (initializer) {
|
|
1199
|
-
super(initializer);
|
|
1272
|
+
super(initializer, caps);
|
|
1200
1273
|
} else {
|
|
1201
|
-
super(constants.BUFFER_CHUNK_SIZE);
|
|
1274
|
+
super(constants.BUFFER_CHUNK_SIZE, caps);
|
|
1202
1275
|
this.size = this.maxSize;
|
|
1203
1276
|
}
|
|
1204
1277
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2023,
|
|
1
|
+
// Copyright (c) 2023, 2026, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -754,7 +754,8 @@ class OsonEncoder extends GrowableBuffer {
|
|
|
754
754
|
this.maxFieldNameSize = maxFieldNameSize;
|
|
755
755
|
|
|
756
756
|
// determine the flags to use
|
|
757
|
-
let flags = constants.TNS_JSON_FLAG_INLINE_LEAF
|
|
757
|
+
let flags = constants.TNS_JSON_FLAG_INLINE_LEAF |
|
|
758
|
+
constants.TNS_JSON_FLAG_LEN_IN_PCODE;
|
|
758
759
|
if (Array.isArray(value) || (value && Array.isArray(value.fields))) {
|
|
759
760
|
// examine all values recursively to determine the unique set of field
|
|
760
761
|
// names and whether they need to be added to the long field names
|
package/lib/impl/resultset.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2022,
|
|
1
|
+
// Copyright (c) 2022, 2026, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -200,6 +200,17 @@ class ResultSetImpl extends BaseImpl {
|
|
|
200
200
|
return this._parentObj;
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
+
//---------------------------------------------------------------------------
|
|
204
|
+
// _getDbObjectType()
|
|
205
|
+
//
|
|
206
|
+
// Return the object identifying the object type. These are cached by fully
|
|
207
|
+
// qualified name and by OID (thin mode only).
|
|
208
|
+
//---------------------------------------------------------------------------
|
|
209
|
+
_getDbObjectType(schema, name, packageName, oid) {
|
|
210
|
+
return this._getConnImpl()._getDbObjectType(schema, name, packageName,
|
|
211
|
+
oid);
|
|
212
|
+
}
|
|
213
|
+
|
|
203
214
|
//---------------------------------------------------------------------------
|
|
204
215
|
// _setup()
|
|
205
216
|
//
|
|
@@ -210,7 +221,7 @@ class ResultSetImpl extends BaseImpl {
|
|
|
210
221
|
//---------------------------------------------------------------------------
|
|
211
222
|
_setup(options, metaData) {
|
|
212
223
|
this._parentObj = options.connection._impl;
|
|
213
|
-
this.metaData =
|
|
224
|
+
this.metaData = [];
|
|
214
225
|
this.lobIndices = [];
|
|
215
226
|
this.dbObjectIndices = [];
|
|
216
227
|
this.nestedCursorIndices = [];
|
|
@@ -227,13 +238,23 @@ class ResultSetImpl extends BaseImpl {
|
|
|
227
238
|
}
|
|
228
239
|
}
|
|
229
240
|
for (let i = 0; i < metaData.length; i++) {
|
|
230
|
-
const
|
|
231
|
-
if (
|
|
232
|
-
const cls = options.connection._getDbObjectClass(
|
|
233
|
-
|
|
241
|
+
const fetchInfo = metaData[i];
|
|
242
|
+
if (fetchInfo.dbTypeClass) {
|
|
243
|
+
const cls = options.connection._getDbObjectClass(fetchInfo.dbTypeClass);
|
|
244
|
+
fetchInfo.dbTypeClass = cls;
|
|
234
245
|
}
|
|
235
|
-
nodbUtil.addTypeProperties(
|
|
246
|
+
nodbUtil.addTypeProperties(fetchInfo, "dbType");
|
|
247
|
+
|
|
248
|
+
// Use a per-resultset metadata copy so any fetchTypeHandler or
|
|
249
|
+
// resultset-specific metadata mutations (for example renaming columns)
|
|
250
|
+
// do not leak back into the underlying statement metadata.
|
|
251
|
+
// This is also applied in thick mode for consistency, even though the
|
|
252
|
+
// extra copy is only needed to protect the thin-mode cached metadata.
|
|
253
|
+
const info = {...fetchInfo};
|
|
254
|
+
this.metaData.push(info);
|
|
236
255
|
this._determineFetchType(info, options, metaData);
|
|
256
|
+
fetchInfo.fetchType = info.fetchType;
|
|
257
|
+
fetchInfo.converter = info.converter;
|
|
237
258
|
if (info.fetchType === types.DB_TYPE_CURSOR) {
|
|
238
259
|
this.nestedCursorIndices.push(i);
|
|
239
260
|
} else if (info.fetchType === types.DB_TYPE_CLOB ||
|
|
@@ -281,7 +302,9 @@ class ResultSetImpl extends BaseImpl {
|
|
|
281
302
|
//---------------------------------------------------------------------------
|
|
282
303
|
// _getAllRows() [INTERNAL]
|
|
283
304
|
//
|
|
284
|
-
// Fetches all the rows from the database to use internally.
|
|
305
|
+
// Fetches all the rows from the database to use internally. getRows()
|
|
306
|
+
// already materializes and consumes each batch, so this method only
|
|
307
|
+
// accumulates the returned rows.
|
|
285
308
|
//---------------------------------------------------------------------------
|
|
286
309
|
async _getAllRows() {
|
|
287
310
|
const fetchArraySize = 100;
|
|
@@ -290,10 +313,8 @@ class ResultSetImpl extends BaseImpl {
|
|
|
290
313
|
while (true) {
|
|
291
314
|
// constant default value for fetchArraySize
|
|
292
315
|
const rows = await this.getRows(fetchArraySize, {});
|
|
293
|
-
if (rows)
|
|
294
|
-
await this._processRows(rows, false);
|
|
316
|
+
if (rows)
|
|
295
317
|
rowsFetched = rowsFetched.concat(rows);
|
|
296
|
-
}
|
|
297
318
|
if (rows.length < fetchArraySize) {
|
|
298
319
|
break;
|
|
299
320
|
}
|
package/lib/oracledb.js
CHANGED
|
@@ -66,6 +66,7 @@ const SodaCollection = require('./sodaCollection.js');
|
|
|
66
66
|
const SodaDocCursor = require('./sodaDocCursor.js');
|
|
67
67
|
const SodaDocument = require('./sodaDocument.js');
|
|
68
68
|
const SodaOperation = require('./sodaOperation.js');
|
|
69
|
+
const securityContextProviderModule = require('./securityContextProvider.js');
|
|
69
70
|
const EndUserSecurityContext = require('./endUserSecurityContext.js');
|
|
70
71
|
|
|
71
72
|
const poolCache = {};
|
|
@@ -417,6 +418,12 @@ async function _verifyOptions(options, inCreatePool) {
|
|
|
417
418
|
outOptions.appContext = options.appContext;
|
|
418
419
|
}
|
|
419
420
|
|
|
421
|
+
// txnPriority must be a supported value
|
|
422
|
+
if (options.txnPriority !== undefined) {
|
|
423
|
+
errors.assertTxnPriority(options.txnPriority);
|
|
424
|
+
outOptions.txnPriority = options.txnPriority;
|
|
425
|
+
}
|
|
426
|
+
|
|
420
427
|
// check pool specific options
|
|
421
428
|
if (inCreatePool) {
|
|
422
429
|
|
|
@@ -631,6 +638,11 @@ async function createPool(options) {
|
|
|
631
638
|
errors.throwWrapErr(error, errors.ERR_CALLOUT_FN);
|
|
632
639
|
}
|
|
633
640
|
}
|
|
641
|
+
// Connect-string parsing can rebuild the options object and omit internal
|
|
642
|
+
// fields. Preserve the hook-provided unified-security state before that.
|
|
643
|
+
const securityContextProviderForPool = options._securityContextProvider;
|
|
644
|
+
// This is driver-only state and must not be passed to the implementation.
|
|
645
|
+
delete options._securityContextProvider;
|
|
634
646
|
options = await _updateUserOptionsFromConnectString(options, true);
|
|
635
647
|
const sessionCallback = options.sessionCallback;
|
|
636
648
|
if (typeof sessionCallback === 'function')
|
|
@@ -715,6 +727,7 @@ async function createPool(options) {
|
|
|
715
727
|
}
|
|
716
728
|
|
|
717
729
|
pool._setup(options, poolAlias);
|
|
730
|
+
pool._securityContextProvider = securityContextProviderForPool;
|
|
718
731
|
pool._sessionCallback = sessionCallback;
|
|
719
732
|
pool.on('_afterPoolClose', () => {
|
|
720
733
|
if (pool.poolAlias) {
|
|
@@ -781,6 +794,9 @@ async function getConnection(a1) {
|
|
|
781
794
|
errors.throwWrapErr(error, errors.ERR_CALLOUT_FN);
|
|
782
795
|
}
|
|
783
796
|
}
|
|
797
|
+
const securityContextProviderForConnection = options._securityContextProvider;
|
|
798
|
+
// This is driver-only state and must not be passed to the implementation.
|
|
799
|
+
delete options._securityContextProvider;
|
|
784
800
|
// create a standalone connection
|
|
785
801
|
options = await _updateUserOptionsFromConnectString(options, false);
|
|
786
802
|
settings.addToOptions(options,
|
|
@@ -799,6 +815,7 @@ async function getConnection(a1) {
|
|
|
799
815
|
}
|
|
800
816
|
const conn = new Connection();
|
|
801
817
|
conn._impl = new impl.ConnectionImpl();
|
|
818
|
+
conn._impl._securityContextProvider = securityContextProviderForConnection;
|
|
802
819
|
|
|
803
820
|
conn._impl._connectString = options.connectString;
|
|
804
821
|
conn._impl._user = options.user;
|
|
@@ -1213,6 +1230,16 @@ function registerConfigurationProviderHook(configProvider, fn) {
|
|
|
1213
1230
|
registeredConfigProviderHooks[configProvider] = fn;
|
|
1214
1231
|
}
|
|
1215
1232
|
|
|
1233
|
+
//-----------------------------------------------------------------------------
|
|
1234
|
+
// getSecurityContextProvider()
|
|
1235
|
+
//
|
|
1236
|
+
// Exposes the internal security context provider helpers without requiring
|
|
1237
|
+
// callers to reference the module path directly.
|
|
1238
|
+
//-----------------------------------------------------------------------------
|
|
1239
|
+
function getSecurityContextProvider() {
|
|
1240
|
+
return securityContextProviderModule;
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1216
1243
|
//-----------------------------------------------------------------------------
|
|
1217
1244
|
// enquoteLiteral()
|
|
1218
1245
|
//
|
|
@@ -1302,6 +1329,7 @@ module.exports = {
|
|
|
1302
1329
|
createPool: nodbUtil.callbackify(nodbUtil.wrapFn(createPool)),
|
|
1303
1330
|
getNetworkServiceNames: nodbUtil.callbackify(nodbUtil.wrapFn(getNetworkServiceNames)),
|
|
1304
1331
|
getPool,
|
|
1332
|
+
getSecurityContextProvider,
|
|
1305
1333
|
initOracleClient,
|
|
1306
1334
|
isQualifiedSqlName,
|
|
1307
1335
|
isSimpleSqlName,
|
|
@@ -1500,6 +1528,12 @@ module.exports = {
|
|
|
1500
1528
|
ARRAY: constants.OUT_FORMAT_ARRAY,
|
|
1501
1529
|
OBJECT: constants.OUT_FORMAT_OBJECT,
|
|
1502
1530
|
|
|
1531
|
+
// txnPriority
|
|
1532
|
+
TXN_PRIORITY_HIGH: constants.TXN_PRIORITY_HIGH,
|
|
1533
|
+
TXN_PRIORITY_MEDIUM: constants.TXN_PRIORITY_MEDIUM,
|
|
1534
|
+
TXN_PRIORITY_LOW: constants.TXN_PRIORITY_LOW,
|
|
1535
|
+
TXN_PRIORITY_DEFAULT: constants.TXN_PRIORITY_DEFAULT,
|
|
1536
|
+
|
|
1503
1537
|
// Trace Interface
|
|
1504
1538
|
traceHandler,
|
|
1505
1539
|
|
package/lib/pool.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2016,
|
|
1
|
+
// Copyright (c) 2016, 2026, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -115,6 +115,7 @@ class Pool extends EventEmitter {
|
|
|
115
115
|
this._user = options.user;
|
|
116
116
|
this._connectString = options.connectString;
|
|
117
117
|
this._status = constants.POOL_STATUS_OPEN;
|
|
118
|
+
// Current number of connections that are out for processing or being used
|
|
118
119
|
this._connectionsOut = 0;
|
|
119
120
|
this._poolAlias = poolAlias;
|
|
120
121
|
this._bgRequestHandler();
|
|
@@ -514,6 +515,9 @@ class Pool extends EventEmitter {
|
|
|
514
515
|
this._connectionsOut += 1;
|
|
515
516
|
this._pendingRequestQueue.delete(request);
|
|
516
517
|
conn._impl = await this._impl.getConnection(request.options);
|
|
518
|
+
// Each acquired connection uses the provider configured for this pool.
|
|
519
|
+
// Pools can have distinct Azure, OCI, or custom OBO configurations.
|
|
520
|
+
conn._impl._securityContextProvider = this._securityContextProvider;
|
|
517
521
|
conn._pool = this;
|
|
518
522
|
await this._tagFixup(conn, request.options.tag);
|
|
519
523
|
if (request.isWaiting)
|
|
@@ -572,12 +576,12 @@ class Pool extends EventEmitter {
|
|
|
572
576
|
// _processRequest' to decrease connectionsOut & wake up _bgRequestWaiter
|
|
573
577
|
//---------------------------------------------------------------------------
|
|
574
578
|
async _release(impl, options) {
|
|
575
|
-
this._connectionsOut -= 1;
|
|
576
579
|
try {
|
|
577
580
|
// Directly close the connection using the underlying connection impl
|
|
578
581
|
if (impl)
|
|
579
582
|
await impl.close(options);
|
|
580
583
|
} finally {
|
|
584
|
+
this._connectionsOut -= 1;
|
|
581
585
|
if (this._connectionsOut == 0)
|
|
582
586
|
this.emit('_allCheckedIn');
|
|
583
587
|
setImmediate(() => {
|
package/lib/queryStream.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2015,
|
|
1
|
+
// Copyright (c) 2015, 2026, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -31,10 +31,11 @@ const { Readable } = require('stream');
|
|
|
31
31
|
|
|
32
32
|
class QueryStream extends Readable {
|
|
33
33
|
|
|
34
|
-
constructor(rs) {
|
|
34
|
+
constructor(rs, rowsPerDataEvent = 1) {
|
|
35
35
|
super({ objectMode: true });
|
|
36
36
|
this._fetching = false;
|
|
37
37
|
this._numRows = 0;
|
|
38
|
+
this._rowsPerDataEvent = rowsPerDataEvent;
|
|
38
39
|
|
|
39
40
|
// calling open via process.nextTick to allow event handlers to be
|
|
40
41
|
// registered prior to the events being emitted
|
|
@@ -95,10 +96,17 @@ class QueryStream extends Readable {
|
|
|
95
96
|
// created via ResultSet.toQueryStream()
|
|
96
97
|
try {
|
|
97
98
|
this._fetching = true;
|
|
99
|
+
const rows = [];
|
|
98
100
|
this._resultSet._allowGetRowCall = true;
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
101
|
+
for (let i = 0; i < this._rowsPerDataEvent; i++) {
|
|
102
|
+
const row = await this._resultSet.getRow();
|
|
103
|
+
if (!row)
|
|
104
|
+
break;
|
|
105
|
+
rows.push(row);
|
|
106
|
+
this._resultSet._allowGetRowCall = true;
|
|
107
|
+
}
|
|
108
|
+
if (rows.length > 0) {
|
|
109
|
+
this.push(this._rowsPerDataEvent === 1 ? rows[0] : rows);
|
|
102
110
|
} else {
|
|
103
111
|
this.push(null);
|
|
104
112
|
}
|
package/lib/resultset.js
CHANGED
|
@@ -341,8 +341,15 @@ class ResultSet {
|
|
|
341
341
|
//
|
|
342
342
|
// Converts a result set to a QueryStream object.
|
|
343
343
|
//---------------------------------------------------------------------------
|
|
344
|
-
toQueryStream() {
|
|
345
|
-
errors.assertArgCount(arguments, 0,
|
|
344
|
+
toQueryStream(options) {
|
|
345
|
+
errors.assertArgCount(arguments, 0, 1);
|
|
346
|
+
if (arguments.length == 1) {
|
|
347
|
+
errors.assertParamValue(nodbUtil.isObject(options), 1);
|
|
348
|
+
options = {...options};
|
|
349
|
+
} else {
|
|
350
|
+
options = {};
|
|
351
|
+
}
|
|
352
|
+
errors.assertParamPropUnsignedIntNonZero(options, 1, "rowsPerDataEvent");
|
|
346
353
|
|
|
347
354
|
if (this._processingStarted) {
|
|
348
355
|
errors.throwErr(errors.ERR_CANNOT_CONVERT_RS_TO_STREAM);
|
|
@@ -354,7 +361,7 @@ class ResultSet {
|
|
|
354
361
|
|
|
355
362
|
this._convertedToStream = true;
|
|
356
363
|
|
|
357
|
-
return new QueryStream(this);
|
|
364
|
+
return new QueryStream(this, options.rowsPerDataEvent);
|
|
358
365
|
}
|
|
359
366
|
|
|
360
367
|
[Symbol.asyncIterator]() {
|