oracledb 6.7.2 → 6.9.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 +39 -3
- package/build/Release/oracledb-6.9.0-darwin-arm64.node +0 -0
- package/build/Release/oracledb-6.9.0-darwin-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.9.0-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.9.0-darwin-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.9.0-js-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.9.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.9.0-linux-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.9.0-linux-x64.node +0 -0
- package/build/Release/oracledb-6.9.0-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.9.0-win32-x64.node +0 -0
- package/build/Release/oracledb-6.9.0-win32-x64.node-buildinfo.txt +1 -0
- package/lib/aqMessage.js +10 -1
- package/lib/configProviders/file.js +72 -0
- package/lib/connection.js +153 -4
- package/lib/dbObject.js +51 -10
- package/lib/errors.js +144 -36
- package/lib/impl/connection.js +24 -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/impl/pool.js +10 -1
- package/lib/impl/resultset.js +5 -4
- package/lib/lob.js +9 -1
- package/lib/oracledb.js +209 -20
- package/lib/pool.js +12 -1
- package/lib/poolStatistics.js +3 -1
- package/lib/settings.js +5 -1
- package/lib/thin/connection.js +130 -12
- package/lib/thin/dbObject.js +46 -13
- package/lib/thin/lob.js +2 -3
- package/lib/thin/pool.js +112 -31
- package/lib/thin/protocol/capabilities.js +8 -4
- package/lib/thin/protocol/constants.js +31 -1
- package/lib/thin/protocol/messages/auth.js +42 -6
- package/lib/thin/protocol/messages/base.js +98 -9
- package/lib/thin/protocol/messages/dataType.js +2 -1
- package/lib/thin/protocol/messages/execute.js +46 -4
- package/lib/thin/protocol/messages/fastAuth.js +6 -1
- package/lib/thin/protocol/messages/lobOp.js +5 -22
- package/lib/thin/protocol/messages/logOff.js +0 -1
- package/lib/thin/protocol/messages/sessionRelease.js +0 -1
- package/lib/thin/protocol/messages/transactionSwitch.js +12 -4
- package/lib/thin/protocol/messages/withData.js +10 -1
- package/lib/thin/protocol/packet.js +1 -1
- package/lib/thin/protocol/protocol.js +2 -1
- package/lib/thin/sqlnet/ANO.js +438 -0
- package/lib/thin/sqlnet/connStrategy.js +2 -1
- package/lib/thin/sqlnet/constants.js +5 -1
- package/lib/thin/sqlnet/ezConnectResolver.js +4 -2
- package/lib/thin/sqlnet/navNodes.js +22 -3
- package/lib/thin/sqlnet/networkSession.js +94 -16
- package/lib/thin/sqlnet/ntTcp.js +50 -3
- package/lib/thin/sqlnet/packet.js +32 -4
- package/lib/thin/sqlnet/sessionAtts.js +24 -2
- package/lib/thin/util.js +3 -8
- package/lib/transformer.js +13 -2
- package/lib/types.js +220 -8
- package/lib/util.js +77 -3
- package/lib/version.js +2 -2
- package/package/install.js +3 -3
- package/package/prunebinaries.js +6 -12
- package/package.json +2 -2
- package/{lib/configProviders/azure.js → plugins/configProviders/azure/index.js} +70 -63
- package/plugins/configProviders/azurevault/index.js +84 -0
- package/{lib → plugins}/configProviders/base.js +13 -3
- package/{lib/configProviders/ociobject.js → plugins/configProviders/ociobject/index.js} +43 -78
- package/plugins/configProviders/ocivault/index.js +100 -0
- package/plugins/token/extensionAzure/index.js +101 -0
- package/plugins/token/extensionOci/index.js +210 -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) 2022,
|
|
1
|
+
// Copyright (c) 2022, 2025, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -405,6 +405,7 @@ module.exports = {
|
|
|
405
405
|
TNS_DATA_TYPE_UD21: 639,
|
|
406
406
|
TNS_DATA_TYPE_TNP: 640,
|
|
407
407
|
TNS_DATA_TYPE_OAC: 646,
|
|
408
|
+
TNS_DATA_TYPE_SESSSIGN: 647,
|
|
408
409
|
TNS_DATA_TYPE_OER: 652,
|
|
409
410
|
TNS_DATA_TYPE_UDS: 663,
|
|
410
411
|
|
|
@@ -439,6 +440,7 @@ module.exports = {
|
|
|
439
440
|
// parameter keyword numbers,
|
|
440
441
|
TNS_KEYWORD_NUM_CURRENT_SCHEMA: 168,
|
|
441
442
|
TNS_KEYWORD_NUM_EDITION: 172,
|
|
443
|
+
TNS_KEYWORD_NUM_TRANSACTION_ID: 201,
|
|
442
444
|
|
|
443
445
|
// bind flags
|
|
444
446
|
TNS_BIND_USE_INDICATORS: 0x0001,
|
|
@@ -476,6 +478,7 @@ module.exports = {
|
|
|
476
478
|
TNS_SERVER_PIGGYBACK_LTXID: 7,
|
|
477
479
|
TNS_SERVER_PIGGYBACK_AC_REPLAY_CONTEXT: 8,
|
|
478
480
|
TNS_SERVER_PIGGYBACK_EXT_SYNC: 9,
|
|
481
|
+
TNS_SERVER_PIGGYBACK_SESS_SIGNATURE: 10,
|
|
479
482
|
|
|
480
483
|
// session return constants
|
|
481
484
|
TNS_SESSGET_SESSION_CHANGED: 4,
|
|
@@ -582,7 +585,9 @@ module.exports = {
|
|
|
582
585
|
TNS_CCAP_UB2_DTY: 27,
|
|
583
586
|
TNS_CCAP_OCI2: 31,
|
|
584
587
|
TNS_CCAP_CLIENT_FN: 34,
|
|
588
|
+
TNS_CCAP_OCI3: 35,
|
|
585
589
|
TNS_CCAP_TTC3: 37,
|
|
590
|
+
TNS_CCAP_SESS_SIGNATURE_VERSION: 39,
|
|
586
591
|
TNS_CCAP_TTC4: 40,
|
|
587
592
|
TNS_CCAP_LOB2: 42,
|
|
588
593
|
TNS_CCAP_TTC5: 44,
|
|
@@ -625,6 +630,7 @@ module.exports = {
|
|
|
625
630
|
TNS_CCAP_RPC_VERSION_MAX: 7,
|
|
626
631
|
TNS_CCAP_RPC_SIG_VALUE: 3,
|
|
627
632
|
TNS_CCAP_DBF_VERSION_MAX: 1,
|
|
633
|
+
TNS_CCAP_LTXID: 0x08,
|
|
628
634
|
TNS_CCAP_IMPLICIT_RESULTS: 0x10,
|
|
629
635
|
TNS_CCAP_BIG_CHUNK_CLR: 0x20,
|
|
630
636
|
TNS_CCAP_KEEP_OUT_ORDER: 0x80,
|
|
@@ -644,6 +650,9 @@ module.exports = {
|
|
|
644
650
|
TNS_CCAP_CTB_IMPLICIT_POOL: 0x08,
|
|
645
651
|
TNS_CCAP_VECTOR_SUPPORT: 0x08,
|
|
646
652
|
TNS_CCAP_VECTOR_FEATURE_BINARY: 0x01,
|
|
653
|
+
TNS_CCAP_VECTOR_FEATURE_SPARSE: 0x02,
|
|
654
|
+
TNS_CCAP_TTC5_SESSIONLESS_TXNS: 0x20,
|
|
655
|
+
TNS_CCAP_OCI3_OCSSYNC: 0x20,
|
|
647
656
|
|
|
648
657
|
// runtime capability indices
|
|
649
658
|
TNS_RCAP_COMPAT: 0,
|
|
@@ -673,6 +682,7 @@ module.exports = {
|
|
|
673
682
|
// transaction switching op codes
|
|
674
683
|
TNS_TPC_TXN_START: 0x01,
|
|
675
684
|
TNS_TPC_TXN_DETACH: 0x02,
|
|
685
|
+
TNS_TPC_TXN_POST_DETACH: 0x04,
|
|
676
686
|
|
|
677
687
|
// transaction change state op codes
|
|
678
688
|
TNS_TPC_TXN_COMMIT: 0x01,
|
|
@@ -688,6 +698,25 @@ module.exports = {
|
|
|
688
698
|
TNS_TPC_TXN_STATE_READ_ONLY: 4,
|
|
689
699
|
TNS_TPC_TXN_STATE_FORGOTTEN: 5,
|
|
690
700
|
|
|
701
|
+
// sessionless transaction flag
|
|
702
|
+
TNS_TPC_TRANS_SESSIONLESS: 0x00000010,
|
|
703
|
+
|
|
704
|
+
// sessionless transaction format
|
|
705
|
+
TNS_TPC_TRANS_SESSIONLESS_FORMAT: 0x4e5c3e,
|
|
706
|
+
|
|
707
|
+
// sessionless sync version
|
|
708
|
+
TNS_TPC_TRANS_TRANSACTION_ID_SYNC_VERSION_1: 0x01,
|
|
709
|
+
|
|
710
|
+
// sessionless server states
|
|
711
|
+
TNS_TPC_TRANS_TRANSACTION_ID_SYNC_SET: 0x40,
|
|
712
|
+
TNS_TPC_TRANS_TRANSACTION_ID_SYNC_UNSET: 0x80,
|
|
713
|
+
|
|
714
|
+
// sessionless state reason
|
|
715
|
+
TNS_TPC_TRANS_TRANSACTION_ID_SYNC_SERVER: 0x01,
|
|
716
|
+
TNS_TPC_TRANS_TRANSACTION_ID_SYNC_CLIENT: 0x02,
|
|
717
|
+
TNS_TPC_TRANS_TRANSACTION_ID_SYNC_TXEND_XA: 0x03,
|
|
718
|
+
|
|
719
|
+
|
|
691
720
|
// other constants
|
|
692
721
|
TNS_ESCAPE_CHAR: 253,
|
|
693
722
|
TNS_LONG_LENGTH_INDICATOR: dataHandlerConstants.TNS_LONG_LENGTH_INDICATOR,
|
|
@@ -767,6 +796,7 @@ module.exports = {
|
|
|
767
796
|
TNS_VECTOR_MAX_LENGTH: 1048576,
|
|
768
797
|
VECTOR_FORMAT_FLEX: 0,
|
|
769
798
|
VECTOR_META_FLAG_FLEXIBLE_DIM: 1,
|
|
799
|
+
VECTOR_META_FLAG_SPARSE: 2,
|
|
770
800
|
|
|
771
801
|
// other constants
|
|
772
802
|
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,12 @@ 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
|
+
}
|
|
117
|
+
this.appContext = config.appContext;
|
|
110
118
|
this.setAuthMode(config);
|
|
111
119
|
}
|
|
112
120
|
|
|
@@ -141,7 +149,7 @@ class AuthMessage extends Message {
|
|
|
141
149
|
if (this.newPassword) {
|
|
142
150
|
this.authMode |= constants.TNS_AUTH_MODE_CHANGE_PASSWORD;
|
|
143
151
|
}
|
|
144
|
-
if (!
|
|
152
|
+
if (!config.externalAuth) {
|
|
145
153
|
this.authMode |= constants.TNS_AUTH_MODE_WITH_PASSWORD;
|
|
146
154
|
}
|
|
147
155
|
}
|
|
@@ -199,8 +207,10 @@ class AuthMessage extends Message {
|
|
|
199
207
|
numPairs = 2;
|
|
200
208
|
} else {
|
|
201
209
|
numPairs = 4;
|
|
202
|
-
if (this.
|
|
203
|
-
numPairs +=
|
|
210
|
+
if (this.externalAuth) {
|
|
211
|
+
numPairs += 5;
|
|
212
|
+
if (this.token)
|
|
213
|
+
numPairs += 1;
|
|
204
214
|
} else {
|
|
205
215
|
numPairs += 2;
|
|
206
216
|
if (this.verifierType === constants.TNS_VERIFIER_TYPE_11G_1 ||
|
|
@@ -235,6 +245,12 @@ class AuthMessage extends Message {
|
|
|
235
245
|
this.encryptedJDWPData = ED.getEncryptedJSWPData(this.sessionKey, this.conn.jdwpData);
|
|
236
246
|
numPairs += 1;
|
|
237
247
|
}
|
|
248
|
+
if (this.edition) {
|
|
249
|
+
numPairs += 1;
|
|
250
|
+
}
|
|
251
|
+
if (this.appContext) {
|
|
252
|
+
numPairs += this.appContext.length * 3;
|
|
253
|
+
}
|
|
238
254
|
if (this.schemaUser.length !== 0) {
|
|
239
255
|
numPairs += 1;
|
|
240
256
|
}
|
|
@@ -246,10 +262,17 @@ class AuthMessage extends Message {
|
|
|
246
262
|
buf.writeUInt8(1);
|
|
247
263
|
if (this.userByteLen > 0)
|
|
248
264
|
buf.writeBytesWithLength(Buffer.from(this.username));
|
|
265
|
+
if (this.externalAuth) {
|
|
266
|
+
buf.writeKeyValue("AUTH_TERMINAL", this.terminal ?? cInfo.terminal);
|
|
267
|
+
buf.writeKeyValue("AUTH_PROGRAM_NM", this.program ?? cInfo.program);
|
|
268
|
+
buf.writeKeyValue("AUTH_MACHINE", this.machine ?? cInfo.hostName);
|
|
269
|
+
buf.writeKeyValue("AUTH_PID", cInfo.pid);
|
|
270
|
+
buf.writeKeyValue("AUTH_SID", this.osUser ?? cInfo.userName);
|
|
271
|
+
}
|
|
249
272
|
if (this.token) {
|
|
250
273
|
buf.writeKeyValue("AUTH_TOKEN", this.token);
|
|
251
274
|
} else {
|
|
252
|
-
if (!this.changePassword) {
|
|
275
|
+
if (!this.changePassword && !this.externalAuth) {
|
|
253
276
|
buf.writeKeyValue("AUTH_SESSKEY", this.sessionKey, 1);
|
|
254
277
|
if (!verifier11G) {
|
|
255
278
|
buf.writeKeyValue("AUTH_PBKDF2_SPEEDY_KEY", this.speedyKey);
|
|
@@ -297,6 +320,18 @@ class AuthMessage extends Message {
|
|
|
297
320
|
if (this.conn.jdwpData) {
|
|
298
321
|
buf.writeKeyValue("AUTH_ORA_DEBUG_JDWP", this.encryptedJDWPData);
|
|
299
322
|
}
|
|
323
|
+
if (this.edition) {
|
|
324
|
+
buf.writeKeyValue("AUTH_ORA_EDITION", this.edition);
|
|
325
|
+
}
|
|
326
|
+
if (this.appContext) {
|
|
327
|
+
// NOTE: these keys require a trailing null character as the server
|
|
328
|
+
// expects it!
|
|
329
|
+
for (const entry of this.appContext) {
|
|
330
|
+
buf.writeKeyValue("AUTH_APPCTX_NSPACE\0", entry[0]);
|
|
331
|
+
buf.writeKeyValue("AUTH_APPCTX_ATTR\0", entry[1]);
|
|
332
|
+
buf.writeKeyValue("AUTH_APPCTX_VALUE\0", entry[2]);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
300
335
|
|
|
301
336
|
}
|
|
302
337
|
}
|
|
@@ -331,6 +366,7 @@ class AuthMessage extends Message {
|
|
|
331
366
|
this.conn.maxOpenCursors = Number(this.sessionData['AUTH_MAX_OPEN_CURSORS'] || 0);
|
|
332
367
|
this.conn.serviceName = this.sessionData['AUTH_SC_SERVICE_NAME'];
|
|
333
368
|
this.conn.instanceName = this.sessionData['AUTH_INSTANCENAME'];
|
|
369
|
+
this.conn.maxIdentifierLength = Number(this.sessionData['AUTH_MAX_IDEN_LENGTH'] || 30);
|
|
334
370
|
const fullVersionNum = Number(this.sessionData['AUTH_VERSION_NO']);
|
|
335
371
|
const versionNum = (fullVersionNum >> 24) & 0xFF;
|
|
336
372
|
this.conn.warning = this.warning;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2022,
|
|
1
|
+
// Copyright (c) 2022, 2025, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -30,6 +30,34 @@ const { Buffer } = require('buffer');
|
|
|
30
30
|
const constants = require("../constants.js");
|
|
31
31
|
const errors = require("../../../errors.js");
|
|
32
32
|
|
|
33
|
+
// List of recoverable errors
|
|
34
|
+
const RECOVERABLE_ERRORS = new Set([
|
|
35
|
+
28, // session has been terminated
|
|
36
|
+
31, // session marked for kill
|
|
37
|
+
376, // file %s cannot be read at this time
|
|
38
|
+
603, // ORACLE server session terminated
|
|
39
|
+
1012, // not logged on
|
|
40
|
+
1033, // ORACLE initialization or shutdown in progress
|
|
41
|
+
1034, // the Oracle instance is not available for use
|
|
42
|
+
1089, // immediate shutdown or close in progress
|
|
43
|
+
1090, // shutdown in progress
|
|
44
|
+
1092, // ORACLE instance terminated
|
|
45
|
+
1115, // IO error reading block from file %s (block # %s)
|
|
46
|
+
2396, // exceeded maximum idle time
|
|
47
|
+
3113, // end-of-file on communication channel
|
|
48
|
+
3114, // not connected to ORACLE
|
|
49
|
+
3135, // connection lost contact
|
|
50
|
+
12153, // TNS:not connected
|
|
51
|
+
12514, // Service %s is not registered with the listener
|
|
52
|
+
12537, // TNS:connection closed
|
|
53
|
+
12547, // TNS:lost contact
|
|
54
|
+
12570, // TNS:packet reader failure
|
|
55
|
+
12571, // TNS:packet writer failure
|
|
56
|
+
12583, // TNS:no reader
|
|
57
|
+
12757, // instance does not currently know of requested service
|
|
58
|
+
16456 // missing or invalid value
|
|
59
|
+
]);
|
|
60
|
+
|
|
33
61
|
/**
|
|
34
62
|
*
|
|
35
63
|
* Base class for all the RPC messages to support encode/decode functions
|
|
@@ -52,6 +80,7 @@ class Message {
|
|
|
52
80
|
async postProcess() { }
|
|
53
81
|
|
|
54
82
|
writeFunctionHeader(buf) {
|
|
83
|
+
this.writePiggybacks(buf);
|
|
55
84
|
buf.writeUInt8(this.messageType);
|
|
56
85
|
buf.writeUInt8(this.functionCode);
|
|
57
86
|
buf.writeSeqNum();
|
|
@@ -160,6 +189,8 @@ class Message {
|
|
|
160
189
|
*/
|
|
161
190
|
this.errorInfo.message = this.errorInfo.message.trim();
|
|
162
191
|
}
|
|
192
|
+
this.errorInfo.isRecoverable = RECOVERABLE_ERRORS.has(this.errorInfo.num);
|
|
193
|
+
|
|
163
194
|
this.endOfResponse = !this.connection.nscon.endOfRequestSupport;
|
|
164
195
|
}
|
|
165
196
|
|
|
@@ -220,7 +251,7 @@ class Message {
|
|
|
220
251
|
if (opcode === constants.TNS_SERVER_PIGGYBACK_LTXID) {
|
|
221
252
|
const num_bytes = buf.readUB4();
|
|
222
253
|
if (num_bytes > 0) {
|
|
223
|
-
buf.
|
|
254
|
+
this.connection._ltxid = Buffer.from(buf.readBytesWithLength());
|
|
224
255
|
}
|
|
225
256
|
} else if ((opcode === constants.TNS_SERVER_PIGGYBACK_QUERY_CACHE_INVALIDATION)
|
|
226
257
|
|| (opcode === constants.TNS_SERVER_PIGGYBACK_TRACE_EVENT)) {
|
|
@@ -235,15 +266,22 @@ class Message {
|
|
|
235
266
|
const num_elements = buf.readUB4();
|
|
236
267
|
buf.skipBytes(1); // skip length
|
|
237
268
|
for (let i = 0; i < num_elements; i++) {
|
|
238
|
-
let
|
|
239
|
-
|
|
240
|
-
|
|
269
|
+
let numBytes = buf.readUB2();
|
|
270
|
+
let keyTextValue, value;
|
|
271
|
+
if (numBytes > 0) { // read key
|
|
272
|
+
keyTextValue = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
241
273
|
}
|
|
242
|
-
|
|
243
|
-
if (
|
|
244
|
-
buf.
|
|
274
|
+
numBytes = buf.readUB2();
|
|
275
|
+
if (numBytes > 0) // read value
|
|
276
|
+
value = buf.readBytesWithLength();
|
|
277
|
+
const keywordNum = buf.readUB2(); // read keyword number
|
|
278
|
+
if (keywordNum == constants.TNS_KEYWORD_NUM_TRANSACTION_ID) {
|
|
279
|
+
this._updateSessionlessTxnState(value);
|
|
280
|
+
} else if (keywordNum === constants.TNS_KEYWORD_NUM_CURRENT_SCHEMA) {
|
|
281
|
+
this.connection.currentSchema = keyTextValue;
|
|
282
|
+
} else if (keywordNum === constants.TNS_KEYWORD_NUM_EDITION) {
|
|
283
|
+
this.connection._edition = keyTextValue;
|
|
245
284
|
}
|
|
246
|
-
buf.skipUB2(); // skip flags
|
|
247
285
|
}
|
|
248
286
|
buf.skipUB4(); // skip overall flags
|
|
249
287
|
} else if (opcode === constants.TNS_SERVER_PIGGYBACK_EXT_SYNC) {
|
|
@@ -286,12 +324,22 @@ class Message {
|
|
|
286
324
|
this.connection._drcpEstablishSession = false;
|
|
287
325
|
buf.skipUB4(); // session id
|
|
288
326
|
buf.skipUB2(); // serial number
|
|
327
|
+
} else if (opcode === constants.TNS_SERVER_PIGGYBACK_SESS_SIGNATURE) {
|
|
328
|
+
buf.skipUB2(); // number of dtys
|
|
329
|
+
buf.skipUB1(); // length of dty
|
|
330
|
+
buf.skipUB8(); // signature flags
|
|
331
|
+
buf.skipUB8(); // client signature
|
|
332
|
+
buf.skipUB8(); // server signature
|
|
289
333
|
} else {
|
|
290
334
|
errors.throwErr(errors.ERR_UNKOWN_SERVER_SIDE_PIGGYBACK, opcode);
|
|
291
335
|
}
|
|
292
336
|
}
|
|
293
337
|
|
|
294
338
|
writePiggybacks(buf) {
|
|
339
|
+
// Don't write piggybacks if not authenticated yet
|
|
340
|
+
if (this.connection._protocol.connInProgress)
|
|
341
|
+
return;
|
|
342
|
+
|
|
295
343
|
if (this.connection._currentSchemaModified) {
|
|
296
344
|
this._writeCurrentSchemaPiggyback(buf);
|
|
297
345
|
}
|
|
@@ -313,6 +361,11 @@ class Message {
|
|
|
313
361
|
if (this.connection._tempLobsTotalSize > 0) {
|
|
314
362
|
this.writeCloseTempLobsPiggyback(buf);
|
|
315
363
|
}
|
|
364
|
+
if (this.connection._sessionlessData?.pending) {
|
|
365
|
+
this.connection._sessionlessData.pending = false;
|
|
366
|
+
this.connection._sessionlessData.piggyback.encode(buf);
|
|
367
|
+
this.connection._sessionlessData.piggyback = null;
|
|
368
|
+
}
|
|
316
369
|
}
|
|
317
370
|
|
|
318
371
|
writePiggybackHeader(buf, functionCode) {
|
|
@@ -474,6 +527,42 @@ class Message {
|
|
|
474
527
|
this.deferredErr = errors.getErr(...arguments);
|
|
475
528
|
}
|
|
476
529
|
}
|
|
530
|
+
|
|
531
|
+
_updateSessionlessTxnState(buf) {
|
|
532
|
+
const length = buf.length;
|
|
533
|
+
const sessionlessState = buf.readUInt8(length - 2);
|
|
534
|
+
const syncVersion = buf.readUInt8(length - 1);
|
|
535
|
+
let startedOnServer;
|
|
536
|
+
|
|
537
|
+
if (syncVersion == constants.TNS_TPC_TRANS_TRANSACTION_ID_SYNC_VERSION_1) {
|
|
538
|
+
// transactionId got unset for this session (txn ended or suspended)
|
|
539
|
+
if (sessionlessState &
|
|
540
|
+
constants.TNS_TPC_TRANS_TRANSACTION_ID_SYNC_UNSET) {
|
|
541
|
+
this.connection._sessionlessData = null;
|
|
542
|
+
this.connection._protocol.txnInProgress = false;
|
|
543
|
+
// transactionId got set for this session
|
|
544
|
+
} else if (sessionlessState &
|
|
545
|
+
constants.TNS_TPC_TRANS_TRANSACTION_ID_SYNC_SET) {
|
|
546
|
+
|
|
547
|
+
// transaction initialized by PL/SQL procedure
|
|
548
|
+
if (sessionlessState &
|
|
549
|
+
constants.TNS_TPC_TRANS_TRANSACTION_ID_SYNC_SERVER)
|
|
550
|
+
startedOnServer = true;
|
|
551
|
+
// transaction initialized by calling client API(RPC call)
|
|
552
|
+
else if (sessionlessState &
|
|
553
|
+
constants.TNS_TPC_TRANS_TRANSACTION_ID_SYNC_CLIENT)
|
|
554
|
+
startedOnServer = false;
|
|
555
|
+
|
|
556
|
+
this.connection._sessionlessData = {
|
|
557
|
+
startedOnServer: startedOnServer,
|
|
558
|
+
};
|
|
559
|
+
this.connection._protocol.txnInProgress = true;
|
|
560
|
+
}
|
|
561
|
+
} else
|
|
562
|
+
errors.throwErr(errors.ERR_INTERNAL, 'Unexpected TransactionId sync ' +
|
|
563
|
+
'version in session sync piggyback.');
|
|
564
|
+
}
|
|
565
|
+
|
|
477
566
|
}
|
|
478
567
|
|
|
479
568
|
module.exports = Message;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2022,
|
|
1
|
+
// Copyright (c) 2022, 2025, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -394,6 +394,7 @@ const dataTypes = [
|
|
|
394
394
|
[constants.TNS_DATA_TYPE_TNP, constants.TNS_DATA_TYPE_TNP, constants.TNS_TYPE_REP_UNIVERSAL],
|
|
395
395
|
[constants.TNS_DATA_TYPE_OER, constants.TNS_DATA_TYPE_OER, constants.TNS_TYPE_REP_UNIVERSAL],
|
|
396
396
|
[constants.TNS_DATA_TYPE_OAC, constants.TNS_DATA_TYPE_OAC, constants.TNS_TYPE_REP_UNIVERSAL],
|
|
397
|
+
[constants.TNS_DATA_TYPE_SESSSIGN, constants.TNS_DATA_TYPE_SESSSIGN, constants.TNS_TYPE_REP_UNIVERSAL],
|
|
397
398
|
[constants.TNS_DATA_TYPE_VECTOR, constants.TNS_DATA_TYPE_VECTOR, constants.TNS_TYPE_REP_UNIVERSAL]
|
|
398
399
|
];
|
|
399
400
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2022,
|
|
1
|
+
// Copyright (c) 2022, 2025, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
const MessageWithData = require("./withData.js");
|
|
30
30
|
const constants = require("../constants.js");
|
|
31
31
|
const errors = require("../../../errors.js");
|
|
32
|
+
const TransactionSwitchMessage = require("./transactionSwitch.js");
|
|
32
33
|
|
|
33
34
|
/**
|
|
34
35
|
*
|
|
@@ -110,12 +111,18 @@ class ExecuteMessage extends MessageWithData {
|
|
|
110
111
|
options |= constants.TNS_EXEC_OPTION_BATCH_ERRORS;
|
|
111
112
|
}
|
|
112
113
|
if (this.arrayDmlRowCounts) {
|
|
113
|
-
dmlOptions
|
|
114
|
+
dmlOptions |= constants.TNS_EXEC_OPTION_DML_ROWCOUNTS;
|
|
114
115
|
}
|
|
115
116
|
if (this.options.autoCommit) {
|
|
116
117
|
options |= constants.TNS_EXEC_OPTION_COMMIT;
|
|
117
118
|
}
|
|
118
|
-
|
|
119
|
+
|
|
120
|
+
// In case SuspendOnSuccess is set for execute and a sessionless transaction
|
|
121
|
+
// is active we add a piggyback for post-call suspend
|
|
122
|
+
if (this.options.suspendOnSuccess) {
|
|
123
|
+
this._handleSuspendSessionless();
|
|
124
|
+
}
|
|
125
|
+
|
|
119
126
|
this.writeFunctionHeader(buf);
|
|
120
127
|
buf.writeUB4(options); // execute options
|
|
121
128
|
buf.writeUB4(stmt.cursorId); // cursor id
|
|
@@ -258,7 +265,13 @@ class ExecuteMessage extends MessageWithData {
|
|
|
258
265
|
}
|
|
259
266
|
numIters = this.numExecs;
|
|
260
267
|
}
|
|
261
|
-
|
|
268
|
+
|
|
269
|
+
// In case SuspendOnSuccess is set for execute and a sessionless transaction
|
|
270
|
+
// is active we add a piggyback for post-call suspend
|
|
271
|
+
if (this.options.suspendOnSuccess) {
|
|
272
|
+
this._handleSuspendSessionless();
|
|
273
|
+
}
|
|
274
|
+
|
|
262
275
|
this.writeFunctionHeader(buf);
|
|
263
276
|
buf.writeUB4(stmt.cursorId);
|
|
264
277
|
buf.writeUB4(numIters);
|
|
@@ -267,6 +280,35 @@ class ExecuteMessage extends MessageWithData {
|
|
|
267
280
|
return params;
|
|
268
281
|
}
|
|
269
282
|
|
|
283
|
+
//-------------------------------------------------------------------------
|
|
284
|
+
// _handleSuspendSessionless()
|
|
285
|
+
//
|
|
286
|
+
// Suspend the active sessionless transaction after DML execution if
|
|
287
|
+
// suspendOnSuccess option was given to execute()
|
|
288
|
+
//-------------------------------------------------------------------------
|
|
289
|
+
_handleSuspendSessionless() {
|
|
290
|
+
const sessionlessData = this.connection._sessionlessData;
|
|
291
|
+
// If sessionless transaction was started by server-call we cannot suspend
|
|
292
|
+
// using client API(RPC) calls
|
|
293
|
+
this.connection._validateSessionlessState();
|
|
294
|
+
|
|
295
|
+
if (!sessionlessData)
|
|
296
|
+
errors.throwErr(errors.ERR_SESSIONLESS_INACTIVE);
|
|
297
|
+
// If a piggybacks already exists it is most likely a start/resume for a
|
|
298
|
+
// sessionless transaction, add a post-call detach opcode to it
|
|
299
|
+
if (sessionlessData.piggyback) {
|
|
300
|
+
sessionlessData.piggyback.operation |=
|
|
301
|
+
constants.TNS_TPC_TXN_POST_DETACH;
|
|
302
|
+
} else {
|
|
303
|
+
const message = new TransactionSwitchMessage(this.connection);
|
|
304
|
+
message.operation = constants.TNS_TPC_TXN_POST_DETACH;
|
|
305
|
+
message.flags = constants.TNS_TPC_TRANS_SESSIONLESS;
|
|
306
|
+
message.messageType = constants.TNS_MSG_TYPE_PIGGYBACK;
|
|
307
|
+
sessionlessData.piggyback = message;
|
|
308
|
+
sessionlessData.pending = true;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
270
312
|
//-------------------------------------------------------------------------
|
|
271
313
|
// encode()
|
|
272
314
|
//
|
|
@@ -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
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2022,
|
|
1
|
+
// Copyright (c) 2022, 2025, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -45,10 +45,6 @@ class LobOpMessage extends Message {
|
|
|
45
45
|
*/
|
|
46
46
|
this.sourceLobImpl = options.sourceLobImpl || null;
|
|
47
47
|
this.operation = options.operation;
|
|
48
|
-
/*
|
|
49
|
-
* Destination LOB locator. For copy, append operations,...
|
|
50
|
-
*/
|
|
51
|
-
this.destLobImpl = options.destLobImpl || null;
|
|
52
48
|
/*
|
|
53
49
|
* Offset from where sourceLob operation to start
|
|
54
50
|
*/
|
|
@@ -64,6 +60,7 @@ class LobOpMessage extends Message {
|
|
|
64
60
|
this.functionCode = constants.TNS_FUNC_LOB_OP;
|
|
65
61
|
this.sendAmount = options.sendAmount;
|
|
66
62
|
this.amount = options.amount || 0; // LOB length
|
|
63
|
+
this.destLength = options.destLength || 0;
|
|
67
64
|
}
|
|
68
65
|
|
|
69
66
|
encode(buf) {
|
|
@@ -75,13 +72,8 @@ class LobOpMessage extends Message {
|
|
|
75
72
|
buf.writeUInt8(1);
|
|
76
73
|
buf.writeUB4(this.sourceLobImpl._locator.length);
|
|
77
74
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
buf.writeUB4(0);
|
|
81
|
-
} else {
|
|
82
|
-
buf.writeUInt8(1);
|
|
83
|
-
buf.writeUB4(this.destLobImpl._locator.length);
|
|
84
|
-
}
|
|
75
|
+
buf.writeUInt8(0);
|
|
76
|
+
buf.writeUB4(this.destLength);
|
|
85
77
|
buf.writeUB4(0);
|
|
86
78
|
buf.writeUB4(0);
|
|
87
79
|
if (this.operation === constants.TNS_LOB_OP_CREATE_TEMP) {
|
|
@@ -117,9 +109,6 @@ class LobOpMessage extends Message {
|
|
|
117
109
|
if (this.sourceLobImpl) {
|
|
118
110
|
buf.writeBytes(this.sourceLobImpl._locator);
|
|
119
111
|
}
|
|
120
|
-
if (this.destLobImpl) {
|
|
121
|
-
buf.writeBytes(this.destLobImpl._locator);
|
|
122
|
-
}
|
|
123
112
|
if (this.operation === constants.TNS_LOB_OP_CREATE_TEMP) {
|
|
124
113
|
if (this.sourceLobImpl.dbType._csfrm === constants.CSFRM_NCHAR) {
|
|
125
114
|
buf.caps.checkNCharsetId();
|
|
@@ -185,15 +174,9 @@ class LobOpMessage extends Message {
|
|
|
185
174
|
locator = lobArray.slice(0, numBytes);
|
|
186
175
|
locator.copy(this.sourceLobImpl._locator);
|
|
187
176
|
}
|
|
188
|
-
if (this.destLobImpl !== null) {
|
|
189
|
-
numBytes = this.destLobImpl._locator.length;
|
|
190
|
-
lobArray = buf.readBytes(numBytes);
|
|
191
|
-
locator = lobArray.slice(0, numBytes);
|
|
192
|
-
locator.copy(this.destLobImpl._locator);
|
|
193
|
-
}
|
|
194
177
|
if (this.operation === constants.TNS_LOB_OP_CREATE_TEMP) {
|
|
195
178
|
buf.skipUB2(); // skip character set
|
|
196
|
-
buf.
|
|
179
|
+
buf.skipUB1(); // skip trailing flags
|
|
197
180
|
} else if (this.sendAmount) {
|
|
198
181
|
this.amount = buf.readSB8();
|
|
199
182
|
}
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
|
|
29
29
|
const Message = require("./base.js");
|
|
30
30
|
const constants = require("../constants.js");
|
|
31
|
+
const errors = require("../../../errors.js");
|
|
31
32
|
|
|
32
33
|
/**
|
|
33
34
|
* Used for two-phase commit (TPC) transaction start, attach and detach.
|
|
@@ -61,18 +62,25 @@ class TransactionSwitchMessage extends Message {
|
|
|
61
62
|
}
|
|
62
63
|
|
|
63
64
|
encode(buf) {
|
|
65
|
+
// We unset the pending flag in writePiggybacks just before encode is
|
|
66
|
+
// called to ensure message is written
|
|
67
|
+
if (this.connection._sessionlessData?.pending)
|
|
68
|
+
errors.throwErr(errors.ERR_SESSIONLESS_ALREADY_ACTIVE);
|
|
69
|
+
|
|
64
70
|
// writes the message to the database
|
|
65
71
|
// acquire data to send to the server
|
|
66
72
|
let xidBytes;
|
|
67
73
|
if (this.xid) {
|
|
68
74
|
xidBytes = Buffer.alloc(128);
|
|
69
75
|
this.xid.globalTransactionId.copy(xidBytes);
|
|
70
|
-
this.xid.branchQualifier
|
|
71
|
-
this.xid.
|
|
76
|
+
if (this.xid.branchQualifier)
|
|
77
|
+
this.xid.branchQualifier.copy(xidBytes,
|
|
78
|
+
this.xid.globalTransactionId.length);
|
|
72
79
|
}
|
|
73
80
|
|
|
74
|
-
// write message
|
|
75
81
|
this.writeFunctionHeader(buf);
|
|
82
|
+
|
|
83
|
+
|
|
76
84
|
buf.writeUB4(this.operation);
|
|
77
85
|
if (this.context) {
|
|
78
86
|
buf.writeUInt8(1); // pointer (transaction context)
|
|
@@ -97,7 +105,7 @@ class TransactionSwitchMessage extends Message {
|
|
|
97
105
|
}
|
|
98
106
|
|
|
99
107
|
buf.writeUB4(this.flags);
|
|
100
|
-
buf.writeUB4(this.timeout);
|
|
108
|
+
buf.writeUB4(this.timeout ? this.timeout : 0);
|
|
101
109
|
buf.writeUInt8(1); // pointer (application value)
|
|
102
110
|
buf.writeUInt8(1); // pointer (return context)
|
|
103
111
|
buf.writeUInt8(1); // pointer (return context length)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2022,
|
|
1
|
+
// Copyright (c) 2022, 2025, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -280,6 +280,7 @@ class MessageWithData extends Message {
|
|
|
280
280
|
if (!(vectorFlags & constants.VECTOR_META_FLAG_FLEXIBLE_DIM)) {
|
|
281
281
|
fetchInfo.vectorDimensions = dimensions;
|
|
282
282
|
}
|
|
283
|
+
fetchInfo.isSparseVector = Boolean(vectorFlags & constants.VECTOR_META_FLAG_SPARSE);
|
|
283
284
|
if (vectorFormat !== constants.VECTOR_FORMAT_FLEX) {
|
|
284
285
|
fetchInfo.vectorFormat = vectorFormat;
|
|
285
286
|
}
|
|
@@ -501,6 +502,10 @@ class MessageWithData extends Message {
|
|
|
501
502
|
}
|
|
502
503
|
} else if (oraTypeNum === constants.TNS_DATA_TYPE_BOOLEAN) {
|
|
503
504
|
colValue = buf.readBool();
|
|
505
|
+
} else if (oraTypeNum === constants.TNS_DATA_TYPE_INTERVAL_YM) {
|
|
506
|
+
colValue = buf.readOracleIntervalYM();
|
|
507
|
+
} else if (oraTypeNum === constants.TNS_DATA_TYPE_INTERVAL_DS) {
|
|
508
|
+
colValue = buf.readOracleIntervalDS();
|
|
504
509
|
} else if (
|
|
505
510
|
oraTypeNum === constants.TNS_DATA_TYPE_CLOB ||
|
|
506
511
|
oraTypeNum === constants.TNS_DATA_TYPE_BLOB ||
|
|
@@ -861,6 +866,10 @@ class MessageWithData extends Message {
|
|
|
861
866
|
} else {
|
|
862
867
|
buf.writeUInt16BE(0x0100);
|
|
863
868
|
}
|
|
869
|
+
} else if (oraTypeNum === constants.TNS_DATA_TYPE_INTERVAL_YM) {
|
|
870
|
+
buf.writeOracleIntervalYM(value);
|
|
871
|
+
} else if (oraTypeNum === constants.TNS_DATA_TYPE_INTERVAL_DS) {
|
|
872
|
+
buf.writeOracleIntervalDS(value);
|
|
864
873
|
} else if (
|
|
865
874
|
oraTypeNum === constants.TNS_DATA_TYPE_CLOB ||
|
|
866
875
|
oraTypeNum === constants.TNS_DATA_TYPE_BLOB ||
|