oracledb 6.0.3 → 6.2.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 (65) hide show
  1. package/README.md +2 -2
  2. package/build/Release/oracledb-6.2.0-darwin-x64.node +0 -0
  3. package/build/Release/oracledb-6.2.0-darwin-x64.node-buildinfo.txt +1 -0
  4. package/build/Release/oracledb-6.2.0-js-buildinfo.txt +1 -0
  5. package/build/Release/oracledb-6.2.0-linux-arm64.node +0 -0
  6. package/build/Release/oracledb-6.2.0-linux-arm64.node-buildinfo.txt +1 -0
  7. package/build/Release/oracledb-6.2.0-linux-x64.node +0 -0
  8. package/build/Release/oracledb-6.2.0-linux-x64.node-buildinfo.txt +1 -0
  9. package/build/Release/oracledb-6.2.0-win32-x64.node +0 -0
  10. package/build/Release/oracledb-6.2.0-win32-x64.node-buildinfo.txt +1 -0
  11. package/examples/dbconfig.js +7 -14
  12. package/examples/example.js +0 -1
  13. package/lib/aqQueue.js +40 -26
  14. package/lib/connection.js +16 -4
  15. package/lib/dbObject.js +9 -0
  16. package/lib/errors.js +17 -13
  17. package/lib/impl/connection.js +9 -0
  18. package/lib/impl/resultset.js +7 -4
  19. package/lib/oracledb.js +26 -18
  20. package/lib/pool.js +7 -1
  21. package/lib/sodaCollection.js +12 -1
  22. package/lib/sodaOperation.js +16 -0
  23. package/lib/thin/connection.js +229 -182
  24. package/lib/thin/dbObject.js +4 -1
  25. package/lib/thin/pool.js +153 -68
  26. package/lib/thin/protocol/buffer.js +83 -64
  27. package/lib/thin/protocol/constants.js +3 -14
  28. package/lib/thin/protocol/encryptDecrypt.js +17 -17
  29. package/lib/thin/protocol/messages/auth.js +21 -23
  30. package/lib/thin/protocol/messages/base.js +29 -45
  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 +7 -7
  34. package/lib/thin/protocol/messages/index.js +2 -0
  35. package/lib/thin/protocol/messages/protocol.js +31 -20
  36. package/lib/thin/protocol/messages/withData.js +58 -47
  37. package/lib/thin/protocol/oson.js +17 -14
  38. package/lib/thin/protocol/packet.js +36 -14
  39. package/lib/thin/protocol/utils.js +2 -2
  40. package/lib/thin/resultSet.js +6 -6
  41. package/lib/thin/sqlnet/connStrategy.js +130 -5
  42. package/lib/thin/sqlnet/constants.js +2 -0
  43. package/lib/thin/sqlnet/ezConnectResolver.js +29 -61
  44. package/lib/thin/sqlnet/navNodes.js +34 -27
  45. package/lib/thin/sqlnet/networkSession.js +46 -47
  46. package/lib/thin/sqlnet/ntTcp.js +30 -14
  47. package/lib/thin/sqlnet/nvStrToNvPair.js +16 -16
  48. package/lib/thin/sqlnet/packet.js +10 -3
  49. package/lib/thin/sqlnet/paramParser.js +9 -9
  50. package/lib/thin/sqlnet/sessionAtts.js +4 -0
  51. package/lib/thin/statement.js +345 -113
  52. package/lib/thin/util.js +23 -86
  53. package/lib/transformer.js +3 -1
  54. package/lib/util.js +4 -13
  55. package/lib/version.js +2 -2
  56. package/package.json +1 -1
  57. package/build/Release/oracledb-6.0.3-darwin-x64.node +0 -0
  58. package/build/Release/oracledb-6.0.3-darwin-x64.node-buildinfo.txt +0 -1
  59. package/build/Release/oracledb-6.0.3-js-buildinfo.txt +0 -1
  60. package/build/Release/oracledb-6.0.3-linux-arm64.node +0 -0
  61. package/build/Release/oracledb-6.0.3-linux-arm64.node-buildinfo.txt +0 -1
  62. package/build/Release/oracledb-6.0.3-linux-x64.node +0 -0
  63. package/build/Release/oracledb-6.0.3-linux-x64.node-buildinfo.txt +0 -1
  64. package/build/Release/oracledb-6.0.3-win32-x64.node +0 -0
  65. package/build/Release/oracledb-6.0.3-win32-x64.node-buildinfo.txt +0 -1
@@ -50,9 +50,9 @@ class EncryptDecrypt {
50
50
  }
51
51
 
52
52
  _encrypt(key, val, padding) {
53
- let block_size = 16;
53
+ const block_size = 16;
54
54
  const iv = Buffer.alloc(block_size, 0);
55
- let n = block_size - (val.length % block_size);
55
+ const n = block_size - (val.length % block_size);
56
56
  const nv = Buffer.alloc(n, n);
57
57
  if (n > 0) {
58
58
  if (padding) {
@@ -73,15 +73,15 @@ class EncryptDecrypt {
73
73
 
74
74
  // Encrypt password and newPassword using comboKey
75
75
  _setEncryptedPasswordBuffers(passwordBytes, newPasswordBytes, comboKey, authObj) {
76
- let salt = Buffer.alloc(16);
76
+ const salt = Buffer.alloc(16);
77
77
  crypto.randomFillSync(salt, 0, 16);
78
- let temp = Buffer.concat([salt, passwordBytes]);
78
+ const temp = Buffer.concat([salt, passwordBytes]);
79
79
  authObj.encodedPassword = this._encrypt(comboKey, temp);
80
80
  temp.fill(0);
81
81
  authObj.encodedPassword = authObj.encodedPassword.slice().toString('hex').toUpperCase();
82
82
 
83
83
  if (newPasswordBytes) {
84
- let newPasswordWithSalt = Buffer.concat([salt, newPasswordBytes]);
84
+ const newPasswordWithSalt = Buffer.concat([salt, newPasswordBytes]);
85
85
  authObj.encodedNewPassword = this._encrypt(comboKey, newPasswordWithSalt);
86
86
  newPasswordWithSalt.fill(0);
87
87
  authObj.encodedNewPassword = authObj.encodedNewPassword.slice().toString('hex').toUpperCase();
@@ -106,10 +106,10 @@ class EncryptDecrypt {
106
106
  let keyLen = 32;
107
107
  let hashAlg = 'sha512';
108
108
 
109
- let verifierData = Buffer.from(sessionData['AUTH_VFR_DATA'], 'hex');
110
- let encodedServerKey = Buffer.from(sessionData['AUTH_SESSKEY'], 'hex');
109
+ const verifierData = Buffer.from(sessionData['AUTH_VFR_DATA'], 'hex');
110
+ const encodedServerKey = Buffer.from(sessionData['AUTH_SESSKEY'], 'hex');
111
111
  let iterations = Number(sessionData['AUTH_PBKDF2_VGEN_COUNT']);
112
- let passwordBytes = Buffer.from(password, 'utf8');
112
+ const passwordBytes = Buffer.from(password, 'utf8');
113
113
  let passwordHash;
114
114
  let passwordKey;
115
115
 
@@ -117,18 +117,18 @@ class EncryptDecrypt {
117
117
  algorithm = 'aes-192-cbc';
118
118
  keyLen = 24;
119
119
  hashAlg = 'sha1';
120
- let h = crypto.createHash(hashAlg);
120
+ const h = crypto.createHash(hashAlg);
121
121
  h.update(passwordBytes);
122
122
  h.update(verifierData);
123
- let ph = h.digest();
123
+ const ph = h.digest();
124
124
  passwordHash = Buffer.alloc(ph.length + 4);
125
125
  ph.copy(passwordHash, 0, 0, ph.length);
126
126
  } else {
127
127
  algorithm = 'aes-256-cbc';
128
- let temp = Buffer.from('AUTH_PBKDF2_SPEEDY_KEY', 'utf8');
129
- let salt = Buffer.concat([verifierData, temp]);
128
+ const temp = Buffer.from('AUTH_PBKDF2_SPEEDY_KEY', 'utf8');
129
+ const salt = Buffer.concat([verifierData, temp]);
130
130
  passwordKey = crypto.pbkdf2Sync(passwordBytes, salt, iterations, 64, 'sha512');
131
- let h = crypto.createHash(hashAlg);
131
+ const h = crypto.createHash(hashAlg);
132
132
  h.update(passwordKey);
133
133
  h.update(verifierData);
134
134
  passwordHash = h.digest().slice(0, keyLen);
@@ -163,10 +163,10 @@ class EncryptDecrypt {
163
163
  iterations, keyLen, 'sha512');
164
164
  }
165
165
 
166
- let salt = Buffer.alloc(16);
166
+ const salt = Buffer.alloc(16);
167
167
  if (!verifier11G) {
168
168
  crypto.randomFillSync(salt, 0, 16);
169
- let temp = Buffer.concat([salt, passwordKey]);
169
+ const temp = Buffer.concat([salt, passwordKey]);
170
170
  authObj.speedyKey = this._encrypt(authObj.comboKey, temp);
171
171
  authObj.speedyKey = authObj.speedyKey.slice(0, 80).toString('hex').toUpperCase();
172
172
  }
@@ -184,7 +184,7 @@ class EncryptDecrypt {
184
184
  }
185
185
 
186
186
  updatePasswordsWithComboKey(password, newPassword, comboKey, authObj) {
187
- let passwordBytes = Buffer.from(password, 'utf8');
187
+ const passwordBytes = Buffer.from(password, 'utf8');
188
188
  let newPasswordBytes;
189
189
  if (newPassword) {
190
190
  newPasswordBytes = Buffer.from(newPassword, 'utf8');
@@ -193,5 +193,5 @@ class EncryptDecrypt {
193
193
  }
194
194
  }
195
195
 
196
- let encryptDecryptInst = new EncryptDecrypt();
196
+ const encryptDecryptInst = new EncryptDecrypt();
197
197
  module.exports = encryptDecryptInst;
@@ -103,32 +103,32 @@ class AuthMessage extends Message {
103
103
  }
104
104
  this.serviceName = this.conn.serviceName;
105
105
  this.remoteAddress = this.conn.remoteAddress;
106
- this.setAuthMode();
106
+ this.setAuthMode(config);
107
107
  }
108
108
 
109
- setAuthMode() {
109
+ setAuthMode(config) {
110
110
  if (!this.newPassword) {
111
111
  this.authMode = constants.TNS_AUTH_MODE_LOGON;
112
112
  }
113
- if (this.conn.privilege & constants.SYSDBA) {
113
+ if (config.privilege & constants.SYSDBA) {
114
114
  this.authMode |= constants.TNS_AUTH_MODE_SYSDBA;
115
115
  }
116
- if (this.conn.privilege & constants.SYSOPER) {
116
+ if (config.privilege & constants.SYSOPER) {
117
117
  this.authMode |= constants.TNS_AUTH_MODE_SYSOPER;
118
118
  }
119
- if (this.conn.privilege & constants.SYSASM) {
119
+ if (config.privilege & constants.SYSASM) {
120
120
  this.authMode |= constants.TNS_AUTH_MODE_SYSASM;
121
121
  }
122
- if (this.conn.privilege & constants.SYSBKP) {
122
+ if (config.privilege & constants.SYSBKP) {
123
123
  this.authMode |= constants.TNS_AUTH_MODE_SYSBKP;
124
124
  }
125
- if (this.conn.privilege & constants.SYSDG) {
125
+ if (config.privilege & constants.SYSDG) {
126
126
  this.authMode |= constants.TNS_AUTH_MODE_SYSDGD;
127
127
  }
128
- if (this.conn.privilege & constants.SYSKM) {
128
+ if (config.privilege & constants.SYSKM) {
129
129
  this.authMode |= constants.TNS_AUTH_MODE_SYSKMT;
130
130
  }
131
- if (this.conn.privilege & constants.SYSRAC) {
131
+ if (config.privilege & constants.SYSRAC) {
132
132
  this.authMode |= constants.TNS_AUTH_MODE_SYSRAC;
133
133
  }
134
134
  if (this.privateKey) {
@@ -221,7 +221,7 @@ class AuthMessage extends Message {
221
221
  if (this.privateKey) {
222
222
  numPairs += 2;
223
223
  }
224
- if (this.conn.connClass) {
224
+ if (this.conn.connectionClass) {
225
225
  numPairs += 1;
226
226
  }
227
227
  if (this.conn.purity) {
@@ -268,8 +268,8 @@ class AuthMessage extends Message {
268
268
  if (this.encodedNewPassword) {
269
269
  buf.writeKeyValue("AUTH_NEWPASSWORD", this.encodedNewPassword);
270
270
  }
271
- if (this.conn.connClass) {
272
- buf.writeKeyValue("AUTH_KPPL_CONN_CLASS", this.conn.connClass);
271
+ if (this.conn.connectionClass) {
272
+ buf.writeKeyValue("AUTH_KPPL_CONN_CLASS", this.conn.connectionClass);
273
273
  }
274
274
  if (this.conn.purity) {
275
275
  buf.writeKeyValue("AUTH_KPPL_PURITY", '' + this.conn.purity);
@@ -278,11 +278,11 @@ class AuthMessage extends Message {
278
278
  const currentDate = new Date();
279
279
  const currentDateFormatted = currentDate.toGMTString();
280
280
 
281
- let header = "date: " + currentDateFormatted + "\n" +
281
+ const header = "date: " + currentDateFormatted + "\n" +
282
282
  "(request-target): " + this.serviceName + "\n" +
283
283
  "host: " + this.remoteAddress;
284
284
 
285
- let signature = crypto.createSign('RSA-SHA256')
285
+ const signature = crypto.createSign('RSA-SHA256')
286
286
  .update(header)
287
287
  .sign(this.privateKey, 'base64');
288
288
 
@@ -297,16 +297,16 @@ class AuthMessage extends Message {
297
297
  }
298
298
 
299
299
  processReturnParameter(buf) {
300
- let numParams = buf.readUB2();
300
+ const numParams = buf.readUB2();
301
301
  for (let i = 0; i < numParams;i++) {
302
302
  buf.skipUB4();
303
- let key = buf.readStr(constants.CSFRM_IMPLICIT);
303
+ const key = buf.readStr(constants.CSFRM_IMPLICIT);
304
304
  let value = "";
305
- let numBytes = buf.readUB4();
305
+ const numBytes = buf.readUB4();
306
306
  if (numBytes > 0) {
307
307
  value = buf.readStr(constants.CSFRM_IMPLICIT);
308
308
  }
309
- let flag = buf.readUB4();
309
+ const flag = buf.readUB4();
310
310
  if (key === "AUTH_VFR_DATA") {
311
311
  this.verifierType = flag;
312
312
  }
@@ -316,16 +316,14 @@ class AuthMessage extends Message {
316
316
  if (this.functionCode === constants.TNS_FUNC_AUTH_PHASE_ONE) {
317
317
  this.functionCode = constants.TNS_FUNC_AUTH_PHASE_TWO;
318
318
  } else {
319
- let versionNum;
320
319
  let releaseNum;
321
320
  let updateNum;
322
321
  let portReleaseNum;
323
322
  let portUpdateNum;
324
323
 
325
- this.conn.sessionID = this.sessionData['AUTH_SESSION_ID'];
326
- this.conn.serialNum = this.sessionData['AUTH_SERIAL_NUM'];
327
- let fullVersionNum = Number(this.sessionData['AUTH_VERSION_NO']);
328
- versionNum = (fullVersionNum >> 24) & 0xFF;
324
+ this.conn.instanceName = this.sessionData['AUTH_INSTANCENAME'];
325
+ const fullVersionNum = Number(this.sessionData['AUTH_VERSION_NO']);
326
+ const versionNum = (fullVersionNum >> 24) & 0xFF;
329
327
  if (buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_18_1_EXT_1) {
330
328
  releaseNum = (fullVersionNum >> 16) & 0xFF;
331
329
  updateNum = (fullVersionNum >> 12) & 0x0F;
@@ -30,37 +30,13 @@ const { Buffer } = require('buffer');
30
30
  const constants = require("../constants.js");
31
31
  const errors = require("../../../errors.js");
32
32
 
33
- class OracleErrorInfo {
34
- constructor() {
35
- this.num = 0;
36
- this.cursorId = 0;
37
- this.pos = 0;
38
- this.rowCount = 0;
39
- this.message = "";
40
- this.rowID = null;
41
- this.batchErrors;
42
- }
43
- }
44
-
45
- class Error {
46
- constructor(num, message = "", context = "", isRecoverable = false, isWarning = false, code = 0, offset = 0) {
47
- this.num = num;
48
- this.message = message;
49
- this.context = context;
50
- this.isRecoverable = isRecoverable;
51
- this.isWarning = isWarning;
52
- this.code = code;
53
- this.offset = offset;
54
- }
55
- }
56
-
57
33
  /**
58
34
  *
59
35
  * Base class for all the RPC messages to support encode/decode functions
60
36
  */
61
37
  class Message {
62
38
  constructor(connection) {
63
- this.errorInfo = new OracleErrorInfo();
39
+ this.errorInfo = {};
64
40
  this.connection = connection;
65
41
  this.messageType = constants.TNS_MSG_TYPE_FUNCTION;
66
42
  this.functionCode = 0;
@@ -106,7 +82,7 @@ class Message {
106
82
  buf.skipUB1(); // call number
107
83
  buf.skipUB2(); // padding
108
84
  buf.skipUB4(); // success iters
109
- let numBytes = buf.readUB4(); // oerrdd (logical rowid)
85
+ const numBytes = buf.readUB4(); // oerrdd (logical rowid)
110
86
  if (numBytes > 0) {
111
87
  buf.skipBytesChunked();
112
88
  }
@@ -114,12 +90,12 @@ class Message {
114
90
  let numEntries = buf.readUB2(); // batch error codes array
115
91
  if (numEntries > 0) {
116
92
  this.errorInfo.batchErrors = [];
117
- let firstByte = buf.readUInt8();
93
+ const firstByte = buf.readUInt8();
118
94
  for (let i = 0; i < numEntries; i++) {
119
95
  if (firstByte === constants.TNS_LONG_LENGTH_INDICATOR) {
120
96
  buf.skipUB4(); // chunk length ignored
121
97
  }
122
- let errorCode = buf.readUB2();
98
+ const errorCode = buf.readUB2();
123
99
  this.errorInfo.batchErrors.push(new Error(errorCode));
124
100
  }
125
101
  if (firstByte === constants.TNS_LONG_LENGTH_INDICATOR) {
@@ -130,7 +106,7 @@ class Message {
130
106
  // batch error offset
131
107
  numEntries = buf.readUB2(); // batch error row offset array
132
108
  if (numEntries > 0) {
133
- let firstByte = buf.readUInt8();
109
+ const firstByte = buf.readUInt8();
134
110
  for (let i = 0; i < numEntries; i++) {
135
111
  if (firstByte === constants.TNS_LONG_LENGTH_INDICATOR) {
136
112
  buf.skipUB4(); // chunk length ignored
@@ -172,7 +148,7 @@ class Message {
172
148
 
173
149
  processWarningInfo(buf) {
174
150
  this.errorInfo.num = buf.readUB2(); // error number
175
- let numBytes = buf.readUB2(); // length of error message
151
+ const numBytes = buf.readUB2(); // length of error message
176
152
  buf.skipUB2(); // flags
177
153
  if (this.errorInfo.num != 0 && numBytes > 0) {
178
154
  this.errorInfo.message = buf.readStr(constants.CSFRM_IMPLICIT);
@@ -224,18 +200,19 @@ class Message {
224
200
  if (opcode === constants.TNS_SERVER_PIGGYBACK_LTXID) {
225
201
  const num_bytes = buf.readUB4();
226
202
  if (num_bytes > 0) {
227
- buf.skipBytes(num_bytes);
203
+ buf.skipBytesChunked();
228
204
  }
229
205
  } else if ((opcode === constants.TNS_SERVER_PIGGYBACK_QUERY_CACHE_INVALIDATION)
230
206
  || (opcode === constants.TNS_SERVER_PIGGYBACK_TRACE_EVENT)) {
231
207
  // pass
232
208
  } else if (opcode === constants.TNS_SERVER_PIGGYBACK_OS_PID_MTS) {
233
- buf.skipUB2();
234
- buf.skipBytesChunked();
209
+ const numDtys = buf.readUB2();
210
+ buf.skipUB1();
211
+ buf.skipBytes(numDtys);
235
212
  } else if (opcode === constants.TNS_SERVER_PIGGYBACK_SYNC) {
236
213
  buf.skipUB2(); // skip number of DTYs
237
214
  buf.skipUB1(); // skip length of DTYs
238
- const num_elements = buf.readUB2();
215
+ const num_elements = buf.readUB4();
239
216
  buf.skipBytes(1); // skip length
240
217
  for (let i = 0; i < num_elements; i++) {
241
218
  let temp16 = buf.readUB2();
@@ -247,20 +224,20 @@ class Message {
247
224
  buf.skipBytesChunked();
248
225
  }
249
226
  buf.skipUB2(); // skip flags
250
- buf.skipUB4(); // skip overall flags
251
227
  }
228
+ buf.skipUB4(); // skip overall flags
252
229
  } else if (opcode === constants.TNS_SERVER_PIGGYBACK_EXT_SYNC) {
253
230
  buf.skipUB2();
254
231
  buf.skipUB1();
255
232
  } else if (opcode === constants.TNS_SERVER_PIGGYBACK_AC_REPLAY_CONTEXT) {
256
233
  buf.skipUB2(); // skip number of DTYs
257
- buf.skipUB1(1); // skip length of DTYs
234
+ buf.skipUB1(); // skip length of DTYs
258
235
  buf.skipUB4(); // skip flags
259
236
  buf.skipUB4(); // skip error code
260
237
  buf.skipUB1(); // skip queue
261
238
  const num_bytes = buf.readUB4(); // skip replay context
262
239
  if (num_bytes > 0) {
263
- buf.skipBytes(num_bytes);
240
+ buf.skipBytesChunked();
264
241
  }
265
242
  } else if (opcode === constants.TNS_SERVER_PIGGYBACK_SESS_RET) {
266
243
  buf.skipUB2();
@@ -283,7 +260,7 @@ class Message {
283
260
  const flags = buf.readUB4(); // session flags
284
261
  if (flags & constants.TNS_SESSGET_SESSION_CHANGED) {
285
262
  if (this.connection._drcpEstablishSession) {
286
- this.connection.resetStatmentCache();
263
+ this.connection.resetStatementCache();
287
264
  }
288
265
  }
289
266
  this.connection._drcpEstablishSession = false;
@@ -335,8 +312,8 @@ class Message {
335
312
  }
336
313
 
337
314
  writeCloseTempLobsPiggyback(buf) {
338
- let lobsToClose = this.connection._tempLobsToClose;
339
- let opCode = constants.TNS_LOB_OP_FREE_TEMP | constants.TNS_LOB_OP_ARRAY;
315
+ const lobsToClose = this.connection._tempLobsToClose;
316
+ const opCode = constants.TNS_LOB_OP_FREE_TEMP | constants.TNS_LOB_OP_ARRAY;
340
317
 
341
318
  this.writePiggybackHeader(buf, constants.TNS_FUNC_LOB_OP);
342
319
 
@@ -406,9 +383,9 @@ class Message {
406
383
  buf.writeUInt8(0); // pointer (cidser)
407
384
  buf.writeUB4(flags);
408
385
 
409
- let clientIdentifierBytes = this.writeEndEndTraceValue(buf, this.connection._clientIdentifier, this.connection._clientIdentifierModified);
410
- let moduleBytes = this.writeEndEndTraceValue(buf, this.connection._module, this.connection._moduleModified);
411
- let actionBytes = this.writeEndEndTraceValue(buf, this.connection._action, this.connection._actionModified);
386
+ const clientIdentifierBytes = this.writeEndEndTraceValue(buf, this.connection._clientIdentifier, this.connection._clientIdentifierModified);
387
+ const moduleBytes = this.writeEndEndTraceValue(buf, this.connection._module, this.connection._moduleModified);
388
+ const actionBytes = this.writeEndEndTraceValue(buf, this.connection._action, this.connection._actionModified);
412
389
 
413
390
  // write unsupported bits
414
391
  buf.writeUInt8(0); // pointer (cideci)
@@ -416,13 +393,13 @@ class Message {
416
393
  buf.writeUInt8(0); // cidcct
417
394
  buf.writeUB4(0); // cidecs
418
395
 
419
- let clientInfoBytes = this.writeEndEndTraceValue(buf, this.connection._clientInfo, this.connection._clientInfoModified);
396
+ const clientInfoBytes = this.writeEndEndTraceValue(buf, this.connection._clientInfo, this.connection._clientInfoModified);
420
397
  // write unsupported bits
421
398
  buf.writeUInt8(0); // pointer (cideci)
422
399
  buf.writeUB4(0); // length (cideci)
423
400
  buf.writeUInt8(0); // cidcct
424
401
  buf.writeUB4(0); // cidecs
425
- let dbOpBytes = this.writeEndEndTraceValue(buf, this.connection._dbOp, this.connection._dbOpModified);
402
+ const dbOpBytes = this.writeEndEndTraceValue(buf, this.connection._dbOp, this.connection._dbOpModified);
426
403
 
427
404
  // write strings
428
405
  if (this.connection._clientIdentifierModified && this.connection._clientIdentifier) {
@@ -471,6 +448,13 @@ class Message {
471
448
  }
472
449
  return writtenBytes;
473
450
  }
451
+
452
+ // Called when an error is encountered during decode of RPC
453
+ saveDeferredErr() {
454
+ if (!this.deferredErr) {
455
+ this.deferredErr = errors.getErr(...arguments);
456
+ }
457
+ }
474
458
  }
475
459
 
476
460
  module.exports = Message;
@@ -0,0 +1,76 @@
1
+ // Copyright (c) 2023 Oracle and/or its affiliates.
2
+
3
+ //-----------------------------------------------------------------------------
4
+ //
5
+ // This software is dual-licensed to you under the Universal Permissive License
6
+ // (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
7
+ // 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
8
+ // either license.
9
+ //
10
+ // If you elect to accept the software under the Apache License, Version 2.0,
11
+ // the following applies:
12
+ //
13
+ // Licensed under the Apache License, Version 2.0 (the "License");
14
+ // you may not use this file except in compliance with the License.
15
+ // You may obtain a copy of the License at
16
+ //
17
+ // https://www.apache.org/licenses/LICENSE-2.0
18
+ //
19
+ // Unless required by applicable law or agreed to in writing, software
20
+ // distributed under the License is distributed on an "AS IS" BASIS,
21
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22
+ // See the License for the specific language governing permissions and
23
+ // limitations under the License.
24
+ //
25
+ //-----------------------------------------------------------------------------
26
+
27
+ 'use strict';
28
+
29
+ const constants = require("../constants.js");
30
+ const Message = require("./base.js");
31
+
32
+ /**
33
+ * Executes a Fast Negotiation RPC function.
34
+ * It sends Protocol Negotiation, Cookie Message, Datatype Negotiation
35
+ * and OSESS Key RPC in single round trip.
36
+ *
37
+ * @class ConnectionCookieMessage
38
+ * @extends {Message}
39
+ */
40
+ class ConnectionCookieMessage extends Message {
41
+
42
+ /**
43
+ * Serializes the ConnectionCookieMessage function arguments
44
+ *
45
+ * @param {object} buf input arguments
46
+ */
47
+ encode(buf) {
48
+ this.protocolMessage.encode(buf);
49
+ buf.writeUInt8(constants.TNS_MSG_TYPE_COOKIE);
50
+ buf.writeUInt8(1); // cookie version
51
+ buf.writeUInt8(this.cookie.protocolVersion);
52
+ buf.writeUInt16LE(this.cookie.charsetID);
53
+ buf.writeUInt8(this.cookie.flags);
54
+ buf.writeUInt16LE(this.cookie.ncharsetID);
55
+ buf.writeBytesWithLength(this.cookie.serverBanner);
56
+ buf.writeBytesWithLength(this.cookie.compileCaps);
57
+ buf.writeBytesWithLength(this.cookie.runtimeCaps);
58
+ this.dataTypeMessage.encode(buf);
59
+ this.authMessage.encode(buf);
60
+ }
61
+
62
+ processMessage(buf, messageType) {
63
+ if (messageType === constants.TNS_MSG_TYPE_RENEGOTIATE) {
64
+ this.cookie.populated = false;
65
+ } else if (messageType === constants.TNS_MSG_TYPE_PROTOCOL) {
66
+ this.protocolMessage.processMessage(buf, messageType);
67
+ } else if (messageType === constants.TNS_MSG_TYPE_DATA_TYPES) {
68
+ this.dataTypeMessage.processMessage(buf, messageType);
69
+ } else {
70
+ this.authMessage.processMessage(buf, messageType);
71
+ }
72
+ }
73
+
74
+ }
75
+
76
+ module.exports = ConnectionCookieMessage;
@@ -38,14 +38,18 @@ const Message = require("./base.js");
38
38
  */
39
39
  class DataTypeMessage extends Message {
40
40
 
41
- processMessage(buf) {
42
- while (true) { // eslint-disable-line
43
- const dataType = buf.readUInt16BE();
44
- if (dataType === 0)
45
- break;
46
- const convDataType = buf.readUInt16BE();
47
- if (convDataType !== 0)
48
- buf.skipBytes(4);
41
+ processMessage(buf, messageType) {
42
+ if (messageType === constants.TNS_MSG_TYPE_DATA_TYPES) {
43
+ while (true) { // eslint-disable-line
44
+ const dataType = buf.readUInt16BE();
45
+ if (dataType === 0)
46
+ break;
47
+ const convDataType = buf.readUInt16BE();
48
+ if (convDataType !== 0)
49
+ buf.skipBytes(4);
50
+ }
51
+ } else {
52
+ super.processMessage(buf, messageType);
49
53
  }
50
54
  }
51
55
 
@@ -57,7 +61,7 @@ class DataTypeMessage extends Message {
57
61
  constants.TNS_ENCODING_CONV_LENGTH);
58
62
  buf.writeBytesWithLength(buf.caps.compileCaps);
59
63
  buf.writeBytesWithLength(buf.caps.runtimeCaps);
60
- for (let val of dataTypes) {
64
+ for (const val of dataTypes) {
61
65
  buf.writeUInt16BE(val[0]);
62
66
  buf.writeUInt16BE(val[1]);
63
67
  buf.writeUInt16BE(val[2]);
@@ -65,8 +65,8 @@ class ExecuteMessage extends MessageWithData {
65
65
  let numParams = 0;
66
66
  let numIters = 1;
67
67
  // Configuring the options field thats send to the server
68
- 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;
@@ -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 && !stmt.noPrefetch && 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,
@@ -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