oracledb 6.5.1 → 6.7.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 (73) hide show
  1. package/README.md +2 -2
  2. package/build/Release/oracledb-6.7.0-darwin-arm64.node +0 -0
  3. package/build/Release/oracledb-6.7.0-darwin-arm64.node-buildinfo.txt +1 -0
  4. package/build/Release/oracledb-6.7.0-darwin-x64.node +0 -0
  5. package/build/Release/oracledb-6.7.0-darwin-x64.node-buildinfo.txt +1 -0
  6. package/build/Release/oracledb-6.7.0-js-buildinfo.txt +1 -0
  7. package/build/Release/oracledb-6.7.0-linux-arm64.node +0 -0
  8. package/build/Release/oracledb-6.7.0-linux-arm64.node-buildinfo.txt +1 -0
  9. package/build/Release/oracledb-6.7.0-linux-x64.node +0 -0
  10. package/build/Release/oracledb-6.7.0-linux-x64.node-buildinfo.txt +1 -0
  11. package/build/Release/oracledb-6.7.0-win32-x64.node +0 -0
  12. package/build/Release/oracledb-6.7.0-win32-x64.node-buildinfo.txt +1 -0
  13. package/examples/README.md +4 -0
  14. package/lib/configProviders/azure.js +178 -0
  15. package/lib/configProviders/base.js +85 -0
  16. package/lib/configProviders/ociobject.js +211 -0
  17. package/lib/connection.js +97 -14
  18. package/lib/constants.js +1 -0
  19. package/lib/errors.js +68 -6
  20. package/lib/impl/aqQueue.js +2 -1
  21. package/lib/impl/base.js +45 -0
  22. package/lib/impl/connection.js +53 -0
  23. package/lib/impl/datahandlers/constants.js +3 -1
  24. package/lib/impl/datahandlers/vector.js +24 -9
  25. package/lib/impl/lob.js +29 -1
  26. package/lib/impl/pool.js +15 -0
  27. package/lib/impl/resultset.js +28 -2
  28. package/lib/impl/sodaCollection.js +2 -1
  29. package/lib/impl/sodaDatabase.js +2 -1
  30. package/lib/impl/sodaDocCursor.js +2 -1
  31. package/lib/impl/sodaOperation.js +2 -1
  32. package/lib/lob.js +55 -3
  33. package/lib/oracledb.js +246 -7
  34. package/lib/pool.js +14 -5
  35. package/lib/settings.js +1 -0
  36. package/lib/thin/connection.js +304 -29
  37. package/lib/thin/dbObject.js +4 -0
  38. package/lib/thin/lob.js +193 -1
  39. package/lib/thin/pool.js +18 -0
  40. package/lib/thin/protocol/capabilities.js +2 -0
  41. package/lib/thin/protocol/constants.js +29 -1
  42. package/lib/thin/protocol/messages/auth.js +12 -6
  43. package/lib/thin/protocol/messages/base.js +3 -0
  44. package/lib/thin/protocol/messages/index.js +5 -1
  45. package/lib/thin/protocol/messages/lobOp.js +17 -5
  46. package/lib/thin/protocol/messages/sessionRelease.js +1 -0
  47. package/lib/thin/protocol/messages/transactionChangeState.js +99 -0
  48. package/lib/thin/protocol/messages/transactionSwitch.js +139 -0
  49. package/lib/thin/protocol/messages/withData.js +21 -6
  50. package/lib/thin/protocol/protocol.js +23 -0
  51. package/lib/thin/sqlnet/connStrategy.js +9 -1
  52. package/lib/thin/sqlnet/constants.js +2 -0
  53. package/lib/thin/sqlnet/navNodes.js +14 -2
  54. package/lib/thin/sqlnet/networkSession.js +11 -10
  55. package/lib/thin/sqlnet/ntTcp.js +1 -1
  56. package/lib/thin/sqlnet/paramParser.js +87 -50
  57. package/lib/thin/sqlnet/sessionAtts.js +14 -2
  58. package/lib/thin/util.js +4 -3
  59. package/lib/traceHandler.js +133 -0
  60. package/lib/transformer.js +1 -2
  61. package/lib/types.js +1 -1
  62. package/lib/util.js +213 -35
  63. package/lib/version.js +2 -2
  64. package/package.json +1 -1
  65. package/build/Release/oracledb-6.5.1-darwin-x64.node +0 -0
  66. package/build/Release/oracledb-6.5.1-darwin-x64.node-buildinfo.txt +0 -1
  67. package/build/Release/oracledb-6.5.1-js-buildinfo.txt +0 -1
  68. package/build/Release/oracledb-6.5.1-linux-arm64.node +0 -0
  69. package/build/Release/oracledb-6.5.1-linux-arm64.node-buildinfo.txt +0 -1
  70. package/build/Release/oracledb-6.5.1-linux-x64.node +0 -0
  71. package/build/Release/oracledb-6.5.1-linux-x64.node-buildinfo.txt +0 -1
  72. package/build/Release/oracledb-6.5.1-win32-x64.node +0 -0
  73. package/build/Release/oracledb-6.5.1-win32-x64.node-buildinfo.txt +0 -1
package/lib/thin/lob.js CHANGED
@@ -31,6 +31,7 @@ const LobImpl = require('../impl/lob.js');
31
31
  const constants = require('./protocol/constants.js');
32
32
  const LobOpMessage = require('./protocol/messages/lobOp.js');
33
33
  const errors = require('../errors.js');
34
+ const types = require('../types.js');
34
35
 
35
36
  class ThinLobImpl extends LobImpl {
36
37
 
@@ -54,15 +55,31 @@ class ThinLobImpl extends LobImpl {
54
55
  await this.conn._protocol._processMessage(message);
55
56
  if (options.operation === constants.TNS_LOB_OP_READ) {
56
57
  return (message.data) ? message.data : null;
58
+ } else if (
59
+ options.operation === constants.TNS_LOB_OP_FILE_EXISTS ||
60
+ options.operation === constants.TNS_LOB_OP_FILE_ISOPEN
61
+ ) {
62
+ return message.boolFlag;
57
63
  } else {
58
64
  return message.amount;
59
65
  }
60
66
  }
61
67
 
68
+ //---------------------------------------------------------------------------
69
+ // getChunkSize()
70
+ //
71
+ // Internal method for returning the chunk size of the LOB.
72
+ //---------------------------------------------------------------------------
62
73
  getChunkSize() {
63
74
  return this._chunkSize;
64
75
  }
65
76
 
77
+ //---------------------------------------------------------------------------
78
+ // _getChunkSizeAsync()
79
+ //
80
+ // Internal method for returning the chunk size of the LOB fetched from
81
+ // the database.
82
+ //---------------------------------------------------------------------------
66
83
  async _getChunkSizeAsync() {
67
84
  this.checkConn();
68
85
  const options = {
@@ -73,29 +90,76 @@ class ThinLobImpl extends LobImpl {
73
90
  this._chunkSize = this._pieceSize = await this._sendMessage(options);
74
91
  }
75
92
 
93
+ //---------------------------------------------------------------------------
94
+ // getLength()
95
+ //
96
+ // Internal method for returning the length of a LOB.
97
+ //---------------------------------------------------------------------------
76
98
  getLength() {
77
99
  return this._length;
78
100
  }
79
101
 
102
+ //---------------------------------------------------------------------------
103
+ // getPieceSize()
104
+ //
105
+ // Internal method returning the size to use for each piece that is
106
+ // transferred when reading from the LOB.
107
+ //---------------------------------------------------------------------------
80
108
  getPieceSize() {
81
109
  return this._pieceSize;
82
110
  }
83
111
 
112
+ //---------------------------------------------------------------------------
113
+ // setPieceSize()
114
+ //
115
+ // Internal method to set the pieceSize for LOBs.
116
+ //---------------------------------------------------------------------------
84
117
  setPieceSize(value) {
85
118
  this._pieceSize = value;
86
119
  }
87
120
 
121
+ //---------------------------------------------------------------------------
122
+ // getType()
123
+ //
124
+ // Internal method returning the datatype of LOBs.
125
+ //---------------------------------------------------------------------------
88
126
  getType() {
89
127
  return this.dbType;
90
128
  }
91
129
 
130
+ //---------------------------------------------------------------------------
131
+ // getData()
132
+ //
133
+ // Internal method returning the data obtained from the database.
134
+ //---------------------------------------------------------------------------
92
135
  async getData(offset = 1, len = this._length) {
136
+ let shouldClose = false;
93
137
  if (!len) {
94
138
  len = this._length;
95
139
  }
96
- return await this.read(offset, len);
140
+ if (this.dbType === types.DB_TYPE_BFILE) {
141
+ if (!await this.isFileOpen()) {
142
+ shouldClose = true;
143
+ await this.openFile();
144
+ }
145
+ }
146
+ let data;
147
+ // if read fails and BFILE was opened by application, we close it.
148
+ try {
149
+ data = await this.read(offset, len);
150
+ } finally {
151
+ if (shouldClose) {
152
+ await this.closeFile();
153
+ }
154
+ }
155
+ return data;
97
156
  }
98
157
 
158
+ //---------------------------------------------------------------------------
159
+ // read()
160
+ //
161
+ // Internal method for reading a portion (or all) of the data in the LOB.
162
+ //---------------------------------------------------------------------------
99
163
  async read(offset, length) {
100
164
  this.checkConn();
101
165
  const options = {
@@ -108,6 +172,11 @@ class ThinLobImpl extends LobImpl {
108
172
  return await this._sendMessage(options);
109
173
  }
110
174
 
175
+ //---------------------------------------------------------------------------
176
+ // write()
177
+ //
178
+ // Internal method for writing data to the LOB object.
179
+ //---------------------------------------------------------------------------
111
180
  async write(offset, data) {
112
181
  this.checkConn();
113
182
  const options = {
@@ -120,6 +189,11 @@ class ThinLobImpl extends LobImpl {
120
189
  this._length += data.length;
121
190
  }
122
191
 
192
+ //---------------------------------------------------------------------------
193
+ // getCsfrm()
194
+ //
195
+ // Return the character set encoding used by the LOB.
196
+ //---------------------------------------------------------------------------
123
197
  getCsfrm() {
124
198
  if (this.dbType._csfrm !== constants.CSFRM_NCHAR) {
125
199
  if (this._locator[constants.TNS_LOB_LOC_OFFSET_FLAG_3] &
@@ -155,11 +229,60 @@ class ThinLobImpl extends LobImpl {
155
229
  await this._getChunkSizeAsync();
156
230
  }
157
231
 
232
+ //---------------------------------------------------------------------------
233
+ // fileExists()
234
+ //
235
+ // Internal method for returning whether the file referenced by a BFILE
236
+ // exists.
237
+ //---------------------------------------------------------------------------
238
+ async fileExists() {
239
+ this.checkConn();
240
+ const options = {
241
+ operation: constants.TNS_LOB_OP_FILE_EXISTS,
242
+ sourceLobImpl: this,
243
+ };
244
+ return await this._sendMessage(options);
245
+ }
246
+
247
+ //---------------------------------------------------------------------------
248
+ // getDirFileName()
249
+ //
250
+ // Internal method for returning the directory alias and name of the file
251
+ // referenced by a BFILE
252
+ //---------------------------------------------------------------------------
253
+ getDirFileName() {
254
+ const dirNameOffset = constants.TNS_LOB_LOC_FIXED_OFFSET + 2;
255
+ const dirNameLen = this._locator.readUInt16BE(
256
+ constants.TNS_LOB_LOC_FIXED_OFFSET
257
+ );
258
+ const fileNameOffset = constants.TNS_LOB_LOC_FIXED_OFFSET + dirNameLen + 4;
259
+ const fileNameLen = this._locator.readUInt16BE(
260
+ dirNameOffset + dirNameLen
261
+ );
262
+ const dirName = this._locator.slice(
263
+ dirNameOffset, dirNameOffset + dirNameLen
264
+ ).toString();
265
+ const fileName = this._locator.slice(
266
+ fileNameOffset, fileNameOffset + fileNameLen
267
+ ).toString();
268
+ return { dirName: dirName, fileName: fileName };
269
+ }
270
+
271
+ //---------------------------------------------------------------------------
272
+ // checkConn()
273
+ //
274
+ // Internal method to check the connection.
275
+ //---------------------------------------------------------------------------
158
276
  checkConn() {
159
277
  if (!this.conn.nscon.connected)
160
278
  errors.throwErr(errors.ERR_INVALID_CONNECTION);
161
279
  }
162
280
 
281
+ //---------------------------------------------------------------------------
282
+ // close()
283
+ //
284
+ // Internal method to close the LOBs using piggyback mechanism.
285
+ //---------------------------------------------------------------------------
163
286
  close() {
164
287
  this.checkConn();
165
288
  if (this._isTempLob) {
@@ -169,6 +292,25 @@ class ThinLobImpl extends LobImpl {
169
292
  }
170
293
  }
171
294
 
295
+ //---------------------------------------------------------------------------
296
+ // closeFile()
297
+ //
298
+ // Internal method to close the opened file for BFILE LOBs.
299
+ //---------------------------------------------------------------------------
300
+ async closeFile() {
301
+ this.checkConn();
302
+ const options = {
303
+ operation: constants.TNS_LOB_OP_FILE_CLOSE,
304
+ sourceLobImpl: this,
305
+ };
306
+ await this._sendMessage(options);
307
+ }
308
+
309
+ //---------------------------------------------------------------------------
310
+ // init()
311
+ //
312
+ // Internal method to initialize LOBs.
313
+ //---------------------------------------------------------------------------
172
314
  init(conn, locator, dbType, len, chunkSize) {
173
315
  this.dirtyLength = false;
174
316
  this.conn = conn;
@@ -184,6 +326,56 @@ class ThinLobImpl extends LobImpl {
184
326
  this._pieceSize = chunkSize;
185
327
  }
186
328
 
329
+ //---------------------------------------------------------------------------
330
+ // isFileOpen()
331
+ //
332
+ // Internal method to check if the file is already open.
333
+ //---------------------------------------------------------------------------
334
+ async isFileOpen() {
335
+ const options = {
336
+ operation: constants.TNS_LOB_OP_FILE_ISOPEN,
337
+ sourceLobImpl: this
338
+ };
339
+ await this._sendMessage(options);
340
+ }
341
+
342
+ //---------------------------------------------------------------------------
343
+ // openFile()
344
+ //
345
+ // Internal method for opening file (BFILE).
346
+ //---------------------------------------------------------------------------
347
+ async openFile() {
348
+ this.checkConn();
349
+ const options = {
350
+ operation: constants.TNS_LOB_OP_FILE_OPEN,
351
+ sourceLobImpl: this,
352
+ amount: constants.TNS_LOB_OPEN_READ_ONLY,
353
+ sendAmount: true
354
+ };
355
+ return await this._sendMessage(options);
356
+ }
357
+
358
+ //---------------------------------------------------------------------------
359
+ // setDirFileName()
360
+ //
361
+ // Internal method for setting the directory alias and name of the file
362
+ // referenced by a BFILE
363
+ //---------------------------------------------------------------------------
364
+ setDirFileName(dirObject) {
365
+ const dirNameLen = Buffer.byteLength(dirObject.dirName);
366
+ const dirNameOffset = constants.TNS_LOB_LOC_FIXED_OFFSET + 2;
367
+ const fileNameOffset = dirNameOffset + dirNameLen + 2;
368
+ const fileNameLen = Buffer.byteLength(dirObject.fileName);
369
+ const newLocLen = fileNameOffset + fileNameLen;
370
+ const newLocator = Buffer.allocUnsafe(newLocLen);
371
+ this._locator.copy(newLocator, 0, 0, constants.TNS_LOB_LOC_FIXED_OFFSET + 1);
372
+ newLocator.writeUInt16BE(dirNameLen, constants.TNS_LOB_LOC_FIXED_OFFSET);
373
+ newLocator.write(dirObject.dirName, dirNameOffset);
374
+ newLocator.writeInt16BE(fileNameLen, dirNameOffset + dirNameLen);
375
+ newLocator.write(dirObject.fileName, fileNameOffset);
376
+ this._locator = newLocator;
377
+ }
378
+
187
379
  }
188
380
 
189
381
  module.exports = ThinLobImpl;
package/lib/thin/pool.js CHANGED
@@ -44,6 +44,9 @@ class ThinPoolImpl extends PoolImpl {
44
44
  if (!params.homogeneous) {
45
45
  errors.throwErr(errors.ERR_NOT_IMPLEMENTED, 'Heterogeneous Pooling');
46
46
  }
47
+ if (!params.connectString) {
48
+ errors.throwErr(errors.ERR_EMPTY_CONNECT_STRING);
49
+ }
47
50
  thinUtil.checkCredentials(params);
48
51
 
49
52
  this._availableObjects = [];
@@ -64,6 +67,7 @@ class ThinPoolImpl extends PoolImpl {
64
67
  this._usedConnectionList = new Set();
65
68
  this._password = params.password;
66
69
  this._walletPassword = params.walletPassword;
70
+ this._walletContent = params.walletContent;
67
71
  this._obfuscatedPassword = [];
68
72
  this._obfuscatedWalletPassword = [];
69
73
  this._token = params.token;
@@ -88,6 +92,13 @@ class ThinPoolImpl extends PoolImpl {
88
92
  this._obfuscatedWalletPassword = obj.obfuscatedValue;
89
93
  this._userConfig.walletPassword = null;
90
94
  }
95
+ // wallet content obfuscation
96
+ if (this._walletContent !== undefined) {
97
+ const obj = protocolUtil.setObfuscatedValue(this._walletContent);
98
+ this._walletContent = obj.value;
99
+ this._obfuscatedWalletContent = obj.obfuscatedValue;
100
+ this._userConfig.walletConent = null;
101
+ }
91
102
  // token obfuscation
92
103
  if (this._token !== undefined) {
93
104
  const obj = protocolUtil.setObfuscatedValue(this._token);
@@ -172,6 +183,13 @@ class ThinPoolImpl extends PoolImpl {
172
183
  this._obfuscatedWalletPassword);
173
184
  }
174
185
 
186
+ // deobfuscate wallet content
187
+ if (clonedAttrs.walletContent === null) {
188
+ clonedAttrs.walletContent =
189
+ protocolUtil.getDeobfuscatedValue(this._walletContent,
190
+ this._obfuscatedWalletContent);
191
+ }
192
+
175
193
  // deobfuscate token and private key
176
194
  // check for token expiry
177
195
  if (clonedAttrs.token === null) {
@@ -118,6 +118,8 @@ class Capabilities {
118
118
  constants.TNS_CCAP_CTB_IMPLICIT_POOL;
119
119
  this.compileCaps[constants.TNS_CCAP_TTC5] =
120
120
  constants.TNS_CCAP_VECTOR_SUPPORT;
121
+ this.compileCaps[constants.TNS_CCAP_VECTOR_FEATURES] =
122
+ constants.TNS_CCAP_VECTOR_FEATURE_BINARY;
121
123
  }
122
124
 
123
125
  initRuntimeCaps() {
@@ -492,12 +492,17 @@ module.exports = {
492
492
  TNS_LOB_OP_CLOSE: 0x10000,
493
493
  TNS_LOB_OP_IS_OPEN: 0x11000,
494
494
  TNS_LOB_OP_ARRAY: 0x80000,
495
+ TNS_LOB_OP_FILE_OPEN: 0x0100,
496
+ TNS_LOB_OP_FILE_CLOSE: 0x0200,
497
+ TNS_LOB_OP_FILE_ISOPEN: 0x0400,
498
+ TNS_LOB_OP_FILE_EXISTS: 0x0800,
495
499
 
496
500
  // LOB locator constants
497
501
  TNS_LOB_LOC_OFFSET_FLAG_1: 4,
498
502
  TNS_LOB_LOC_OFFSET_FLAG_3: 6,
499
503
  TNS_LOB_LOC_OFFSET_FLAG_4: 7,
500
504
  TNS_LOB_QLOCATOR_VERSION: 4,
505
+ TNS_LOB_LOC_FIXED_OFFSET: 16,
501
506
 
502
507
  // LOB locator flags (byte 1)
503
508
  TNS_LOB_LOC_FLAGS_BLOB: 0x01,
@@ -513,6 +518,7 @@ module.exports = {
513
518
 
514
519
  // other LOB constants
515
520
  TNS_LOB_OPEN_READ_WRITE: 2,
521
+ TNS_LOB_OPEN_READ_ONLY: 11,
516
522
  TNS_LOB_PREFETCH_FLAG: 0x2000000,
517
523
 
518
524
  // base JSON constants
@@ -548,6 +554,8 @@ module.exports = {
548
554
  TNS_FUNC_SESSION_RELEASE: 163,
549
555
  TNS_FUNC_SESSION_STATE: 176, // piggyback fn
550
556
  TNS_FUNC_CANCEL_ALL: 120, // piggyback fn
557
+ TNS_FUNC_TPC_TXN_SWITCH: 103,
558
+ TNS_FUNC_TPC_TXN_CHANGE_STATE: 104,
551
559
 
552
560
  // character sets and encodings
553
561
  TNS_CHARSET_UTF8: 873,
@@ -578,7 +586,8 @@ module.exports = {
578
586
  TNS_CCAP_TTC4: 40,
579
587
  TNS_CCAP_LOB2: 42,
580
588
  TNS_CCAP_TTC5: 44,
581
- TNS_CCAP_MAX: 51,
589
+ TNS_CCAP_VECTOR_FEATURES: 52,
590
+ TNS_CCAP_MAX: 53,
582
591
 
583
592
  // compile time capability values
584
593
  TNS_CCAP_SQL_VERSION_MAX: 6,
@@ -634,6 +643,7 @@ module.exports = {
634
643
  TNS_CCAP_LOB2_2GB_PREFETCH: 0x04,
635
644
  TNS_CCAP_CTB_IMPLICIT_POOL: 0x08,
636
645
  TNS_CCAP_VECTOR_SUPPORT: 0x08,
646
+ TNS_CCAP_VECTOR_FEATURE_BINARY: 0x01,
637
647
 
638
648
  // runtime capability indices
639
649
  TNS_RCAP_COMPAT: 0,
@@ -660,6 +670,24 @@ module.exports = {
660
670
  TNS_EOCS_FLAGS_TXN_IN_PROGRESS: 0x00000002,
661
671
  TNS_EOCS_FLAGS_SESS_RELEASE: 0x00008000,
662
672
 
673
+ // transaction switching op codes
674
+ TNS_TPC_TXN_START: 0x01,
675
+ TNS_TPC_TXN_DETACH: 0x02,
676
+
677
+ // transaction change state op codes
678
+ TNS_TPC_TXN_COMMIT: 0x01,
679
+ TNS_TPC_TXN_ABORT: 0x02,
680
+ TNS_TPC_TXN_PREPARE: 0x03,
681
+ TNS_TPC_TXN_FORGET: 0x04,
682
+
683
+ // transaction states
684
+ TNS_TPC_TXN_STATE_PREPARE: 0,
685
+ TNS_TPC_TXN_STATE_REQUIRES_COMMIT: 1,
686
+ TNS_TPC_TXN_STATE_COMMITTED: 2,
687
+ TNS_TPC_TXN_STATE_ABORTED: 3,
688
+ TNS_TPC_TXN_STATE_READ_ONLY: 4,
689
+ TNS_TPC_TXN_STATE_FORGOTTEN: 5,
690
+
663
691
  // other constants
664
692
  TNS_ESCAPE_CHAR: 253,
665
693
  TNS_LONG_LENGTH_INDICATOR: dataHandlerConstants.TNS_LONG_LENGTH_INDICATOR,
@@ -102,6 +102,11 @@ class AuthMessage extends Message {
102
102
  }
103
103
  this.serviceName = this.conn.serviceName;
104
104
  this.remoteAddress = this.conn.remoteAddress;
105
+ this.driverName = config.driverName;
106
+ this.machine = config.machine;
107
+ this.osUser = config.osUser;
108
+ this.program = config.program;
109
+ this.terminal = config.terminal;
105
110
  this.setAuthMode(config);
106
111
  }
107
112
 
@@ -181,11 +186,11 @@ class AuthMessage extends Message {
181
186
  if (this.userByteLen > 0) {
182
187
  buf.writeBytesWithLength(Buffer.from(this.username));
183
188
  }
184
- buf.writeKeyValue("AUTH_TERMINAL", cInfo.terminal);
185
- buf.writeKeyValue("AUTH_PROGRAM_NM", cInfo.program);
186
- buf.writeKeyValue("AUTH_MACHINE", cInfo.hostName);
189
+ buf.writeKeyValue("AUTH_TERMINAL", this.terminal ?? cInfo.terminal);
190
+ buf.writeKeyValue("AUTH_PROGRAM_NM", this.program ?? cInfo.program);
191
+ buf.writeKeyValue("AUTH_MACHINE", this.machine ?? cInfo.hostName);
187
192
  buf.writeKeyValue("AUTH_PID", cInfo.pid);
188
- buf.writeKeyValue("AUTH_SID", cInfo.userName);
193
+ buf.writeKeyValue("AUTH_SID", this.osUser ?? cInfo.userName);
189
194
  } else {
190
195
  let numPairs = 0;
191
196
 
@@ -253,7 +258,8 @@ class AuthMessage extends Message {
253
258
  }
254
259
  if (!this.changePassword) {
255
260
  buf.writeKeyValue("SESSION_CLIENT_CHARSET", "873");
256
- buf.writeKeyValue("SESSION_CLIENT_DRIVER_NAME", constants.DRIVER_NAME);
261
+ buf.writeKeyValue("SESSION_CLIENT_DRIVER_NAME",
262
+ this.driverName ?? constants.DRIVER_NAME);
257
263
  buf.writeKeyValue("SESSION_CLIENT_VERSION",
258
264
  constants.CLIENT_VERSION.toString());
259
265
  buf.writeKeyValue("AUTH_ALTER_SESSION", this.getAlterTimezoneStatement(), 1);
@@ -321,7 +327,7 @@ class AuthMessage extends Message {
321
327
  let portUpdateNum;
322
328
 
323
329
  this.conn.dbDomain = this.sessionData['AUTH_SC_DB_DOMAIN'];
324
- this.conn.dbName = this.sessionData['AUTH_SC_DBUNIQUE_NAME'];
330
+ this.conn.dbName = this.sessionData['AUTH_DBNAME'];
325
331
  this.conn.maxOpenCursors = Number(this.sessionData['AUTH_MAX_OPEN_CURSORS'] || 0);
326
332
  this.conn.serviceName = this.sessionData['AUTH_SC_SERVICE_NAME'];
327
333
  this.conn.instanceName = this.sessionData['AUTH_INSTANCENAME'];
@@ -296,6 +296,9 @@ class Message {
296
296
  this._writeCurrentSchemaPiggyback(buf);
297
297
  }
298
298
  if (this.connection.statementCache._cursorsToClose.size > 0 && !this.connection._drcpEstablishSession) {
299
+ // skip closing cursors when '_drcpEstablishSession = true' Since we don't know whether the same session
300
+ // is in use. We can not send the information across until after the session information has been returned
301
+ // (on the first round trip).
299
302
  this.writeCloseCursorsPiggyBack(buf);
300
303
  }
301
304
  if (
@@ -38,6 +38,8 @@ const ProtocolMessage = require('./protocol.js');
38
38
  const RollbackMessage = require('./rollback.js');
39
39
  const SessionReleaseMessage = require('./sessionRelease.js');
40
40
  const FastAuthMessage = require('./fastAuth.js');
41
+ const TransactionChangeStateMessage = require('./transactionChangeState.js');
42
+ const TransactionSwitchMessage = require('./transactionSwitch.js');
41
43
 
42
44
  module.exports = {
43
45
  AuthMessage,
@@ -51,5 +53,7 @@ module.exports = {
51
53
  PingMessage,
52
54
  ProtocolMessage,
53
55
  RollbackMessage,
54
- SessionReleaseMessage
56
+ SessionReleaseMessage,
57
+ TransactionChangeStateMessage,
58
+ TransactionSwitchMessage
55
59
  };
@@ -90,8 +90,13 @@ class LobOpMessage extends Message {
90
90
  buf.writeUInt8(0);
91
91
  }
92
92
  buf.writeUInt8(0);
93
- if (this.operation === constants.TNS_LOB_OP_CREATE_TEMP
94
- || this.operation === constants.TNS_LOB_OP_IS_OPEN) {
93
+ const operations = [
94
+ constants.TNS_LOB_OP_CREATE_TEMP,
95
+ constants.TNS_LOB_OP_IS_OPEN,
96
+ constants.TNS_LOB_OP_FILE_EXISTS,
97
+ constants.TNS_LOB_OP_FILE_ISOPEN,
98
+ ];
99
+ if (operations.includes(this.operation)) {
95
100
  buf.writeUInt8(1);
96
101
  } else {
97
102
  buf.writeUInt8(0);
@@ -152,7 +157,10 @@ class LobOpMessage extends Message {
152
157
  const oraTypeNum = this.sourceLobImpl.dbType._oraTypeNum;
153
158
  let data = buf.readBytesWithLength();
154
159
  if (data !== null) {
155
- if (oraTypeNum === constants.TNS_DATA_TYPE_BLOB) {
160
+ if (
161
+ oraTypeNum === constants.TNS_DATA_TYPE_BLOB ||
162
+ oraTypeNum === constants.TNS_DATA_TYPE_BFILE
163
+ ) {
156
164
  data = Buffer.from(data);
157
165
  } else if (this.sourceLobImpl.getCsfrm() === constants.CSFRM_NCHAR) {
158
166
  data = Buffer.from(data).swap16().toString('utf16le');
@@ -189,8 +197,12 @@ class LobOpMessage extends Message {
189
197
  } else if (this.sendAmount) {
190
198
  this.amount = buf.readSB8();
191
199
  }
192
- if (this.operation === constants.TNS_LOB_OP_IS_OPEN) {
193
- temp8 = buf.readUB1();
200
+ if (
201
+ this.operation === constants.TNS_LOB_OP_IS_OPEN
202
+ || this.operation === constants.TNS_LOB_OP_FILE_EXISTS
203
+ || this.operation === constants.TNS_LOB_OP_FILE_ISOPEN
204
+ ) {
205
+ temp8 = buf.readUInt8();
194
206
  this.boolFlag = temp8 > 0;
195
207
  }
196
208
  }
@@ -45,6 +45,7 @@ class SessionReleaseMessage extends Message {
45
45
  }
46
46
 
47
47
  encode(buf) {
48
+ this.writePiggybacks(buf);
48
49
  this.writeFunctionHeader(buf);
49
50
  buf.writeUInt8(0); // pointer (tag name)
50
51
  buf.writeUInt8(0); // tag name length
@@ -0,0 +1,99 @@
1
+ // Copyright (c) 2024, 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 Message = require("./base.js");
30
+ const constants = require("../constants.js");
31
+
32
+ /**
33
+ * Used for two-phase commit (TPC) transaction change state: commit, rollback,
34
+ * forget, etc.
35
+ *
36
+ * @class TransactionChangeStateMessage
37
+ * @extends {Message}
38
+ */
39
+ class TransactionChangeStateMessage extends Message {
40
+
41
+ constructor(connImpl) {
42
+ super(connImpl);
43
+ this.functionCode = constants.TNS_FUNC_TPC_TXN_CHANGE_STATE;
44
+ }
45
+
46
+ processReturnParameter(buf) {
47
+ // process the parameters returned by the datatabase
48
+ this.state = buf.readUB4();
49
+ }
50
+
51
+ encode(buf) {
52
+ // writes the message to the database
53
+ // acquire data to send to the server
54
+ let xidBytes;
55
+ if (this.xid) {
56
+ xidBytes = Buffer.alloc(128);
57
+ this.xid.globalTransactionId.copy(xidBytes);
58
+ this.xid.branchQualifier.copy(xidBytes,
59
+ this.xid.globalTransactionId.length);
60
+ }
61
+
62
+ this.writeFunctionHeader(buf);
63
+ buf.writeUB4(this.operation);
64
+ if (this.context) {
65
+ buf.writeUInt8(1);
66
+ buf.writeUB4(this.context.length);
67
+ } else {
68
+ buf.writeUInt8(0);
69
+ buf.writeUB4(0);
70
+ }
71
+
72
+ if (this.xid) {
73
+ buf.writeUB4(this.xid.formatId);
74
+ buf.writeUB4(this.xid.globalTransactionId.length);
75
+ buf.writeUB4(this.xid.branchQualifier.length);
76
+ buf.writeUInt8(1);
77
+ buf.writeUB4(xidBytes.length);
78
+ } else {
79
+ buf.writeUB4(0);
80
+ buf.writeUB4(0);
81
+ buf.writeUB4(0);
82
+ buf.writeUInt8(0);
83
+ buf.writeUB4(0);
84
+ }
85
+ buf.writeUB4(0);
86
+ buf.writeUB4(this.state);
87
+ buf.writeUInt8(1);
88
+ buf.writeUB4(this.flags);
89
+
90
+ if (this.context) {
91
+ buf.writeBytes(this.context);
92
+ }
93
+ if (this.xid) {
94
+ buf.writeBytes(xidBytes);
95
+ }
96
+ }
97
+ }
98
+
99
+ module.exports = TransactionChangeStateMessage;