oracledb 6.8.0 → 6.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -3
- package/build/Release/oracledb-6.10.0-darwin-arm64.node +0 -0
- package/build/Release/oracledb-6.10.0-darwin-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.10.0-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.10.0-darwin-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.10.0-js-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.10.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.10.0-linux-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.10.0-linux-x64.node +0 -0
- package/build/Release/oracledb-6.10.0-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.10.0-win32-x64.node +0 -0
- package/build/Release/oracledb-6.10.0-win32-x64.node-buildinfo.txt +1 -0
- package/lib/aqDeqOptions.js +18 -1
- package/lib/aqMessage.js +10 -1
- package/lib/aqQueue.js +10 -6
- package/lib/configProviders/file.js +72 -0
- package/lib/connection.js +93 -4
- package/lib/dbObject.js +34 -4
- package/lib/errors.js +70 -35
- package/lib/impl/aqDeqOptions.js +10 -1
- package/lib/impl/connection.js +9 -0
- package/lib/impl/datahandlers/buffer.js +49 -0
- package/lib/impl/datahandlers/oson.js +7 -2
- package/lib/impl/pool.js +10 -1
- package/lib/impl/resultset.js +5 -4
- package/lib/impl/sodaDocument.js +5 -14
- package/lib/lob.js +9 -1
- package/lib/oracledb.js +152 -30
- package/lib/pool.js +199 -147
- package/lib/poolStatistics.js +4 -2
- package/lib/sodaCollection.js +12 -8
- package/lib/sodaDatabase.js +35 -8
- package/lib/sodaDocument.js +24 -6
- package/lib/sodaOperation.js +7 -6
- package/lib/thin/aq.js +475 -0
- package/lib/thin/connection.js +171 -14
- package/lib/thin/dbObject.js +8 -6
- package/lib/thin/lob.js +2 -3
- package/lib/thin/pool.js +105 -28
- package/lib/thin/protocol/capabilities.js +10 -4
- package/lib/thin/protocol/constants.js +90 -1
- package/lib/thin/protocol/encryptDecrypt.js +2 -2
- package/lib/thin/protocol/messages/aqArray.js +238 -0
- package/lib/thin/protocol/messages/aqBase.js +305 -0
- package/lib/thin/protocol/messages/aqDeq.js +164 -0
- package/lib/thin/protocol/messages/aqEnq.js +135 -0
- package/lib/thin/protocol/messages/auth.js +25 -27
- 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/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 +3 -3
- package/lib/thin/protocol/packet.js +6 -5
- package/lib/thin/protocol/protocol.js +2 -1
- package/lib/thin/sqlnet/connStrategy.js +2 -1
- package/lib/thin/sqlnet/navNodes.js +1 -1
- package/lib/thin/sqlnet/networkSession.js +10 -4
- package/lib/thin/sqlnet/packet.js +2 -1
- package/lib/thin/sqlnet/sessionAtts.js +2 -3
- package/lib/types.js +6 -11
- package/lib/util.js +72 -11
- package/lib/version.js +1 -1
- 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} +73 -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/extensionOci/index.js +71 -35
- package/build/Release/oracledb-6.8.0-darwin-arm64.node +0 -0
- package/build/Release/oracledb-6.8.0-darwin-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.8.0-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.8.0-darwin-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.8.0-js-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.8.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.8.0-linux-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.8.0-linux-x64.node +0 -0
- package/build/Release/oracledb-6.8.0-linux-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.8.0-win32-x64.node +0 -0
- package/build/Release/oracledb-6.8.0-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
|
//
|
|
@@ -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) 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)
|
|
@@ -156,7 +156,6 @@ class MessageWithData extends Message {
|
|
|
156
156
|
if (statement.numQueryVars > 0) {
|
|
157
157
|
buf.skipUB1();
|
|
158
158
|
}
|
|
159
|
-
resultSet.metadata = [];
|
|
160
159
|
const metadata = [];
|
|
161
160
|
const queryVars = [];
|
|
162
161
|
for (let i = 0; i < statement.numQueryVars; i++) {
|
|
@@ -185,7 +184,7 @@ class MessageWithData extends Message {
|
|
|
185
184
|
* at end of the DescribeInfo function so that an OutOfPacketsError
|
|
186
185
|
* won't cause partial information state to be stored.
|
|
187
186
|
*/
|
|
188
|
-
resultSet.
|
|
187
|
+
resultSet.metaData = metadata;
|
|
189
188
|
statement.queryVars = queryVars;
|
|
190
189
|
this.resultSetsToSetup.push(resultSet);
|
|
191
190
|
}
|
|
@@ -236,6 +235,7 @@ class MessageWithData extends Message {
|
|
|
236
235
|
// build metadata
|
|
237
236
|
const fetchInfo = {
|
|
238
237
|
name: name,
|
|
238
|
+
dbColumnName: name,
|
|
239
239
|
dbType: types.getTypeByOraTypeNum(dataType, csfrm),
|
|
240
240
|
nullable: nullable
|
|
241
241
|
};
|
|
@@ -628,7 +628,7 @@ class MessageWithData extends Message {
|
|
|
628
628
|
}
|
|
629
629
|
await this.connection._populatePartialDbObjectTypes();
|
|
630
630
|
for (const resultSet of this.resultSetsToSetup) {
|
|
631
|
-
resultSet._setup(this.options, resultSet.
|
|
631
|
+
resultSet._setup(this.options, resultSet.metaData);
|
|
632
632
|
// LOBs always require define and they change the type that is actually
|
|
633
633
|
// returned by the server
|
|
634
634
|
for (const variable of resultSet.statement.queryVars) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2022,
|
|
1
|
+
// Copyright (c) 2022, 2025, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -576,10 +576,10 @@ class WritePacket extends BaseBuffer {
|
|
|
576
576
|
* Encodes a JavaScript object into OSON and then writes it (QLocator
|
|
577
577
|
* followed by data) to the buffer.
|
|
578
578
|
*/
|
|
579
|
-
writeOson(value, osonMaxFieldSize) {
|
|
579
|
+
writeOson(value, osonMaxFieldSize, writeLength = true) {
|
|
580
580
|
const encoder = new oson.OsonEncoder();
|
|
581
581
|
const buf = encoder.encode(value, osonMaxFieldSize);
|
|
582
|
-
this.writeQLocator(buf.length);
|
|
582
|
+
this.writeQLocator(buf.length, writeLength);
|
|
583
583
|
this.writeBytesWithLength(buf);
|
|
584
584
|
}
|
|
585
585
|
|
|
@@ -604,9 +604,10 @@ class WritePacket extends BaseBuffer {
|
|
|
604
604
|
//
|
|
605
605
|
// Writes a QLocator. QLocators are always 40 bytes in length.
|
|
606
606
|
//---------------------------------------------------------------------------
|
|
607
|
-
writeQLocator(numBytes) {
|
|
607
|
+
writeQLocator(numBytes, writeLength = true) {
|
|
608
608
|
this.writeUB4(40); // QLocator length
|
|
609
|
-
|
|
609
|
+
if (writeLength)
|
|
610
|
+
this.writeUInt8(40); // repeated length
|
|
610
611
|
this.writeUInt16BE(38); // internal length
|
|
611
612
|
this.writeUInt16BE(constants.TNS_LOB_QLOCATOR_VERSION);
|
|
612
613
|
this.writeUInt8(constants.TNS_LOB_LOC_FLAGS_VALUE_BASED |
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2022,
|
|
1
|
+
// Copyright (c) 2022, 2025, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -204,6 +204,7 @@ class Protocol {
|
|
|
204
204
|
let err = new Error(message.errorInfo.message);
|
|
205
205
|
err.offset = message.errorInfo.pos;
|
|
206
206
|
err.errorNum = message.errorInfo.num;
|
|
207
|
+
err.isRecoverable = message.errorInfo.isRecoverable;
|
|
207
208
|
err = errors.transformErr(err);
|
|
208
209
|
if (err.code === errors.ERR_CONNECTION_CLOSED_CODE) {
|
|
209
210
|
this.nsi.disconnect();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2022,
|
|
1
|
+
// Copyright (c) 2022, 2025, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -194,6 +194,7 @@ async function createNode(str, userConfig) {
|
|
|
194
194
|
cs.terminal = userConfig.terminal;
|
|
195
195
|
cs.osUser = userConfig.osUser;
|
|
196
196
|
cs.program = userConfig.program;
|
|
197
|
+
cs.httpsProxy = userConfig.httpsProxy;
|
|
197
198
|
await navobj.navigate(cs);
|
|
198
199
|
return cs;
|
|
199
200
|
}
|
|
@@ -500,7 +500,7 @@ class NavAddress extends Address {
|
|
|
500
500
|
cs.newConnectionDescription();
|
|
501
501
|
needToCloseDescription = true;
|
|
502
502
|
}
|
|
503
|
-
if (!net.isIP(this.host)) {
|
|
503
|
+
if (!net.isIP(this.host) && !(cs.httpsProxy || this.httpsProxy)) {
|
|
504
504
|
try {
|
|
505
505
|
addresses = await dnsPromises.lookup(this.host, options);
|
|
506
506
|
for (const addr of addresses) {
|
|
@@ -298,7 +298,6 @@ class NetworkSession {
|
|
|
298
298
|
|
|
299
299
|
/* Accepted */
|
|
300
300
|
|
|
301
|
-
this.connected = true;
|
|
302
301
|
this.cData = null;
|
|
303
302
|
this.sndDatapkt = new Packet.DataPacket(this.sAtts.largeSDU);
|
|
304
303
|
this.markerPkt = new Packet.MarkerPacket(this.sAtts.largeSDU);
|
|
@@ -319,6 +318,7 @@ class NetworkSession {
|
|
|
319
318
|
this.sndDatapkt.createPacket(constants.NSPDADAT); //Currently only used for disconnect
|
|
320
319
|
this.sndDatapkt.offset = this.sndDatapkt.dataPtr;
|
|
321
320
|
this.sndDatapkt.len = this.sndDatapkt.bufLen;
|
|
321
|
+
this.connected = true;
|
|
322
322
|
return (true);
|
|
323
323
|
}
|
|
324
324
|
|
|
@@ -374,9 +374,9 @@ class NetworkSession {
|
|
|
374
374
|
const buffertoDeCompress = packet.buf.subarray(constants.NSPDADAT, size);
|
|
375
375
|
let deCompressedDataBuffer;
|
|
376
376
|
try {
|
|
377
|
-
if (this.sAtts.
|
|
377
|
+
if (this.sAtts.firstRecvCompressedPacket) {
|
|
378
378
|
deCompressedDataBuffer = zlib.inflateSync(buffertoDeCompress, {finishFlush: zlib.constants.Z_SYNC_FLUSH});
|
|
379
|
-
this.sAtts.
|
|
379
|
+
this.sAtts.firstRecvCompressedPacket = 0;
|
|
380
380
|
} else {
|
|
381
381
|
deCompressedDataBuffer = zlib.inflateRawSync(buffertoDeCompress, {finishFlush: zlib.constants.Z_SYNC_FLUSH});
|
|
382
382
|
}
|
|
@@ -457,7 +457,13 @@ class NetworkSession {
|
|
|
457
457
|
const bufferHeader = buf.subarray(0, constants.NSPDADAT);
|
|
458
458
|
let compressedDataBuffer;
|
|
459
459
|
try {
|
|
460
|
-
|
|
460
|
+
if (this.sAtts.firstSendCompressedPacket) {
|
|
461
|
+
compressedDataBuffer = zlib.deflateSync(buffertoCompress, {finishFlush: zlib.
|
|
462
|
+
constants.Z_SYNC_FLUSH});
|
|
463
|
+
this.sAtts.firstSendCompressedPacket = 0;
|
|
464
|
+
} else {
|
|
465
|
+
compressedDataBuffer = zlib.deflateRawSync(buffertoCompress, {finishFlush: zlib.constants.Z_SYNC_FLUSH});
|
|
466
|
+
}
|
|
461
467
|
} catch (err) {
|
|
462
468
|
errors.throwErr(errors.ERR_DATA_COMPRESSION, err.message);
|
|
463
469
|
}
|
|
@@ -258,7 +258,8 @@ function AcceptPacket(packet, sAtts) {
|
|
|
258
258
|
if ((this.cflag & constants.NSPACCFON) != 0) { // compression ON
|
|
259
259
|
sAtts.negotiatedNetworkCompressionScheme = (this.cflag & 0x3c) >> 2; // 0x3c
|
|
260
260
|
sAtts.networkCompressionEnabled = true;
|
|
261
|
-
sAtts.
|
|
261
|
+
sAtts.firstRecvCompressedPacket = true;
|
|
262
|
+
sAtts.firstSendCompressedPacket = true;
|
|
262
263
|
} else {
|
|
263
264
|
sAtts.networkCompressionEnabled = false;
|
|
264
265
|
}
|
|
@@ -62,6 +62,7 @@ class SessionAtts {
|
|
|
62
62
|
this.nt.sslServerDNMatch = true;
|
|
63
63
|
this.nt.sslAllowWeakDNMatch = false;
|
|
64
64
|
this.nt.useSNI = false;
|
|
65
|
+
this.networkCompressionThreshold = 1024;
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
/**
|
|
@@ -85,9 +86,7 @@ class SessionAtts {
|
|
|
85
86
|
}
|
|
86
87
|
if (params.networkCompressionThreshold >= 200) {
|
|
87
88
|
this.networkCompressionThreshold = parseInt(params.networkCompressionThreshold);
|
|
88
|
-
}
|
|
89
|
-
this.networkCompressionThreshold = 1024;
|
|
90
|
-
|
|
89
|
+
}
|
|
91
90
|
|
|
92
91
|
if (typeof params.walletLocation === 'string') {
|
|
93
92
|
this.nt.walletFile = path.join(params.walletLocation, constants.PEM_WALLET_FILE_NAME);
|
package/lib/types.js
CHANGED
|
@@ -46,7 +46,7 @@ class DbType {
|
|
|
46
46
|
this._oraTypeNum = options.oraTypeNum || 0;
|
|
47
47
|
this._csfrm = options.csfrm || 0;
|
|
48
48
|
dbTypeByNum.set(num, this);
|
|
49
|
-
const key =
|
|
49
|
+
const key = this._csfrm * 256 + this._oraTypeNum;
|
|
50
50
|
dbTypeByOraTypeNum.set(key, this);
|
|
51
51
|
dbTypeByColumnTypeName.set(columnTypeName, this);
|
|
52
52
|
}
|
|
@@ -322,14 +322,9 @@ const DB_TYPE_FETCH_TYPE_MAP = new Map([
|
|
|
322
322
|
]);
|
|
323
323
|
|
|
324
324
|
// additional aliases for types by column type name
|
|
325
|
-
dbTypeByColumnTypeName.set("DOUBLE PRECISION", DB_TYPE_NUMBER);
|
|
326
|
-
dbTypeByColumnTypeName.set("FLOAT", DB_TYPE_NUMBER);
|
|
327
|
-
dbTypeByColumnTypeName.set("INTEGER", DB_TYPE_NUMBER);
|
|
328
325
|
dbTypeByColumnTypeName.set("PL/SQL BOOLEAN", DB_TYPE_BOOLEAN);
|
|
329
326
|
dbTypeByColumnTypeName.set("PL/SQL BINARY INTEGER", DB_TYPE_BINARY_INTEGER);
|
|
330
327
|
dbTypeByColumnTypeName.set("PL/SQL PLS INTEGER", DB_TYPE_BINARY_INTEGER);
|
|
331
|
-
dbTypeByColumnTypeName.set("REAL", DB_TYPE_NUMBER);
|
|
332
|
-
dbTypeByColumnTypeName.set("SMALLINT", DB_TYPE_NUMBER);
|
|
333
328
|
dbTypeByColumnTypeName.set("TIMESTAMP WITH LOCAL TZ", DB_TYPE_TIMESTAMP_LTZ);
|
|
334
329
|
dbTypeByColumnTypeName.set("TIMESTAMP WITH TZ", DB_TYPE_TIMESTAMP_TZ);
|
|
335
330
|
|
|
@@ -530,8 +525,8 @@ class IntervalYM {
|
|
|
530
525
|
errors.assertParamPropInt(obj, 1, "years");
|
|
531
526
|
errors.assertParamPropInt(obj, 1, "months");
|
|
532
527
|
}
|
|
533
|
-
this.years = obj?.years || 0;
|
|
534
528
|
this.months = obj?.months || 0;
|
|
529
|
+
this.years = obj?.years || 0;
|
|
535
530
|
}
|
|
536
531
|
}
|
|
537
532
|
|
|
@@ -545,11 +540,11 @@ class IntervalDS {
|
|
|
545
540
|
errors.assertParamPropInt(obj, 1, "seconds");
|
|
546
541
|
errors.assertParamPropInt(obj, 1, "fseconds");
|
|
547
542
|
}
|
|
548
|
-
this.days = obj?.days || 0;
|
|
549
|
-
this.hours = obj?.hours || 0;
|
|
550
|
-
this.minutes = obj?.minutes || 0;
|
|
551
|
-
this.seconds = obj?.seconds || 0;
|
|
552
543
|
this.fseconds = obj?.fseconds || 0;
|
|
544
|
+
this.seconds = obj?.seconds || 0;
|
|
545
|
+
this.minutes = obj?.minutes || 0;
|
|
546
|
+
this.hours = obj?.hours || 0;
|
|
547
|
+
this.days = obj?.days || 0;
|
|
553
548
|
}
|
|
554
549
|
}
|
|
555
550
|
|