oracledb 7.0.0 → 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/aqDeqOptions.js +4 -4
- package/lib/aqEnqOptions.js +2 -2
- package/lib/aqQueue.js +11 -6
- package/lib/connection.js +73 -18
- package/lib/constants.js +4 -0
- package/lib/endUserSecurityContext.js +30 -25
- package/lib/errors.js +92 -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/parserHelpers.js +6 -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 +380 -24
- package/lib/thin/dbObject.js +20 -11
- package/lib/thin/pool.js +4 -3
- package/lib/thin/protocol/capabilities.js +37 -4
- package/lib/thin/protocol/constants.js +49 -1
- package/lib/thin/protocol/messages/aqArray.js +2 -2
- package/lib/thin/protocol/messages/aqBase.js +2 -2
- package/lib/thin/protocol/messages/auth.js +17 -6
- package/lib/thin/protocol/messages/base.js +75 -17
- 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 +23 -10
- 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 +9 -2
- package/lib/thin/sqlnet/navNodes.js +7 -5
- package/lib/thin/sqlnet/networkSession.js +17 -11
- package/lib/thin/sqlnet/ntTcp.js +24 -8
- package/lib/thin/sqlnet/packet.js +24 -4
- package/lib/thin/sqlnet/sessionAtts.js +2 -2
- 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 +1 -1
- 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.0-darwin-arm64.node +0 -0
- package/build/Release/oracledb-7.0.0-darwin-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-7.0.0-js-buildinfo.txt +0 -1
- package/build/Release/oracledb-7.0.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-7.0.0-linux-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-7.0.0-linux-x64.node +0 -0
- package/build/Release/oracledb-7.0.0-linux-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-7.0.0-win32-x64.node +0 -0
- package/build/Release/oracledb-7.0.0-win32-x64.node-buildinfo.txt +0 -1
- package/eslint.config.js +0 -39
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]() {
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
// Copyright (c) 2026, Oracle and/or its affiliates.
|
|
2
|
+
|
|
3
|
+
//-----------------------------------------------------------------------------
|
|
4
|
+
//
|
|
5
|
+
// This software is dual-licensed to you under the Universal Permissive License
|
|
6
|
+
// (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
|
7
|
+
// 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
|
8
|
+
// either license.
|
|
9
|
+
//
|
|
10
|
+
// If you elect to accept the software under the Apache License, Version 2.0,
|
|
11
|
+
// the following applies:
|
|
12
|
+
//
|
|
13
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
14
|
+
// you may not use this file except in compliance with the License.
|
|
15
|
+
// You may obtain a copy of the License at
|
|
16
|
+
//
|
|
17
|
+
// https://www.apache.org/licenses/LICENSE-2.0
|
|
18
|
+
//
|
|
19
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
20
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
21
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
22
|
+
// See the License for the specific language governing permissions and
|
|
23
|
+
// limitations under the License.
|
|
24
|
+
//
|
|
25
|
+
//-----------------------------------------------------------------------------
|
|
26
|
+
'use strict';
|
|
27
|
+
|
|
28
|
+
const { AsyncLocalStorage } = require('async_hooks');
|
|
29
|
+
const errors = require('./errors.js');
|
|
30
|
+
|
|
31
|
+
const asyncLocalStorage = new AsyncLocalStorage();
|
|
32
|
+
// One driver-wide invocation hook dispatches every supported operation. It
|
|
33
|
+
// does not hold security configuration: applyForOperation() selects the
|
|
34
|
+
// provider from the individual connection, so pools may use different
|
|
35
|
+
// providers concurrently.
|
|
36
|
+
let invocationHook = null;
|
|
37
|
+
|
|
38
|
+
//---------------------------------------------------------------------------
|
|
39
|
+
// getInvocationHook()
|
|
40
|
+
//---------------------------------------------------------------------------
|
|
41
|
+
function getInvocationHook() {
|
|
42
|
+
return invocationHook;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
//---------------------------------------------------------------------------
|
|
46
|
+
// setInvocationHook()
|
|
47
|
+
//---------------------------------------------------------------------------
|
|
48
|
+
function setInvocationHook(hook) {
|
|
49
|
+
invocationHook = hook;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
//---------------------------------------------------------------------------
|
|
53
|
+
// _getProvider()
|
|
54
|
+
//
|
|
55
|
+
// Determines the provider associated with the supplied connection.
|
|
56
|
+
//---------------------------------------------------------------------------
|
|
57
|
+
function _getProvider(connection) {
|
|
58
|
+
// A token configuration hook attaches a provider to an individual pool or
|
|
59
|
+
// standalone connection. This permits multiple pools to use different
|
|
60
|
+
// identity providers in the same process without process-global state.
|
|
61
|
+
return connection?._securityContextProvider;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
//---------------------------------------------------------------------------
|
|
65
|
+
// _clearConnection()
|
|
66
|
+
//
|
|
67
|
+
// Clears cached security context for the provided connection.
|
|
68
|
+
//---------------------------------------------------------------------------
|
|
69
|
+
function _clearConnection(connection) {
|
|
70
|
+
connection.clearEndUserSecurityContext();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
//---------------------------------------------------------------------------
|
|
74
|
+
// getCurrentContext()
|
|
75
|
+
//
|
|
76
|
+
// Returns the current context stored in AsyncLocalStorage.
|
|
77
|
+
//---------------------------------------------------------------------------
|
|
78
|
+
function getCurrentContext() {
|
|
79
|
+
return asyncLocalStorage.getStore()?.metadata ?? null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
//---------------------------------------------------------------------------
|
|
83
|
+
// _getScopedValue() / _setScopedValue()
|
|
84
|
+
//
|
|
85
|
+
// Internal per-runWithContext() scratch storage; it never holds application
|
|
86
|
+
// metadata. The built-in provider uses it to cache an encoded EUSC in
|
|
87
|
+
// operation resolution. Values are keyed by provider because one scope may
|
|
88
|
+
// use connections from differently configured pools. The Map is fresh for
|
|
89
|
+
// every scope and is released with that asynchronous scope.
|
|
90
|
+
//---------------------------------------------------------------------------
|
|
91
|
+
function _getScopedValue(key) {
|
|
92
|
+
return asyncLocalStorage.getStore()?.values.get(key);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function _setScopedValue(key, value) {
|
|
96
|
+
const scope = asyncLocalStorage.getStore();
|
|
97
|
+
if (scope) {
|
|
98
|
+
scope.values.set(key, value);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
//---------------------------------------------------------------------------
|
|
103
|
+
// applyForOperation()
|
|
104
|
+
//
|
|
105
|
+
// Invokes the registered provider before the supplied database operation. A
|
|
106
|
+
// provider returns a ready-to-apply EndUserSecurityContext, or undefined when
|
|
107
|
+
// this operation should use the normal database login.
|
|
108
|
+
//---------------------------------------------------------------------------
|
|
109
|
+
async function applyForOperation(connection) {
|
|
110
|
+
const provider = _getProvider(connection);
|
|
111
|
+
if (!provider) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const perOperation = provider._contextResolution === 'operation';
|
|
115
|
+
if (!perOperation && connection._securityContextInitialized) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
let securityContext;
|
|
119
|
+
try {
|
|
120
|
+
securityContext = await provider();
|
|
121
|
+
} catch (err) {
|
|
122
|
+
const error = errors.getErr(errors.ERR_END_USER_SECURITY_CONTEXT_PROVIDER);
|
|
123
|
+
error.cause = err;
|
|
124
|
+
throw error;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (securityContext) {
|
|
128
|
+
connection.setEndUserSecurityContext(securityContext);
|
|
129
|
+
}
|
|
130
|
+
if (!perOperation) {
|
|
131
|
+
// The implementation already owns the installed context. Keep only the
|
|
132
|
+
// fact that this borrowed connection has resolved its provider.
|
|
133
|
+
connection._securityContextInitialized = true;
|
|
134
|
+
} else if (securityContext) {
|
|
135
|
+
return { connection };
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
//---------------------------------------------------------------------------
|
|
140
|
+
// _validateContext()
|
|
141
|
+
//
|
|
142
|
+
// Security metadata is an object assembled by the application. Token syntax is
|
|
143
|
+
// deliberately not validated here; the configured identity provider remains
|
|
144
|
+
// authoritative for token validation and exchange.
|
|
145
|
+
//---------------------------------------------------------------------------
|
|
146
|
+
function _validateContext(context) {
|
|
147
|
+
if (context === null || typeof context !== 'object' || Array.isArray(context)) {
|
|
148
|
+
errors.throwErr(errors.ERR_INVALID_SECURITY_CONTEXT_METADATA);
|
|
149
|
+
}
|
|
150
|
+
const hasEndUserToken = context.endUserToken !== undefined &&
|
|
151
|
+
context.endUserToken !== null;
|
|
152
|
+
const hasEndUserName = context.endUserName !== undefined &&
|
|
153
|
+
context.endUserName !== null;
|
|
154
|
+
const hasKey = context.key !== undefined && context.key !== null;
|
|
155
|
+
// These fields represent mutually exclusive EUSC identity forms. Validate
|
|
156
|
+
// them before entering the callback so a conflicting request cannot perform
|
|
157
|
+
// unrelated work or reach a database operation before being rejected.
|
|
158
|
+
if (hasEndUserToken && (hasEndUserName || hasKey)) {
|
|
159
|
+
errors.throwErr(errors.ERR_CONFLICTING_SECURITY_CONTEXT_IDENTITIES);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
//---------------------------------------------------------------------------
|
|
164
|
+
// runWithContext()
|
|
165
|
+
//
|
|
166
|
+
// Associates the supplied metadata object with the callback's asynchronous
|
|
167
|
+
// work. Applications must treat the metadata object, including nested values, as
|
|
168
|
+
// immutable until the callback and all its database operations complete. The
|
|
169
|
+
// separate Map is mutable driver-only scratch storage, not a copy of metadata.
|
|
170
|
+
//---------------------------------------------------------------------------
|
|
171
|
+
function runWithContext(context, fn, ...args) {
|
|
172
|
+
_validateContext(context);
|
|
173
|
+
if (typeof fn !== 'function') {
|
|
174
|
+
errors.throwErr(errors.ERR_INVALID_SECURITY_CONTEXT_CALLBACK);
|
|
175
|
+
}
|
|
176
|
+
return asyncLocalStorage.run({ metadata: context, values: new Map() },
|
|
177
|
+
() => fn(...args));
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
//---------------------------------------------------------------------------
|
|
181
|
+
function createInvocationHook() {
|
|
182
|
+
return {
|
|
183
|
+
before: async ({ connection }) => {
|
|
184
|
+
if (!connection) {
|
|
185
|
+
return undefined;
|
|
186
|
+
}
|
|
187
|
+
return await applyForOperation(connection);
|
|
188
|
+
},
|
|
189
|
+
after: (state) => {
|
|
190
|
+
if (state?.connection) {
|
|
191
|
+
_clearConnection(state.connection);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
module.exports = {
|
|
198
|
+
applyForOperation,
|
|
199
|
+
runWithContext,
|
|
200
|
+
getCurrentContext,
|
|
201
|
+
_getScopedValue,
|
|
202
|
+
_setScopedValue,
|
|
203
|
+
getInvocationHook,
|
|
204
|
+
setInvocationHook,
|
|
205
|
+
createInvocationHook
|
|
206
|
+
};
|
package/lib/thin/aq.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2025, Oracle and/or its affiliates.
|
|
1
|
+
// Copyright (c) 2025, 2026, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -354,7 +354,6 @@ class ThinMsgPropsImpl {
|
|
|
354
354
|
this.recipients = [];
|
|
355
355
|
this.numAttempts = 0;
|
|
356
356
|
this.deliveryMode = 0;
|
|
357
|
-
this.enqTime = null;
|
|
358
357
|
this.msgId = null;
|
|
359
358
|
this.state = 0;
|
|
360
359
|
this.payload = null;
|
|
@@ -472,4 +471,4 @@ class ThinMsgPropsImpl {
|
|
|
472
471
|
|
|
473
472
|
}
|
|
474
473
|
|
|
475
|
-
module.exports = { ThinQueueImpl };
|
|
474
|
+
module.exports = { ThinQueueImpl, ThinMsgPropsImpl };
|