oracledb 6.0.2 → 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 +15 -17
- package/SECURITY.md +1 -1
- 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 +15 -10
- package/lib/impl/connection.js +9 -0
- package/lib/impl/resultset.js +7 -4
- package/lib/oracledb.js +15 -12
- package/lib/pool.js +11 -2
- package/lib/settings.js +1 -1
- package/lib/sodaCollection.js +1 -1
- package/lib/thin/connection.js +92 -30
- package/lib/thin/dbObject.js +2 -2
- package/lib/thin/lob.js +2 -2
- package/lib/thin/pool.js +153 -71
- package/lib/thin/protocol/buffer.js +24 -6
- package/lib/thin/protocol/constants.js +8 -18
- package/lib/thin/protocol/encryptDecrypt.js +17 -17
- package/lib/thin/protocol/messages/auth.js +27 -31
- package/lib/thin/protocol/messages/base.js +30 -53
- 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 +11 -11
- package/lib/thin/protocol/messages/index.js +2 -0
- package/lib/thin/protocol/messages/lobOp.js +3 -3
- package/lib/thin/protocol/messages/protocol.js +31 -20
- package/lib/thin/protocol/messages/withData.js +60 -53
- package/lib/thin/protocol/oson.js +4 -4
- package/lib/thin/protocol/packet.js +51 -28
- package/lib/thin/protocol/protocol.js +12 -7
- package/lib/thin/protocol/utils.js +2 -2
- package/lib/thin/resultSet.js +6 -6
- package/lib/thin/sqlnet/connStrategy.js +134 -7
- package/lib/thin/sqlnet/constants.js +2 -0
- package/lib/thin/sqlnet/ezConnectResolver.js +29 -24
- package/lib/thin/sqlnet/navNodes.js +35 -28
- package/lib/thin/sqlnet/networkSession.js +45 -40
- package/lib/thin/sqlnet/ntTcp.js +70 -35
- package/lib/thin/sqlnet/nvStrToNvPair.js +16 -16
- package/lib/thin/sqlnet/packet.js +17 -10
- package/lib/thin/sqlnet/paramParser.js +9 -9
- package/lib/thin/sqlnet/sessionAtts.js +4 -0
- package/lib/thin/statement.js +4 -3
- package/lib/thin/util.js +28 -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.2-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.0.2-darwin-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.2-js-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.2-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.0.2-linux-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.2-linux-x64.node +0 -0
- package/build/Release/oracledb-6.0.2-linux-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.2-win32-x64.node +0 -0
- package/build/Release/oracledb-6.0.2-win32-x64.node-buildinfo.txt +0 -1
|
@@ -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;
|
|
@@ -77,21 +77,21 @@ class ExecuteMessage extends MessageWithData {
|
|
|
77
77
|
dmlOptions = constants.TNS_EXEC_OPTION_IMPLICIT_RESULTSET;
|
|
78
78
|
options |= constants.TNS_EXEC_OPTION_EXECUTE;
|
|
79
79
|
}
|
|
80
|
-
if (stmt.cursorId
|
|
80
|
+
if (stmt.cursorId === 0 || stmt.isDdl) {
|
|
81
81
|
options |= constants.TNS_EXEC_OPTION_PARSE;
|
|
82
82
|
}
|
|
83
83
|
if (stmt.isQuery) {
|
|
84
84
|
if (this.parseOnly) {
|
|
85
85
|
options |= constants.TNS_EXEC_OPTION_DESCRIBE;
|
|
86
86
|
} else {
|
|
87
|
-
if (this.options.prefetchRows > 0) {
|
|
88
|
-
options |= constants.TNS_EXEC_OPTION_FETCH;
|
|
89
|
-
}
|
|
90
87
|
if (stmt.cursorId === 0 || stmt.requiresDefine) {
|
|
91
88
|
numIters = this.options.prefetchRows;
|
|
92
89
|
} else {
|
|
93
90
|
numIters = this.options.fetchArraySize;
|
|
94
91
|
}
|
|
92
|
+
if (numIters > 0 && !stmt.noPrefetch) {
|
|
93
|
+
options |= constants.TNS_EXEC_OPTION_FETCH;
|
|
94
|
+
}
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
if (!stmt.isPlSql && !this.parseOnly) {
|
|
@@ -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,
|
|
@@ -116,7 +116,7 @@ class LobOpMessage extends Message {
|
|
|
116
116
|
buf.writeBytes(this.destLobImpl._locator);
|
|
117
117
|
}
|
|
118
118
|
if (this.operation === constants.TNS_LOB_OP_CREATE_TEMP) {
|
|
119
|
-
if (this.sourceLobImpl.dbType._csfrm === constants.
|
|
119
|
+
if (this.sourceLobImpl.dbType._csfrm === constants.CSFRM_NCHAR) {
|
|
120
120
|
buf.caps.checkNCharsetId();
|
|
121
121
|
buf.writeUB4(constants.TNS_CHARSET_UTF16);
|
|
122
122
|
} else {
|
|
@@ -128,7 +128,7 @@ class LobOpMessage extends Message {
|
|
|
128
128
|
buf.writeUInt8(constants.TNS_MSG_TYPE_LOB_DATA);
|
|
129
129
|
if (this.sourceLobImpl.dbType._oraTypeNum === constants.TNS_DATA_TYPE_BLOB) {
|
|
130
130
|
data = this.data;
|
|
131
|
-
} else if (this.sourceLobImpl.getCsfrm() === constants.
|
|
131
|
+
} else if (this.sourceLobImpl.getCsfrm() === constants.CSFRM_NCHAR) {
|
|
132
132
|
data = this.data;
|
|
133
133
|
// TODO: avoid conversion back to string, if possible
|
|
134
134
|
// this is since bind data is converted to buffer automatically, but if
|
|
@@ -154,7 +154,7 @@ class LobOpMessage extends Message {
|
|
|
154
154
|
if (data !== null) {
|
|
155
155
|
if (oraTypeNum === constants.TNS_DATA_TYPE_BLOB) {
|
|
156
156
|
data = Buffer.from(data);
|
|
157
|
-
} else if (this.sourceLobImpl.getCsfrm() === constants.
|
|
157
|
+
} else if (this.sourceLobImpl.getCsfrm() === constants.CSFRM_NCHAR) {
|
|
158
158
|
data = Buffer.from(data).swap16().toString('utf16le');
|
|
159
159
|
} else {
|
|
160
160
|
data = data.toString();
|
|
@@ -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,13 +149,16 @@ 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
|
}
|
|
139
158
|
|
|
140
159
|
let numBytes = buf.readUB4();
|
|
141
160
|
if (numBytes > 0) {
|
|
142
|
-
buf.
|
|
161
|
+
buf.skipBytesChunked(); // current date
|
|
143
162
|
}
|
|
144
163
|
buf.skipUB4(); // dcbflag
|
|
145
164
|
buf.skipUB4(); // dcbmdbz
|
|
@@ -147,7 +166,7 @@ class MessageWithData extends Message {
|
|
|
147
166
|
buf.skipUB4(); // dcbmxpr
|
|
148
167
|
numBytes = buf.readUB4();
|
|
149
168
|
if (numBytes > 0) {
|
|
150
|
-
buf.
|
|
169
|
+
buf.skipBytesChunked();
|
|
151
170
|
}
|
|
152
171
|
|
|
153
172
|
this.resultSetsToSetup.push(resultSet);
|
|
@@ -190,17 +209,17 @@ class MessageWithData extends Message {
|
|
|
190
209
|
let name;
|
|
191
210
|
numBytes = buf.readUB4();
|
|
192
211
|
if (numBytes > 0) {
|
|
193
|
-
name = buf.readStr(constants.
|
|
212
|
+
name = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
194
213
|
}
|
|
195
214
|
let schema;
|
|
196
215
|
numBytes = buf.readUB4();
|
|
197
216
|
if (numBytes > 0) {
|
|
198
|
-
schema = buf.readStr(constants.
|
|
217
|
+
schema = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
199
218
|
}
|
|
200
219
|
numBytes = buf.readUB4();
|
|
201
220
|
let typeName;
|
|
202
221
|
if (numBytes > 0) {
|
|
203
|
-
typeName = buf.readStr(constants.
|
|
222
|
+
typeName = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
204
223
|
}
|
|
205
224
|
buf.skipUB2(); // column position
|
|
206
225
|
buf.skipUB4(); // uds flag
|
|
@@ -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;
|
|
@@ -356,7 +374,7 @@ class MessageWithData extends Message {
|
|
|
356
374
|
oraTypeNum === constants.TNS_DATA_TYPE_CHAR ||
|
|
357
375
|
oraTypeNum === constants.TNS_DATA_TYPE_LONG
|
|
358
376
|
) {
|
|
359
|
-
if (csfrm === constants.
|
|
377
|
+
if (csfrm === constants.CSFRM_NCHAR) {
|
|
360
378
|
buf.caps.checkNCharsetId();
|
|
361
379
|
}
|
|
362
380
|
colValue = buf.readStr(csfrm);
|
|
@@ -381,19 +399,19 @@ class MessageWithData extends Message {
|
|
|
381
399
|
colValue = buf.readOracleDate(useLocalTime);
|
|
382
400
|
} else if (oraTypeNum === constants.TNS_DATA_TYPE_ROWID) {
|
|
383
401
|
if (!this.inFetch) {
|
|
384
|
-
colValue = buf.readStr(constants.
|
|
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
|
}
|
|
394
412
|
} else if (oraTypeNum === constants.TNS_DATA_TYPE_UROWID) {
|
|
395
413
|
if (!this.inFetch) {
|
|
396
|
-
colValue = buf.readStr(constants.
|
|
414
|
+
colValue = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
397
415
|
} else {
|
|
398
416
|
colValue = buf.readURowID();
|
|
399
417
|
}
|
|
@@ -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();
|
|
@@ -479,7 +497,7 @@ class MessageWithData extends Message {
|
|
|
479
497
|
for (let i = 0; i < numParams; i++) {
|
|
480
498
|
numBytes = buf.readUB2(); // key
|
|
481
499
|
if (numBytes > 0) {
|
|
482
|
-
keyTextValue = buf.readStr(constants.
|
|
500
|
+
keyTextValue = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
483
501
|
}
|
|
484
502
|
numBytes = buf.readUB2(); // value
|
|
485
503
|
if (numBytes > 0) {
|
|
@@ -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,7 +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.
|
|
557
|
+
if (!resultSet.statement.noPrefetch) {
|
|
558
|
+
resultSet.statement.requiresDefine = true;
|
|
559
|
+
resultSet.statement.noPrefetch = true;
|
|
560
|
+
}
|
|
550
561
|
}
|
|
551
562
|
}
|
|
552
563
|
}
|
|
@@ -579,10 +590,6 @@ class MessageWithData extends Message {
|
|
|
579
590
|
if (this.statement.numQueryVars % 8 > 0) {
|
|
580
591
|
numBytes += 1;
|
|
581
592
|
}
|
|
582
|
-
this.getBitVector(buf, numBytes);
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
getBitVector(buf, numBytes) {
|
|
586
593
|
this.bitVector = Buffer.from(buf.readBytes(numBytes));
|
|
587
594
|
}
|
|
588
595
|
|
|
@@ -608,7 +615,7 @@ class MessageWithData extends Message {
|
|
|
608
615
|
// NCHAR, NVARCHAR reports ORA-01460: unimplemented or unreasonable
|
|
609
616
|
// conversion requested if maxSize is not multiplied by the
|
|
610
617
|
// bufferSizeFactor
|
|
611
|
-
if (variable.type._csfrm === constants.
|
|
618
|
+
if (variable.type._csfrm === constants.CSFRM_NCHAR) {
|
|
612
619
|
maxSize *= variable.type._bufferSizeFactor;
|
|
613
620
|
}
|
|
614
621
|
if ([constants.TNS_DATA_TYPE_ROWID, constants.TNS_DATA_TYPE_UROWID].includes(oraTypeNum)) {
|
|
@@ -650,15 +657,15 @@ class MessageWithData extends Message {
|
|
|
650
657
|
const objType = variable.objType;
|
|
651
658
|
buf.writeUB4(objType.oid.length);
|
|
652
659
|
buf.writeBytesWithLength(objType.oid);
|
|
653
|
-
buf.
|
|
660
|
+
buf.writeUB2(objType.version);
|
|
654
661
|
} else {
|
|
655
662
|
buf.writeUB4(0); // OID
|
|
656
|
-
buf.
|
|
663
|
+
buf.writeUB2(0); // version
|
|
657
664
|
}
|
|
658
665
|
if (variable.type._csfrm !== 0) {
|
|
659
|
-
buf.
|
|
666
|
+
buf.writeUB2(constants.TNS_CHARSET_UTF8);
|
|
660
667
|
} else {
|
|
661
|
-
buf.
|
|
668
|
+
buf.writeUB2(0);
|
|
662
669
|
}
|
|
663
670
|
buf.writeUInt8(variable.type._csfrm);
|
|
664
671
|
buf.writeUB4(lobPrefetchLength); // max chars (LOB prefetch)
|
|
@@ -669,14 +676,14 @@ class MessageWithData extends Message {
|
|
|
669
676
|
}
|
|
670
677
|
|
|
671
678
|
writeBindParamsRow(buf, params, pos) {
|
|
672
|
-
|
|
679
|
+
const offset = this.offset;
|
|
673
680
|
let foundLong = false;
|
|
674
681
|
for (const bindInfo of params) {
|
|
675
682
|
if (bindInfo.isReturnBind)
|
|
676
683
|
continue;
|
|
677
|
-
|
|
684
|
+
const variable = bindInfo.bindVar;
|
|
678
685
|
if (variable.isArray) {
|
|
679
|
-
|
|
686
|
+
const numElements = variable.values.length;
|
|
680
687
|
buf.writeUB4(numElements);
|
|
681
688
|
for (let i = 0; i < numElements; i++) {
|
|
682
689
|
this.writeBindParamsColumn(buf, variable, variable.values[i]);
|
|
@@ -732,7 +739,7 @@ class MessageWithData extends Message {
|
|
|
732
739
|
oraTypeNum === constants.TNS_DATA_TYPE_LONG ||
|
|
733
740
|
oraTypeNum === constants.TNS_DATA_TYPE_RAW ||
|
|
734
741
|
oraTypeNum === constants.TNS_DATA_TYPE_LONG_RAW) {
|
|
735
|
-
if (variable.type._csfrm === constants.
|
|
742
|
+
if (variable.type._csfrm === constants.CSFRM_NCHAR) {
|
|
736
743
|
buf.caps.checkNCharsetId();
|
|
737
744
|
value = Buffer.from(value, constants.TNS_ENCODING_UTF16).swap16();
|
|
738
745
|
} else {
|
|
@@ -799,7 +806,7 @@ class MessageWithData extends Message {
|
|
|
799
806
|
for (let i = 0; i < numResults; i++) {
|
|
800
807
|
const numBytes = buf.readUInt8();
|
|
801
808
|
buf.skipBytes(numBytes);
|
|
802
|
-
|
|
809
|
+
const childResultSet = this.createCursorFromDescribe(buf);
|
|
803
810
|
childResultSet.statement.cursorId = buf.readUB2();
|
|
804
811
|
this.options.implicitResultSet.push(childResultSet);
|
|
805
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 {
|
|
@@ -31,6 +31,7 @@ const { Buffer } = require('buffer');
|
|
|
31
31
|
const constants = require("./constants.js");
|
|
32
32
|
const oson = require('./oson.js');
|
|
33
33
|
const utils = require('./utils.js');
|
|
34
|
+
const errors = require("../../errors.js");
|
|
34
35
|
|
|
35
36
|
const TNS_BASE64_ALPHABET_ARRAY = Buffer.from("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", 'utf8');
|
|
36
37
|
|
|
@@ -254,46 +255,48 @@ class ReadPacket extends BaseBuffer {
|
|
|
254
255
|
* Receives a packet from the adapter.
|
|
255
256
|
*/
|
|
256
257
|
receivePacket() {
|
|
257
|
-
if (this.
|
|
258
|
+
if (this.savedPacketPos === this.savedPackets.length) {
|
|
258
259
|
const packet = this.nsi.syncRecvPacket();
|
|
259
|
-
if (!packet)
|
|
260
|
+
if (!packet || this.nsi.isBreak)
|
|
260
261
|
throw new utils.OutOfPacketsError();
|
|
261
|
-
this.
|
|
262
|
+
this.savedPackets.push(packet);
|
|
262
263
|
}
|
|
263
|
-
this.startPacket(this.
|
|
264
|
+
this.startPacket(this.savedPackets[this.savedPacketPos++]);
|
|
264
265
|
}
|
|
265
266
|
|
|
266
267
|
restorePoint() {
|
|
267
|
-
this.
|
|
268
|
-
this.startPacket(this.
|
|
268
|
+
this.savedPacketPos = 0;
|
|
269
|
+
this.startPacket(this.savedPackets[this.savedPacketPos++]);
|
|
269
270
|
this.pos = this.savedPos;
|
|
270
271
|
}
|
|
271
272
|
|
|
272
273
|
savePoint() {
|
|
273
|
-
if (this.
|
|
274
|
-
this.
|
|
274
|
+
if (this.savedPackets) {
|
|
275
|
+
this.savedPackets = this.savedPackets.splice(this.savedPacketPos - 1);
|
|
275
276
|
} else {
|
|
276
|
-
this.
|
|
277
|
+
this.savedPackets = [this.packet];
|
|
277
278
|
}
|
|
278
|
-
this.
|
|
279
|
+
this.savedPacketPos = 1;
|
|
279
280
|
this.savedPos = this.pos;
|
|
280
281
|
}
|
|
281
282
|
|
|
282
|
-
startPacket(
|
|
283
|
-
this.
|
|
283
|
+
startPacket(packet) {
|
|
284
|
+
this.packet = packet;
|
|
285
|
+
this.buf = packet.buf;
|
|
284
286
|
this.pos = 10; // skip packet heaader and data flags
|
|
285
|
-
this.size = buf.length;
|
|
287
|
+
this.size = packet.buf.length;
|
|
288
|
+
this.packetNum = packet.num;
|
|
286
289
|
}
|
|
287
290
|
|
|
288
291
|
async waitForPackets() {
|
|
289
292
|
const packet = await this.nsi.recvPacket();
|
|
290
|
-
if (!this.
|
|
291
|
-
this.
|
|
292
|
-
this.
|
|
293
|
+
if (!this.savedPackets) {
|
|
294
|
+
this.savedPackets = [packet];
|
|
295
|
+
this.savedPacketPos = 0;
|
|
293
296
|
} else {
|
|
294
|
-
this.
|
|
297
|
+
this.savedPackets.push(packet);
|
|
295
298
|
}
|
|
296
|
-
this.startPacket(this.
|
|
299
|
+
this.startPacket(this.savedPackets[this.savedPacketPos++]);
|
|
297
300
|
}
|
|
298
301
|
|
|
299
302
|
/**
|
|
@@ -322,23 +325,23 @@ class ReadPacket extends BaseBuffer {
|
|
|
322
325
|
|
|
323
326
|
// Handle physical rowid
|
|
324
327
|
if (buf && buf[0] === 1) {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
328
|
+
const rba = buf.readUInt32BE(1);
|
|
329
|
+
const partitionID = buf.readUInt16BE(5);
|
|
330
|
+
const blockNum = buf.readUInt32BE(7);
|
|
331
|
+
const slotNum = buf.readUInt16BE(11);
|
|
329
332
|
return utils.encodeRowID({rba, partitionID, blockNum, slotNum});
|
|
330
333
|
}
|
|
331
334
|
|
|
332
335
|
// handle logical rowid
|
|
333
336
|
let outputLen = Math.floor(inputLen / 3) * 4;
|
|
334
|
-
|
|
337
|
+
const remainder = inputLen % 3;
|
|
335
338
|
if (remainder === 1) {
|
|
336
339
|
outputLen += 1;
|
|
337
340
|
} else if (remainder === 2) {
|
|
338
341
|
outputLen += 3;
|
|
339
342
|
}
|
|
340
343
|
|
|
341
|
-
|
|
344
|
+
const outputValue = Buffer.alloc(outputLen);
|
|
342
345
|
inputLen -= 1;
|
|
343
346
|
outputValue[0] = 42;
|
|
344
347
|
outputOffset += 1;
|
|
@@ -383,16 +386,19 @@ class ReadPacket extends BaseBuffer {
|
|
|
383
386
|
}
|
|
384
387
|
|
|
385
388
|
readRowID() {
|
|
386
|
-
|
|
387
|
-
|
|
389
|
+
const rba = this.readUB4();
|
|
390
|
+
const partitionID = this.readUB2();
|
|
388
391
|
this.skipUB1();
|
|
389
|
-
|
|
390
|
-
|
|
392
|
+
const blockNum = this.readUB4();
|
|
393
|
+
const slotNum = this.readUB2();
|
|
391
394
|
return {rba, partitionID, blockNum, slotNum};
|
|
392
395
|
}
|
|
393
396
|
|
|
394
397
|
skipBytesChunked() {
|
|
395
398
|
const numBytes = this.readUInt8();
|
|
399
|
+
if (numBytes === 0 || numBytes === constants.TNS_NULL_LENGTH_INDICATOR) {
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
396
402
|
if (numBytes !== constants.TNS_LONG_LENGTH_INDICATOR) {
|
|
397
403
|
this.skipBytes(numBytes);
|
|
398
404
|
} else {
|
|
@@ -405,6 +411,23 @@ class ReadPacket extends BaseBuffer {
|
|
|
405
411
|
}
|
|
406
412
|
}
|
|
407
413
|
|
|
414
|
+
readNullTerminatedBytes(maxSize = 50) {
|
|
415
|
+
let offset = 0;
|
|
416
|
+
const tmp = Buffer.allocUnsafe(maxSize);
|
|
417
|
+
while (offset < maxSize) {
|
|
418
|
+
tmp[offset] = this.readUInt8();
|
|
419
|
+
if (tmp[offset] === 0) {
|
|
420
|
+
break;
|
|
421
|
+
}
|
|
422
|
+
offset = offset + 1;
|
|
423
|
+
}
|
|
424
|
+
if (offset === maxSize) {
|
|
425
|
+
const reason = `Byte Arrray Exceeded MaxSize ${maxSize}`;
|
|
426
|
+
errors.throwErr(errors.ERR_INTERNAL, reason);
|
|
427
|
+
}
|
|
428
|
+
return tmp.subarray(0, offset + 1);
|
|
429
|
+
}
|
|
430
|
+
|
|
408
431
|
}
|
|
409
432
|
|
|
410
433
|
|