oracledb 6.0.3 → 6.1.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 +2 -2
- package/build/Release/oracledb-6.1.0-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.1.0-darwin-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.1.0-js-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.1.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.1.0-linux-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.1.0-linux-x64.node +0 -0
- package/build/Release/oracledb-6.1.0-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.1.0-win32-x64.node +0 -0
- package/build/Release/oracledb-6.1.0-win32-x64.node-buildinfo.txt +1 -0
- package/examples/example.js +0 -1
- package/lib/aqQueue.js +40 -26
- package/lib/connection.js +15 -3
- package/lib/errors.js +10 -6
- package/lib/impl/connection.js +9 -0
- package/lib/impl/resultset.js +7 -4
- package/lib/oracledb.js +15 -12
- package/lib/pool.js +7 -1
- package/lib/sodaCollection.js +1 -1
- package/lib/thin/connection.js +92 -30
- package/lib/thin/pool.js +153 -68
- package/lib/thin/protocol/buffer.js +19 -1
- package/lib/thin/protocol/constants.js +3 -14
- package/lib/thin/protocol/encryptDecrypt.js +17 -17
- package/lib/thin/protocol/messages/auth.js +21 -23
- package/lib/thin/protocol/messages/base.js +22 -45
- package/lib/thin/protocol/messages/connectionCookie.js +76 -0
- package/lib/thin/protocol/messages/dataType.js +13 -9
- package/lib/thin/protocol/messages/execute.js +7 -7
- package/lib/thin/protocol/messages/index.js +2 -0
- package/lib/thin/protocol/messages/protocol.js +31 -20
- package/lib/thin/protocol/messages/withData.js +49 -43
- package/lib/thin/protocol/oson.js +4 -4
- package/lib/thin/protocol/packet.js +31 -10
- package/lib/thin/protocol/utils.js +2 -2
- package/lib/thin/resultSet.js +6 -6
- package/lib/thin/sqlnet/connStrategy.js +130 -5
- package/lib/thin/sqlnet/constants.js +2 -0
- package/lib/thin/sqlnet/ezConnectResolver.js +20 -19
- package/lib/thin/sqlnet/navNodes.js +32 -25
- package/lib/thin/sqlnet/networkSession.js +35 -30
- package/lib/thin/sqlnet/ntTcp.js +30 -14
- package/lib/thin/sqlnet/nvStrToNvPair.js +16 -16
- package/lib/thin/sqlnet/packet.js +9 -2
- package/lib/thin/sqlnet/paramParser.js +9 -9
- package/lib/thin/sqlnet/sessionAtts.js +4 -0
- package/lib/thin/statement.js +3 -3
- package/lib/thin/util.js +7 -8
- package/lib/transformer.js +3 -1
- package/lib/util.js +0 -13
- package/lib/version.js +2 -2
- package/package.json +1 -1
- package/build/Release/oracledb-6.0.3-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.0.3-darwin-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.3-js-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.3-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.0.3-linux-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.3-linux-x64.node +0 -0
- package/build/Release/oracledb-6.0.3-linux-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.3-win32-x64.node +0 -0
- package/build/Release/oracledb-6.0.3-win32-x64.node-buildinfo.txt +0 -1
|
@@ -30,37 +30,13 @@ const { Buffer } = require('buffer');
|
|
|
30
30
|
const constants = require("../constants.js");
|
|
31
31
|
const errors = require("../../../errors.js");
|
|
32
32
|
|
|
33
|
-
class OracleErrorInfo {
|
|
34
|
-
constructor() {
|
|
35
|
-
this.num = 0;
|
|
36
|
-
this.cursorId = 0;
|
|
37
|
-
this.pos = 0;
|
|
38
|
-
this.rowCount = 0;
|
|
39
|
-
this.message = "";
|
|
40
|
-
this.rowID = null;
|
|
41
|
-
this.batchErrors;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
class Error {
|
|
46
|
-
constructor(num, message = "", context = "", isRecoverable = false, isWarning = false, code = 0, offset = 0) {
|
|
47
|
-
this.num = num;
|
|
48
|
-
this.message = message;
|
|
49
|
-
this.context = context;
|
|
50
|
-
this.isRecoverable = isRecoverable;
|
|
51
|
-
this.isWarning = isWarning;
|
|
52
|
-
this.code = code;
|
|
53
|
-
this.offset = offset;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
33
|
/**
|
|
58
34
|
*
|
|
59
35
|
* Base class for all the RPC messages to support encode/decode functions
|
|
60
36
|
*/
|
|
61
37
|
class Message {
|
|
62
38
|
constructor(connection) {
|
|
63
|
-
this.errorInfo =
|
|
39
|
+
this.errorInfo = {};
|
|
64
40
|
this.connection = connection;
|
|
65
41
|
this.messageType = constants.TNS_MSG_TYPE_FUNCTION;
|
|
66
42
|
this.functionCode = 0;
|
|
@@ -106,7 +82,7 @@ class Message {
|
|
|
106
82
|
buf.skipUB1(); // call number
|
|
107
83
|
buf.skipUB2(); // padding
|
|
108
84
|
buf.skipUB4(); // success iters
|
|
109
|
-
|
|
85
|
+
const numBytes = buf.readUB4(); // oerrdd (logical rowid)
|
|
110
86
|
if (numBytes > 0) {
|
|
111
87
|
buf.skipBytesChunked();
|
|
112
88
|
}
|
|
@@ -114,12 +90,12 @@ class Message {
|
|
|
114
90
|
let numEntries = buf.readUB2(); // batch error codes array
|
|
115
91
|
if (numEntries > 0) {
|
|
116
92
|
this.errorInfo.batchErrors = [];
|
|
117
|
-
|
|
93
|
+
const firstByte = buf.readUInt8();
|
|
118
94
|
for (let i = 0; i < numEntries; i++) {
|
|
119
95
|
if (firstByte === constants.TNS_LONG_LENGTH_INDICATOR) {
|
|
120
96
|
buf.skipUB4(); // chunk length ignored
|
|
121
97
|
}
|
|
122
|
-
|
|
98
|
+
const errorCode = buf.readUB2();
|
|
123
99
|
this.errorInfo.batchErrors.push(new Error(errorCode));
|
|
124
100
|
}
|
|
125
101
|
if (firstByte === constants.TNS_LONG_LENGTH_INDICATOR) {
|
|
@@ -130,7 +106,7 @@ class Message {
|
|
|
130
106
|
// batch error offset
|
|
131
107
|
numEntries = buf.readUB2(); // batch error row offset array
|
|
132
108
|
if (numEntries > 0) {
|
|
133
|
-
|
|
109
|
+
const firstByte = buf.readUInt8();
|
|
134
110
|
for (let i = 0; i < numEntries; i++) {
|
|
135
111
|
if (firstByte === constants.TNS_LONG_LENGTH_INDICATOR) {
|
|
136
112
|
buf.skipUB4(); // chunk length ignored
|
|
@@ -172,7 +148,7 @@ class Message {
|
|
|
172
148
|
|
|
173
149
|
processWarningInfo(buf) {
|
|
174
150
|
this.errorInfo.num = buf.readUB2(); // error number
|
|
175
|
-
|
|
151
|
+
const numBytes = buf.readUB2(); // length of error message
|
|
176
152
|
buf.skipUB2(); // flags
|
|
177
153
|
if (this.errorInfo.num != 0 && numBytes > 0) {
|
|
178
154
|
this.errorInfo.message = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
@@ -224,18 +200,19 @@ class Message {
|
|
|
224
200
|
if (opcode === constants.TNS_SERVER_PIGGYBACK_LTXID) {
|
|
225
201
|
const num_bytes = buf.readUB4();
|
|
226
202
|
if (num_bytes > 0) {
|
|
227
|
-
buf.
|
|
203
|
+
buf.skipBytesChunked();
|
|
228
204
|
}
|
|
229
205
|
} else if ((opcode === constants.TNS_SERVER_PIGGYBACK_QUERY_CACHE_INVALIDATION)
|
|
230
206
|
|| (opcode === constants.TNS_SERVER_PIGGYBACK_TRACE_EVENT)) {
|
|
231
207
|
// pass
|
|
232
208
|
} else if (opcode === constants.TNS_SERVER_PIGGYBACK_OS_PID_MTS) {
|
|
233
|
-
buf.
|
|
234
|
-
buf.
|
|
209
|
+
const numDtys = buf.readUB2();
|
|
210
|
+
buf.skipUB1();
|
|
211
|
+
buf.skipBytes(numDtys);
|
|
235
212
|
} else if (opcode === constants.TNS_SERVER_PIGGYBACK_SYNC) {
|
|
236
213
|
buf.skipUB2(); // skip number of DTYs
|
|
237
214
|
buf.skipUB1(); // skip length of DTYs
|
|
238
|
-
const num_elements = buf.
|
|
215
|
+
const num_elements = buf.readUB4();
|
|
239
216
|
buf.skipBytes(1); // skip length
|
|
240
217
|
for (let i = 0; i < num_elements; i++) {
|
|
241
218
|
let temp16 = buf.readUB2();
|
|
@@ -247,20 +224,20 @@ class Message {
|
|
|
247
224
|
buf.skipBytesChunked();
|
|
248
225
|
}
|
|
249
226
|
buf.skipUB2(); // skip flags
|
|
250
|
-
buf.skipUB4(); // skip overall flags
|
|
251
227
|
}
|
|
228
|
+
buf.skipUB4(); // skip overall flags
|
|
252
229
|
} else if (opcode === constants.TNS_SERVER_PIGGYBACK_EXT_SYNC) {
|
|
253
230
|
buf.skipUB2();
|
|
254
231
|
buf.skipUB1();
|
|
255
232
|
} else if (opcode === constants.TNS_SERVER_PIGGYBACK_AC_REPLAY_CONTEXT) {
|
|
256
233
|
buf.skipUB2(); // skip number of DTYs
|
|
257
|
-
buf.skipUB1(
|
|
234
|
+
buf.skipUB1(); // skip length of DTYs
|
|
258
235
|
buf.skipUB4(); // skip flags
|
|
259
236
|
buf.skipUB4(); // skip error code
|
|
260
237
|
buf.skipUB1(); // skip queue
|
|
261
238
|
const num_bytes = buf.readUB4(); // skip replay context
|
|
262
239
|
if (num_bytes > 0) {
|
|
263
|
-
buf.
|
|
240
|
+
buf.skipBytesChunked();
|
|
264
241
|
}
|
|
265
242
|
} else if (opcode === constants.TNS_SERVER_PIGGYBACK_SESS_RET) {
|
|
266
243
|
buf.skipUB2();
|
|
@@ -283,7 +260,7 @@ class Message {
|
|
|
283
260
|
const flags = buf.readUB4(); // session flags
|
|
284
261
|
if (flags & constants.TNS_SESSGET_SESSION_CHANGED) {
|
|
285
262
|
if (this.connection._drcpEstablishSession) {
|
|
286
|
-
this.connection.
|
|
263
|
+
this.connection.resetStatementCache();
|
|
287
264
|
}
|
|
288
265
|
}
|
|
289
266
|
this.connection._drcpEstablishSession = false;
|
|
@@ -335,8 +312,8 @@ class Message {
|
|
|
335
312
|
}
|
|
336
313
|
|
|
337
314
|
writeCloseTempLobsPiggyback(buf) {
|
|
338
|
-
|
|
339
|
-
|
|
315
|
+
const lobsToClose = this.connection._tempLobsToClose;
|
|
316
|
+
const opCode = constants.TNS_LOB_OP_FREE_TEMP | constants.TNS_LOB_OP_ARRAY;
|
|
340
317
|
|
|
341
318
|
this.writePiggybackHeader(buf, constants.TNS_FUNC_LOB_OP);
|
|
342
319
|
|
|
@@ -406,9 +383,9 @@ class Message {
|
|
|
406
383
|
buf.writeUInt8(0); // pointer (cidser)
|
|
407
384
|
buf.writeUB4(flags);
|
|
408
385
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
386
|
+
const clientIdentifierBytes = this.writeEndEndTraceValue(buf, this.connection._clientIdentifier, this.connection._clientIdentifierModified);
|
|
387
|
+
const moduleBytes = this.writeEndEndTraceValue(buf, this.connection._module, this.connection._moduleModified);
|
|
388
|
+
const actionBytes = this.writeEndEndTraceValue(buf, this.connection._action, this.connection._actionModified);
|
|
412
389
|
|
|
413
390
|
// write unsupported bits
|
|
414
391
|
buf.writeUInt8(0); // pointer (cideci)
|
|
@@ -416,13 +393,13 @@ class Message {
|
|
|
416
393
|
buf.writeUInt8(0); // cidcct
|
|
417
394
|
buf.writeUB4(0); // cidecs
|
|
418
395
|
|
|
419
|
-
|
|
396
|
+
const clientInfoBytes = this.writeEndEndTraceValue(buf, this.connection._clientInfo, this.connection._clientInfoModified);
|
|
420
397
|
// write unsupported bits
|
|
421
398
|
buf.writeUInt8(0); // pointer (cideci)
|
|
422
399
|
buf.writeUB4(0); // length (cideci)
|
|
423
400
|
buf.writeUInt8(0); // cidcct
|
|
424
401
|
buf.writeUB4(0); // cidecs
|
|
425
|
-
|
|
402
|
+
const dbOpBytes = this.writeEndEndTraceValue(buf, this.connection._dbOp, this.connection._dbOpModified);
|
|
426
403
|
|
|
427
404
|
// write strings
|
|
428
405
|
if (this.connection._clientIdentifierModified && this.connection._clientIdentifier) {
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// Copyright (c) 2023 Oracle and/or its affiliates.
|
|
2
|
+
|
|
3
|
+
//-----------------------------------------------------------------------------
|
|
4
|
+
//
|
|
5
|
+
// This software is dual-licensed to you under the Universal Permissive License
|
|
6
|
+
// (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
|
7
|
+
// 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
|
8
|
+
// either license.
|
|
9
|
+
//
|
|
10
|
+
// If you elect to accept the software under the Apache License, Version 2.0,
|
|
11
|
+
// the following applies:
|
|
12
|
+
//
|
|
13
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
14
|
+
// you may not use this file except in compliance with the License.
|
|
15
|
+
// You may obtain a copy of the License at
|
|
16
|
+
//
|
|
17
|
+
// https://www.apache.org/licenses/LICENSE-2.0
|
|
18
|
+
//
|
|
19
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
20
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
21
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
22
|
+
// See the License for the specific language governing permissions and
|
|
23
|
+
// limitations under the License.
|
|
24
|
+
//
|
|
25
|
+
//-----------------------------------------------------------------------------
|
|
26
|
+
|
|
27
|
+
'use strict';
|
|
28
|
+
|
|
29
|
+
const constants = require("../constants.js");
|
|
30
|
+
const Message = require("./base.js");
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Executes a Fast Negotiation RPC function.
|
|
34
|
+
* It sends Protocol Negotiation, Cookie Message, Datatype Negotiation
|
|
35
|
+
* and OSESS Key RPC in single round trip.
|
|
36
|
+
*
|
|
37
|
+
* @class ConnectionCookieMessage
|
|
38
|
+
* @extends {Message}
|
|
39
|
+
*/
|
|
40
|
+
class ConnectionCookieMessage extends Message {
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Serializes the ConnectionCookieMessage function arguments
|
|
44
|
+
*
|
|
45
|
+
* @param {object} buf input arguments
|
|
46
|
+
*/
|
|
47
|
+
encode(buf) {
|
|
48
|
+
this.protocolMessage.encode(buf);
|
|
49
|
+
buf.writeUInt8(constants.TNS_MSG_TYPE_COOKIE);
|
|
50
|
+
buf.writeUInt8(1); // cookie version
|
|
51
|
+
buf.writeUInt8(this.cookie.protocolVersion);
|
|
52
|
+
buf.writeUInt16LE(this.cookie.charsetID);
|
|
53
|
+
buf.writeUInt8(this.cookie.flags);
|
|
54
|
+
buf.writeUInt16LE(this.cookie.ncharsetID);
|
|
55
|
+
buf.writeBytesWithLength(this.cookie.serverBanner);
|
|
56
|
+
buf.writeBytesWithLength(this.cookie.compileCaps);
|
|
57
|
+
buf.writeBytesWithLength(this.cookie.runtimeCaps);
|
|
58
|
+
this.dataTypeMessage.encode(buf);
|
|
59
|
+
this.authMessage.encode(buf);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
processMessage(buf, messageType) {
|
|
63
|
+
if (messageType === constants.TNS_MSG_TYPE_RENEGOTIATE) {
|
|
64
|
+
this.cookie.populated = false;
|
|
65
|
+
} else if (messageType === constants.TNS_MSG_TYPE_PROTOCOL) {
|
|
66
|
+
this.protocolMessage.processMessage(buf, messageType);
|
|
67
|
+
} else if (messageType === constants.TNS_MSG_TYPE_DATA_TYPES) {
|
|
68
|
+
this.dataTypeMessage.processMessage(buf, messageType);
|
|
69
|
+
} else {
|
|
70
|
+
this.authMessage.processMessage(buf, messageType);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
module.exports = ConnectionCookieMessage;
|
|
@@ -38,14 +38,18 @@ const Message = require("./base.js");
|
|
|
38
38
|
*/
|
|
39
39
|
class DataTypeMessage extends Message {
|
|
40
40
|
|
|
41
|
-
processMessage(buf) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
41
|
+
processMessage(buf, messageType) {
|
|
42
|
+
if (messageType === constants.TNS_MSG_TYPE_DATA_TYPES) {
|
|
43
|
+
while (true) { // eslint-disable-line
|
|
44
|
+
const dataType = buf.readUInt16BE();
|
|
45
|
+
if (dataType === 0)
|
|
46
|
+
break;
|
|
47
|
+
const convDataType = buf.readUInt16BE();
|
|
48
|
+
if (convDataType !== 0)
|
|
49
|
+
buf.skipBytes(4);
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
super.processMessage(buf, messageType);
|
|
49
53
|
}
|
|
50
54
|
}
|
|
51
55
|
|
|
@@ -57,7 +61,7 @@ class DataTypeMessage extends Message {
|
|
|
57
61
|
constants.TNS_ENCODING_CONV_LENGTH);
|
|
58
62
|
buf.writeBytesWithLength(buf.caps.compileCaps);
|
|
59
63
|
buf.writeBytesWithLength(buf.caps.runtimeCaps);
|
|
60
|
-
for (
|
|
64
|
+
for (const val of dataTypes) {
|
|
61
65
|
buf.writeUInt16BE(val[0]);
|
|
62
66
|
buf.writeUInt16BE(val[1]);
|
|
63
67
|
buf.writeUInt16BE(val[2]);
|
|
@@ -65,8 +65,8 @@ class ExecuteMessage extends MessageWithData {
|
|
|
65
65
|
let numParams = 0;
|
|
66
66
|
let numIters = 1;
|
|
67
67
|
// Configuring the options field thats send to the server
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
const stmt = this.statement;
|
|
69
|
+
const params = stmt.bindInfoList;
|
|
70
70
|
|
|
71
71
|
if (!stmt.requiresDefine && !this.parseOnly && params) {
|
|
72
72
|
numParams = params.length;
|
|
@@ -223,7 +223,7 @@ class ExecuteMessage extends MessageWithData {
|
|
|
223
223
|
// Write the message header for a re-execute and return the bind parameters.
|
|
224
224
|
//-------------------------------------------------------------------------
|
|
225
225
|
writeReExecuteMessage(buf) {
|
|
226
|
-
|
|
226
|
+
const stmt = this.statement;
|
|
227
227
|
let params = stmt.bindInfoList;
|
|
228
228
|
let execFlag1 = 0, execFlag2 = 0, numIters;
|
|
229
229
|
if (params !== undefined) {
|
|
@@ -236,7 +236,7 @@ class ExecuteMessage extends MessageWithData {
|
|
|
236
236
|
});
|
|
237
237
|
}
|
|
238
238
|
|
|
239
|
-
|
|
239
|
+
const tmpparams = [];
|
|
240
240
|
params.forEach(info => {
|
|
241
241
|
if (info.bindDir !== constants.TNS_BIND_DIR_OUTPUT && !info.isReturnBind) {
|
|
242
242
|
tmpparams.push(info);
|
|
@@ -274,9 +274,9 @@ class ExecuteMessage extends MessageWithData {
|
|
|
274
274
|
|
|
275
275
|
// no rows have yet been sent so the header information needs to be sent
|
|
276
276
|
if (this.currentRow === 0) {
|
|
277
|
-
|
|
278
|
-
if (stmt.cursorId !== 0 && !stmt.requiresFullExecute && !this.parseOnly && !stmt.requiresDefine && !stmt.isDdl && !this.batchErrors) {
|
|
279
|
-
if (stmt.isQuery &&
|
|
277
|
+
const stmt = this.statement;
|
|
278
|
+
if (stmt.cursorId !== 0 && !stmt.requiresFullExecute && !this.parseOnly && !stmt.requiresDefine && !stmt.noPrefetch && !stmt.isDdl && !this.batchErrors) {
|
|
279
|
+
if (stmt.isQuery && this.options.prefetchRows > 0) {
|
|
280
280
|
this.functionCode = constants.TNS_FUNC_REEXECUTE_AND_FETCH;
|
|
281
281
|
} else {
|
|
282
282
|
this.functionCode = constants.TNS_FUNC_REEXECUTE;
|
|
@@ -37,10 +37,12 @@ const PingMessage = require('./ping.js');
|
|
|
37
37
|
const ProtocolMessage = require('./protocol.js');
|
|
38
38
|
const RollbackMessage = require('./rollback.js');
|
|
39
39
|
const SessionReleaseMessage = require('./sessionRelease.js');
|
|
40
|
+
const ConnectionCookieMessage = require('./connectionCookie.js');
|
|
40
41
|
|
|
41
42
|
module.exports = {
|
|
42
43
|
AuthMessage,
|
|
43
44
|
CommitMessage,
|
|
45
|
+
ConnectionCookieMessage,
|
|
44
46
|
DataTypeMessage,
|
|
45
47
|
ExecuteMessage,
|
|
46
48
|
FetchMessage,
|
|
@@ -50,26 +50,37 @@ class ProtocolMessage extends Message {
|
|
|
50
50
|
buf.writeUInt8(0);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
53
|
+
processMessage(buf, messageType) {
|
|
54
|
+
if (messageType === constants.TNS_MSG_TYPE_PROTOCOL) {
|
|
55
|
+
this.processProtocolInfo(buf);
|
|
56
|
+
} else {
|
|
57
|
+
super.processMessage(buf, messageType);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
processProtocolInfo(buf) {
|
|
62
|
+
this.serverVersion = buf.readUInt8();
|
|
63
|
+
buf.skipUB1();
|
|
64
|
+
this.serverBanner = buf.readNullTerminatedBytes(48);
|
|
65
|
+
buf.caps.charSetID = buf.readUInt16LE();
|
|
66
|
+
this.serverFlags = buf.readUInt8();
|
|
67
|
+
const num_elem = buf.readUInt16LE();
|
|
68
|
+
if (num_elem > 0) { // skip elements
|
|
69
|
+
buf.skipBytes(num_elem * 5);
|
|
70
|
+
}
|
|
71
|
+
const fdoLen = buf.readUInt16BE();
|
|
72
|
+
const fdo = buf.readBytes(fdoLen);
|
|
73
|
+
const ix = 6 + fdo[5] + fdo[6];
|
|
74
|
+
buf.caps.nCharsetId = (fdo[ix + 3] << 8) + fdo[ix + 4];
|
|
75
|
+
const serverCompileCaps = buf.readBytesWithLength();
|
|
76
|
+
if (serverCompileCaps) {
|
|
77
|
+
this.serverCompileCaps = Buffer.from(serverCompileCaps);
|
|
78
|
+
buf.caps.adjustForServerCompileCaps(this.serverCompileCaps);
|
|
79
|
+
}
|
|
80
|
+
const serverRunTimeCaps = buf.readBytesWithLength();
|
|
81
|
+
if (serverRunTimeCaps) {
|
|
82
|
+
this.serverRunTimeCaps = Buffer.from(serverRunTimeCaps);
|
|
83
|
+
buf.caps.adjustForServerRuntimeCaps(this.serverRunTimeCaps);
|
|
73
84
|
}
|
|
74
85
|
}
|
|
75
86
|
|
|
@@ -65,11 +65,12 @@ class MessageWithData extends Message {
|
|
|
65
65
|
processMessage(buf, messageType) {
|
|
66
66
|
if (messageType === constants.TNS_MSG_TYPE_DESCRIBE_INFO) {
|
|
67
67
|
buf.skipBytesChunked();
|
|
68
|
+
const prevQueryVars = this.statement.queryVars;
|
|
68
69
|
this.statement.queryVars = [];
|
|
69
70
|
this.statement.numQueryVars = 0;
|
|
70
71
|
this.statement.bufferRowCount = 0;
|
|
71
72
|
this.statement.bufferRowIndex = 0;
|
|
72
|
-
this.processDescribeInfo(buf, this.resultSet);
|
|
73
|
+
this.processDescribeInfo(buf, this.resultSet, prevQueryVars);
|
|
73
74
|
this.outVariables = this.statement.queryVars;
|
|
74
75
|
} else if (messageType === constants.TNS_MSG_TYPE_ROW_HEADER) {
|
|
75
76
|
this.processRowHeader(buf);
|
|
@@ -123,7 +124,22 @@ class MessageWithData extends Message {
|
|
|
123
124
|
}
|
|
124
125
|
}
|
|
125
126
|
|
|
126
|
-
|
|
127
|
+
//---------------------------------------------------------------------------
|
|
128
|
+
// If we have fetched this column earlier, we set that
|
|
129
|
+
// fetch type for the describe info variable received
|
|
130
|
+
// assuming the returned column order is same as previous.
|
|
131
|
+
//---------------------------------------------------------------------------
|
|
132
|
+
_adjustFetchType(pVar, cVar) {
|
|
133
|
+
if ((cVar.fetchInfo.dbType._oraTypeNum === constants.TNS_DATA_TYPE_CLOB
|
|
134
|
+
&& pVar.fetchInfo.fetchType._oraTypeNum === constants.TNS_DATA_TYPE_LONG)
|
|
135
|
+
|| (cVar.fetchInfo.dbType._oraTypeNum === constants.TNS_DATA_TYPE_BLOB
|
|
136
|
+
&& pVar.fetchInfo.fetchType._oraTypeNum === constants.TNS_DATA_TYPE_LONG_RAW)) {
|
|
137
|
+
cVar.type = pVar.fetchInfo.fetchType;
|
|
138
|
+
cVar.maxSize = pVar.maxSize;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
processDescribeInfo(buf, resultSet, prevQueryVars) {
|
|
127
143
|
const statement = resultSet.statement;
|
|
128
144
|
buf.skipUB4(); // max row size
|
|
129
145
|
statement.numQueryVars = buf.readUB4();
|
|
@@ -133,6 +149,9 @@ class MessageWithData extends Message {
|
|
|
133
149
|
resultSet.metadata = [];
|
|
134
150
|
for (let i = 0; i < statement.numQueryVars; i++) {
|
|
135
151
|
const variable = this.processColumnInfo(buf, i + 1);
|
|
152
|
+
if (prevQueryVars && i < prevQueryVars.length) {
|
|
153
|
+
this._adjustFetchType(prevQueryVars[i], variable);
|
|
154
|
+
}
|
|
136
155
|
statement.queryVars.push(variable);
|
|
137
156
|
resultSet.metadata.push(variable.fetchInfo);
|
|
138
157
|
}
|
|
@@ -257,8 +276,7 @@ class MessageWithData extends Message {
|
|
|
257
276
|
buf.skipUB2(); // buffer length
|
|
258
277
|
let numBytes = buf.readUB4();
|
|
259
278
|
if (numBytes > 0) {
|
|
260
|
-
buf.
|
|
261
|
-
this.getBitVector(buf, numBytes);
|
|
279
|
+
this.bitVector = Buffer.from(buf.readBytesWithLength());
|
|
262
280
|
}
|
|
263
281
|
numBytes = buf.readUB4();
|
|
264
282
|
if (numBytes > 0) {
|
|
@@ -267,28 +285,28 @@ class MessageWithData extends Message {
|
|
|
267
285
|
}
|
|
268
286
|
|
|
269
287
|
isDuplicateData(columnName) {
|
|
270
|
-
if (this.bitVector
|
|
288
|
+
if (!this.bitVector) {
|
|
271
289
|
return false;
|
|
272
290
|
}
|
|
273
|
-
|
|
274
|
-
|
|
291
|
+
const byteNum = Math.floor(columnName / 8);
|
|
292
|
+
const bitNum = columnName % 8;
|
|
275
293
|
return (this.bitVector[byteNum] & (1 << bitNum)) === 0;
|
|
276
294
|
}
|
|
277
295
|
|
|
278
296
|
processRowData(buf) {
|
|
279
297
|
let value;
|
|
280
|
-
for (
|
|
298
|
+
for (const [col, variable] of this.outVariables.entries()) {
|
|
281
299
|
if (variable.isArray) {
|
|
282
300
|
variable.numElementsInArray = buf.readUB4();
|
|
283
|
-
|
|
301
|
+
const values = new Array(variable.numElementsInArray).fill(null);
|
|
284
302
|
for (let pos = 0; pos < variable.numElementsInArray; pos++) {
|
|
285
303
|
value = this.processColumnData(buf, variable, pos);
|
|
286
304
|
values[pos] = value;
|
|
287
305
|
}
|
|
288
306
|
variable.values[this.rowIndex] = values;
|
|
289
307
|
} else if (this.statement.isReturning) {
|
|
290
|
-
|
|
291
|
-
|
|
308
|
+
const numRows = buf.readUB4();
|
|
309
|
+
const values = Array(numRows).fill(null);
|
|
292
310
|
for (let j = 0; j < numRows; j++) {
|
|
293
311
|
values[j] = this.processColumnData(buf, variable, j);
|
|
294
312
|
}
|
|
@@ -331,7 +349,7 @@ class MessageWithData extends Message {
|
|
|
331
349
|
}
|
|
332
350
|
this.outVariables = [];
|
|
333
351
|
for (let i = 0; i < numBinds; i++) { // bind directions
|
|
334
|
-
|
|
352
|
+
const bindInfo = this.statement.bindInfoList[i];
|
|
335
353
|
bindInfo.bindDir = buf.readUInt8();
|
|
336
354
|
if (bindInfo.bindDir === constants.TNS_BIND_DIR_INPUT) {
|
|
337
355
|
continue;
|
|
@@ -383,11 +401,11 @@ class MessageWithData extends Message {
|
|
|
383
401
|
if (!this.inFetch) {
|
|
384
402
|
colValue = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
385
403
|
} else {
|
|
386
|
-
|
|
404
|
+
const numBytes = buf.readUInt8();
|
|
387
405
|
if (isNullLength(numBytes)) {
|
|
388
406
|
colValue = null;
|
|
389
407
|
} else {
|
|
390
|
-
|
|
408
|
+
const rowid = buf.readRowID();
|
|
391
409
|
colValue = utils.encodeRowID(rowid);
|
|
392
410
|
}
|
|
393
411
|
}
|
|
@@ -406,7 +424,7 @@ class MessageWithData extends Message {
|
|
|
406
424
|
if (colValue !== null)
|
|
407
425
|
colValue = parseFloat(colValue);
|
|
408
426
|
} else if (oraTypeNum === constants.TNS_DATA_TYPE_CURSOR) {
|
|
409
|
-
|
|
427
|
+
const numBytes = buf.readUInt8();
|
|
410
428
|
if (isNullLength(numBytes)) {
|
|
411
429
|
colValue = null;
|
|
412
430
|
} else {
|
|
@@ -425,7 +443,7 @@ class MessageWithData extends Message {
|
|
|
425
443
|
} else if (oraTypeNum === constants.TNS_DATA_TYPE_BOOLEAN) {
|
|
426
444
|
colValue = buf.readBool();
|
|
427
445
|
} else if (oraTypeNum === constants.TNS_DATA_TYPE_CLOB || oraTypeNum === constants.TNS_DATA_TYPE_BLOB) {
|
|
428
|
-
|
|
446
|
+
const bvalue = buf.readUB4();
|
|
429
447
|
if (bvalue > 0) { // Non Null data in column
|
|
430
448
|
colValue = new ThinLobImpl();
|
|
431
449
|
const length = buf.readUB8();
|
|
@@ -497,25 +515,15 @@ class MessageWithData extends Message {
|
|
|
497
515
|
buf.skip(numBytes);
|
|
498
516
|
}
|
|
499
517
|
if (this.arrayDmlRowCounts) {
|
|
500
|
-
|
|
501
|
-
|
|
518
|
+
const numRows = buf.readUB4();
|
|
519
|
+
const rowCounts = this.options.dmlRowCounts = [];
|
|
502
520
|
for (let i = 0; i < numRows; i++) {
|
|
503
|
-
|
|
521
|
+
const rowCount = buf.readUB8();
|
|
504
522
|
rowCounts.push(rowCount);
|
|
505
523
|
}
|
|
506
524
|
}
|
|
507
525
|
}
|
|
508
526
|
|
|
509
|
-
process(buf) {
|
|
510
|
-
this.bitVector = this.savedBitVector;
|
|
511
|
-
super.process(buf);
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
savePoint(buf) {
|
|
515
|
-
this.savedBitVector = this.bitVector;
|
|
516
|
-
super.savePoint(buf);
|
|
517
|
-
}
|
|
518
|
-
|
|
519
527
|
async postProcess() {
|
|
520
528
|
if (this.outVariables) {
|
|
521
529
|
for (const variable of this.outVariables) {
|
|
@@ -546,8 +554,10 @@ class MessageWithData extends Message {
|
|
|
546
554
|
variable.type = variable.fetchInfo.fetchType;
|
|
547
555
|
variable.maxSize = constants.TNS_MAX_LONG_LENGTH;
|
|
548
556
|
}
|
|
549
|
-
resultSet.statement.
|
|
550
|
-
|
|
557
|
+
if (!resultSet.statement.noPrefetch) {
|
|
558
|
+
resultSet.statement.requiresDefine = true;
|
|
559
|
+
resultSet.statement.noPrefetch = true;
|
|
560
|
+
}
|
|
551
561
|
}
|
|
552
562
|
}
|
|
553
563
|
}
|
|
@@ -580,10 +590,6 @@ class MessageWithData extends Message {
|
|
|
580
590
|
if (this.statement.numQueryVars % 8 > 0) {
|
|
581
591
|
numBytes += 1;
|
|
582
592
|
}
|
|
583
|
-
this.getBitVector(buf, numBytes);
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
getBitVector(buf, numBytes) {
|
|
587
593
|
this.bitVector = Buffer.from(buf.readBytes(numBytes));
|
|
588
594
|
}
|
|
589
595
|
|
|
@@ -651,15 +657,15 @@ class MessageWithData extends Message {
|
|
|
651
657
|
const objType = variable.objType;
|
|
652
658
|
buf.writeUB4(objType.oid.length);
|
|
653
659
|
buf.writeBytesWithLength(objType.oid);
|
|
654
|
-
buf.
|
|
660
|
+
buf.writeUB2(objType.version);
|
|
655
661
|
} else {
|
|
656
662
|
buf.writeUB4(0); // OID
|
|
657
|
-
buf.
|
|
663
|
+
buf.writeUB2(0); // version
|
|
658
664
|
}
|
|
659
665
|
if (variable.type._csfrm !== 0) {
|
|
660
|
-
buf.
|
|
666
|
+
buf.writeUB2(constants.TNS_CHARSET_UTF8);
|
|
661
667
|
} else {
|
|
662
|
-
buf.
|
|
668
|
+
buf.writeUB2(0);
|
|
663
669
|
}
|
|
664
670
|
buf.writeUInt8(variable.type._csfrm);
|
|
665
671
|
buf.writeUB4(lobPrefetchLength); // max chars (LOB prefetch)
|
|
@@ -670,14 +676,14 @@ class MessageWithData extends Message {
|
|
|
670
676
|
}
|
|
671
677
|
|
|
672
678
|
writeBindParamsRow(buf, params, pos) {
|
|
673
|
-
|
|
679
|
+
const offset = this.offset;
|
|
674
680
|
let foundLong = false;
|
|
675
681
|
for (const bindInfo of params) {
|
|
676
682
|
if (bindInfo.isReturnBind)
|
|
677
683
|
continue;
|
|
678
|
-
|
|
684
|
+
const variable = bindInfo.bindVar;
|
|
679
685
|
if (variable.isArray) {
|
|
680
|
-
|
|
686
|
+
const numElements = variable.values.length;
|
|
681
687
|
buf.writeUB4(numElements);
|
|
682
688
|
for (let i = 0; i < numElements; i++) {
|
|
683
689
|
this.writeBindParamsColumn(buf, variable, variable.values[i]);
|
|
@@ -800,7 +806,7 @@ class MessageWithData extends Message {
|
|
|
800
806
|
for (let i = 0; i < numResults; i++) {
|
|
801
807
|
const numBytes = buf.readUInt8();
|
|
802
808
|
buf.skipBytes(numBytes);
|
|
803
|
-
|
|
809
|
+
const childResultSet = this.createCursorFromDescribe(buf);
|
|
804
810
|
childResultSet.statement.cursorId = buf.readUB2();
|
|
805
811
|
this.options.implicitResultSet.push(childResultSet);
|
|
806
812
|
}
|
|
@@ -352,7 +352,7 @@ class OsonFieldNamesSegment extends GrowableBuffer {
|
|
|
352
352
|
//---------------------------------------------------------------------------
|
|
353
353
|
_examineNode(value) {
|
|
354
354
|
if (Array.isArray(value)) {
|
|
355
|
-
for (
|
|
355
|
+
for (const element of value) {
|
|
356
356
|
this._examineNode(element);
|
|
357
357
|
}
|
|
358
358
|
} else if (value && Array.isArray(value.fields)) {
|
|
@@ -418,7 +418,7 @@ class OsonTreeSegment extends GrowableBuffer {
|
|
|
418
418
|
this._encodeContainer(constants.TNS_JSON_TYPE_ARRAY, value.length);
|
|
419
419
|
let offsetsBufPos = 0;
|
|
420
420
|
const offsetsBuf = this.reserveBytes(value.length * 4);
|
|
421
|
-
for (
|
|
421
|
+
for (const element of value) {
|
|
422
422
|
offsetsBuf.writeUInt32BE(this.pos, offsetsBufPos);
|
|
423
423
|
offsetsBufPos += 4;
|
|
424
424
|
this.encodeNode(element, fnamesSeg);
|
|
@@ -627,12 +627,12 @@ class OsonEncoder extends GrowableBuffer {
|
|
|
627
627
|
this.writeUInt16BE(0);
|
|
628
628
|
|
|
629
629
|
// write array of hash ids
|
|
630
|
-
for (
|
|
630
|
+
for (const fieldName of fnamesSeg.fieldNames) {
|
|
631
631
|
this.writeUInt8(fieldName.hashId);
|
|
632
632
|
}
|
|
633
633
|
|
|
634
634
|
// write array of field name offsets
|
|
635
|
-
for (
|
|
635
|
+
for (const fieldName of fnamesSeg.fieldNames) {
|
|
636
636
|
if (fnamesSeg.pos < 65536) {
|
|
637
637
|
this.writeUInt16BE(fieldName.offset);
|
|
638
638
|
} else {
|