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.
Files changed (67) hide show
  1. package/README.md +15 -17
  2. package/SECURITY.md +1 -1
  3. package/build/Release/oracledb-6.1.0-darwin-x64.node +0 -0
  4. package/build/Release/oracledb-6.1.0-darwin-x64.node-buildinfo.txt +1 -0
  5. package/build/Release/oracledb-6.1.0-js-buildinfo.txt +1 -0
  6. package/build/Release/oracledb-6.1.0-linux-arm64.node +0 -0
  7. package/build/Release/oracledb-6.1.0-linux-arm64.node-buildinfo.txt +1 -0
  8. package/build/Release/oracledb-6.1.0-linux-x64.node +0 -0
  9. package/build/Release/oracledb-6.1.0-linux-x64.node-buildinfo.txt +1 -0
  10. package/build/Release/oracledb-6.1.0-win32-x64.node +0 -0
  11. package/build/Release/oracledb-6.1.0-win32-x64.node-buildinfo.txt +1 -0
  12. package/examples/example.js +0 -1
  13. package/lib/aqQueue.js +40 -26
  14. package/lib/connection.js +15 -3
  15. package/lib/errors.js +15 -10
  16. package/lib/impl/connection.js +9 -0
  17. package/lib/impl/resultset.js +7 -4
  18. package/lib/oracledb.js +15 -12
  19. package/lib/pool.js +11 -2
  20. package/lib/settings.js +1 -1
  21. package/lib/sodaCollection.js +1 -1
  22. package/lib/thin/connection.js +92 -30
  23. package/lib/thin/dbObject.js +2 -2
  24. package/lib/thin/lob.js +2 -2
  25. package/lib/thin/pool.js +153 -71
  26. package/lib/thin/protocol/buffer.js +24 -6
  27. package/lib/thin/protocol/constants.js +8 -18
  28. package/lib/thin/protocol/encryptDecrypt.js +17 -17
  29. package/lib/thin/protocol/messages/auth.js +27 -31
  30. package/lib/thin/protocol/messages/base.js +30 -53
  31. package/lib/thin/protocol/messages/connectionCookie.js +76 -0
  32. package/lib/thin/protocol/messages/dataType.js +13 -9
  33. package/lib/thin/protocol/messages/execute.js +11 -11
  34. package/lib/thin/protocol/messages/index.js +2 -0
  35. package/lib/thin/protocol/messages/lobOp.js +3 -3
  36. package/lib/thin/protocol/messages/protocol.js +31 -20
  37. package/lib/thin/protocol/messages/withData.js +60 -53
  38. package/lib/thin/protocol/oson.js +4 -4
  39. package/lib/thin/protocol/packet.js +51 -28
  40. package/lib/thin/protocol/protocol.js +12 -7
  41. package/lib/thin/protocol/utils.js +2 -2
  42. package/lib/thin/resultSet.js +6 -6
  43. package/lib/thin/sqlnet/connStrategy.js +134 -7
  44. package/lib/thin/sqlnet/constants.js +2 -0
  45. package/lib/thin/sqlnet/ezConnectResolver.js +29 -24
  46. package/lib/thin/sqlnet/navNodes.js +35 -28
  47. package/lib/thin/sqlnet/networkSession.js +45 -40
  48. package/lib/thin/sqlnet/ntTcp.js +70 -35
  49. package/lib/thin/sqlnet/nvStrToNvPair.js +16 -16
  50. package/lib/thin/sqlnet/packet.js +17 -10
  51. package/lib/thin/sqlnet/paramParser.js +9 -9
  52. package/lib/thin/sqlnet/sessionAtts.js +4 -0
  53. package/lib/thin/statement.js +4 -3
  54. package/lib/thin/util.js +28 -8
  55. package/lib/transformer.js +3 -1
  56. package/lib/util.js +0 -13
  57. package/lib/version.js +2 -2
  58. package/package.json +1 -1
  59. package/build/Release/oracledb-6.0.2-darwin-x64.node +0 -0
  60. package/build/Release/oracledb-6.0.2-darwin-x64.node-buildinfo.txt +0 -1
  61. package/build/Release/oracledb-6.0.2-js-buildinfo.txt +0 -1
  62. package/build/Release/oracledb-6.0.2-linux-arm64.node +0 -0
  63. package/build/Release/oracledb-6.0.2-linux-arm64.node-buildinfo.txt +0 -1
  64. package/build/Release/oracledb-6.0.2-linux-x64.node +0 -0
  65. package/build/Release/oracledb-6.0.2-linux-x64.node-buildinfo.txt +0 -1
  66. package/build/Release/oracledb-6.0.2-win32-x64.node +0 -0
  67. 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
- let stmt = this.statement;
69
- let params = stmt.bindInfoList;
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 == 0 || stmt.isDdl) {
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
- let stmt = this.statement;
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
- let tmpparams = [];
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
- let stmt = this.statement;
278
- if (stmt.cursorId !== 0 && !stmt.requiresFullExecute && !this.parseOnly && !stmt.requiresDefine && !stmt.isDdl && !this.batchErrors) {
279
- if (stmt.isQuery && !stmt.requiresDefine && this.options.prefetchRows > 0) {
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.TNS_CS_NCHAR) {
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.TNS_CS_NCHAR) {
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.TNS_CS_NCHAR) {
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
- decode(buf) {
54
- let message_type = buf.readUInt8();
55
- if (message_type === constants.TNS_MSG_TYPE_PROTOCOL) {
56
- buf.skipBytes(2); // skip protocol array
57
- let x = buf.readUInt8();
58
- while (x !== 0) { // skip server banner
59
- x = buf.readUInt8();
60
- }
61
- buf.skipBytes(2); // character set ID
62
- buf.skipUB1(1); // skip server flags
63
- let num_elem = buf.readUInt16LE();
64
- if (num_elem > 0) { // skip elements
65
- buf.skipBytes(num_elem * 5);
66
- }
67
- let fdoLen = buf.readUInt16BE();
68
- let fdo = buf.readBytes(fdoLen);
69
- let ix = 6 + fdo[5] + fdo[6];
70
- buf.caps.nCharsetId = (fdo[ix + 3] << 8) + fdo[ix + 4];
71
- buf.caps.adjustForServerCompileCaps(buf.readBytesWithLength());
72
- buf.caps.adjustForServerRuntimeCaps(buf.readBytesWithLength());
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
- processDescribeInfo(buf, resultSet) {
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.skipBytes(numBytes + 1); // current date
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.skipBytes(numBytes + 1);
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.TNS_CS_IMPLICIT);
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.TNS_CS_IMPLICIT);
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.TNS_CS_IMPLICIT);
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.skipUB1(); // skip repeated length
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 === null || this.bitVector === undefined) {
288
+ if (!this.bitVector) {
271
289
  return false;
272
290
  }
273
- let byteNum = Math.floor(columnName / 8);
274
- let bitNum = columnName % 8;
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 (let [col, variable] of this.outVariables.entries()) {
298
+ for (const [col, variable] of this.outVariables.entries()) {
281
299
  if (variable.isArray) {
282
300
  variable.numElementsInArray = buf.readUB4();
283
- let values = new Array(variable.numElementsInArray).fill(null);
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
- let numRows = buf.readUB4();
291
- let values = Array(numRows).fill(null);
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
- let bindInfo = this.statement.bindInfoList[i];
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.TNS_CS_NCHAR) {
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.TNS_CS_IMPLICIT);
402
+ colValue = buf.readStr(constants.CSFRM_IMPLICIT);
385
403
  } else {
386
- let numBytes = buf.readUInt8();
404
+ const numBytes = buf.readUInt8();
387
405
  if (isNullLength(numBytes)) {
388
406
  colValue = null;
389
407
  } else {
390
- let rowid = buf.readRowID();
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.TNS_CS_IMPLICIT);
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
- let numBytes = buf.readUInt8();
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
- let bvalue = buf.readUB4();
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.TNS_CS_IMPLICIT);
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
- let numRows = buf.readUB4();
501
- let rowCounts = this.options.dmlRowCounts = [];
518
+ const numRows = buf.readUB4();
519
+ const rowCounts = this.options.dmlRowCounts = [];
502
520
  for (let i = 0; i < numRows; i++) {
503
- let rowCount = buf.readUB8();
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.requiresDefine = true;
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.TNS_CS_NCHAR) {
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.writeUB4(objType.version);
660
+ buf.writeUB2(objType.version);
654
661
  } else {
655
662
  buf.writeUB4(0); // OID
656
- buf.writeUB4(0); // version
663
+ buf.writeUB2(0); // version
657
664
  }
658
665
  if (variable.type._csfrm !== 0) {
659
- buf.writeUB4(constants.TNS_CHARSET_UTF8);
666
+ buf.writeUB2(constants.TNS_CHARSET_UTF8);
660
667
  } else {
661
- buf.writeUB4(0);
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
- let offset = this.offset;
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
- let variable = bindInfo.bindVar;
684
+ const variable = bindInfo.bindVar;
678
685
  if (variable.isArray) {
679
- let numElements = variable.values.length;
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.TNS_CS_NCHAR) {
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
- let childResultSet = this.createCursorFromDescribe(buf);
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 (let element of value) {
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 (let element of value) {
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 (let fieldName of fnamesSeg.fieldNames) {
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 (let fieldName of fnamesSeg.fieldNames) {
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.savedBufferPos === this.savedBuffers.length) {
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.savedBuffers.push(packet.buf);
262
+ this.savedPackets.push(packet);
262
263
  }
263
- this.startPacket(this.savedBuffers[this.savedBufferPos++]);
264
+ this.startPacket(this.savedPackets[this.savedPacketPos++]);
264
265
  }
265
266
 
266
267
  restorePoint() {
267
- this.savedBufferPos = 0;
268
- this.startPacket(this.savedBuffers[this.savedBufferPos++]);
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.savedBuffers) {
274
- this.savedBuffers = this.savedBuffers.splice(this.savedBufferPos - 1);
274
+ if (this.savedPackets) {
275
+ this.savedPackets = this.savedPackets.splice(this.savedPacketPos - 1);
275
276
  } else {
276
- this.savedBuffers = [this.buf];
277
+ this.savedPackets = [this.packet];
277
278
  }
278
- this.savedBufferPos = 1;
279
+ this.savedPacketPos = 1;
279
280
  this.savedPos = this.pos;
280
281
  }
281
282
 
282
- startPacket(buf) {
283
- this.buf = buf;
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.savedBuffers) {
291
- this.savedBuffers = [packet.buf];
292
- this.savedBufferPos = 0;
293
+ if (!this.savedPackets) {
294
+ this.savedPackets = [packet];
295
+ this.savedPacketPos = 0;
293
296
  } else {
294
- this.savedBuffers.push(packet.buf);
297
+ this.savedPackets.push(packet);
295
298
  }
296
- this.startPacket(this.savedBuffers[this.savedBufferPos++]);
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
- let rba = buf.readUInt32BE(1);
326
- let partitionID = buf.readUInt16BE(5);
327
- let blockNum = buf.readUInt32BE(7);
328
- let slotNum = buf.readUInt16BE(11);
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
- let remainder = inputLen % 3;
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
- let outputValue = Buffer.alloc(outputLen);
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
- let rba = this.readUB4();
387
- let partitionID = this.readUB2();
389
+ const rba = this.readUB4();
390
+ const partitionID = this.readUB2();
388
391
  this.skipUB1();
389
- let blockNum = this.readUB4();
390
- let slotNum = this.readUB2();
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