oracledb 6.3.0 → 6.5.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 +3 -3
- package/build/Release/oracledb-6.5.0-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.5.0-darwin-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.5.0-js-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.5.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.5.0-linux-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.5.0-linux-x64.node +0 -0
- package/build/Release/oracledb-6.5.0-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.5.0-win32-x64.node +0 -0
- package/build/Release/oracledb-6.5.0-win32-x64.node-buildinfo.txt +1 -0
- package/examples/README.md +3 -0
- package/lib/aqQueue.js +8 -8
- package/lib/connection.js +65 -22
- package/lib/constants.js +7 -1
- package/lib/dbObject.js +72 -1
- package/lib/errors.js +51 -10
- package/lib/impl/connection.js +2 -1
- package/lib/{thin/protocol → impl/datahandlers}/buffer.js +36 -32
- package/lib/impl/datahandlers/constants.js +106 -0
- package/lib/{thin/protocol → impl/datahandlers}/oson.js +320 -151
- package/lib/impl/datahandlers/vector.js +137 -0
- package/lib/impl/pool.js +9 -0
- package/lib/impl/resultset.js +34 -17
- package/lib/lob.js +22 -6
- package/lib/oracledb.js +35 -1
- package/lib/pool.js +17 -2
- package/lib/poolStatistics.js +3 -1
- package/lib/settings.js +31 -6
- package/lib/sodaDocCursor.js +14 -1
- package/lib/thin/connection.js +120 -193
- package/lib/thin/dbObject.js +4 -2
- package/lib/thin/lob.js +6 -6
- package/lib/thin/pool.js +84 -10
- package/lib/thin/protocol/capabilities.js +20 -6
- package/lib/thin/protocol/constants.js +34 -54
- package/lib/thin/protocol/messages/auth.js +2 -2
- package/lib/thin/protocol/messages/base.js +28 -27
- package/lib/thin/protocol/messages/dataType.js +4 -2
- package/lib/thin/protocol/messages/execute.js +5 -1
- package/lib/thin/protocol/messages/{connectionCookie.js → fastAuth.js} +18 -16
- package/lib/thin/protocol/messages/fetch.js +4 -0
- package/lib/thin/protocol/messages/index.js +2 -2
- package/lib/thin/protocol/messages/protocol.js +9 -1
- package/lib/thin/protocol/messages/withData.js +40 -11
- package/lib/thin/protocol/packet.js +93 -8
- package/lib/thin/protocol/protocol.js +10 -5
- package/lib/thin/protocol/utils.js +11 -18
- package/lib/thin/sqlnet/constants.js +5 -2
- package/lib/thin/sqlnet/ezConnectResolver.js +9 -5
- package/lib/thin/sqlnet/navNodes.js +4 -3
- package/lib/thin/sqlnet/networkSession.js +27 -4
- package/lib/thin/sqlnet/packet.js +2 -5
- package/lib/thin/statement.js +43 -7
- package/lib/thin/statementCache.js +190 -0
- package/lib/thin/util.js +2 -2
- package/lib/transformer.js +21 -6
- package/lib/types.js +21 -3
- package/lib/util.js +30 -1
- package/lib/version.js +2 -2
- package/package.json +1 -1
- package/build/Release/oracledb-6.3.0-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.3.0-darwin-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.3.0-js-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.3.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.3.0-linux-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.3.0-linux-x64.node +0 -0
- package/build/Release/oracledb-6.3.0-linux-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.3.0-win32-x64.node +0 -0
- package/build/Release/oracledb-6.3.0-win32-x64.node-buildinfo.txt +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2022,
|
|
1
|
+
// Copyright (c) 2022, 2024, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -59,7 +59,7 @@ async function getConnectionInfo(userConfig) {
|
|
|
59
59
|
const sid = findValue(nvpair, ["DESCRIPTION", "CONNECT_DATA", "SID"]);
|
|
60
60
|
const poolPurity = findValue(nvpair, ["DESCRIPTION", "CONNECT_DATA", "POOL_PURITY"]);
|
|
61
61
|
|
|
62
|
-
return [serverVal, connClass, svcname, poolPurity, sid, addressNode
|
|
62
|
+
return [serverVal, connClass, svcname, poolPurity, sid, addressNode];
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
/**
|
|
@@ -83,6 +83,12 @@ async function resolveConnectStr(connectString, configDir) {
|
|
|
83
83
|
resolvedVal = p.get(connStr.toUpperCase());
|
|
84
84
|
if (!resolvedVal)
|
|
85
85
|
errors.throwErr(errors.ERR_TNS_ENTRY_NOT_FOUND, connStr, configDir ? configDir + '/tnsnames.ora' : process.env.TNS_ADMIN + '/tnsnames.ora');
|
|
86
|
+
if (resolvedVal.rhsType == 1) {
|
|
87
|
+
const rString = resolvedVal.atom;
|
|
88
|
+
if ((rString.indexOf(':') != -1) || (rString.indexOf('/') != -1)) {
|
|
89
|
+
return new EzConnect(rString).getResolvedUrl();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
86
92
|
resolvedVal = resolvedVal.getListElement(0);
|
|
87
93
|
}
|
|
88
94
|
|
|
@@ -354,8 +360,13 @@ class NetworkSession {
|
|
|
354
360
|
break;
|
|
355
361
|
case constants.NSPTAC: /* ACCEPT */
|
|
356
362
|
Packet.AcceptPacket(packet, this.sAtts);
|
|
357
|
-
this.
|
|
358
|
-
|
|
363
|
+
if (this.sAtts.version >= constants.TNS_VERSION_MIN_END_OF_RESPONSE
|
|
364
|
+
&& (packet.flags & constants.TNS_ACCEPT_FLAG_HAS_END_OF_REQUEST)) {
|
|
365
|
+
this.endOfRequestSupport = true;
|
|
366
|
+
}
|
|
367
|
+
if (packet.flags & constants.TNS_ACCEPT_FLAG_FAST_AUTH) {
|
|
368
|
+
this.supportsFastAuth = true;
|
|
369
|
+
}
|
|
359
370
|
break;
|
|
360
371
|
case constants.NSPTRF: /* REFUSE */
|
|
361
372
|
this.refusePkt = new Packet.RefusePacket(packet);
|
|
@@ -530,6 +541,18 @@ class NetworkSession {
|
|
|
530
541
|
await this.connect1(address, addressNode, userConfig);
|
|
531
542
|
}
|
|
532
543
|
|
|
544
|
+
/**
|
|
545
|
+
* Force Disconnect the stream, primarily used
|
|
546
|
+
* to disconnect dead/hung connections.
|
|
547
|
+
*/
|
|
548
|
+
forceDisconnect(err) {
|
|
549
|
+
if (!this.connected) {
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
552
|
+
this.ntAdapter.stream.destroy(err);
|
|
553
|
+
this.connected = false;
|
|
554
|
+
}
|
|
555
|
+
|
|
533
556
|
/**
|
|
534
557
|
* Disconnect
|
|
535
558
|
* @param {int} type of disconnect
|
|
@@ -246,11 +246,8 @@ function AcceptPacket(packet, sAtts) {
|
|
|
246
246
|
this.flag0 = packet.buf.readUInt8(constants.NSPACFL0);
|
|
247
247
|
this.flag1 = packet.buf.readUInt8(constants.NSPACFL1);
|
|
248
248
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
packet.dbUUID = packet.buf.subarray(constants.TNS_UUID_OFFSET,
|
|
252
|
-
constants.TNS_UUID_OFFSET + 16);
|
|
253
|
-
packet.dbUUID = packet.dbUUID.toString('base64');
|
|
249
|
+
if (sAtts.version >= constants.TNS_VERSION_MIN_DATA_FLAGS) {
|
|
250
|
+
packet.flags = packet.buf.readUInt32BE(constants.NSPACFL2);
|
|
254
251
|
}
|
|
255
252
|
}
|
|
256
253
|
|
package/lib/thin/statement.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2022,
|
|
1
|
+
// Copyright (c) 2022, 2024, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
|
|
29
29
|
const { Buffer } = require('buffer');
|
|
30
30
|
const constants = require('../constants');
|
|
31
|
+
const errors = require('../errors');
|
|
31
32
|
|
|
32
33
|
/**
|
|
33
34
|
* It is used to cache the metadata about bind information
|
|
@@ -219,10 +220,10 @@ class Parser {
|
|
|
219
220
|
|
|
220
221
|
/**
|
|
221
222
|
* Single line comments consist of two dashes and all characters up to the
|
|
222
|
-
* next line break. This method is called when
|
|
223
|
-
* and checks for the subsequent dash. If found,
|
|
224
|
-
* is traversed and the current position is updated;
|
|
225
|
-
* current position is left untouched.
|
|
223
|
+
* next line break (or the end of the data). This method is called when
|
|
224
|
+
* the first dash is detected and checks for the subsequent dash. If found,
|
|
225
|
+
* the single line comment is traversed and the current position is updated;
|
|
226
|
+
* otherwise, the current position is left untouched.
|
|
226
227
|
*/
|
|
227
228
|
_parseSingleLineComment() {
|
|
228
229
|
let inComment = false;
|
|
@@ -233,15 +234,15 @@ class Parser {
|
|
|
233
234
|
ch = this.sqlData[pos];
|
|
234
235
|
if (!inComment) {
|
|
235
236
|
if (ch !== '-') {
|
|
236
|
-
|
|
237
|
+
return;
|
|
237
238
|
}
|
|
238
239
|
inComment = true;
|
|
239
240
|
} else if (ch === '\n') {
|
|
240
|
-
this.pos = pos;
|
|
241
241
|
break;
|
|
242
242
|
}
|
|
243
243
|
pos += 1;
|
|
244
244
|
}
|
|
245
|
+
this.pos = pos;
|
|
245
246
|
}
|
|
246
247
|
|
|
247
248
|
/**
|
|
@@ -359,6 +360,7 @@ class Statement {
|
|
|
359
360
|
this.inUse = false;
|
|
360
361
|
this.bufferRowIndex = 0;
|
|
361
362
|
this.bufferRowCount = 0;
|
|
363
|
+
this.pendingClear = false;
|
|
362
364
|
this.statementType = constants.STMT_TYPE_UNKNOWN;
|
|
363
365
|
}
|
|
364
366
|
|
|
@@ -495,6 +497,12 @@ class Statement {
|
|
|
495
497
|
const info = new BindInfo(name, this.isReturning);
|
|
496
498
|
this.bindInfoList.push(info);
|
|
497
499
|
if (this.bindInfoDict.has(info.bindName)) {
|
|
500
|
+
if (this.isReturning) {
|
|
501
|
+
const origInfo = this.bindInfoDict.get(info.bindName)[0];
|
|
502
|
+
if (!origInfo.isReturnBind) {
|
|
503
|
+
errors.throwErr(errors.ERR_DML_RETURNING_DUP_BINDS, name);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
498
506
|
this.bindInfoDict.get(info.bindName).push(info);
|
|
499
507
|
} else {
|
|
500
508
|
this.bindInfoDict.set(info.bindName, [info]);
|
|
@@ -528,6 +536,34 @@ class Statement {
|
|
|
528
536
|
|
|
529
537
|
bindInfo.bindVar = variable;
|
|
530
538
|
}
|
|
539
|
+
|
|
540
|
+
//---------------------------------------------------------------------------
|
|
541
|
+
// _clearAllState
|
|
542
|
+
//
|
|
543
|
+
// clear all state associated with the cursor
|
|
544
|
+
//---------------------------------------------------------------------------
|
|
545
|
+
_clearAllState() {
|
|
546
|
+
this.cursorId = 0;
|
|
547
|
+
this.requiresDefine = false;
|
|
548
|
+
this.noPrefetch = false;
|
|
549
|
+
this.requiresFullExecute = false;
|
|
550
|
+
this.queryVars = [];
|
|
551
|
+
this.numQueryVars = 0;
|
|
552
|
+
this.bufferRowCount = 0;
|
|
553
|
+
this.bufferRowIndex = 0;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
//---------------------------------------------------------------------------
|
|
557
|
+
// _clearState
|
|
558
|
+
//
|
|
559
|
+
// clear some state associated with the cursor
|
|
560
|
+
//---------------------------------------------------------------------------
|
|
561
|
+
_clearState() {
|
|
562
|
+
this.cursorId = 0;
|
|
563
|
+
this.requiresDefine = false;
|
|
564
|
+
this.noPrefetch = false;
|
|
565
|
+
this.requiresFullExecute = false;
|
|
566
|
+
}
|
|
531
567
|
}
|
|
532
568
|
|
|
533
569
|
module.exports.Statement = Statement;
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
// Copyright (c) 2024, 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
|
+
// Node file defining the StatementCache class used to manage cached statements
|
|
26
|
+
//-----------------------------------------------------------------------------
|
|
27
|
+
|
|
28
|
+
const errors = require("../errors.js");
|
|
29
|
+
const { Statement } = require("./statement");
|
|
30
|
+
|
|
31
|
+
class StatementCache {
|
|
32
|
+
constructor(maxSize) {
|
|
33
|
+
this._cachedStatements = new Map();
|
|
34
|
+
this._maxSize = maxSize;
|
|
35
|
+
this._cursorsToClose = new Set();
|
|
36
|
+
this._openCursors = new Set();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
//---------------------------------------------------------------------------
|
|
40
|
+
// _addCursorToClose()
|
|
41
|
+
//
|
|
42
|
+
// Add the statement's cursor to the list of cursors that need to be closed.
|
|
43
|
+
//---------------------------------------------------------------------------
|
|
44
|
+
_addCursorToClose(statement) {
|
|
45
|
+
if (this._cursorsToClose.has(statement.cursorId)) {
|
|
46
|
+
const reason = `attempt to close cursor ${statement.cursorId} twice`;
|
|
47
|
+
errors.throwErr(errors.ERR_INTERNAL, reason);
|
|
48
|
+
}
|
|
49
|
+
if (statement.cursorId != 0) {
|
|
50
|
+
this._cursorsToClose.add(statement.cursorId);
|
|
51
|
+
}
|
|
52
|
+
this._openCursors.delete(statement);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
//---------------------------------------------------------------------------
|
|
56
|
+
// _adjustCache()
|
|
57
|
+
// Adjust the cache so that no more than the maximum number of statements
|
|
58
|
+
// are cached by removing least recently used statements
|
|
59
|
+
//---------------------------------------------------------------------------
|
|
60
|
+
_adjustCache() {
|
|
61
|
+
while (this._cachedStatements.size > this._maxSize) {
|
|
62
|
+
const sql = this._cachedStatements.keys().next().value;
|
|
63
|
+
const stmt = this._cachedStatements.get(sql);
|
|
64
|
+
this._cachedStatements.delete(sql);
|
|
65
|
+
if (stmt.inUse) {
|
|
66
|
+
stmt.returnToCache = false;
|
|
67
|
+
} else if (stmt.cursorId !== 0) {
|
|
68
|
+
this._addCursorToClose(stmt);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
//---------------------------------------------------------------------------
|
|
74
|
+
//clearCursors() {
|
|
75
|
+
// Clears the list of open cursors and removes the list of cursors that
|
|
76
|
+
// need to be closed. This is required when a DRCP session change has
|
|
77
|
+
// taken place as the cursor ID values are invalidated.
|
|
78
|
+
//---------------------------------------------------------------------------
|
|
79
|
+
clearCursors() {
|
|
80
|
+
const newOpenCursors = new Set();
|
|
81
|
+
for (const stmt of this._openCursors) {
|
|
82
|
+
if (stmt.inUse || stmt.returnToCache) {
|
|
83
|
+
stmt.pendingClear = true;
|
|
84
|
+
newOpenCursors.add(stmt);
|
|
85
|
+
}
|
|
86
|
+
stmt._clearState();
|
|
87
|
+
}
|
|
88
|
+
this._openCursors = newOpenCursors;
|
|
89
|
+
this._cursorsToClose.clear();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
//---------------------------------------------------------------------------
|
|
93
|
+
//clearPendingState() {
|
|
94
|
+
// Clears state for statment with pending clear flag set and not in use.
|
|
95
|
+
// This will clear all state for open cursors.
|
|
96
|
+
// Called after rows processing is completed.
|
|
97
|
+
//---------------------------------------------------------------------------
|
|
98
|
+
clearPendingStatus() {
|
|
99
|
+
for (const stmt of this._openCursors) {
|
|
100
|
+
if (stmt.pendingClear && !stmt.inUse) {
|
|
101
|
+
stmt._clearAllState();
|
|
102
|
+
stmt.pendingClear = false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
//---------------------------------------------------------------------------
|
|
108
|
+
// get_statement()
|
|
109
|
+
// Get a statement from the statement cache, or prepare a new statement
|
|
110
|
+
// for use. If a statement is already in use or the statement is not
|
|
111
|
+
// supposed to be cached, a copy will be made (and not returned to the
|
|
112
|
+
// cache).
|
|
113
|
+
//---------------------------------------------------------------------------
|
|
114
|
+
getStatement(sql, cacheStatement = false, forceNew = false) {
|
|
115
|
+
let stmt = null;
|
|
116
|
+
if (sql) {
|
|
117
|
+
stmt = this._cachedStatements.get(sql);
|
|
118
|
+
}
|
|
119
|
+
if (!stmt) {
|
|
120
|
+
stmt = new Statement();
|
|
121
|
+
if (sql) {
|
|
122
|
+
stmt._prepare(sql);
|
|
123
|
+
}
|
|
124
|
+
if (cacheStatement && !stmt.isDdl && this._maxSize > 0) {
|
|
125
|
+
stmt.returnToCache = true;
|
|
126
|
+
this._cachedStatements.set(sql, stmt);
|
|
127
|
+
this._adjustCache();
|
|
128
|
+
}
|
|
129
|
+
this._openCursors.add(stmt);
|
|
130
|
+
} else if (forceNew || stmt.inUse) {
|
|
131
|
+
if (!cacheStatement) {
|
|
132
|
+
this._addCursorToClose(stmt);
|
|
133
|
+
this._cachedStatements.delete(sql);
|
|
134
|
+
}
|
|
135
|
+
stmt = stmt._copy();
|
|
136
|
+
this._openCursors.add(stmt);
|
|
137
|
+
} else if (!cacheStatement) {
|
|
138
|
+
this._cachedStatements.delete(sql);
|
|
139
|
+
stmt.returnToCache = false;
|
|
140
|
+
} else {
|
|
141
|
+
this._cachedStatements.delete(sql);
|
|
142
|
+
this._cachedStatements.set(sql, stmt);
|
|
143
|
+
}
|
|
144
|
+
this._openCursors.add(stmt);
|
|
145
|
+
stmt.inUse = true;
|
|
146
|
+
return stmt;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
//---------------------------------------------------------------------------
|
|
150
|
+
// returnStatement()
|
|
151
|
+
// Return the statement to the statement cache, if applicable. If the
|
|
152
|
+
// statement must not be returned to the statement cache, add the cursor
|
|
153
|
+
// id to the list of cursor ids to close on the next round trip to the
|
|
154
|
+
// database. Clear all bind variables and fetch variables in order to
|
|
155
|
+
// ensure that unnecessary references are not retained.
|
|
156
|
+
//---------------------------------------------------------------------------
|
|
157
|
+
returnStatement(statement) {
|
|
158
|
+
if (statement.bindInfoList) {
|
|
159
|
+
statement.bindInfoList.forEach(bindInfo => {
|
|
160
|
+
bindInfo.bindVar = null;
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
if (statement.queryVars) {
|
|
164
|
+
statement.queryVars.forEach(queryVar => {
|
|
165
|
+
queryVar.values.fill(null);
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
if (statement.returnToCache) {
|
|
169
|
+
statement.inUse = false;
|
|
170
|
+
} else {
|
|
171
|
+
this._addCursorToClose(statement);
|
|
172
|
+
}
|
|
173
|
+
// clear all state for statement which is having flag set and not in use
|
|
174
|
+
this.clearPendingStatus();
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
//---------------------------------------------------------------------------
|
|
178
|
+
// writeCursorsToClose()
|
|
179
|
+
// Write the list of cursors to close to the buffer.
|
|
180
|
+
//---------------------------------------------------------------------------
|
|
181
|
+
writeCursorsToClose(buf) {
|
|
182
|
+
buf.writeUB4(this._cursorsToClose.size);
|
|
183
|
+
for (const cursorNum of this._cursorsToClose.keys()) {
|
|
184
|
+
buf.writeUB4(cursorNum);
|
|
185
|
+
}
|
|
186
|
+
this._cursorsToClose.clear();
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
module.exports = StatementCache;
|
package/lib/thin/util.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2022,
|
|
1
|
+
// Copyright (c) 2022, 2024, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -254,5 +254,5 @@ module.exports = {
|
|
|
254
254
|
getOutBinds,
|
|
255
255
|
checkProxyUserValidity,
|
|
256
256
|
checkCredentials,
|
|
257
|
-
normalizePrivateKey
|
|
257
|
+
normalizePrivateKey,
|
|
258
258
|
};
|
package/lib/transformer.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2023, Oracle and/or its affiliates.
|
|
1
|
+
// Copyright (c) 2023, 2024, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -34,6 +34,7 @@ const constants = require('./constants.js');
|
|
|
34
34
|
const errors = require('./errors.js');
|
|
35
35
|
const util = require('util');
|
|
36
36
|
const types = require('./types.js');
|
|
37
|
+
const nodbUtil = require('./util.js');
|
|
37
38
|
|
|
38
39
|
//-----------------------------------------------------------------------------
|
|
39
40
|
// checkType()
|
|
@@ -86,9 +87,9 @@ function transformJsonValue(value) {
|
|
|
86
87
|
|
|
87
88
|
// handle simple scalars
|
|
88
89
|
if (value === undefined || value === null ||
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
typeof value === 'number' || typeof value === 'string' ||
|
|
91
|
+
typeof value === 'boolean' || Buffer.isBuffer(value) ||
|
|
92
|
+
util.types.isDate(value) || nodbUtil.isVectorValue(value))
|
|
92
93
|
return value;
|
|
93
94
|
|
|
94
95
|
// arrays are transformed to a new array with processed values
|
|
@@ -104,6 +105,12 @@ function transformJsonValue(value) {
|
|
|
104
105
|
if (value instanceof BaseDbObject)
|
|
105
106
|
return {fields: [], values: []};
|
|
106
107
|
|
|
108
|
+
// JsonId is a special type to represent autogenerated id
|
|
109
|
+
// for SODA documents.
|
|
110
|
+
if (value instanceof types.JsonId) {
|
|
111
|
+
return value;
|
|
112
|
+
}
|
|
113
|
+
|
|
107
114
|
// all other objects are transformed to an object with two arrays (fields
|
|
108
115
|
// and values)
|
|
109
116
|
const outValue = {};
|
|
@@ -165,7 +172,7 @@ function transformValueIn(info, value, options) {
|
|
|
165
172
|
return value;
|
|
166
173
|
|
|
167
174
|
// handle numbers
|
|
168
|
-
} else if (typeof value === 'number') {
|
|
175
|
+
} else if (typeof value === 'number' || typeof value === 'bigint') {
|
|
169
176
|
checkType(info, options,
|
|
170
177
|
types.DB_TYPE_NUMBER,
|
|
171
178
|
types.DB_TYPE_BINARY_INTEGER,
|
|
@@ -182,7 +189,7 @@ function transformValueIn(info, value, options) {
|
|
|
182
189
|
return value;
|
|
183
190
|
|
|
184
191
|
// handle dates
|
|
185
|
-
} else if (util.isDate(value)) {
|
|
192
|
+
} else if (util.types.isDate(value)) {
|
|
186
193
|
checkType(info, options,
|
|
187
194
|
types.DB_TYPE_TIMESTAMP,
|
|
188
195
|
types.DB_TYPE_TIMESTAMP_TZ,
|
|
@@ -220,6 +227,14 @@ function transformValueIn(info, value, options) {
|
|
|
220
227
|
checkType(info, options, types.DB_TYPE_OBJECT);
|
|
221
228
|
return value._impl;
|
|
222
229
|
|
|
230
|
+
// handle vectors
|
|
231
|
+
} else if (value instanceof Float32Array || value instanceof Float64Array ||
|
|
232
|
+
value instanceof Int8Array) {
|
|
233
|
+
checkType(info, options, types.DB_TYPE_VECTOR);
|
|
234
|
+
return value;
|
|
235
|
+
} else if (info.type === types.DB_TYPE_VECTOR && Array.isArray(value)) {
|
|
236
|
+
return new Float64Array(value);
|
|
237
|
+
|
|
223
238
|
// handle arrays
|
|
224
239
|
} else if (options.allowArray && Array.isArray(value)) {
|
|
225
240
|
info.isArray = true;
|
package/lib/types.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2022,
|
|
1
|
+
// Copyright (c) 2022, 2024, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -199,6 +199,9 @@ const DB_TYPE_VARCHAR = new DbType(2001,
|
|
|
199
199
|
const DB_TYPE_XMLTYPE = new DbType(2032,
|
|
200
200
|
"DB_TYPE_XMLTYPE", "XMLTYPE",
|
|
201
201
|
{ oraTypeNum: 109, csfrm: constants.CSFRM_IMPLICIT, bufferSizeFactor: 2147483647 });
|
|
202
|
+
const DB_TYPE_VECTOR = new DbType(2033,
|
|
203
|
+
"DB_TYPE_VECTOR", "VECTOR",
|
|
204
|
+
{ oraTypeNum: 127 });
|
|
202
205
|
|
|
203
206
|
// database type conversion map: the top level key refers to the database
|
|
204
207
|
// type being fetched and the value is another map; this map's key is the
|
|
@@ -276,6 +279,11 @@ const DB_TYPE_CONVERSION_MAP = new Map([
|
|
|
276
279
|
[DB_TYPE_UROWID, new Map([
|
|
277
280
|
[DB_TYPE_VARCHAR, DB_TYPE_ROWID]
|
|
278
281
|
])],
|
|
282
|
+
[DB_TYPE_VECTOR, new Map([
|
|
283
|
+
[DB_TYPE_VARCHAR, DB_TYPE_LONG],
|
|
284
|
+
[DB_TYPE_LONG, DB_TYPE_LONG],
|
|
285
|
+
[DB_TYPE_CLOB, DB_TYPE_CLOB]
|
|
286
|
+
])],
|
|
279
287
|
]);
|
|
280
288
|
|
|
281
289
|
// default fetch type map
|
|
@@ -308,7 +316,8 @@ const DB_TYPE_FETCH_TYPE_MAP = new Map([
|
|
|
308
316
|
[DB_TYPE_TIMESTAMP_TZ, DB_TYPE_TIMESTAMP_TZ],
|
|
309
317
|
[DB_TYPE_UROWID, DB_TYPE_UROWID],
|
|
310
318
|
[DB_TYPE_VARCHAR, DB_TYPE_VARCHAR],
|
|
311
|
-
[DB_TYPE_XMLTYPE, DB_TYPE_XMLTYPE]
|
|
319
|
+
[DB_TYPE_XMLTYPE, DB_TYPE_XMLTYPE],
|
|
320
|
+
[DB_TYPE_VECTOR, DB_TYPE_VECTOR]
|
|
312
321
|
]);
|
|
313
322
|
|
|
314
323
|
// additional aliases for types by column type name
|
|
@@ -323,6 +332,13 @@ dbTypeByColumnTypeName.set("SMALLINT", DB_TYPE_NUMBER);
|
|
|
323
332
|
dbTypeByColumnTypeName.set("TIMESTAMP WITH LOCAL TZ", DB_TYPE_TIMESTAMP_LTZ);
|
|
324
333
|
dbTypeByColumnTypeName.set("TIMESTAMP WITH TZ", DB_TYPE_TIMESTAMP_TZ);
|
|
325
334
|
|
|
335
|
+
// It abstracts the autogenerated SODA Document key.
|
|
336
|
+
class JsonId extends Uint8Array {
|
|
337
|
+
toJSON() {
|
|
338
|
+
return (Buffer.from(this.buffer).toString('hex'));
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
326
342
|
module.exports = {
|
|
327
343
|
DbType,
|
|
328
344
|
DB_TYPE_BFILE,
|
|
@@ -353,10 +369,12 @@ module.exports = {
|
|
|
353
369
|
DB_TYPE_TIMESTAMP_TZ,
|
|
354
370
|
DB_TYPE_UROWID,
|
|
355
371
|
DB_TYPE_VARCHAR,
|
|
372
|
+
DB_TYPE_VECTOR,
|
|
356
373
|
DB_TYPE_CONVERSION_MAP,
|
|
357
374
|
DB_TYPE_FETCH_TYPE_MAP,
|
|
358
375
|
DB_TYPE_XMLTYPE,
|
|
359
376
|
getTypeByColumnTypeName,
|
|
360
377
|
getTypeByNum,
|
|
361
|
-
getTypeByOraTypeNum
|
|
378
|
+
getTypeByOraTypeNum,
|
|
379
|
+
JsonId
|
|
362
380
|
};
|
package/lib/util.js
CHANGED
|
@@ -231,7 +231,7 @@ function isShardingKey(value) {
|
|
|
231
231
|
const element = value[i];
|
|
232
232
|
const ok = typeof element === 'string' ||
|
|
233
233
|
typeof element === 'number' || Buffer.isBuffer(element) ||
|
|
234
|
-
util.isDate(element);
|
|
234
|
+
util.types.isDate(element);
|
|
235
235
|
if (!ok)
|
|
236
236
|
return false;
|
|
237
237
|
}
|
|
@@ -327,6 +327,33 @@ function addTypeProperties(obj, attrName) {
|
|
|
327
327
|
}
|
|
328
328
|
}
|
|
329
329
|
|
|
330
|
+
//-----------------------------------------------------------------------------
|
|
331
|
+
// isVectorValue()
|
|
332
|
+
//
|
|
333
|
+
// Returns true for list of typed arrays supported for vector column types
|
|
334
|
+
//
|
|
335
|
+
// -----------------------------------------------------------------------------
|
|
336
|
+
function isVectorValue(value) {
|
|
337
|
+
return (value instanceof Float32Array ||
|
|
338
|
+
value instanceof Float64Array ||
|
|
339
|
+
value instanceof Int8Array);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
//-----------------------------------------------------------------------------
|
|
343
|
+
// makeDate()
|
|
344
|
+
//
|
|
345
|
+
// Returns a date from the given components.
|
|
346
|
+
//
|
|
347
|
+
// -----------------------------------------------------------------------------
|
|
348
|
+
function makeDate(useLocal, year, month, day, hour, minute,
|
|
349
|
+
second, fseconds, offset) {
|
|
350
|
+
if (useLocal) {
|
|
351
|
+
return new Date(year, month - 1, day, hour, minute, second, fseconds);
|
|
352
|
+
}
|
|
353
|
+
return new Date(Date.UTC(year, month - 1, day, hour, minute, second,
|
|
354
|
+
fseconds) - offset * 60000);
|
|
355
|
+
}
|
|
356
|
+
|
|
330
357
|
// define exports
|
|
331
358
|
module.exports = {
|
|
332
359
|
BINARY_FILE,
|
|
@@ -346,7 +373,9 @@ module.exports = {
|
|
|
346
373
|
isSodaDocument,
|
|
347
374
|
isTokenExpired,
|
|
348
375
|
isTokenValid,
|
|
376
|
+
isVectorValue,
|
|
349
377
|
isXid,
|
|
378
|
+
makeDate,
|
|
350
379
|
preventConcurrent,
|
|
351
380
|
serialize,
|
|
352
381
|
verifySodaDoc,
|
package/lib/version.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2023, Oracle and/or its affiliates.
|
|
1
|
+
// Copyright (c) 2023, 2024, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
|
|
31
31
|
module.exports = {
|
|
32
32
|
VERSION_MAJOR: 6,
|
|
33
|
-
VERSION_MINOR:
|
|
33
|
+
VERSION_MINOR: 5,
|
|
34
34
|
VERSION_PATCH: 0,
|
|
35
35
|
VERSION_SUFFIX: ''
|
|
36
36
|
};
|
package/package.json
CHANGED
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
oracledb-6.3.0-darwin-x64.node v18.16.0 6430a56e82b0405c4118fcc1060c3568be4c43aa 4b8ebc2af8c9d58f7260c9de81d220f14fcab777 Sun, 17 Dec 2023 09:33:07 GMT
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
6430a56e82b0405c4118fcc1060c3568be4c43aa
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
oracledb-6.3.0-linux-arm64.node v16.20.2 6430a56e82b0405c4118fcc1060c3568be4c43aa 4b8ebc2af8c9d58f7260c9de81d220f14fcab777 Sun, 17 Dec 2023 09:47:35 GMT
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
oracledb-6.3.0-linux-x64.node v16.19.1 6430a56e82b0405c4118fcc1060c3568be4c43aa 4b8ebc2af8c9d58f7260c9de81d220f14fcab777 Fri, 15 Dec 2023 17:32:48 GMT
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
oracledb-6.3.0-win32-x64.node v14.17.3 6430a56e82b0405c4118fcc1060c3568be4c43aa 4b8ebc2af8c9d58f7260c9de81d220f14fcab777 Fri, 15 Dec 2023 17:43:19 GMT
|