oracledb 6.7.2 → 6.8.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/LICENSE.txt +1 -1
- package/NOTICE.txt +1 -1
- package/README.md +2 -2
- package/build/Release/oracledb-6.8.0-darwin-arm64.node +0 -0
- package/build/Release/oracledb-6.8.0-darwin-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.8.0-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.8.0-darwin-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.8.0-js-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.8.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.8.0-linux-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.8.0-linux-x64.node +0 -0
- package/build/Release/oracledb-6.8.0-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.8.0-win32-x64.node +0 -0
- package/build/Release/oracledb-6.8.0-win32-x64.node-buildinfo.txt +1 -0
- package/lib/connection.js +66 -2
- package/lib/dbObject.js +42 -10
- package/lib/errors.js +96 -13
- package/lib/impl/connection.js +15 -1
- package/lib/impl/datahandlers/buffer.js +92 -1
- package/lib/impl/datahandlers/constants.js +2 -0
- package/lib/impl/datahandlers/oson.js +15 -1
- package/lib/impl/datahandlers/vector.js +72 -27
- package/lib/oracledb.js +80 -4
- package/lib/settings.js +5 -1
- package/lib/thin/connection.js +13 -2
- package/lib/thin/dbObject.js +38 -7
- package/lib/thin/pool.js +7 -3
- package/lib/thin/protocol/capabilities.js +1 -1
- package/lib/thin/protocol/constants.js +2 -0
- package/lib/thin/protocol/messages/auth.js +29 -6
- package/lib/thin/protocol/messages/fastAuth.js +6 -1
- package/lib/thin/protocol/messages/withData.js +10 -1
- package/lib/thin/protocol/packet.js +1 -1
- package/lib/thin/sqlnet/ANO.js +438 -0
- package/lib/thin/sqlnet/constants.js +5 -1
- package/lib/thin/sqlnet/ezConnectResolver.js +4 -2
- package/lib/thin/sqlnet/navNodes.js +21 -2
- package/lib/thin/sqlnet/networkSession.js +88 -16
- package/lib/thin/sqlnet/ntTcp.js +50 -3
- package/lib/thin/sqlnet/packet.js +31 -4
- package/lib/thin/sqlnet/sessionAtts.js +25 -2
- package/lib/thin/util.js +3 -8
- package/lib/transformer.js +13 -2
- package/lib/types.js +220 -3
- package/lib/util.js +1 -1
- package/lib/version.js +2 -2
- package/package.json +1 -1
- package/plugins/token/extensionAzure/index.js +101 -0
- package/plugins/token/extensionOci/index.js +174 -0
- package/build/Release/oracledb-6.7.2-darwin-arm64.node +0 -0
- package/build/Release/oracledb-6.7.2-darwin-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.7.2-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.7.2-darwin-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.7.2-js-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.7.2-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.7.2-linux-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.7.2-linux-x64.node +0 -0
- package/build/Release/oracledb-6.7.2-linux-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.7.2-win32-x64.node +0 -0
- package/build/Release/oracledb-6.7.2-win32-x64.node-buildinfo.txt +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2024, Oracle and/or its affiliates.
|
|
1
|
+
// Copyright (c) 2024, 2025, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -30,6 +30,7 @@ const { BaseBuffer, GrowableBuffer } = require('./buffer.js');
|
|
|
30
30
|
const { Buffer } = require('buffer');
|
|
31
31
|
const constants = require("./constants.js");
|
|
32
32
|
const errors = require("../../errors.js");
|
|
33
|
+
const types = require("../../types.js");
|
|
33
34
|
|
|
34
35
|
/**
|
|
35
36
|
* Class used for decoding
|
|
@@ -50,68 +51,83 @@ class VectorDecoder extends BaseBuffer {
|
|
|
50
51
|
errors.throwErr(errors.ERR_UNEXPECTED_DATA,
|
|
51
52
|
Buffer.from([magicByte]).toString('hex'));
|
|
52
53
|
const version = this.readUInt8();
|
|
53
|
-
if (version > constants.
|
|
54
|
+
if (version > constants.TNS_VECTOR_VERSION_WITH_SPARSE)
|
|
54
55
|
errors.throwErr(errors.ERR_VECTOR_VERSION_NOT_SUPPORTED, version);
|
|
55
56
|
const flags = this.readUInt16BE();
|
|
56
57
|
const vectorFormat = this.readUInt8();
|
|
57
58
|
let numElements = this.readUInt32BE();
|
|
58
|
-
let elementSize,
|
|
59
|
+
let elementSize, value, sparseValue;
|
|
60
|
+
|
|
61
|
+
// For binary vector, NORM will never be present but space for NORM is reserved to keep
|
|
62
|
+
// same header lengh across the different vector formats.
|
|
63
|
+
if (vectorFormat === constants.VECTOR_FORMAT_BINARY || flags & constants.TNS_VECTOR_FLAG_NORM)
|
|
64
|
+
this.skipBytes(8);
|
|
65
|
+
|
|
66
|
+
let sparseFormat;
|
|
67
|
+
if (flags & constants.TNS_VECTOR_FLAG_SPARSE) {
|
|
68
|
+
sparseFormat = true;
|
|
69
|
+
sparseValue = {};
|
|
70
|
+
sparseValue.numDimensions = numElements; // vector dimensions.
|
|
71
|
+
numElements = this.readUInt16BE(); // actual elements.
|
|
72
|
+
sparseValue.indices = new Uint32Array(numElements);
|
|
73
|
+
for (let i = 0; i < numElements; i++) {
|
|
74
|
+
sparseValue.indices[i] = this.readUInt32BE();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
59
78
|
if (vectorFormat === constants.VECTOR_FORMAT_FLOAT32) {
|
|
60
79
|
elementSize = 4;
|
|
61
|
-
|
|
80
|
+
value = new Float32Array(numElements);
|
|
62
81
|
} else if (vectorFormat === constants.VECTOR_FORMAT_FLOAT64) {
|
|
63
82
|
elementSize = 8;
|
|
64
|
-
|
|
83
|
+
value = new Float64Array(numElements);
|
|
65
84
|
} else if (vectorFormat === constants.VECTOR_FORMAT_INT8) {
|
|
66
85
|
elementSize = 1;
|
|
67
|
-
|
|
86
|
+
value = new Int8Array(numElements);
|
|
68
87
|
} else if (vectorFormat === constants.VECTOR_FORMAT_BINARY) {
|
|
69
88
|
elementSize = 1;
|
|
70
89
|
// The number of dimensions are assumed to be multiple of 8.
|
|
71
90
|
numElements = numElements / 8;
|
|
72
|
-
|
|
91
|
+
value = new Uint8Array(numElements);
|
|
73
92
|
} else {
|
|
74
93
|
errors.throwErr(errors.ERR_VECTOR_FORMAT_NOT_SUPPORTED, vectorFormat);
|
|
75
94
|
}
|
|
76
95
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
this.skipBytes(8);
|
|
96
|
+
if (sparseFormat) {
|
|
97
|
+
sparseValue.values = value;
|
|
98
|
+
}
|
|
81
99
|
|
|
82
100
|
// parse data
|
|
101
|
+
let res;
|
|
83
102
|
for (let i = 0; i < numElements; i++) {
|
|
84
103
|
const buf = this.readBytes(elementSize);
|
|
85
104
|
if (vectorFormat === constants.VECTOR_FORMAT_FLOAT32) {
|
|
86
|
-
|
|
105
|
+
res = this.parseBinaryFloat(buf);
|
|
87
106
|
} else if (vectorFormat === constants.VECTOR_FORMAT_FLOAT64) {
|
|
88
|
-
|
|
107
|
+
res = this.parseBinaryDouble(buf);
|
|
89
108
|
} else {
|
|
90
|
-
|
|
109
|
+
res = buf[0];
|
|
91
110
|
}
|
|
111
|
+
value[i] = res;
|
|
92
112
|
}
|
|
93
113
|
|
|
94
|
-
return
|
|
114
|
+
return sparseFormat ? types.SparseVector.create(sparseValue) : value;
|
|
95
115
|
}
|
|
96
116
|
|
|
97
117
|
}
|
|
98
118
|
|
|
99
119
|
class VectorEncoder extends GrowableBuffer {
|
|
100
120
|
|
|
101
|
-
|
|
102
|
-
//
|
|
103
|
-
//
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
// determine some basic information about the vector
|
|
109
|
-
let vectorFormat = constants.VECTOR_FORMAT_FLOAT32;
|
|
110
|
-
let writeFn = this.writeBinaryFloat.bind(this);
|
|
121
|
+
// Writes Header from value.
|
|
122
|
+
// It returns function to serialize the value.
|
|
123
|
+
// sparseVal is provided for SparseVector.
|
|
124
|
+
_updateVectorHeader(value, sparseVal) {
|
|
125
|
+
let flags = constants.TNS_VECTOR_FLAG_NORMSRC
|
|
126
|
+
| constants.TNS_VECTOR_FLAG_NORM; // NORM is present and reserve space.
|
|
111
127
|
let numElements = value.length;
|
|
112
128
|
let vectorVersion = constants.TNS_VECTOR_VERSION_BASE;
|
|
113
|
-
let
|
|
114
|
-
|
|
129
|
+
let vectorFormat = constants.VECTOR_FORMAT_FLOAT32;
|
|
130
|
+
let writeFn = this.writeBinaryFloat.bind(this);
|
|
115
131
|
|
|
116
132
|
if (Array.isArray(value) || value instanceof Float64Array) {
|
|
117
133
|
vectorFormat = constants.VECTOR_FORMAT_FLOAT64;
|
|
@@ -127,6 +143,11 @@ class VectorEncoder extends GrowableBuffer {
|
|
|
127
143
|
flags = constants.TNS_VECTOR_FLAG_NORMSRC; // only space is reserved.
|
|
128
144
|
writeFn = this.writeUInt8.bind(this);
|
|
129
145
|
}
|
|
146
|
+
if (sparseVal && sparseVal instanceof types.SparseVector) {
|
|
147
|
+
vectorVersion = constants.TNS_VECTOR_VERSION_WITH_SPARSE;
|
|
148
|
+
numElements = sparseVal.numDimensions;
|
|
149
|
+
flags |= constants.TNS_VECTOR_FLAG_SPARSE;
|
|
150
|
+
}
|
|
130
151
|
|
|
131
152
|
// write header
|
|
132
153
|
this.writeUInt8(constants.TNS_VECTOR_MAGIC_BYTE);
|
|
@@ -135,6 +156,30 @@ class VectorEncoder extends GrowableBuffer {
|
|
|
135
156
|
this.writeUInt8(vectorFormat);
|
|
136
157
|
this.writeUInt32BE(numElements);
|
|
137
158
|
this.reserveBytes(8);
|
|
159
|
+
return writeFn;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
//---------------------------------------------------------------------------
|
|
163
|
+
// encode()
|
|
164
|
+
//
|
|
165
|
+
// Encodes the value as OSON and returns a buffer containing the OSON bytes.
|
|
166
|
+
//---------------------------------------------------------------------------
|
|
167
|
+
encode(value) {
|
|
168
|
+
let writeFn;
|
|
169
|
+
|
|
170
|
+
if (value instanceof types.SparseVector) {
|
|
171
|
+
writeFn = this._updateVectorHeader(value.values, value);
|
|
172
|
+
const numElements = value.indices.length;
|
|
173
|
+
this.writeUInt16BE(numElements);
|
|
174
|
+
|
|
175
|
+
// Write indices
|
|
176
|
+
value.indices.forEach((element) => {
|
|
177
|
+
this.writeUInt32BE(element);
|
|
178
|
+
});
|
|
179
|
+
value = value.values;
|
|
180
|
+
} else {
|
|
181
|
+
writeFn = this._updateVectorHeader(value);
|
|
182
|
+
}
|
|
138
183
|
|
|
139
184
|
// write data
|
|
140
185
|
value.forEach((element) => {
|
package/lib/oracledb.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2015,
|
|
1
|
+
// Copyright (c) 2015, 2025, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -67,6 +67,7 @@ const SodaOperation = require('./sodaOperation.js');
|
|
|
67
67
|
const poolCache = {};
|
|
68
68
|
const tempUsedPoolAliases = {};
|
|
69
69
|
const defaultPoolAlias = 'default';
|
|
70
|
+
const registeredHooks = [];
|
|
70
71
|
let configProviderCache;
|
|
71
72
|
|
|
72
73
|
// save arguments for call to initOracleClient()
|
|
@@ -188,6 +189,18 @@ async function _verifyOptions(options, inCreatePool) {
|
|
|
188
189
|
"walletLocation");
|
|
189
190
|
outOptions.walletLocation = options.walletLocation;
|
|
190
191
|
}
|
|
192
|
+
if (options.networkCompression !== undefined) {
|
|
193
|
+
errors.assertParamPropValue(typeof options.networkCompression === 'boolean', 1,
|
|
194
|
+
"networkCompression");
|
|
195
|
+
outOptions.networkCompression = options.networkCompression;
|
|
196
|
+
outOptions.networkCompressionLevels = [];
|
|
197
|
+
outOptions.networkCompressionLevels.push('high');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (options.networkCompressionThreshold !== undefined) {
|
|
201
|
+
errors.assertParamPropValue(Number.isInteger(options.networkCompressionThreshold), 1, "networkCompressionThreshold");
|
|
202
|
+
outOptions.networkCompressionThreshold = options.networkCompressionThreshold;
|
|
203
|
+
}
|
|
191
204
|
|
|
192
205
|
//wallet content must be a string
|
|
193
206
|
if (options.walletContent !== undefined) {
|
|
@@ -362,6 +375,13 @@ async function _verifyOptions(options, inCreatePool) {
|
|
|
362
375
|
outOptions.terminal = options.terminal;
|
|
363
376
|
}
|
|
364
377
|
|
|
378
|
+
// useSNI must be a boolean
|
|
379
|
+
if (options.useSNI !== undefined) {
|
|
380
|
+
errors.assertParamPropValue(typeof options.useSNI === 'boolean', 1,
|
|
381
|
+
"useSNI");
|
|
382
|
+
outOptions.useSNI = options.useSNI;
|
|
383
|
+
}
|
|
384
|
+
|
|
365
385
|
// check pool specific options
|
|
366
386
|
if (inCreatePool) {
|
|
367
387
|
|
|
@@ -513,9 +533,13 @@ async function _verifyOptions(options, inCreatePool) {
|
|
|
513
533
|
if (typeof options.accessToken === 'function') {
|
|
514
534
|
outOptions.accessTokenFn = options.accessToken;
|
|
515
535
|
outOptions.accessTokenConfig = options.accessTokenConfig;
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
536
|
+
try {
|
|
537
|
+
accessToken = await options.accessToken(false, outOptions.accessTokenConfig);
|
|
538
|
+
if (!nodbUtil.isTokenValid(accessToken)) {
|
|
539
|
+
accessToken = await options.accessToken(true, outOptions.accessTokenConfig);
|
|
540
|
+
}
|
|
541
|
+
} catch (error) {
|
|
542
|
+
errors.throwWrapErr(error, errors.ERR_ACCESS_TOKEN);
|
|
519
543
|
}
|
|
520
544
|
} else {
|
|
521
545
|
accessToken = options.accessToken;
|
|
@@ -568,6 +592,18 @@ async function createPool(options) {
|
|
|
568
592
|
// check arguments
|
|
569
593
|
errors.assertArgCount(arguments, 1, 1);
|
|
570
594
|
errors.assertParamValue(nodbUtil.isObject(options), 1);
|
|
595
|
+
|
|
596
|
+
// this will invoke hookFn() written in application side.
|
|
597
|
+
// for token based auth it will generate access token and save it in options.
|
|
598
|
+
for (const hookFn of registeredHooks) {
|
|
599
|
+
// eslint-disable-next-line no-useless-catch
|
|
600
|
+
try {
|
|
601
|
+
await hookFn(options);
|
|
602
|
+
} catch (error) {
|
|
603
|
+
errors.throwWrapErr(error, errors.ERR_CALLOUT_FN);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
571
607
|
options = await _verifyOptions(options, true);
|
|
572
608
|
const sessionCallback = options.sessionCallback;
|
|
573
609
|
if (typeof sessionCallback === 'function')
|
|
@@ -700,6 +736,17 @@ async function getConnection(a1) {
|
|
|
700
736
|
return await pool.getConnection(options);
|
|
701
737
|
}
|
|
702
738
|
|
|
739
|
+
// this will invoke hookFn() written in application side.
|
|
740
|
+
// for token based auth it will generate access token and save it in options.
|
|
741
|
+
for (const hookFn of registeredHooks) {
|
|
742
|
+
// eslint-disable-next-line no-useless-catch
|
|
743
|
+
try {
|
|
744
|
+
await hookFn(options);
|
|
745
|
+
} catch (error) {
|
|
746
|
+
errors.throwWrapErr(error, errors.ERR_CALLOUT_FN);
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
|
|
703
750
|
// create a standalone connection
|
|
704
751
|
options = await _verifyOptions(options, false);
|
|
705
752
|
settings.addToOptions(options,
|
|
@@ -998,6 +1045,18 @@ async function startup(a1, a2) {
|
|
|
998
1045
|
await conn.close();
|
|
999
1046
|
}
|
|
1000
1047
|
|
|
1048
|
+
//-----------------------------------------------------------------------------
|
|
1049
|
+
// registerProcessConfigurationHook()
|
|
1050
|
+
//
|
|
1051
|
+
// Registers extension modules and registered modules will be called and
|
|
1052
|
+
// executed during pool and standalone connection creation.
|
|
1053
|
+
//-----------------------------------------------------------------------------
|
|
1054
|
+
function registerProcessConfigurationHook(fn) {
|
|
1055
|
+
errors.assertArgCount(arguments, 1, 1);
|
|
1056
|
+
errors.assertParamValue(typeof fn === 'function', 1);
|
|
1057
|
+
registeredHooks.push(fn);
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1001
1060
|
// module exports
|
|
1002
1061
|
module.exports = {
|
|
1003
1062
|
|
|
@@ -1018,6 +1077,9 @@ module.exports = {
|
|
|
1018
1077
|
SodaDocCursor,
|
|
1019
1078
|
SodaDocument,
|
|
1020
1079
|
SodaOperation,
|
|
1080
|
+
SparseVector: types.SparseVector,
|
|
1081
|
+
IntervalYM: types.IntervalYM,
|
|
1082
|
+
IntervalDS: types.IntervalDS,
|
|
1021
1083
|
|
|
1022
1084
|
// top-level functions
|
|
1023
1085
|
getConnection: nodbUtil.callbackify(nodbUtil.wrapFn(getConnection)),
|
|
@@ -1025,6 +1087,7 @@ module.exports = {
|
|
|
1025
1087
|
getNetworkServiceNames: nodbUtil.callbackify(nodbUtil.wrapFn(getNetworkServiceNames)),
|
|
1026
1088
|
getPool,
|
|
1027
1089
|
initOracleClient,
|
|
1090
|
+
registerProcessConfigurationHook,
|
|
1028
1091
|
shutdown: nodbUtil.callbackify(nodbUtil.wrapFn(shutdown)),
|
|
1029
1092
|
startup: nodbUtil.callbackify(nodbUtil.wrapFn(startup)),
|
|
1030
1093
|
|
|
@@ -1269,6 +1332,10 @@ module.exports = {
|
|
|
1269
1332
|
return settings.fetchTypeHandler;
|
|
1270
1333
|
},
|
|
1271
1334
|
|
|
1335
|
+
get dbObjectTypeHandler() {
|
|
1336
|
+
return settings.dbObjectTypeHandler;
|
|
1337
|
+
},
|
|
1338
|
+
|
|
1272
1339
|
get lobPrefetchSize() {
|
|
1273
1340
|
return settings.lobPrefetchSize;
|
|
1274
1341
|
},
|
|
@@ -1329,6 +1396,7 @@ module.exports = {
|
|
|
1329
1396
|
return settings.configProviderCacheTimeout;
|
|
1330
1397
|
},
|
|
1331
1398
|
|
|
1399
|
+
|
|
1332
1400
|
get thin() {
|
|
1333
1401
|
return settings.thin;
|
|
1334
1402
|
},
|
|
@@ -1413,6 +1481,13 @@ module.exports = {
|
|
|
1413
1481
|
settings.fetchTypeHandler = value;
|
|
1414
1482
|
},
|
|
1415
1483
|
|
|
1484
|
+
set dbObjectTypeHandler(value) {
|
|
1485
|
+
if (value !== undefined) {
|
|
1486
|
+
errors.assertPropValue(typeof value === 'function', "dbObjectTypeHandler");
|
|
1487
|
+
}
|
|
1488
|
+
settings.dbObjectTypeHandler = value;
|
|
1489
|
+
},
|
|
1490
|
+
|
|
1416
1491
|
set lobPrefetchSize(value) {
|
|
1417
1492
|
errors.assertPropValue(Number.isInteger(value) && value >= 0,
|
|
1418
1493
|
"lobPrefetchSize");
|
|
@@ -1509,6 +1584,7 @@ module.exports = {
|
|
|
1509
1584
|
errors.assertPropValue(typeof value === 'string', "terminal");
|
|
1510
1585
|
settings.terminal = value;
|
|
1511
1586
|
},
|
|
1587
|
+
|
|
1512
1588
|
set configProviderCacheTimeout(value) {
|
|
1513
1589
|
errors.assertPropValue(Number.isInteger(value) && value >= 0,
|
|
1514
1590
|
"configProviderCacheTimeout");
|
package/lib/settings.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2022,
|
|
1
|
+
// Copyright (c) 2022, 2025, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -64,7 +64,11 @@ class Settings {
|
|
|
64
64
|
this.thinDriverInitialized = false;
|
|
65
65
|
this.createFetchTypeMap(this.fetchAsString, this.fetchAsBuffer);
|
|
66
66
|
this.fetchTypeHandler = undefined;
|
|
67
|
+
this.dbObjectTypeHandler = undefined;
|
|
67
68
|
this._JsonId = types.JsonId;
|
|
69
|
+
this._SparseVector = types.SparseVector;
|
|
70
|
+
this._IntervalYM = types.IntervalYM;
|
|
71
|
+
this._IntervalDS = types.IntervalDS;
|
|
68
72
|
}
|
|
69
73
|
|
|
70
74
|
//---------------------------------------------------------------------------
|
package/lib/thin/connection.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2022,
|
|
1
|
+
// Copyright (c) 2022, 2025, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -715,6 +715,9 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
715
715
|
await this._protocol.breakMessage();
|
|
716
716
|
}
|
|
717
717
|
|
|
718
|
+
isCompressionEnabled() {
|
|
719
|
+
return this.nscon.compressionEnabled;
|
|
720
|
+
}
|
|
718
721
|
isHealthy() {
|
|
719
722
|
try {
|
|
720
723
|
if (this.nscon.recvInbandNotif() === 0)
|
|
@@ -839,7 +842,7 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
839
842
|
this.nscon.endOfRequestSupport = endOfRequestSupport;
|
|
840
843
|
await this._protocol._processMessage(authMessage);
|
|
841
844
|
}
|
|
842
|
-
if (!params.
|
|
845
|
+
if (!params.externalAuth) { // non-token Authentication
|
|
843
846
|
await this._protocol._processMessage(authMessage); // OAUTH
|
|
844
847
|
}
|
|
845
848
|
} catch (err) {
|
|
@@ -1312,6 +1315,14 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
1312
1315
|
return this.maxOpenCursors;
|
|
1313
1316
|
}
|
|
1314
1317
|
|
|
1318
|
+
//---------------------------------------------------------------------------
|
|
1319
|
+
// Returns the maximum length of identifiers supported by the database to
|
|
1320
|
+
// which this connection has been established.
|
|
1321
|
+
//---------------------------------------------------------------------------
|
|
1322
|
+
getMaxIdentifierLength() {
|
|
1323
|
+
return this.maxIdentifierLength;
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1315
1326
|
//---------------------------------------------------------------------------
|
|
1316
1327
|
// Returns the Oracle Database service name associated with the connection.
|
|
1317
1328
|
//---------------------------------------------------------------------------
|
package/lib/thin/dbObject.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2023,
|
|
1
|
+
// Copyright (c) 2023, 2025, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -368,10 +368,7 @@ class ThinDbObjectImpl extends DbObjectImpl {
|
|
|
368
368
|
let isNull, obj, value;
|
|
369
369
|
switch (type) {
|
|
370
370
|
case types.DB_TYPE_NUMBER:
|
|
371
|
-
|
|
372
|
-
if (value !== null)
|
|
373
|
-
value = parseFloat(value);
|
|
374
|
-
return value;
|
|
371
|
+
return buf.readOracleNumber();
|
|
375
372
|
case types.DB_TYPE_BINARY_INTEGER:
|
|
376
373
|
return buf.readBinaryInteger();
|
|
377
374
|
case types.DB_TYPE_VARCHAR:
|
|
@@ -429,7 +426,7 @@ class ThinDbObjectImpl extends DbObjectImpl {
|
|
|
429
426
|
if (objType.maxNumElements > 0 &&
|
|
430
427
|
this.unpackedArray.length >= objType.maxNumElements) {
|
|
431
428
|
errors.throwErr(errors.ERR_INVALID_COLL_INDEX_SET,
|
|
432
|
-
this.unpackedArray.length, 0, objType.maxNumElements);
|
|
429
|
+
this.unpackedArray.length, 0, objType.maxNumElements - 1);
|
|
433
430
|
}
|
|
434
431
|
this.unpackedArray.push(value);
|
|
435
432
|
} else {
|
|
@@ -446,6 +443,26 @@ class ThinDbObjectImpl extends DbObjectImpl {
|
|
|
446
443
|
}
|
|
447
444
|
}
|
|
448
445
|
|
|
446
|
+
//---------------------------------------------------------------------------
|
|
447
|
+
// copy
|
|
448
|
+
//
|
|
449
|
+
// Creates and returns a copy of the ThinDBObjectImpl object. The copy is
|
|
450
|
+
// independent of the original object that was copied.
|
|
451
|
+
//---------------------------------------------------------------------------
|
|
452
|
+
copy() {
|
|
453
|
+
// We send in marshalled data of the original object to the constructor
|
|
454
|
+
// when we create the object copy
|
|
455
|
+
const newObjImpl = new ThinDbObjectImpl(this._objType, this._getPackedData());
|
|
456
|
+
|
|
457
|
+
// Set other properties
|
|
458
|
+
newObjImpl.toid = this.toid;
|
|
459
|
+
newObjImpl.flags = this.flags;
|
|
460
|
+
newObjImpl.imageFlags = this.imageFlags;
|
|
461
|
+
newObjImpl.imageVersion = this.imageVersion;
|
|
462
|
+
|
|
463
|
+
return newObjImpl;
|
|
464
|
+
}
|
|
465
|
+
|
|
449
466
|
//---------------------------------------------------------------------------
|
|
450
467
|
// deleteElement()
|
|
451
468
|
//
|
|
@@ -459,7 +476,7 @@ class ThinDbObjectImpl extends DbObjectImpl {
|
|
|
459
476
|
}
|
|
460
477
|
this.unpackedArray.splice(index, 1);
|
|
461
478
|
} else {
|
|
462
|
-
this.
|
|
479
|
+
this.unpackedAssocKeys = undefined;
|
|
463
480
|
this.unpackedAssocArray.delete(index);
|
|
464
481
|
}
|
|
465
482
|
}
|
|
@@ -610,6 +627,20 @@ class ThinDbObjectImpl extends DbObjectImpl {
|
|
|
610
627
|
return result;
|
|
611
628
|
}
|
|
612
629
|
|
|
630
|
+
//---------------------------------------------------------------------------
|
|
631
|
+
// getLength
|
|
632
|
+
//
|
|
633
|
+
// Gets the size of the database object if it is a collection. Else returns
|
|
634
|
+
// undefined.
|
|
635
|
+
//---------------------------------------------------------------------------
|
|
636
|
+
getLength() {
|
|
637
|
+
this._ensureUnpacked();
|
|
638
|
+
if (this.unpackedArray)
|
|
639
|
+
return this.unpackedArray.length;
|
|
640
|
+
if (this.unpackedAssocArray)
|
|
641
|
+
return this.unpackedAssocArray.size;
|
|
642
|
+
}
|
|
643
|
+
|
|
613
644
|
//---------------------------------------------------------------------------
|
|
614
645
|
// hasElement()
|
|
615
646
|
//
|
package/lib/thin/pool.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2022,
|
|
1
|
+
// Copyright (c) 2022, 2025, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -197,7 +197,11 @@ class ThinPoolImpl extends PoolImpl {
|
|
|
197
197
|
protocolUtil.getDeobfuscatedValue(this._token, this._obfuscatedToken);
|
|
198
198
|
if (util.isTokenExpired(clonedAttrs.token)) {
|
|
199
199
|
if (typeof this._accessTokenFn === 'function') {
|
|
200
|
-
|
|
200
|
+
try {
|
|
201
|
+
accessToken = await this._accessTokenFn(true, this._accessTokenConfig);
|
|
202
|
+
} catch (error) {
|
|
203
|
+
errors.throwWrapErr(error, errors.ERR_ACCESS_TOKEN);
|
|
204
|
+
}
|
|
201
205
|
if (typeof accessToken === 'string') {
|
|
202
206
|
clonedAttrs.token = accessToken;
|
|
203
207
|
if (util.isTokenExpired(clonedAttrs.token)) {
|
|
@@ -211,7 +215,7 @@ class ThinPoolImpl extends PoolImpl {
|
|
|
211
215
|
}
|
|
212
216
|
} else if (typeof accessToken === 'object') {
|
|
213
217
|
clonedAttrs.token = accessToken.token;
|
|
214
|
-
clonedAttrs.privateKey = accessToken.privateKey;
|
|
218
|
+
clonedAttrs.privateKey = util.denormalizePrivateKey(accessToken.privateKey);
|
|
215
219
|
if (util.isTokenExpired(clonedAttrs.token)) {
|
|
216
220
|
// IAM token is expired
|
|
217
221
|
errors.throwErr(errors.ERR_TOKEN_HAS_EXPIRED);
|
|
@@ -119,7 +119,7 @@ class Capabilities {
|
|
|
119
119
|
this.compileCaps[constants.TNS_CCAP_TTC5] =
|
|
120
120
|
constants.TNS_CCAP_VECTOR_SUPPORT;
|
|
121
121
|
this.compileCaps[constants.TNS_CCAP_VECTOR_FEATURES] =
|
|
122
|
-
constants.TNS_CCAP_VECTOR_FEATURE_BINARY;
|
|
122
|
+
constants.TNS_CCAP_VECTOR_FEATURE_BINARY | constants.TNS_CCAP_VECTOR_FEATURE_SPARSE;
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
initRuntimeCaps() {
|
|
@@ -644,6 +644,7 @@ module.exports = {
|
|
|
644
644
|
TNS_CCAP_CTB_IMPLICIT_POOL: 0x08,
|
|
645
645
|
TNS_CCAP_VECTOR_SUPPORT: 0x08,
|
|
646
646
|
TNS_CCAP_VECTOR_FEATURE_BINARY: 0x01,
|
|
647
|
+
TNS_CCAP_VECTOR_FEATURE_SPARSE: 0x02,
|
|
647
648
|
|
|
648
649
|
// runtime capability indices
|
|
649
650
|
TNS_RCAP_COMPAT: 0,
|
|
@@ -767,6 +768,7 @@ module.exports = {
|
|
|
767
768
|
TNS_VECTOR_MAX_LENGTH: 1048576,
|
|
768
769
|
VECTOR_FORMAT_FLEX: 0,
|
|
769
770
|
VECTOR_META_FLAG_FLEXIBLE_DIM: 1,
|
|
771
|
+
VECTOR_META_FLAG_SPARSE: 2,
|
|
770
772
|
|
|
771
773
|
// other constants
|
|
772
774
|
PACKET_HEADER_SIZE: 8,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2022,
|
|
1
|
+
// Copyright (c) 2022, 2025, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -94,8 +94,10 @@ class AuthMessage extends Message {
|
|
|
94
94
|
this.userByteLen = 0;
|
|
95
95
|
}
|
|
96
96
|
this.token = config.token;
|
|
97
|
-
if (
|
|
97
|
+
if (config.externalAuth) {
|
|
98
98
|
this.functionCode = constants.TNS_FUNC_AUTH_PHASE_TWO;
|
|
99
|
+
this.externalAuth = true;
|
|
100
|
+
}
|
|
99
101
|
this.privateKey = config.privateKey;
|
|
100
102
|
if (this.privateKey) {
|
|
101
103
|
this.privateKey = util.normalizePrivateKey(this.privateKey);
|
|
@@ -107,6 +109,11 @@ class AuthMessage extends Message {
|
|
|
107
109
|
this.osUser = config.osUser;
|
|
108
110
|
this.program = config.program;
|
|
109
111
|
this.terminal = config.terminal;
|
|
112
|
+
if (config.edition) {
|
|
113
|
+
this.edition = config.edition;
|
|
114
|
+
} else if (process.env.ORA_EDITION) {
|
|
115
|
+
this.edition = process.env.ORA_EDITION;
|
|
116
|
+
}
|
|
110
117
|
this.setAuthMode(config);
|
|
111
118
|
}
|
|
112
119
|
|
|
@@ -141,7 +148,7 @@ class AuthMessage extends Message {
|
|
|
141
148
|
if (this.newPassword) {
|
|
142
149
|
this.authMode |= constants.TNS_AUTH_MODE_CHANGE_PASSWORD;
|
|
143
150
|
}
|
|
144
|
-
if (!
|
|
151
|
+
if (!config.externalAuth) {
|
|
145
152
|
this.authMode |= constants.TNS_AUTH_MODE_WITH_PASSWORD;
|
|
146
153
|
}
|
|
147
154
|
}
|
|
@@ -199,8 +206,10 @@ class AuthMessage extends Message {
|
|
|
199
206
|
numPairs = 2;
|
|
200
207
|
} else {
|
|
201
208
|
numPairs = 4;
|
|
202
|
-
if (this.
|
|
203
|
-
numPairs +=
|
|
209
|
+
if (this.externalAuth) {
|
|
210
|
+
numPairs += 5;
|
|
211
|
+
if (this.token)
|
|
212
|
+
numPairs += 1;
|
|
204
213
|
} else {
|
|
205
214
|
numPairs += 2;
|
|
206
215
|
if (this.verifierType === constants.TNS_VERIFIER_TYPE_11G_1 ||
|
|
@@ -235,6 +244,9 @@ class AuthMessage extends Message {
|
|
|
235
244
|
this.encryptedJDWPData = ED.getEncryptedJSWPData(this.sessionKey, this.conn.jdwpData);
|
|
236
245
|
numPairs += 1;
|
|
237
246
|
}
|
|
247
|
+
if (this.edition) {
|
|
248
|
+
numPairs += 1;
|
|
249
|
+
}
|
|
238
250
|
if (this.schemaUser.length !== 0) {
|
|
239
251
|
numPairs += 1;
|
|
240
252
|
}
|
|
@@ -246,10 +258,17 @@ class AuthMessage extends Message {
|
|
|
246
258
|
buf.writeUInt8(1);
|
|
247
259
|
if (this.userByteLen > 0)
|
|
248
260
|
buf.writeBytesWithLength(Buffer.from(this.username));
|
|
261
|
+
if (this.externalAuth) {
|
|
262
|
+
buf.writeKeyValue("AUTH_TERMINAL", this.terminal ?? cInfo.terminal);
|
|
263
|
+
buf.writeKeyValue("AUTH_PROGRAM_NM", this.program ?? cInfo.program);
|
|
264
|
+
buf.writeKeyValue("AUTH_MACHINE", this.machine ?? cInfo.hostName);
|
|
265
|
+
buf.writeKeyValue("AUTH_PID", cInfo.pid);
|
|
266
|
+
buf.writeKeyValue("AUTH_SID", this.osUser ?? cInfo.userName);
|
|
267
|
+
}
|
|
249
268
|
if (this.token) {
|
|
250
269
|
buf.writeKeyValue("AUTH_TOKEN", this.token);
|
|
251
270
|
} else {
|
|
252
|
-
if (!this.changePassword) {
|
|
271
|
+
if (!this.changePassword && !this.externalAuth) {
|
|
253
272
|
buf.writeKeyValue("AUTH_SESSKEY", this.sessionKey, 1);
|
|
254
273
|
if (!verifier11G) {
|
|
255
274
|
buf.writeKeyValue("AUTH_PBKDF2_SPEEDY_KEY", this.speedyKey);
|
|
@@ -297,6 +316,9 @@ class AuthMessage extends Message {
|
|
|
297
316
|
if (this.conn.jdwpData) {
|
|
298
317
|
buf.writeKeyValue("AUTH_ORA_DEBUG_JDWP", this.encryptedJDWPData);
|
|
299
318
|
}
|
|
319
|
+
if (this.edition) {
|
|
320
|
+
buf.writeKeyValue("AUTH_ORA_EDITION", this.edition);
|
|
321
|
+
}
|
|
300
322
|
|
|
301
323
|
}
|
|
302
324
|
}
|
|
@@ -331,6 +353,7 @@ class AuthMessage extends Message {
|
|
|
331
353
|
this.conn.maxOpenCursors = Number(this.sessionData['AUTH_MAX_OPEN_CURSORS'] || 0);
|
|
332
354
|
this.conn.serviceName = this.sessionData['AUTH_SC_SERVICE_NAME'];
|
|
333
355
|
this.conn.instanceName = this.sessionData['AUTH_INSTANCENAME'];
|
|
356
|
+
this.conn.maxIdentifierLength = Number(this.sessionData['AUTH_MAX_IDEN_LENGTH'] || 30);
|
|
334
357
|
const fullVersionNum = Number(this.sessionData['AUTH_VERSION_NO']);
|
|
335
358
|
const versionNum = (fullVersionNum >> 24) & 0xFF;
|
|
336
359
|
this.conn.warning = this.warning;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2023,
|
|
1
|
+
// Copyright (c) 2023, 2025, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -70,6 +70,11 @@ class FastAuthMessage extends Message {
|
|
|
70
70
|
} else {
|
|
71
71
|
this.authMessage.processMessage(buf, messageType);
|
|
72
72
|
this.endOfResponse = this.authMessage.endOfResponse;
|
|
73
|
+
if (this.authMessage.errorOccurred) {
|
|
74
|
+
// Capture the Error returned in TNS_MSG_TYPE_ERROR processing.
|
|
75
|
+
this.errorOccurred = this.authMessage.errorOccurred;
|
|
76
|
+
this.errorInfo = this.authMessage.errorInfo;
|
|
77
|
+
}
|
|
73
78
|
}
|
|
74
79
|
}
|
|
75
80
|
|