oracledb 5.5.0 → 6.0.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.
Files changed (107) hide show
  1. package/CHANGELOG.md +1 -1875
  2. package/LICENSE.txt +8 -222
  3. package/NOTICE.txt +1 -1
  4. package/README.md +38 -30
  5. package/SECURITY.md +38 -0
  6. package/build/Release/oracledb-6.0.0-darwin-x64.node +0 -0
  7. package/build/Release/oracledb-6.0.0-darwin-x64.node-buildinfo.txt +1 -0
  8. package/build/Release/oracledb-6.0.0-js-buildinfo.txt +1 -0
  9. package/build/Release/oracledb-6.0.0-linux-arm64.node +0 -0
  10. package/build/Release/oracledb-6.0.0-linux-arm64.node-buildinfo.txt +1 -0
  11. package/build/Release/oracledb-6.0.0-linux-x64.node +0 -0
  12. package/build/Release/oracledb-6.0.0-linux-x64.node-buildinfo.txt +1 -0
  13. package/build/Release/oracledb-6.0.0-win32-x64.node +0 -0
  14. package/build/Release/oracledb-6.0.0-win32-x64.node-buildinfo.txt +1 -0
  15. package/examples/README.md +113 -0
  16. package/examples/dbconfig.js +100 -0
  17. package/examples/example.js +156 -0
  18. package/index.js +26 -0
  19. package/lib/aqDeqOptions.js +146 -7
  20. package/lib/aqEnqOptions.js +59 -7
  21. package/lib/aqMessage.js +118 -7
  22. package/lib/aqQueue.js +242 -53
  23. package/lib/connection.js +1324 -465
  24. package/lib/constants.js +203 -0
  25. package/lib/dbObject.js +346 -32
  26. package/lib/errors.js +781 -0
  27. package/lib/impl/aqDeqOptions.js +197 -0
  28. package/lib/impl/aqEnqOptions.js +89 -0
  29. package/lib/impl/aqMessage.js +134 -0
  30. package/lib/impl/aqQueue.js +81 -0
  31. package/lib/impl/connection.js +529 -0
  32. package/lib/impl/dbObject.js +159 -0
  33. package/lib/impl/index.js +59 -0
  34. package/lib/impl/lob.js +85 -0
  35. package/lib/impl/pool.js +195 -0
  36. package/lib/impl/resultset.js +223 -0
  37. package/lib/impl/sodaCollection.js +174 -0
  38. package/lib/impl/sodaDatabase.js +81 -0
  39. package/lib/impl/sodaDocCursor.js +63 -0
  40. package/lib/impl/sodaDocument.js +98 -0
  41. package/lib/impl/sodaOperation.js +109 -0
  42. package/lib/lob.js +156 -68
  43. package/lib/oracledb.js +1047 -345
  44. package/lib/pool.js +654 -465
  45. package/lib/poolStatistics.js +23 -9
  46. package/lib/queryStream.js +14 -7
  47. package/lib/resultset.js +291 -183
  48. package/lib/settings.js +191 -0
  49. package/lib/sodaCollection.js +214 -201
  50. package/lib/sodaDatabase.js +107 -71
  51. package/lib/sodaDocCursor.js +44 -32
  52. package/lib/sodaDocument.js +76 -14
  53. package/lib/sodaOperation.js +131 -118
  54. package/lib/thin/connection.js +1038 -0
  55. package/lib/thin/dbObject.js +629 -0
  56. package/lib/thin/index.js +40 -0
  57. package/lib/thin/lob.js +188 -0
  58. package/lib/thin/pool.js +481 -0
  59. package/lib/thin/protocol/buffer.js +1040 -0
  60. package/lib/thin/protocol/capabilities.js +116 -0
  61. package/lib/thin/protocol/constants.js +764 -0
  62. package/lib/thin/protocol/encryptDecrypt.js +185 -0
  63. package/lib/thin/protocol/messages/auth.js +348 -0
  64. package/lib/thin/protocol/messages/base.js +475 -0
  65. package/lib/thin/protocol/messages/commit.js +56 -0
  66. package/lib/thin/protocol/messages/dataType.js +382 -0
  67. package/lib/thin/protocol/messages/execute.js +312 -0
  68. package/lib/thin/protocol/messages/fetch.js +60 -0
  69. package/lib/thin/protocol/messages/index.js +53 -0
  70. package/lib/thin/protocol/messages/lobOp.js +200 -0
  71. package/lib/thin/protocol/messages/logOff.js +53 -0
  72. package/lib/thin/protocol/messages/ping.js +56 -0
  73. package/lib/thin/protocol/messages/protocol.js +78 -0
  74. package/lib/thin/protocol/messages/rollback.js +56 -0
  75. package/lib/thin/protocol/messages/sessionRelease.js +60 -0
  76. package/lib/thin/protocol/messages/withData.js +811 -0
  77. package/lib/thin/protocol/oson.js +660 -0
  78. package/lib/thin/protocol/packet.js +520 -0
  79. package/lib/thin/protocol/protocol.js +202 -0
  80. package/lib/thin/protocol/utils.js +88 -0
  81. package/lib/thin/resultSet.js +122 -0
  82. package/lib/thin/sqlnet/connStrategy.js +175 -0
  83. package/lib/thin/sqlnet/constants.js +199 -0
  84. package/lib/thin/sqlnet/ezConnectResolver.js +488 -0
  85. package/lib/thin/sqlnet/navNodes.js +870 -0
  86. package/lib/thin/sqlnet/networkSession.js +620 -0
  87. package/lib/thin/sqlnet/ntTcp.js +525 -0
  88. package/lib/thin/sqlnet/nvStrToNvPair.js +783 -0
  89. package/lib/thin/sqlnet/packet.js +405 -0
  90. package/lib/thin/sqlnet/paramParser.js +205 -0
  91. package/lib/thin/sqlnet/sessionAtts.js +160 -0
  92. package/lib/thin/statement.js +301 -0
  93. package/lib/thin/util.js +289 -0
  94. package/lib/transformer.js +250 -0
  95. package/lib/types.js +357 -0
  96. package/lib/util.js +194 -110
  97. package/lib/version.js +36 -0
  98. package/package/README.md +33 -30
  99. package/package/install.js +89 -64
  100. package/package/prunebinaries.js +60 -12
  101. package/package.json +3 -3
  102. package/build/Release/oracledb-5.5.0-darwin-x64.node +0 -0
  103. package/build/Release/oracledb-5.5.0-darwin-x64.node-buildinfo.txt +0 -1
  104. package/build/Release/oracledb-5.5.0-linux-x64.node +0 -0
  105. package/build/Release/oracledb-5.5.0-linux-x64.node-buildinfo.txt +0 -1
  106. package/build/Release/oracledb-5.5.0-win32-x64.node +0 -0
  107. package/build/Release/oracledb-5.5.0-win32-x64.node-buildinfo.txt +0 -1
@@ -0,0 +1,811 @@
1
+ // Copyright (c) 2022, 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 utils = require("../utils");
30
+ const constants = require("../constants.js");
31
+ const Message = require("./base.js");
32
+ const ThinDbObjectImpl = require("../../dbObject.js");
33
+ const ThinLobImpl = require("../../lob.js");
34
+ const errors = require('../../../errors');
35
+ const types = require('../../../types.js');
36
+
37
+ /**
38
+ * Handles data like row header, rowdata , ... recevied from an RPC Execute
39
+ *
40
+ * @class MessageWithData
41
+ * @extends {Message}
42
+ */
43
+ class MessageWithData extends Message {
44
+ constructor(connection, statement = null, options = null) {
45
+ super(connection);
46
+ this.statement = statement;
47
+ this.options = options;
48
+ this.offset = 0;
49
+ this.numExecs = 1;
50
+ this.arrayDmlRowCounts = false;
51
+ this.requiresDefine = false;
52
+ this.rowIndex = statement.bufferRowCount || 0;
53
+ this.dmlRowCounts = [];
54
+ this.batchErrors = false;
55
+ this.outVariables = [];
56
+ this.inFetch = false;
57
+ this.parseOnly = false;
58
+ this.resultSetsToSetup = [];
59
+ }
60
+
61
+ /**
62
+ * processMessage() - Process the data type message
63
+ */
64
+ processMessage(buf, messageType) {
65
+ if (messageType === constants.TNS_MSG_TYPE_DESCRIBE_INFO) {
66
+ buf.skipBytesChunked();
67
+ this.statement.queryVars = [];
68
+ this.statement.numQueryVars = 0;
69
+ this.statement.bufferRowCount = 0;
70
+ this.statement.bufferRowIndex = 0;
71
+ this.processDescribeInfo(buf, this.resultSet);
72
+ this.outVariables = this.statement.queryVars;
73
+ } else if (messageType === constants.TNS_MSG_TYPE_ROW_HEADER) {
74
+ this.processRowHeader(buf);
75
+ } else if (messageType === constants.TNS_MSG_TYPE_ROW_DATA) {
76
+ this.processRowData(buf);
77
+ } else if (messageType === constants.TNS_MSG_TYPE_IMPLICIT_RESULTSET) {
78
+ this.processImplicitResultSet(buf);
79
+ } else if (messageType === constants.TNS_MSG_TYPE_BIT_VECTOR) {
80
+ this.processBitVector(buf);
81
+ } else if (messageType === constants.TNS_MSG_TYPE_IO_VECTOR) {
82
+ this.processIOVector(buf);
83
+ } else if (messageType === constants.TNS_MSG_TYPE_FLUSH_OUT_BINDS) {
84
+ this.flushOutBinds = true;
85
+ } else if (messageType === constants.TNS_MSG_TYPE_ERROR) {
86
+ this.processErrorInfo(buf);
87
+ } else {
88
+ super.processMessage(buf, messageType);
89
+ }
90
+ }
91
+
92
+ hasMoreData() {
93
+ return !this.processedError && !this.flushOutBinds;
94
+ }
95
+
96
+ processErrorInfo(buf) {
97
+ super.processErrorInfo(buf);
98
+ this.statement.cursorId = this.errorInfo.cursorId;
99
+ if (!this.statement.isPlSql) {
100
+ this.statement.rowCount = this.errorInfo.rowCount;
101
+ }
102
+ // we do not set the lastRowid if the rows affected is 0
103
+ if (this.errorInfo.rowCount > 0) {
104
+ this.statement.lastRowid = utils.encodeRowID(this.errorInfo.rowID);
105
+ }
106
+ this.options.batchErrors = this.errorInfo.batchErrors;
107
+ if (this.batchErrors && this.options.batchErrors === null) {
108
+ this.options.batchErrors = [];
109
+ }
110
+ if (this.errorInfo.num === constants.TNS_ERR_NO_DATA_FOUND && this.statement.isQuery) {
111
+ this.errorInfo.num = 0;
112
+ this.errorOccurred = false;
113
+ this.statement.moreRowsToFetch = false;
114
+ } else if (this.errorInfo.num === constants.TNS_ERR_VAR_NOT_IN_SELECT_LIST) {
115
+ this.connection._addCursorToClose(this.statement);
116
+ this.connection.statementCache.delete(this.statement.sql);
117
+ } else if (this.errorInfo.num !== 0 && this.errorInfo.cursorId !== 0) {
118
+ this.connection._addCursorToClose(this.statement);
119
+ this.connection.statementCache.delete(this.statement.sql);
120
+ }
121
+ if (this.errorInfo.batchErrors) {
122
+ this.errorOccurred = false;
123
+ }
124
+ }
125
+
126
+ processDescribeInfo(buf, resultSet) {
127
+ const statement = resultSet.statement;
128
+ buf.skipUB4(); // max row size
129
+ statement.numQueryVars = buf.readUB4();
130
+ if (statement.numQueryVars > 0) {
131
+ buf.skipUB1();
132
+ }
133
+ resultSet.metadata = [];
134
+ for (let i = 0; i < statement.numQueryVars; i++) {
135
+ const variable = this.processColumnInfo(buf, i + 1);
136
+ statement.queryVars.push(variable);
137
+ resultSet.metadata.push(variable.fetchInfo);
138
+ }
139
+
140
+ let numBytes = buf.readUB4();
141
+ if (numBytes > 0) {
142
+ buf.skipBytes(numBytes + 1); // current date
143
+ }
144
+ buf.skipUB4(); // dcbflag
145
+ buf.skipUB4(); // dcbmdbz
146
+ buf.skipUB4(); // dcbmnpr
147
+ buf.skipUB4(); // dcbmxpr
148
+ numBytes = buf.readUB4();
149
+ if (numBytes > 0) {
150
+ buf.skipBytes(numBytes + 1);
151
+ }
152
+
153
+ this.resultSetsToSetup.push(resultSet);
154
+ }
155
+
156
+ processColumnInfo(buf, columnNum) {
157
+ const dataType = buf.readUInt8();
158
+ buf.skipUB1(); // flags
159
+ const precision = buf.readInt8();
160
+ let scale;
161
+ if (dataType === constants.TNS_DATA_TYPE_NUMBER ||
162
+ dataType === constants.TNS_DATA_TYPE_INTERVAL_DS ||
163
+ dataType === constants.TNS_DATA_TYPE_TIMESTAMP ||
164
+ dataType === constants.TNS_DATA_TYPE_TIMESTAMP_LTZ ||
165
+ dataType === constants.TNS_DATA_TYPE_TIMESTAMP_TZ) {
166
+ scale = buf.readSB2();
167
+ } else {
168
+ scale = buf.readInt8();
169
+ }
170
+ const maxSize = buf.readUB4();
171
+ buf.skipUB4(); // max number of array elements
172
+ buf.skipUB4(); // cont flags
173
+ let oid;
174
+ let numBytes = buf.readUB4(); // OID
175
+ if (numBytes > 0) {
176
+ oid = buf.readBytesWithLength();
177
+ }
178
+ buf.skipUB2(); // version
179
+ buf.skipUB2(); // character set id
180
+ const csfrm = buf.readUInt8(); // character set form
181
+ let size = buf.readUB4();
182
+ if (dataType === constants.TNS_DATA_TYPE_RAW) {
183
+ size = maxSize;
184
+ }
185
+ if (buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_12_2) {
186
+ buf.skipUB4(); // oaccolid
187
+ }
188
+ const nullable = Boolean(buf.readUInt8());
189
+ buf.skipUB1(); // v7 length of name
190
+ let name;
191
+ numBytes = buf.readUB4();
192
+ if (numBytes > 0) {
193
+ name = buf.readStr(constants.TNS_CS_IMPLICIT);
194
+ }
195
+ let schema;
196
+ numBytes = buf.readUB4();
197
+ if (numBytes > 0) {
198
+ schema = buf.readStr(constants.TNS_CS_IMPLICIT);
199
+ }
200
+ numBytes = buf.readUB4();
201
+ let typeName;
202
+ if (numBytes > 0) {
203
+ typeName = buf.readStr(constants.TNS_CS_IMPLICIT);
204
+ }
205
+ buf.skipUB2(); // column position
206
+ buf.skipUB4(); // uds flag
207
+
208
+ // build metadata
209
+ const fetchInfo = {
210
+ name: name,
211
+ dbType: types.getTypeByOraTypeNum(dataType, csfrm),
212
+ nullable: nullable
213
+ };
214
+ switch (fetchInfo.dbType) {
215
+ case types.DB_TYPE_VARCHAR:
216
+ case types.DB_TYPE_NVARCHAR:
217
+ case types.DB_TYPE_CHAR:
218
+ case types.DB_TYPE_NCHAR:
219
+ case types.DB_TYPE_RAW:
220
+ fetchInfo.byteSize = size;
221
+ break;
222
+ case types.DB_TYPE_NUMBER:
223
+ fetchInfo.precision = precision;
224
+ break;
225
+ case types.DB_TYPE_TIMESTAMP:
226
+ case types.DB_TYPE_TIMESTAMP_TZ:
227
+ case types.DB_TYPE_TIMESTAMP_LTZ:
228
+ fetchInfo.precision = scale;
229
+ break;
230
+ case types.DB_TYPE_OBJECT:
231
+ fetchInfo.dbTypeClass = this.connection._getDbObjectType(schema,
232
+ typeName, undefined, oid);
233
+ if (fetchInfo.dbTypeClass.partial) {
234
+ this.connection._partialDbObjectTypes.push(fetchInfo.dbTypeClass);
235
+ }
236
+ break;
237
+ default:
238
+ break;
239
+ }
240
+ if (fetchInfo.dbType === types.DB_TYPE_NUMBER) {
241
+ fetchInfo.scale = scale;
242
+ }
243
+ return {
244
+ fetchInfo: fetchInfo,
245
+ type: fetchInfo.dbType,
246
+ maxSize: maxSize,
247
+ columnNum: columnNum,
248
+ values: new Array(this.options.fetchArraySize)
249
+ };
250
+ }
251
+
252
+ processRowHeader(buf) {
253
+ buf.skipUB1(); // flags
254
+ buf.skipUB2(); // num requests
255
+ buf.skipUB4(); // iteration number
256
+ buf.skipUB4(); // num iters
257
+ buf.skipUB2(); // buffer length
258
+ let numBytes = buf.readUB4();
259
+ if (numBytes > 0) {
260
+ buf.skipUB1(); // skip repeated length
261
+ this.getBitVector(buf, numBytes);
262
+ }
263
+ numBytes = buf.readUB4();
264
+ if (numBytes > 0) {
265
+ buf.skipBytesChunked(); // rxhrid
266
+ }
267
+ }
268
+
269
+ isDuplicateData(columnName) {
270
+ if (this.bitVector === null || this.bitVector === undefined) {
271
+ return false;
272
+ }
273
+ let byteNum = Math.floor(columnName / 8);
274
+ let bitNum = columnName % 8;
275
+ return (this.bitVector[byteNum] & (1 << bitNum)) === 0;
276
+ }
277
+
278
+ processRowData(buf) {
279
+ let value;
280
+ for (let [col, variable] of this.outVariables.entries()) {
281
+ if (variable.isArray) {
282
+ variable.numElementsInArray = buf.readUB4();
283
+ let values = new Array(variable.numElementsInArray).fill(null);
284
+ for (let pos = 0; pos < variable.numElementsInArray; pos++) {
285
+ value = this.processColumnData(buf, variable, pos);
286
+ values[pos] = value;
287
+ }
288
+ variable.values[this.rowIndex] = values;
289
+ } else if (this.statement.isReturning) {
290
+ let numRows = buf.readUB4();
291
+ let values = Array(numRows).fill(null);
292
+ for (let j = 0; j < numRows; j++) {
293
+ values[j] = this.processColumnData(buf, variable, j);
294
+ }
295
+ variable.values[this.rowIndex] = values;
296
+ } else if (this.isDuplicateData(col)) {
297
+ if (this.rowIndex === 0 && variable.outConverter) {
298
+ value = variable.lastRawValue;
299
+ } else {
300
+ value = variable.values[this.statement.lastRowIndex];
301
+ }
302
+ variable.values[this.rowIndex] = value;
303
+ } else {
304
+ value = this.processColumnData(buf, variable, this.rowIndex);
305
+ variable.values[this.rowIndex] = value;
306
+ }
307
+ }
308
+ this.rowIndex++;
309
+ if (this.inFetch) {
310
+ this.statement.lastRowIndex = this.rowIndex - 1;
311
+ this.statement.bufferRowCount++;
312
+ this.bitVector = null;
313
+ }
314
+ }
315
+
316
+ processIOVector(buf) {
317
+ let numBytes;
318
+ buf.skipUB1(); // flag
319
+ const numBinds = buf.readUB2(); // num requests
320
+ this.rowIndex = buf.readUB4(); // iter num
321
+ buf.skipUB4(); // num iters this time
322
+ buf.readUB2(); // uac buffer length
323
+ numBytes = buf.readUB2(); // bit vector for fast fetch
324
+ if (numBytes > 0) {
325
+ buf.skipBytes(numBytes);
326
+ }
327
+ numBytes = buf.readUB2(); // rowid
328
+ if (numBytes > 0) {
329
+ buf.skipBytes(numBytes);
330
+ }
331
+ this.outVariables = [];
332
+ for (let i = 0; i < numBinds; i++) { // bind directions
333
+ let bindInfo = this.statement.bindInfoList[i];
334
+ bindInfo.bindDir = buf.readUInt8();
335
+ if (bindInfo.bindDir === constants.TNS_BIND_DIR_INPUT) {
336
+ continue;
337
+ }
338
+ this.outVariables.push(bindInfo.bindVar);
339
+ }
340
+ }
341
+
342
+ processColumnData(buf, variable) {
343
+ const dbType = variable.type;
344
+ const oraTypeNum = dbType._oraTypeNum;
345
+ const csfrm = dbType._csfrm;
346
+ const maxSize = variable.maxSize;
347
+
348
+ let colValue = null;
349
+ if (maxSize === 0 && oraTypeNum !== constants.TNS_DATA_TYPE_LONG
350
+ && oraTypeNum !== constants.TNS_DATA_TYPE_LONG_RAW
351
+ && oraTypeNum !== constants.TNS_DATA_TYPE_UROWID) {
352
+ colValue = null;
353
+ } else if (
354
+ oraTypeNum === constants.TNS_DATA_TYPE_VARCHAR ||
355
+ oraTypeNum === constants.TNS_DATA_TYPE_CHAR ||
356
+ oraTypeNum === constants.TNS_DATA_TYPE_LONG
357
+ ) {
358
+ if (csfrm === constants.TNS_CS_NCHAR) {
359
+ buf.caps.checkNCharsetId();
360
+ }
361
+ colValue = buf.readStr(csfrm);
362
+ } else if (oraTypeNum === constants.TNS_DATA_TYPE_RAW ||
363
+ oraTypeNum === constants.TNS_DATA_TYPE_LONG_RAW) {
364
+ colValue = buf.readBytesWithLength();
365
+ if (colValue !== null) {
366
+ colValue = Buffer.from(colValue);
367
+ }
368
+ } else if (oraTypeNum === constants.TNS_DATA_TYPE_NUMBER) {
369
+ colValue = buf.readOracleNumber();
370
+ if (!this.inFetch && colValue !== null)
371
+ colValue = parseFloat(colValue);
372
+ } else if (
373
+ oraTypeNum === constants.TNS_DATA_TYPE_DATE ||
374
+ oraTypeNum === constants.TNS_DATA_TYPE_TIMESTAMP ||
375
+ oraTypeNum === constants.TNS_DATA_TYPE_TIMESTAMP_LTZ ||
376
+ oraTypeNum === constants.TNS_DATA_TYPE_TIMESTAMP_TZ
377
+ ) {
378
+ const useLocalTime = (oraTypeNum === constants.TNS_DATA_TYPE_DATE ||
379
+ oraTypeNum === constants.TNS_DATA_TYPE_TIMESTAMP);
380
+ colValue = buf.readOracleDate(useLocalTime);
381
+ } else if (oraTypeNum === constants.TNS_DATA_TYPE_ROWID) {
382
+ if (!this.inFetch) {
383
+ colValue = buf.readStr(constants.TNS_CS_IMPLICIT);
384
+ } else {
385
+ let numBytes = buf.readUInt8();
386
+ if (isNullLength(numBytes)) {
387
+ colValue = null;
388
+ } else {
389
+ let rowid = buf.readRowID();
390
+ colValue = utils.encodeRowID(rowid);
391
+ }
392
+ }
393
+ } else if (oraTypeNum === constants.TNS_DATA_TYPE_UROWID) {
394
+ if (!this.inFetch) {
395
+ colValue = buf.readStr(constants.TNS_CS_IMPLICIT);
396
+ } else {
397
+ colValue = buf.readURowID();
398
+ }
399
+ } else if (oraTypeNum === constants.TNS_DATA_TYPE_BINARY_DOUBLE) {
400
+ colValue = buf.readBinaryDouble();
401
+ } else if (oraTypeNum === constants.TNS_DATA_TYPE_BINARY_FLOAT) {
402
+ colValue = buf.readBinaryFloat();
403
+ } else if (oraTypeNum === constants.TNS_DATA_TYPE_BINARY_INTEGER) {
404
+ colValue = buf.readOracleNumber();
405
+ if (colValue !== null)
406
+ colValue = parseFloat(colValue);
407
+ } else if (oraTypeNum === constants.TNS_DATA_TYPE_CURSOR) {
408
+ let numBytes = buf.readUInt8();
409
+ if (isNullLength(numBytes)) {
410
+ colValue = null;
411
+ } else {
412
+ colValue = this.createCursorFromDescribe(buf);
413
+ colValue.statement.cursorId = buf.readUB2();
414
+ // If the cursor ID is 0 for the returned ref cursor then
415
+ // it is an invalid cursor
416
+ if (colValue.statement.cursorId === 0 && variable.dir !== constants.BIND_IN) {
417
+ if (this.options.nullifyInvalidCursor) {
418
+ colValue = null;
419
+ } else {
420
+ errors.throwErr(errors.ERR_INVALID_REF_CURSOR);
421
+ }
422
+ }
423
+ }
424
+ } else if (oraTypeNum === constants.TNS_DATA_TYPE_BOOLEAN) {
425
+ colValue = buf.readBool();
426
+ } else if (oraTypeNum === constants.TNS_DATA_TYPE_CLOB || oraTypeNum === constants.TNS_DATA_TYPE_BLOB) {
427
+ let bvalue = buf.readUB4();
428
+ if (bvalue > 0) { // Non Null data in column
429
+ colValue = new ThinLobImpl();
430
+ const length = buf.readUB8();
431
+ const chunkSize = buf.readUB4();
432
+ const locator = Buffer.from(buf.readBytesWithLength());
433
+ colValue.init(this.connection, locator, dbType, length, chunkSize);
434
+ }
435
+ } else if (oraTypeNum === constants.TNS_DATA_TYPE_JSON) {
436
+ colValue = buf.readOson();
437
+ } else if (oraTypeNum === constants.TNS_DATA_TYPE_INT_NAMED) {
438
+ const obj = buf.readDbObject();
439
+ if (obj.packedData) {
440
+ const objType = (variable.fetchInfo) ? variable.fetchInfo.dbTypeClass :
441
+ variable.typeClass;
442
+ colValue = new ThinDbObjectImpl(objType, obj.packedData);
443
+ colValue.toid = obj.toid;
444
+ colValue.oid = obj.oid;
445
+ }
446
+ } else {
447
+ errors.throwErr(errors.ERR_UNSUPPORTED_DATA_TYPE, dbType.num,
448
+ variable.columnNum);
449
+ }
450
+
451
+ if (!this.inFetch) {
452
+ const actualNumBytes = buf.readSB4();
453
+ if (actualNumBytes !== 0 && colValue !== null) {
454
+ errors.throwErr(errors.ERR_INSUFFICIENT_BUFFER_FOR_BINDS);
455
+ }
456
+ } else if (oraTypeNum === constants.TNS_DATA_TYPE_LONG || oraTypeNum === constants.TNS_DATA_TYPE_LONG_RAW || variable.maxSize >= constants.TNS_MIN_LONG_LENGTH) {
457
+ buf.skipSB4(); // null indicator
458
+ buf.skipUB4(); // return code
459
+ }
460
+ return colValue;
461
+ }
462
+
463
+ processReturnParameter(buf) {
464
+ let keywordNum = 0;
465
+ let keyTextValue;
466
+ let numParams = buf.readUB2(); // al8o4l (ignored)
467
+
468
+ for (let i = 0; i < numParams; i++) {
469
+ buf.skipUB4();
470
+ }
471
+ let numBytes = buf.readUB2(); // al8txl (ignored)
472
+ if (numBytes > 0) {
473
+ buf.skipBytes(numBytes);
474
+ }
475
+ numParams = buf.readUB2(); // num key/value pairs
476
+ for (let i = 0; i < numParams; i++) {
477
+ numBytes = buf.readUB2(); // key
478
+ if (numBytes > 0) {
479
+ keyTextValue = buf.readStr(constants.TNS_CS_IMPLICIT);
480
+ }
481
+ numBytes = buf.readUB2(); // value
482
+ if (numBytes > 0) {
483
+ buf.skipBytesChunked();
484
+ }
485
+ keywordNum = buf.readUB2(); // keyword num
486
+ if (keywordNum === constants.TNS_KEYWORD_NUM_CURRENT_SCHEMA) {
487
+ this.connection.currentSchema = keyTextValue;
488
+ } else if (keywordNum === constants.TNS_KEYWORD_NUM_EDITION) {
489
+ this.connection._edition = keyTextValue;
490
+ }
491
+ }
492
+ numBytes = buf.readUB2(); // registration
493
+ if (numBytes > 0) {
494
+ buf.skip(numBytes);
495
+ }
496
+ if (this.arrayDmlRowCounts) {
497
+ let numRows = buf.readUB4();
498
+ let rowCounts = this.options.dmlRowCounts = [];
499
+ for (let i = 0; i < numRows; i++) {
500
+ let rowCount = buf.readUB8();
501
+ rowCounts.push(rowCount);
502
+ }
503
+ }
504
+ }
505
+
506
+ process(buf) {
507
+ this.bitVector = this.savedBitVector;
508
+ super.process(buf);
509
+ }
510
+
511
+ savePoint(buf) {
512
+ this.savedBitVector = this.bitVector;
513
+ super.savePoint(buf);
514
+ }
515
+
516
+ async postProcess() {
517
+ if (this.outVariables) {
518
+ for (const variable of this.outVariables) {
519
+ if (variable.isArray) {
520
+ for (let pos = 0; pos < variable.numElementsInArray; pos++) {
521
+ if (variable.outConverter) {
522
+ variable.values[0][pos] = await variable.outConverter(variable.values[0][pos]);
523
+ }
524
+ }
525
+ } else {
526
+ if (variable.outConverter) {
527
+ variable.values[0] = await variable.outConverter(variable.values[0]);
528
+ }
529
+ }
530
+ }
531
+ }
532
+ await this.connection._populatePartialDbObjectTypes();
533
+ for (const resultSet of this.resultSetsToSetup) {
534
+ resultSet._setup(this.options, resultSet.metadata);
535
+ // LOBs always require define and they change the type that is actually
536
+ // returned by the server
537
+ for (const variable of resultSet.statement.queryVars) {
538
+ if (variable.type === types.DB_TYPE_CLOB ||
539
+ variable.type === types.DB_TYPE_NCLOB ||
540
+ variable.type === types.DB_TYPE_BLOB ||
541
+ variable.type === types.DB_TYPE_JSON) {
542
+ if (variable.type !== variable.fetchInfo.fetchType) {
543
+ variable.type = variable.fetchInfo.fetchType;
544
+ variable.maxSize = constants.TNS_MAX_LONG_LENGTH;
545
+ }
546
+ resultSet.statement.requiresDefine = true;
547
+ }
548
+ }
549
+ }
550
+ }
551
+
552
+ preProcess() {
553
+ if (this.statement.isReturning && !this.parseOnly) {
554
+ this.outVariables = [];
555
+ for (const bindInfo of this.statement.bindInfoList) {
556
+ if (bindInfo.isReturnBind) {
557
+ this.outVariables.push(bindInfo.bindVar);
558
+ }
559
+ }
560
+ }
561
+
562
+ if (this.statement.isQuery) {
563
+ this.inFetch = true;
564
+ if (this.statement.queryVars) {
565
+ this.outVariables = [];
566
+ for (let i = 0; i < this.statement.queryVars.length; i++) {
567
+ this.outVariables.push(this.statement.queryVars[i]);
568
+ }
569
+ }
570
+ }
571
+ }
572
+
573
+ processBitVector(buf) {
574
+ this.numColumnsSent = buf.readUB2();
575
+ let numBytes = Math.floor(this.statement.numQueryVars / 8);
576
+ if (this.statement.numQueryVars % 8 > 0) {
577
+ numBytes += 1;
578
+ }
579
+ this.getBitVector(buf, numBytes);
580
+ }
581
+
582
+ getBitVector(buf, numBytes) {
583
+ this.bitVector = buf.readBytes(numBytes);
584
+ }
585
+
586
+ processBindParams(buf, params) {
587
+ const bindVars = [];
588
+ const nonReturningParams = [];
589
+ for (const bindInfo of params) {
590
+ if (!bindInfo.isReturnBind) {
591
+ nonReturningParams.push(bindInfo);
592
+ }
593
+ bindVars.push(bindInfo.bindVar);
594
+ }
595
+ this.writeColumnMetadata(buf, bindVars);
596
+ return nonReturningParams;
597
+ }
598
+
599
+ writeColumnMetadata(buf, bindVars) {
600
+ for (const variable of bindVars) {
601
+ let oraTypeNum = variable.type._oraTypeNum;
602
+ let maxSize = variable.maxSize || variable.type._bufferSizeFactor;
603
+ let lobPrefetchLength = 0;
604
+
605
+ // NCHAR, NVARCHAR reports ORA-01460: unimplemented or unreasonable
606
+ // conversion requested if maxSize is not multiplied by the
607
+ // bufferSizeFactor
608
+ if (variable.type._csfrm === constants.TNS_CS_NCHAR) {
609
+ maxSize *= variable.type._bufferSizeFactor;
610
+ }
611
+ if ([constants.TNS_DATA_TYPE_ROWID, constants.TNS_DATA_TYPE_UROWID].includes(oraTypeNum)) {
612
+ oraTypeNum = constants.TNS_DATA_TYPE_VARCHAR;
613
+ maxSize = constants.TNS_MAX_UROWID_LENGTH;
614
+ }
615
+ let flag = constants.TNS_BIND_USE_INDICATORS;
616
+ if (variable.isArray) {
617
+ flag |= constants.TNS_BIND_ARRAY;
618
+ }
619
+ let contFlag = 0;
620
+ if (variable.type === types.DB_TYPE_BLOB ||
621
+ variable.type === types.DB_TYPE_CLOB ||
622
+ variable.type === types.DB_TYPE_NCLOB) {
623
+ contFlag = constants.TNS_LOB_PREFETCH_FLAG;
624
+ } else if (variable.type === types.DB_TYPE_JSON) {
625
+ contFlag = constants.TNS_LOB_PREFETCH_FLAG;
626
+ maxSize = lobPrefetchLength = constants.TNS_JSON_MAX_LENGTH;
627
+ }
628
+ buf.writeUInt8(oraTypeNum);
629
+ buf.writeUInt8(flag);
630
+ // precision and scale are always written as zero as the server
631
+ // expects that and complains if any other value is sent!
632
+ buf.writeUInt8(0);
633
+ buf.writeUInt8(0);
634
+ if (maxSize >= constants.TNS_MIN_LONG_LENGTH) {
635
+ buf.writeUB4(constants.TNS_MAX_LONG_LENGTH);
636
+ } else {
637
+ buf.writeUB4(maxSize);
638
+ }
639
+
640
+ if (variable.isArray) {
641
+ buf.writeUB4(variable.maxArraySize);
642
+ } else {
643
+ buf.writeUB4(0); // max num elements
644
+ }
645
+ buf.writeUB4(contFlag);
646
+ if (variable.objType) {
647
+ const objType = variable.objType;
648
+ buf.writeUB4(objType.oid.length);
649
+ buf.writeBytesWithLength(objType.oid);
650
+ buf.writeUB4(objType.version);
651
+ } else {
652
+ buf.writeUB4(0); // OID
653
+ buf.writeUB4(0); // version
654
+ }
655
+ if (variable.type._csfrm !== 0) {
656
+ buf.writeUB4(constants.TNS_CHARSET_UTF8);
657
+ } else {
658
+ buf.writeUB4(0);
659
+ }
660
+ buf.writeUInt8(variable.type._csfrm);
661
+ buf.writeUB4(lobPrefetchLength); // max chars (LOB prefetch)
662
+ if (buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_12_2) {
663
+ buf.writeUB4(0); // oaccolid
664
+ }
665
+ }
666
+ }
667
+
668
+ writeBindParamsRow(buf, params, pos) {
669
+ let offset = this.offset;
670
+ let foundLong = false;
671
+ for (const bindInfo of params) {
672
+ if (bindInfo.isReturnBind)
673
+ continue;
674
+ let variable = bindInfo.bindVar;
675
+ if (variable.isArray) {
676
+ let numElements = variable.values.length;
677
+ buf.writeUB4(numElements);
678
+ for (let i = 0; i < numElements; i++) {
679
+ this.writeBindParamsColumn(buf, variable, variable.values[i]);
680
+ }
681
+ } else {
682
+ if (variable.maxSize >= constants.TNS_MIN_LONG_LENGTH) {
683
+ foundLong = true;
684
+ } else {
685
+ this.writeBindParamsColumn(buf, variable,
686
+ variable.values[pos + offset]);
687
+ }
688
+ }
689
+ }
690
+ if (foundLong) {
691
+ for (const bindInfo of params) {
692
+ if (bindInfo.isReturnBind)
693
+ continue;
694
+ const variable = bindInfo.bindVar;
695
+ if (variable.maxSize >= constants.TNS_MIN_LONG_LENGTH) {
696
+ this.writeBindParamsColumn(buf, variable,
697
+ variable.values[pos + offset]);
698
+ }
699
+ }
700
+ }
701
+ }
702
+
703
+ writeBindParamsColumn(buf, variable, value) {
704
+ const oraTypeNum = variable.type._oraTypeNum;
705
+ let tempVal;
706
+ if ((value === undefined || value === null) && oraTypeNum !== constants.TNS_DATA_TYPE_CURSOR && oraTypeNum !== constants.TNS_DATA_TYPE_JSON) {
707
+ if (oraTypeNum === constants.TNS_DATA_TYPE_BOOLEAN) {
708
+ buf.writeUInt8(constants.TNS_ESCAPE_CHAR);
709
+ buf.writeUInt8(1);
710
+ } else if (oraTypeNum === constants.TNS_DATA_TYPE_INT_NAMED) {
711
+ buf.writeUB4(0); // TOID
712
+ buf.writeUB4(0); // OID
713
+ buf.writeUB4(0); // snapshot
714
+ buf.writeUB4(0); // version
715
+ buf.writeUB4(0); // packed data length
716
+ buf.writeUB4(constants.TNS_OBJ_TOP_LEVEL); // flags
717
+ } else {
718
+ buf.writeUInt8(0);
719
+ }
720
+ } else if (oraTypeNum === constants.TNS_DATA_TYPE_NUMBER ||
721
+ oraTypeNum === constants.TNS_DATA_TYPE_BINARY_INTEGER) {
722
+ if (typeof value === 'boolean') {
723
+ tempVal = (value) ? "1" : "0";
724
+ } else {
725
+ tempVal = value.toString();
726
+ }
727
+ buf.writeOracleNumber(tempVal);
728
+ } else if (oraTypeNum === constants.TNS_DATA_TYPE_VARCHAR ||
729
+ oraTypeNum === constants.TNS_DATA_TYPE_CHAR ||
730
+ oraTypeNum === constants.TNS_DATA_TYPE_LONG ||
731
+ oraTypeNum === constants.TNS_DATA_TYPE_RAW ||
732
+ oraTypeNum === constants.TNS_DATA_TYPE_LONG_RAW) {
733
+ if (variable.type._csfrm === constants.TNS_CS_NCHAR) {
734
+ buf.caps.checkNCharsetId();
735
+ value = Buffer.from(value, constants.TNS_ENCODING_UTF16).swap16();
736
+ } else {
737
+ value = Buffer.from(value);
738
+ }
739
+ buf.writeBytesWithLength(value);
740
+ } else if (
741
+ oraTypeNum === constants.TNS_DATA_TYPE_DATE ||
742
+ oraTypeNum === constants.TNS_DATA_TYPE_TIMESTAMP ||
743
+ oraTypeNum === constants.TNS_DATA_TYPE_TIMESTAMP_TZ ||
744
+ oraTypeNum === constants.TNS_DATA_TYPE_TIMESTAMP_LTZ
745
+ ) {
746
+ buf.writeOracleDate(value, variable.type);
747
+ } else if (oraTypeNum === constants.TNS_DATA_TYPE_BINARY_DOUBLE) {
748
+ buf.writeBinaryDouble(value);
749
+ } else if (oraTypeNum === constants.TNS_DATA_TYPE_BINARY_FLOAT) {
750
+ buf.writeBinaryFloat(value);
751
+ } else if (oraTypeNum === constants.TNS_DATA_TYPE_CURSOR) {
752
+ let cursor = value;
753
+ if (!value) {
754
+ cursor = this.connection._createResultSet();
755
+ }
756
+ if (cursor.statement.cursorId === 0) {
757
+ buf.writeUInt8(1);
758
+ buf.writeUInt8(0);
759
+ } else {
760
+ buf.writeUB4(1);
761
+ buf.writeUB4(cursor.statement.cursorId);
762
+ }
763
+ } else if (oraTypeNum === constants.TNS_DATA_TYPE_BOOLEAN) {
764
+ if (value) {
765
+ buf.writeUInt8(2);
766
+ buf.writeUInt16BE(0x0101);
767
+ } else {
768
+ buf.writeUInt16BE(0x0100);
769
+ }
770
+ } else if (oraTypeNum === constants.TNS_DATA_TYPE_CLOB || oraTypeNum === constants.TNS_DATA_TYPE_BLOB) {
771
+ buf.writeUB4(value._locator.length);
772
+ buf.writeBytesWithLength(value._locator);
773
+ } else if ([constants.TNS_DATA_TYPE_ROWID, constants.TNS_DATA_TYPE_UROWID].includes(oraTypeNum)) {
774
+ buf.writeBytesWithLength(Buffer.from(value));
775
+ } else if (oraTypeNum === constants.TNS_DATA_TYPE_JSON) {
776
+ buf.writeOson(value);
777
+ } else if (oraTypeNum === constants.TNS_DATA_TYPE_INT_NAMED) {
778
+ buf.writeDbObject(value);
779
+ } else {
780
+ const message = `Binding data of type ${variable.type}`;
781
+ errors.throwErr(errors.ERR_NOT_IMPLEMENTED, message);
782
+ }
783
+ }
784
+
785
+ createCursorFromDescribe(buf) {
786
+ const resultSet = this.connection._createResultSet(this.options);
787
+ resultSet.options.moreRowsToFetch = true;
788
+ resultSet.statement.isQuery = true;
789
+ resultSet.statement.requiresFullExecute = true;
790
+ this.processDescribeInfo(buf, resultSet);
791
+ return resultSet;
792
+ }
793
+
794
+ processImplicitResultSet(buf) {
795
+ this.options.implicitResultSet = [];
796
+ const numResults = buf.readUB4();
797
+ for (let i = 0; i < numResults; i++) {
798
+ const numBytes = buf.readUInt8();
799
+ buf.skipBytes(numBytes);
800
+ let childResultSet = this.createCursorFromDescribe(buf);
801
+ childResultSet.statement.cursorId = buf.readUB2();
802
+ this.options.implicitResultSet.push(childResultSet);
803
+ }
804
+ }
805
+ }
806
+
807
+ const isNullLength = (len) => {
808
+ return len === 0 || len === constants.TNS_NULL_LENGTH_INDICATOR;
809
+ };
810
+
811
+ module.exports = MessageWithData;