oracledb 6.10.0 → 7.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 (84) hide show
  1. package/LICENSE.txt +1 -1
  2. package/NOTICE.txt +1 -1
  3. package/README.md +9 -9
  4. package/build/Release/oracledb-7.0.0-darwin-arm64.node +0 -0
  5. package/build/Release/oracledb-7.0.0-darwin-arm64.node-buildinfo.txt +1 -0
  6. package/build/Release/oracledb-7.0.0-js-buildinfo.txt +1 -0
  7. package/build/Release/oracledb-7.0.0-linux-arm64.node +0 -0
  8. package/build/Release/oracledb-7.0.0-linux-arm64.node-buildinfo.txt +1 -0
  9. package/build/Release/oracledb-7.0.0-linux-x64.node +0 -0
  10. package/build/Release/oracledb-7.0.0-linux-x64.node-buildinfo.txt +1 -0
  11. package/build/Release/oracledb-7.0.0-win32-x64.node +0 -0
  12. package/build/Release/oracledb-7.0.0-win32-x64.node-buildinfo.txt +1 -0
  13. package/eslint.config.js +39 -0
  14. package/lib/connection.js +412 -37
  15. package/lib/endUserSecurityContext.js +176 -0
  16. package/lib/errors.js +86 -5
  17. package/lib/impl/connection.js +76 -2
  18. package/lib/impl/datahandlers/buffer.js +19 -5
  19. package/lib/impl/datahandlers/vector.js +25 -5
  20. package/lib/impl/lob.js +9 -0
  21. package/lib/impl/parserHelpers.js +443 -0
  22. package/lib/impl/resultset.js +1 -1
  23. package/lib/lob.js +27 -14
  24. package/lib/obfuscation.js +97 -0
  25. package/lib/oracledb.js +148 -43
  26. package/lib/parser.js +204 -0
  27. package/lib/pipeline.js +113 -0
  28. package/lib/pool.js +16 -1
  29. package/lib/resultset.js +42 -21
  30. package/lib/settings.js +1 -0
  31. package/lib/thin/connection.js +467 -53
  32. package/lib/thin/dbObject.js +7 -1
  33. package/lib/thin/lob.js +20 -1
  34. package/lib/thin/pool.js +42 -62
  35. package/lib/thin/protocol/capabilities.js +18 -3
  36. package/lib/thin/protocol/constants.js +82 -2
  37. package/lib/thin/protocol/encryptDecrypt.js +43 -8
  38. package/lib/thin/protocol/messages/auth.js +6 -1
  39. package/lib/thin/protocol/messages/base.js +245 -4
  40. package/lib/thin/protocol/messages/dataType.js +8 -3
  41. package/lib/thin/protocol/messages/directPathLoadStream.js +377 -0
  42. package/lib/thin/protocol/messages/directPathOp.js +65 -0
  43. package/lib/thin/protocol/messages/directPathPrepare.js +158 -0
  44. package/lib/thin/protocol/messages/endPipeline.js +56 -0
  45. package/lib/thin/protocol/messages/execute.js +9 -7
  46. package/lib/thin/protocol/messages/index.js +9 -1
  47. package/lib/thin/protocol/messages/protocol.js +2 -2
  48. package/lib/thin/protocol/messages/withData.js +8 -140
  49. package/lib/thin/protocol/packet.js +115 -24
  50. package/lib/thin/protocol/protocol.js +110 -25
  51. package/lib/thin/protocol/utils.js +1 -26
  52. package/lib/thin/resultSet.js +13 -19
  53. package/lib/thin/sqlnet/ezConnectResolver.js +2 -2
  54. package/lib/thin/sqlnet/networkSession.js +62 -40
  55. package/lib/thin/sqlnet/ntTcp.js +24 -0
  56. package/lib/thin/sqlnet/nvStrToNvPair.js +50 -25
  57. package/lib/thin/sqlnet/packet.js +25 -4
  58. package/lib/thin/sqlnet/paramParser.js +10 -7
  59. package/lib/thin/statementCache.js +2 -4
  60. package/lib/traceHandler.js +59 -2
  61. package/lib/transformer.js +8 -3
  62. package/lib/types.js +35 -21
  63. package/lib/util.js +6 -6
  64. package/lib/version.js +3 -3
  65. package/package/install.js +5 -5
  66. package/package/prunebinaries.js +1 -1
  67. package/package.json +1 -1
  68. package/plugins/configProviders/awsCommon.js +125 -0
  69. package/plugins/configProviders/awss3/index.js +138 -0
  70. package/plugins/configProviders/awssecretsmanager/index.js +147 -0
  71. package/plugins/configProviders/azure/index.js +4 -5
  72. package/plugins/token/extensionAzure/index.js +0 -1
  73. package/plugins/token/extensionOci/index.js +0 -1
  74. package/build/Release/oracledb-6.10.0-darwin-arm64.node +0 -0
  75. package/build/Release/oracledb-6.10.0-darwin-arm64.node-buildinfo.txt +0 -1
  76. package/build/Release/oracledb-6.10.0-darwin-x64.node +0 -0
  77. package/build/Release/oracledb-6.10.0-darwin-x64.node-buildinfo.txt +0 -1
  78. package/build/Release/oracledb-6.10.0-js-buildinfo.txt +0 -1
  79. package/build/Release/oracledb-6.10.0-linux-arm64.node +0 -0
  80. package/build/Release/oracledb-6.10.0-linux-arm64.node-buildinfo.txt +0 -1
  81. package/build/Release/oracledb-6.10.0-linux-x64.node +0 -0
  82. package/build/Release/oracledb-6.10.0-linux-x64.node-buildinfo.txt +0 -1
  83. package/build/Release/oracledb-6.10.0-win32-x64.node +0 -0
  84. package/build/Release/oracledb-6.10.0-win32-x64.node-buildinfo.txt +0 -1
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2022, 2025, Oracle and/or its affiliates.
1
+ // Copyright (c) 2022, 2026, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -29,6 +29,8 @@
29
29
  const { Buffer } = require('buffer');
30
30
  const constants = require("../constants.js");
31
31
  const errors = require("../../../errors.js");
32
+ const types = require('../../../types.js');
33
+
32
34
 
33
35
  // List of recoverable errors
34
36
  const RECOVERABLE_ERRORS = new Set([
@@ -58,6 +60,9 @@ const RECOVERABLE_ERRORS = new Set([
58
60
  16456 // missing or invalid value
59
61
  ]);
60
62
 
63
+ // App Context constants.
64
+ const KeyValueSetContext = 0x01; // SET CONTEXT -send to server side
65
+ const KeyValueClearContext = 0x02; // CLEAR CONTEXT -send to server side
61
66
  /**
62
67
  *
63
68
  * Base class for all the RPC messages to support encode/decode functions
@@ -74,6 +79,8 @@ class Message {
74
79
  this.endToEndSeqNum = 0;
75
80
  this.errorOccurred = false;
76
81
  this.warning = undefined;
82
+ this.tokenNum = 0; // used for request-response correlation in pipelining
83
+ this.isPipeline = connection.pipelineMode !== 0;
77
84
  }
78
85
 
79
86
  preProcess() { }
@@ -85,10 +92,164 @@ class Message {
85
92
  buf.writeUInt8(this.functionCode);
86
93
  buf.writeSeqNum();
87
94
  if (buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_23_1_EXT_1) {
88
- buf.writeUB8(0); // token number
95
+ buf.writeUB8(this.tokenNum); // token number for pipelining
89
96
  }
90
97
  }
91
98
 
99
+ processColumnInfo(buf, columnNum) {
100
+ const dataType = buf.readUInt8();
101
+ buf.skipUB1(); // flags
102
+ const precision = buf.readInt8();
103
+ const scale = buf.readInt8();
104
+ const maxSize = buf.readUB4();
105
+ buf.skipUB4(); // max number of array elements
106
+ buf.skipUB8(); // cont flags
107
+ let oid;
108
+ let numBytes = buf.readUB4(); // OID
109
+ if (numBytes > 0) {
110
+ oid = Buffer.from(buf.readBytesWithLength());
111
+ }
112
+ buf.skipUB2(); // version
113
+ buf.skipUB2(); // character set id
114
+ const csfrm = buf.readUInt8(); // character set form
115
+ let size = buf.readUB4();
116
+ if (dataType === constants.TNS_DATA_TYPE_RAW) {
117
+ size = maxSize;
118
+ }
119
+ if (buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_12_2) {
120
+ buf.skipUB4(); // oaccolid
121
+ }
122
+ const nullable = Boolean(buf.readUInt8());
123
+ buf.skipUB1(); // v7 length of name
124
+ let name;
125
+ numBytes = buf.readUB4();
126
+ if (numBytes > 0) {
127
+ name = buf.readStr(constants.CSFRM_IMPLICIT);
128
+ }
129
+ let schema;
130
+ numBytes = buf.readUB4();
131
+ if (numBytes > 0) {
132
+ schema = buf.readStr(constants.CSFRM_IMPLICIT);
133
+ }
134
+ numBytes = buf.readUB4();
135
+ let typeName;
136
+ if (numBytes > 0) {
137
+ typeName = buf.readStr(constants.CSFRM_IMPLICIT);
138
+ }
139
+ buf.skipUB2(); // column position
140
+ const udsFlags = buf.readUB4(); // uds flag
141
+
142
+ // build metadata
143
+ const fetchInfo = {
144
+ name: name,
145
+ dbColumnName: name,
146
+ nullable: nullable,
147
+ };
148
+
149
+ try {
150
+ fetchInfo.dbType = types.getTypeByOraTypeNum(dataType, csfrm);
151
+ } catch {
152
+ fetchInfo.dbType = types.getTypeByOraTypeNum(dataType, 0);
153
+ }
154
+
155
+ fetchInfo.isJson = Boolean(udsFlags & constants.TNS_UDS_FLAGS_IS_JSON);
156
+ fetchInfo.isOson = Boolean(udsFlags & constants.TNS_UDS_FLAGS_IS_OSON);
157
+ if (buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_23_1) {
158
+ numBytes = buf.readUB4();
159
+ if (numBytes > 0) {
160
+ fetchInfo.domainSchema = buf.readStr(constants.CSFRM_IMPLICIT);
161
+ }
162
+ numBytes = buf.readUB4();
163
+ if (numBytes > 0) {
164
+ fetchInfo.domainName = buf.readStr(constants.CSFRM_IMPLICIT);
165
+ }
166
+ }
167
+ if (
168
+ buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_23_1_EXT_3
169
+ ) {
170
+ if (buf.readUB4() > 0) {
171
+ fetchInfo.annotations = {};
172
+ buf.skipUB1();
173
+ const numAnnotations = buf.readUB4();
174
+ buf.skipUB1();
175
+ let key, value;
176
+ for (let i = 0; i < numAnnotations; i++) {
177
+ buf.skipUB4();
178
+ value = "";
179
+ key = buf.readStr(constants.CSFRM_IMPLICIT);
180
+ numBytes = buf.readUB4();
181
+ if (numBytes > 0) {
182
+ value = buf.readStr(constants.CSFRM_IMPLICIT);
183
+ }
184
+ fetchInfo.annotations[key] = value;
185
+ buf.skipUB4(); // flags
186
+ }
187
+ buf.skipUB4(); // flags
188
+ }
189
+ }
190
+ if (buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_23_4) {
191
+ const dimensions = buf.readUB4();
192
+ const vectorFormat = buf.readUInt8();
193
+ const vectorFlags = buf.readUInt8();
194
+ if (fetchInfo.dbType === types.DB_TYPE_VECTOR) {
195
+ if (!(vectorFlags & constants.VECTOR_META_FLAG_FLEXIBLE_DIM)) {
196
+ fetchInfo.vectorDimensions = dimensions;
197
+ }
198
+ fetchInfo.isSparseVector = Boolean(
199
+ vectorFlags & constants.VECTOR_META_FLAG_SPARSE
200
+ );
201
+ if (vectorFormat !== constants.VECTOR_FORMAT_FLEX) {
202
+ fetchInfo.vectorFormat = vectorFormat;
203
+ }
204
+ }
205
+ }
206
+
207
+ switch (fetchInfo.dbType) {
208
+ case types.DB_TYPE_VARCHAR:
209
+ case types.DB_TYPE_NVARCHAR:
210
+ case types.DB_TYPE_CHAR:
211
+ case types.DB_TYPE_NCHAR:
212
+ case types.DB_TYPE_RAW:
213
+ fetchInfo.byteSize = size;
214
+ break;
215
+ case types.DB_TYPE_NUMBER:
216
+ fetchInfo.precision = precision;
217
+ break;
218
+ case types.DB_TYPE_TIMESTAMP:
219
+ case types.DB_TYPE_TIMESTAMP_TZ:
220
+ case types.DB_TYPE_TIMESTAMP_LTZ:
221
+ fetchInfo.precision = scale;
222
+ break;
223
+ case types.DB_TYPE_OBJECT:
224
+ fetchInfo.dbTypeClass = this.connection._getDbObjectType(
225
+ schema,
226
+ typeName,
227
+ undefined,
228
+ oid
229
+ );
230
+ if (fetchInfo.dbTypeClass.partial) {
231
+ this.connection._partialDbObjectTypes.push(fetchInfo.dbTypeClass);
232
+ }
233
+ if (fetchInfo.dbTypeClass.isXmlType) {
234
+ fetchInfo.dbType = types.DB_TYPE_XMLTYPE;
235
+ }
236
+ break;
237
+ default:
238
+ break;
239
+ }
240
+ if (fetchInfo.dbType === types.DB_TYPE_NUMBER) {
241
+ fetchInfo.scale = scale;
242
+ }
243
+ const result = {
244
+ fetchInfo: fetchInfo,
245
+ type: fetchInfo.dbType,
246
+ maxSize: maxSize,
247
+ columnNum: columnNum,
248
+ values: new Array(this.options?.fetchArraySize)
249
+ };
250
+ return result;
251
+ }
252
+
92
253
  processErrorInfo(buf) {
93
254
  this.callStatus = buf.readUB4(); // end of call status
94
255
  buf.skipUB2(); // end to end seq number
@@ -241,6 +402,12 @@ class Message {
241
402
  this.processServerSidePiggyBack(buf);
242
403
  } else if (messageType === constants.TNS_MSG_TYPE_END_OF_REQUEST) {
243
404
  this.endOfResponse = true;
405
+ } else if (messageType === constants.TNS_MSG_TYPE_TOKEN) {
406
+ const tokenNum = buf.readUB8();
407
+ if (tokenNum !== this.tokenNum) {
408
+ errors.throwErr(errors.ERR_PIPELINE_MISMATCHED_TOKEN, tokenNum,
409
+ this.tokenNum);
410
+ }
244
411
  } else {
245
412
  errors.throwErr(errors.ERR_UNEXPECTED_MESSAGE_TYPE, messageType, buf.pos, buf.packetNum);
246
413
  }
@@ -281,6 +448,10 @@ class Message {
281
448
  this.connection.currentSchema = keyTextValue;
282
449
  } else if (keywordNum === constants.TNS_KEYWORD_NUM_EDITION) {
283
450
  this.connection._edition = keyTextValue;
451
+ } else if (keywordNum === constants.TNS_KEYWORD_DBNAME) {
452
+ this.connection.dbName = keyTextValue;
453
+ } else if (keywordNum === constants.TNS_KEYWORD_PDBNAME) {
454
+ this.connection.pdbName = keyTextValue;
284
455
  }
285
456
  }
286
457
  buf.skipUB4(); // skip overall flags
@@ -335,14 +506,30 @@ class Message {
335
506
  }
336
507
  }
337
508
 
509
+ _writeBeginPipelinePiggyback(buf) {
510
+ buf._dataFlags |= constants.TNS_DATA_FLAGS_BEGIN_PIPELINE;
511
+ this.writePiggybackHeader(buf, constants.TNS_FUNC_PIPELINE_BEGIN);
512
+ buf.writeUB2(0); // error set ID
513
+ buf.writeUInt8(0); // error set mode
514
+ buf.writeUInt8(this.connection.pipelineMode);
515
+ }
516
+
338
517
  writePiggybacks(buf) {
339
518
  // Don't write piggybacks if not authenticated yet
340
519
  if (this.connection._protocol.connInProgress)
341
520
  return;
342
521
 
522
+ if (this.connection.securityContext) {
523
+ this._writeEndUserSecurityContextPiggyback(buf);
524
+ }
525
+ if (this.connection.pipelineMode) {
526
+ this._writeBeginPipelinePiggyback(buf);
527
+ this.connection.pipelineMode = 0;
528
+ }
343
529
  if (this.connection._currentSchemaModified) {
344
530
  this._writeCurrentSchemaPiggyback(buf);
345
531
  }
532
+ this._writeApplicationContextPiggyback(buf);
346
533
  if (this.connection.statementCache._cursorsToClose.size > 0 && !this.connection._drcpEstablishSession) {
347
534
  // skip closing cursors when '_drcpEstablishSession = true' Since we don't know whether the same session
348
535
  // is in use. We can not send the information across until after the session information has been returned
@@ -372,8 +559,9 @@ class Message {
372
559
  buf.writeUInt8(constants.TNS_MSG_TYPE_PIGGYBACK);
373
560
  buf.writeUInt8(functionCode);
374
561
  buf.writeSeqNum();
375
- if (buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_23_1_EXT_1) {
376
- buf.writeUB8(0); // token number
562
+ if (buf.caps.ttcFieldVersion >=
563
+ constants.TNS_CCAP_FIELD_VERSION_23_1_EXT_1) {
564
+ buf.writeUB8(buf.tokenNum); // token number for pipelining
377
565
  }
378
566
  }
379
567
 
@@ -429,6 +617,17 @@ class Message {
429
617
  buf.writeBytesWithLength(Buffer.from(this.connection.currentSchema));
430
618
  }
431
619
 
620
+ // Writes the piggyback that informs the server of the EndUserSecurityContext.
621
+ _writeEndUserSecurityContextPiggyback(buf) {
622
+ const encoded = this.connection.securityContext.getDeobfuscatedValue();
623
+ this.writePiggybackHeader(buf, constants.TNS_FUNC_END_USER_SECURITY_CTX);
624
+ buf.writeUB4(constants.TNS_SECURITY_CONTEXT_ATTACH_FLAG);
625
+ buf.writeUInt8(1); // pointer(kpdkve)
626
+ buf.writeUB4(1); // number of key values
627
+ buf.writeStrKeywordValuePair("ORCL_XS_AUTHZ_CONTEXT", encoded);
628
+ encoded.fill(0);
629
+ }
630
+
432
631
  _writeEndToEndPiggybacks(buf) {
433
632
  let flags = 0;
434
633
 
@@ -521,6 +720,48 @@ class Message {
521
720
  return writtenBytes;
522
721
  }
523
722
 
723
+ _writeApplicationContextPiggyback(buf) {
724
+ const nameSpaces = this.connection._nameSpaceMap;
725
+ if (!nameSpaces) {
726
+ return; // nothing to send
727
+ }
728
+
729
+ for (const [key, nameSpace] of nameSpaces) {
730
+ this.writePiggybackHeader(buf, constants.TNS_FUNC_APP_CONTEXT);
731
+
732
+ // send metadata first
733
+ const nsBytes = Buffer.from(nameSpace.nameSpaceName);
734
+ if (nsBytes.length > 0) {
735
+ buf.writeUInt8(1); // ptr
736
+ buf.writeUB4(nsBytes.length);
737
+ } else {
738
+ buf.writeUInt8(0); // null ptr
739
+ }
740
+ const keyValues = nameSpace.keyValues;
741
+ if (keyValues.length > 0) {
742
+ buf.writeUInt8(1); // ptr
743
+ } else {
744
+ buf.writeUInt8(0); // null ptr
745
+ }
746
+ buf.writeUB4(keyValues.length);
747
+
748
+ let flag = 0;
749
+ if (keyValues.length > 0) flag = KeyValueSetContext;
750
+ if (nameSpace.pendingClear) flag |= KeyValueClearContext;
751
+ buf.writeUB2(flag);
752
+ buf.writeUInt8(0);
753
+ // --- end of metadata
754
+
755
+ // --- now send the values
756
+ buf.writeBytesWithLength(nsBytes);
757
+ for (const obj of keyValues) {
758
+ const [entryKey, entryValue] = Object.entries(obj)[0];
759
+ buf.writeKeyValue(entryKey, entryValue);
760
+ }
761
+ nameSpaces.delete(key);
762
+ }
763
+ }
764
+
524
765
  // Called when an error is encountered during decode of RPC
525
766
  saveDeferredErr() {
526
767
  if (!this.deferredErr) {
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2022, 2025, Oracle and/or its affiliates.
1
+ // Copyright (c) 2022, 2026, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -40,7 +40,7 @@ class DataTypeMessage extends Message {
40
40
 
41
41
  processMessage(buf, messageType) {
42
42
  if (messageType === constants.TNS_MSG_TYPE_DATA_TYPES) {
43
- while (true) { // eslint-disable-line
43
+ while (true) {
44
44
  const dataType = buf.readUInt16BE();
45
45
  if (dataType === 0)
46
46
  break;
@@ -395,7 +395,12 @@ const dataTypes = [
395
395
  [constants.TNS_DATA_TYPE_OER, constants.TNS_DATA_TYPE_OER, constants.TNS_TYPE_REP_UNIVERSAL],
396
396
  [constants.TNS_DATA_TYPE_OAC, constants.TNS_DATA_TYPE_OAC, constants.TNS_TYPE_REP_UNIVERSAL],
397
397
  [constants.TNS_DATA_TYPE_SESSSIGN, constants.TNS_DATA_TYPE_SESSSIGN, constants.TNS_TYPE_REP_UNIVERSAL],
398
- [constants.TNS_DATA_TYPE_VECTOR, constants.TNS_DATA_TYPE_VECTOR, constants.TNS_TYPE_REP_UNIVERSAL]
398
+ [constants.TNS_DATA_TYPE_VECTOR, constants.TNS_DATA_TYPE_VECTOR, constants.TNS_TYPE_REP_UNIVERSAL],
399
+ [constants.TNS_DATA_TYPE_PLEND, constants.TNS_DATA_TYPE_PLEND, constants.TNS_TYPE_REP_UNIVERSAL],
400
+ [constants.TNS_DATA_TYPE_PLBGN, constants.TNS_DATA_TYPE_PLBGN, constants.TNS_TYPE_REP_UNIVERSAL],
401
+ [constants.TNS_DATA_TYPE_PLOP, constants.TNS_DATA_TYPE_PLOP, constants.TNS_TYPE_REP_UNIVERSAL],
402
+ [constants.TNS_DATA_TYPE_KVE, constants.TNS_DATA_TYPE_KVE, constants.TNS_TYPE_REP_UNIVERSAL],
403
+ [constants.TNS_DATA_TYPE_EUSC, constants.TNS_DATA_TYPE_EUSC, constants.TNS_TYPE_REP_UNIVERSAL]
399
404
  ];
400
405
 
401
406
  module.exports = DataTypeMessage;