oracledb 6.9.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 (100) 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/aqDeqOptions.js +18 -1
  15. package/lib/aqQueue.js +10 -6
  16. package/lib/connection.js +418 -39
  17. package/lib/dbObject.js +25 -4
  18. package/lib/endUserSecurityContext.js +176 -0
  19. package/lib/errors.js +99 -8
  20. package/lib/impl/aqDeqOptions.js +10 -1
  21. package/lib/impl/connection.js +76 -2
  22. package/lib/impl/datahandlers/buffer.js +68 -5
  23. package/lib/impl/datahandlers/oson.js +7 -2
  24. package/lib/impl/datahandlers/vector.js +25 -5
  25. package/lib/impl/lob.js +9 -0
  26. package/lib/impl/parserHelpers.js +443 -0
  27. package/lib/impl/resultset.js +1 -1
  28. package/lib/impl/sodaDocument.js +5 -14
  29. package/lib/lob.js +27 -14
  30. package/lib/obfuscation.js +97 -0
  31. package/lib/oracledb.js +163 -49
  32. package/lib/parser.js +204 -0
  33. package/lib/pipeline.js +113 -0
  34. package/lib/pool.js +203 -147
  35. package/lib/poolStatistics.js +1 -1
  36. package/lib/resultset.js +42 -21
  37. package/lib/settings.js +1 -0
  38. package/lib/sodaCollection.js +12 -8
  39. package/lib/sodaDatabase.js +35 -8
  40. package/lib/sodaDocument.js +24 -6
  41. package/lib/sodaOperation.js +7 -6
  42. package/lib/thin/aq.js +475 -0
  43. package/lib/thin/connection.js +518 -54
  44. package/lib/thin/dbObject.js +7 -1
  45. package/lib/thin/lob.js +20 -1
  46. package/lib/thin/pool.js +42 -62
  47. package/lib/thin/protocol/capabilities.js +21 -4
  48. package/lib/thin/protocol/constants.js +143 -2
  49. package/lib/thin/protocol/encryptDecrypt.js +45 -10
  50. package/lib/thin/protocol/messages/aqArray.js +238 -0
  51. package/lib/thin/protocol/messages/aqBase.js +305 -0
  52. package/lib/thin/protocol/messages/aqDeq.js +164 -0
  53. package/lib/thin/protocol/messages/aqEnq.js +135 -0
  54. package/lib/thin/protocol/messages/auth.js +18 -28
  55. package/lib/thin/protocol/messages/base.js +245 -4
  56. package/lib/thin/protocol/messages/dataType.js +8 -3
  57. package/lib/thin/protocol/messages/directPathLoadStream.js +377 -0
  58. package/lib/thin/protocol/messages/directPathOp.js +65 -0
  59. package/lib/thin/protocol/messages/directPathPrepare.js +158 -0
  60. package/lib/thin/protocol/messages/endPipeline.js +56 -0
  61. package/lib/thin/protocol/messages/execute.js +9 -7
  62. package/lib/thin/protocol/messages/index.js +9 -1
  63. package/lib/thin/protocol/messages/protocol.js +2 -2
  64. package/lib/thin/protocol/messages/withData.js +10 -142
  65. package/lib/thin/protocol/packet.js +120 -28
  66. package/lib/thin/protocol/protocol.js +110 -25
  67. package/lib/thin/protocol/utils.js +1 -26
  68. package/lib/thin/resultSet.js +13 -19
  69. package/lib/thin/sqlnet/ezConnectResolver.js +2 -2
  70. package/lib/thin/sqlnet/networkSession.js +63 -41
  71. package/lib/thin/sqlnet/ntTcp.js +24 -0
  72. package/lib/thin/sqlnet/nvStrToNvPair.js +50 -25
  73. package/lib/thin/sqlnet/packet.js +25 -4
  74. package/lib/thin/sqlnet/paramParser.js +10 -7
  75. package/lib/thin/statementCache.js +2 -4
  76. package/lib/traceHandler.js +59 -2
  77. package/lib/transformer.js +8 -3
  78. package/lib/types.js +36 -22
  79. package/lib/util.js +6 -19
  80. package/lib/version.js +3 -3
  81. package/package/install.js +5 -5
  82. package/package/prunebinaries.js +1 -1
  83. package/package.json +1 -1
  84. package/plugins/configProviders/awsCommon.js +125 -0
  85. package/plugins/configProviders/awss3/index.js +138 -0
  86. package/plugins/configProviders/awssecretsmanager/index.js +147 -0
  87. package/plugins/configProviders/azure/index.js +7 -5
  88. package/plugins/token/extensionAzure/index.js +0 -1
  89. package/plugins/token/extensionOci/index.js +0 -1
  90. package/build/Release/oracledb-6.9.0-darwin-arm64.node +0 -0
  91. package/build/Release/oracledb-6.9.0-darwin-arm64.node-buildinfo.txt +0 -1
  92. package/build/Release/oracledb-6.9.0-darwin-x64.node +0 -0
  93. package/build/Release/oracledb-6.9.0-darwin-x64.node-buildinfo.txt +0 -1
  94. package/build/Release/oracledb-6.9.0-js-buildinfo.txt +0 -1
  95. package/build/Release/oracledb-6.9.0-linux-arm64.node +0 -0
  96. package/build/Release/oracledb-6.9.0-linux-arm64.node-buildinfo.txt +0 -1
  97. package/build/Release/oracledb-6.9.0-linux-x64.node +0 -0
  98. package/build/Release/oracledb-6.9.0-linux-x64.node-buildinfo.txt +0 -1
  99. package/build/Release/oracledb-6.9.0-win32-x64.node +0 -0
  100. package/build/Release/oracledb-6.9.0-win32-x64.node-buildinfo.txt +0 -1
@@ -0,0 +1,377 @@
1
+ // Copyright (c) 2025, 2026, 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
+ const errors = require("../../../errors.js");
32
+ const { Buffer } = require("buffer");
33
+ const types = require("../../../types.js");
34
+ const { BaseBuffer } = require("../../../impl/datahandlers/buffer.js");
35
+ const vector = require("../../../impl/datahandlers/vector.js");
36
+ const oson = require("../../../impl/datahandlers/oson.js");
37
+ const transformer = require("../../../transformer.js");
38
+
39
+ class DirectPathPiece {
40
+ constructor() {
41
+ this.isFast = false;
42
+ this.isFirst = false;
43
+ this.isLast = false;
44
+ this.isSplitWithPrev = false;
45
+ this.isSplitWithNext = false;
46
+ this.flags = 0;
47
+ this.numSegments = 0;
48
+ this.length = 0;
49
+ this.data = null;
50
+ }
51
+
52
+ finalize(buf) {
53
+ this.length = buf.pos;
54
+ this.data = Buffer.from(buf.buf.slice(0, buf.pos));
55
+ buf.pos = 0;
56
+ if (this.isFirst) {
57
+ this.flags |= constants.TNS_DPLS_ROW_HEADER_FIRST;
58
+ } else if (this.isSplitWithPrev) {
59
+ this.flags |= constants.TNS_DPLS_ROW_HEADER_SPLIT_WITH_PREV;
60
+ }
61
+ if (this.isLast) {
62
+ this.flags |= constants.TNS_DPLS_ROW_HEADER_LAST;
63
+ } else if (this.isSplitWithNext) {
64
+ this.flags |= constants.TNS_DPLS_ROW_HEADER_SPLIT_WITH_NEXT;
65
+ }
66
+ if (this.isFastRow()) {
67
+ this.flags |= constants.TNS_DPLS_ROW_HEADER_FAST_ROW;
68
+ this.flags |= constants.TNS_DPLS_ROW_HEADER_FAST_PIECE;
69
+ }
70
+ }
71
+
72
+ headerLength() {
73
+ let length = 2;
74
+ if (this.isFastRow()) {
75
+ length += 2;
76
+ }
77
+ return length;
78
+ }
79
+
80
+ isFastRow() {
81
+ return this.isFirst && this.isLast && this.isFast;
82
+ }
83
+
84
+ writeToMessage(buf) {
85
+ buf.writeUInt8(this.flags);
86
+ if (this.isFastRow()) {
87
+ buf.writeUInt16BE(this.length + this.headerLength());
88
+ }
89
+ buf.writeUInt8(this.numSegments);
90
+ buf.writeBytes(this.data);
91
+ }
92
+ }
93
+
94
+ class PieceBuffer extends BaseBuffer {
95
+ constructor(connection) {
96
+ super(Buffer.alloc(constants.TNS_DPLS_MAX_PIECE_SIZE));
97
+ this.connection = connection;
98
+ this.currentPiece = null;
99
+ this.totalPieceLength = 0;
100
+ this.pieces = [];
101
+ this._encodingTempBuf = new BaseBuffer(
102
+ Buffer.alloc(constants.TNS_DPLS_MAX_BUFFER_SIZE_FACTOR)
103
+ );
104
+ }
105
+
106
+ _writeMoreData() {
107
+ this._finalizePiece();
108
+ this.currentPiece = new DirectPathPiece();
109
+ }
110
+
111
+ _finalizePiece() {
112
+ this.currentPiece.finalize(this);
113
+ this.pieces.push(this.currentPiece);
114
+ const newLength =
115
+ this.totalPieceLength +
116
+ this.currentPiece.length +
117
+ this.currentPiece.headerLength();
118
+ if (newLength > constants.TNS_DPLS_MAX_MESSAGE_SIZE)
119
+ errors.throwErr(errors.ERR_DPL_TOO_MUCH_DATA);
120
+ this.totalPieceLength = newLength;
121
+ }
122
+
123
+ // Overloads the already existing function in BaseBuffer for DPL specs
124
+ // This also handles writing length of the encoding done in addColumnValue().
125
+ _writeRawBytesAndLength(value, numBytes) {
126
+ let bytesLeft = this.maxSize - this.pos;
127
+ if (numBytes <= constants.TNS_DPLS_MAX_SHORT_LENGTH) {
128
+ if (numBytes + 1 > bytesLeft) {
129
+ this._finalizePiece();
130
+ this.currentPiece = new DirectPathPiece();
131
+ }
132
+ this.writeUInt8(numBytes);
133
+ if (numBytes > 0) {
134
+ this.writeBytes(value);
135
+ }
136
+ this.currentPiece.numSegments += 1;
137
+ } else {
138
+ let startPos = 0;
139
+ while (numBytes + 3 > bytesLeft) {
140
+ const bytesToWrite = bytesLeft - 3;
141
+ this.writeUInt8(constants.TNS_LONG_LENGTH_INDICATOR);
142
+ this.writeUInt16BE(bytesToWrite);
143
+ this.writeBytes(value.subarray(startPos, startPos + bytesToWrite));
144
+ startPos += bytesToWrite;
145
+ numBytes -= bytesToWrite;
146
+ bytesLeft = this.maxSize;
147
+ this.currentPiece.isSplitWithNext = true;
148
+ this.currentPiece.numSegments += 1;
149
+ this._finalizePiece();
150
+ this.currentPiece = new DirectPathPiece();
151
+ this.currentPiece.isSplitWithPrev = numBytes > 0;
152
+ }
153
+ if (numBytes > 0) {
154
+ this.currentPiece.numSegments += 1;
155
+ this.writeUInt8(constants.TNS_LONG_LENGTH_INDICATOR);
156
+ this.writeUInt16BE(numBytes);
157
+ this.writeBytes(value.subarray(startPos));
158
+ }
159
+ }
160
+ }
161
+
162
+ addColumnValue(metadata, value, caps) {
163
+ if (this.currentPiece.numSegments === 255) {
164
+ this._finalizePiece();
165
+ this.currentPiece = new DirectPathPiece();
166
+ }
167
+
168
+ if (!metadata.type.isFast) {
169
+ this.currentPiece.isFast = false;
170
+ }
171
+
172
+ if (value === null) {
173
+ if (!metadata.fetchInfo.nullable)
174
+ errors.throwErr(
175
+ errors.ERR_NULLS_NOT_ALLOWED,
176
+ metadata.fetchInfo.dbColumnName,
177
+ metadata.rowNum
178
+ );
179
+ this.writeUInt8(constants.TNS_NULL_LENGTH_INDICATOR);
180
+ this.currentPiece.numSegments += 1;
181
+ return;
182
+ }
183
+
184
+ // Reset the temporary encoding buffer for each column, as it's reused
185
+ this._encodingTempBuf.pos = 0;
186
+
187
+ const oraType = metadata.type;
188
+ let columnDataBuffer;
189
+
190
+ value = transformer.transformValueIn(
191
+ {
192
+ type: oraType,
193
+ maxSize: metadata.maxSize,
194
+ checkSize: true,
195
+ },
196
+ value,
197
+ {
198
+ allowArray: false,
199
+ pos: metadata.rowNum + 1,
200
+ }
201
+ );
202
+
203
+ // TODO use oraTypeNum similar to python for simple int check.
204
+ // Writing only the encoding (data bytes) on buffers for column values
205
+ if (
206
+ [
207
+ types.DB_TYPE_CHAR,
208
+ types.DB_TYPE_VARCHAR,
209
+ types.DB_TYPE_NCHAR,
210
+ types.DB_TYPE_NVARCHAR,
211
+ types.DB_TYPE_LONG,
212
+ types.DB_TYPE_LONG_NVARCHAR,
213
+ ].includes(oraType)
214
+ ) {
215
+ // Encode the data bytes directly after checking charset for strings
216
+ if (oraType._csfrm === constants.CSFRM_NCHAR) {
217
+ caps.checkNCharsetId();
218
+ columnDataBuffer = Buffer.from(
219
+ value,
220
+ constants.TNS_ENCODING_UTF16
221
+ ).swap16();
222
+ } else {
223
+ caps.checkCharsetId();
224
+ columnDataBuffer = Buffer.from(value);
225
+ }
226
+ } else if (
227
+ [
228
+ types.DB_TYPE_RAW,
229
+ types.DB_TYPE_LONG_RAW
230
+ ].includes(oraType)
231
+ ) {
232
+ // Encode the data bytes directly for raw/long types
233
+ columnDataBuffer = Buffer.from(value);
234
+ // Encode the data bytes into a temporary buffer for Oracle types
235
+ } else if (oraType === types.DB_TYPE_NUMBER) {
236
+ this._encodingTempBuf.writeOracleNumber(value.toString(), false);
237
+ } else if (oraType === types.DB_TYPE_BINARY_DOUBLE) {
238
+ this._encodingTempBuf.writeBinaryDouble(value);
239
+ } else if (oraType === types.DB_TYPE_BINARY_FLOAT) {
240
+ this._encodingTempBuf.writeBinaryFloat(value);
241
+ } else if (
242
+ [
243
+ types.DB_TYPE_DATE,
244
+ types.DB_TYPE_TIMESTAMP,
245
+ types.DB_TYPE_TIMESTAMP_LTZ,
246
+ types.DB_TYPE_TIMESTAMP_TZ,
247
+ ].includes(oraType)
248
+ ) {
249
+ this._encodingTempBuf.writeOracleDate(value, oraType, false);
250
+ } else if (oraType === types.DB_TYPE_INTERVAL_DS) {
251
+ this._encodingTempBuf.writeOracleIntervalDS(value, false);
252
+ } else if (oraType === types.DB_TYPE_INTERVAL_YM) {
253
+ this._encodingTempBuf.writeOracleIntervalYM(value, false);
254
+ } else if (oraType === types.DB_TYPE_BOOLEAN) {
255
+ // Needs clarity as normal boolean encoding causes corruption
256
+ if (value) {
257
+ this._encodingTempBuf.writeUInt8(0x01);
258
+ } else {
259
+ this._encodingTempBuf.writeUInt8(0x00);
260
+ }
261
+ } else if (oraType === types.DB_TYPE_JSON) {
262
+ const encoder = new oson.OsonEncoder();
263
+ columnDataBuffer = encoder.encode(
264
+ value,
265
+ this.connection._osonMaxFieldSize
266
+ );
267
+ } else if (oraType === types.DB_TYPE_VECTOR) {
268
+ const encoder = new vector.VectorEncoder();
269
+ columnDataBuffer = encoder.encode(value);
270
+ } else {
271
+ errors.throwErr(
272
+ errors.ERR_UNSUPPORTED_DATA_TYPE,
273
+ oraType.oraTypeNum,
274
+ metadata.columnNum
275
+ );
276
+ }
277
+
278
+ // If the type was an Oracle Type we had written the data on a temporary
279
+ // BaseBuffer, so we copy the data to our temporaryBuffer
280
+ if (!columnDataBuffer)
281
+ columnDataBuffer = this._encodingTempBuf.buf.slice(
282
+ 0,
283
+ this._encodingTempBuf.pos
284
+ );
285
+
286
+ this._writeRawBytesAndLength(columnDataBuffer, columnDataBuffer.length);
287
+ }
288
+
289
+ finishRow() {
290
+ this.currentPiece.isLast = true;
291
+ this._finalizePiece();
292
+ this.currentPiece = null;
293
+ }
294
+
295
+ startRow() {
296
+ this.currentPiece = new DirectPathPiece();
297
+ this.currentPiece.isFirst = true;
298
+ this.currentPiece.isFast = true;
299
+ }
300
+ }
301
+
302
+ class DirectPathLoadStreamMessage extends Message {
303
+ constructor(connection) {
304
+ super(connection);
305
+ this.caps = connection._protocol.caps;
306
+ this.totalPieceLength = 0;
307
+ this.cursorId = 0;
308
+ this.rowPieces = [];
309
+ this.functionCode = constants.TNS_FUNC_DIRECT_PATH_LOAD_STREAM;
310
+ }
311
+
312
+ _calculatePieces(data, columnMetadata) {
313
+ // Probably better to maintain a MAX_BUFFER_SIZE_FACTOR in types.js
314
+ const numRows = data.length;
315
+ const buf = new PieceBuffer(this.connection);
316
+
317
+ for (let rowNum = 0; rowNum < numRows; rowNum++) {
318
+ const row = data[rowNum];
319
+ if (row.length !== columnMetadata.length) {
320
+ errors.throwErr(
321
+ errors.ERR_WRONG_NUMBER_OF_BINDS,
322
+ columnMetadata.length,
323
+ row.length
324
+ );
325
+ }
326
+ buf.startRow();
327
+ for (let colNum = 0; colNum < columnMetadata.length; colNum++) {
328
+ const metadata = columnMetadata[colNum];
329
+ metadata.rowNum = rowNum;
330
+ const value = row[colNum];
331
+ buf.addColumnValue(metadata, value, this.caps);
332
+ }
333
+ buf.finishRow();
334
+ }
335
+
336
+ this.totalPieceLength = buf.totalPieceLength;
337
+ this.rowPieces = buf.pieces;
338
+ }
339
+
340
+ processErrorInfo(buf) {
341
+ super.processErrorInfo(buf);
342
+ if (this.errorInfo.num === constants.TNS_ERR_NO_DATA_FOUND) {
343
+ this.errorInfo.num = 0;
344
+ this.errorOccurred = false;
345
+ }
346
+ }
347
+
348
+ processReturnParameter(buf) {
349
+ const numOutValues = buf.readUB2();
350
+ for (let i = 0; i < numOutValues; i++) {
351
+ buf.skipBytes(4);
352
+ }
353
+ }
354
+
355
+ encode(buf) {
356
+ this.writeFunctionHeader(buf);
357
+ buf.writeUB2(this.cursorId);
358
+ buf.writeUInt8(1); // pointer (buffer)
359
+ buf.writeUB4(this.totalPieceLength);
360
+ buf.writeUB4(constants.TNS_DP_STREAM_VERSION);
361
+ buf.writeUInt8(0); // pointer (input values)
362
+ buf.writeUB4(0); // number of input values
363
+ buf.writeUInt8(1); // pointer (output values)
364
+ buf.writeUInt8(1); // pointer (output values length)
365
+
366
+ for (const piece of this.rowPieces) {
367
+ piece.writeToMessage(buf);
368
+ }
369
+ }
370
+
371
+ prepare(cursorId, data, columnMetadata) {
372
+ this.cursorId = cursorId;
373
+ this._calculatePieces(data, columnMetadata);
374
+ }
375
+ }
376
+
377
+ module.exports = DirectPathLoadStreamMessage;
@@ -0,0 +1,65 @@
1
+ // Copyright (c) 2025, 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 BaseMessage = require('./base.js');
30
+ const constants = require('../constants.js');
31
+
32
+ class DirectPathOpMessage extends BaseMessage {
33
+
34
+ constructor(connection) {
35
+ super(connection);
36
+ this.cursorId = 0;
37
+ this.opCode = 0;
38
+ this.functionCode = constants.TNS_FUNC_DIRECT_PATH_OP;
39
+ }
40
+
41
+ processReturnParameter(buf) {
42
+ const numOutValues = buf.readUB2();
43
+ for (let i = 0; i < numOutValues; i++) {
44
+ buf.skipUB4();
45
+ }
46
+ }
47
+
48
+ encode(buf) {
49
+ this.writeFunctionHeader(buf);
50
+ buf.writeUB4(this.opCode);
51
+ buf.writeUB2(this.cursorId);
52
+ buf.writeUInt8(0); // pointer (input values)
53
+ buf.writeUB4(0); // number of input values
54
+ buf.writeUInt8(1); // pointer (output values)
55
+ buf.writeUInt8(1); // pointer (output values length)
56
+ }
57
+
58
+ prepare(cursorId, opCode) {
59
+ this.cursorId = cursorId;
60
+ this.opCode = opCode;
61
+ }
62
+
63
+ }
64
+
65
+ module.exports = DirectPathOpMessage;
@@ -0,0 +1,158 @@
1
+ // Copyright (c) 2025, 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 BaseMessage = require('./base.js');
30
+ const constants = require('../constants.js');
31
+ const errors = require('../../../errors.js');
32
+ const types = require('../../../types.js');
33
+
34
+ class DirectPathPrepareMessage extends BaseMessage {
35
+
36
+ constructor(connection) {
37
+ super(connection);
38
+ this.schemaName = null;
39
+ this.tableName = null;
40
+ this.columnNames = [];
41
+ this.columnMetadata = [];
42
+ this.cursorId = 0;
43
+ this.inValues = new Array(constants.TNS_DPP_IN_MAX_PARAMS).fill(0);
44
+ this.inValuesLength = 0;
45
+ this.outValues = null;
46
+ this.outValuesLength = 0;
47
+ this.functionCode = constants.TNS_FUNC_DIRECT_PATH_PREPARE;
48
+ }
49
+
50
+ //---------------------------------------------------------------------------
51
+ // _setInValue()
52
+ // Sets the value in the input array and updates the maximum value set.
53
+ //---------------------------------------------------------------------------
54
+ _setInValue(key, value) {
55
+ this.inValues[key] = value;
56
+ this.inValuesLength = Math.max(this.inValuesLength, key + 1);
57
+ }
58
+
59
+ //---------------------------------------------------------------------------
60
+ // _writeKeywordParam()
61
+ // Writes a keyword parameter to the buffer.
62
+ //---------------------------------------------------------------------------
63
+ _writeKeywordParam(buf, index, value) {
64
+ const valueBytes = Buffer.from(value, 'utf-8');
65
+ buf.writeUB2(0); // text length (placeholder?)
66
+ buf.writeUB2(valueBytes.length);
67
+ buf.writeBytesWithLength(valueBytes);
68
+ buf.writeUB2(index);
69
+ }
70
+
71
+ //---------------------------------------------------------------------------
72
+ // write()
73
+ // Write the message to the given buffer.
74
+ //---------------------------------------------------------------------------
75
+ encode(buf) {
76
+ // Initialize input array
77
+ this._setInValue(constants.TNS_DPP_IN_INDEX_INTERFACE_VERSION, constants.TNS_DP_INTERFACE_VERSION);
78
+ this._setInValue(constants.TNS_DPP_IN_INDEX_STREAM_VERSION, constants.TNS_DP_STREAM_VERSION);
79
+ this._setInValue(constants.TNS_DPP_IN_INDEX_LOCK_WAIT, 1);
80
+ this._setInValue(constants.TNS_DPP_KW_INDEX_NFOBJ_OID_POS, 0xffff);
81
+ this._setInValue(constants.TNS_DPP_KW_INDEX_NFOBJ_SID_POS, 0xffff);
82
+ this._setInValue(constants.TNS_DPP_KW_INDEX_NFOBJ_VARRAY_INDEX, 0xffff);
83
+
84
+ // Write message
85
+ this.writeFunctionHeader(buf);
86
+ const keywordParametersLength = this.columnNames.length + 2;
87
+ buf.writeUB4(constants.TNS_DPP_OP_CODE_LOAD); // op code
88
+ buf.writeUInt8(1); // keyword parameters (pointer)
89
+ buf.writeUB4(keywordParametersLength);
90
+ buf.writeUInt8(1); // input array (pointer)
91
+ buf.writeUB2(this.inValuesLength);
92
+ buf.writeUInt8(1); // metadata (pointer)
93
+ buf.writeUInt8(1); // metadata length (pointer)
94
+ buf.writeUInt8(1); // parameters (pointer)
95
+ buf.writeUInt8(1); // parameters length (pointer)
96
+ buf.writeUInt8(1); // output array (pointer)
97
+ buf.writeUInt8(1); // output array length (pointer)
98
+
99
+ this._writeKeywordParam(buf, constants.TNS_DPP_KW_INDEX_SCHEMA_NAME, this.schemaName);
100
+ this._writeKeywordParam(buf, constants.TNS_DPP_KW_INDEX_OBJECT_NAME, this.tableName);
101
+ for (const name of this.columnNames) {
102
+ this._writeKeywordParam(buf, constants.TNS_DPP_KW_INDEX_COLUMN_NAME, name);
103
+ }
104
+
105
+ for (let i = 0; i < this.inValuesLength; i++) {
106
+ buf.writeUB4(this.inValues[i]);
107
+ }
108
+ }
109
+
110
+ //---------------------------------------------------------------------------
111
+ // processColumnInfo()
112
+ // Process column metadata returned by the database. CLOB and BLOB are
113
+ // always treated as strings and bytes when using direct path load.
114
+ //---------------------------------------------------------------------------
115
+ processColumnInfo(buf, columnNum) {
116
+ const metadata = super.processColumnInfo(buf, columnNum);
117
+ if (metadata.type === types.DB_TYPE_CLOB) {
118
+ let csfrm = metadata.type._csfrm;
119
+ if (csfrm === constants.CSFRM_IMPLICIT) {
120
+ const caps = this.connection._protocol.caps;
121
+ // character set ids < 800 are all single-byte character sets
122
+ // while character set ids >= 800 are all multi-byte character sets
123
+ if (caps.charsetId >= 800)
124
+ csfrm = constants.CSFRM_NCHAR;
125
+ }
126
+ metadata.type = types.getTypeByOraTypeNum(types.DB_TYPE_LONG._oraTypeNum,
127
+ csfrm);
128
+ } else if (metadata.type === types.DB_TYPE_BLOB) {
129
+ metadata.type = types.DB_TYPE_LONG_RAW;
130
+ }
131
+ return metadata;
132
+ }
133
+
134
+ //---------------------------------------------------------------------------
135
+ // processReturnParameter()
136
+ // Process the return parameters sent by the database.
137
+ //---------------------------------------------------------------------------
138
+ processReturnParameter(buf) {
139
+ const numColumns = buf.readUB4();
140
+ this.columnMetadata = [];
141
+ for (let i = 0; i < numColumns; i++) {
142
+ this.columnMetadata.push(this.processColumnInfo(buf, i));
143
+ }
144
+ const numParams = buf.readUB2();
145
+ if (numParams > 0) {
146
+ errors.throwErr(errors.ERR_UNEXPECTED_DATA, 'directPathLoad numParams');
147
+ }
148
+ this.outValuesLength = buf.readUB2();
149
+ this.outValues = [];
150
+ for (let i = 0; i < this.outValuesLength; i++) {
151
+ this.outValues.push(buf.readUB4());
152
+ }
153
+ this.cursorId = this.outValues[constants.TNS_DPP_OUT_INDEX_CURSOR];
154
+ }
155
+
156
+ }
157
+
158
+ module.exports = DirectPathPrepareMessage;
@@ -0,0 +1,56 @@
1
+ // Copyright (c) 2026, 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
+ * Executes endPipeline RPC
34
+ *
35
+ * @class EndPipelineMessage
36
+ * @extends {Message}
37
+ */
38
+ class EndPipelineMessage extends Message {
39
+
40
+ constructor(connImpl) {
41
+ super(connImpl);
42
+ this.functionCode = constants.TNS_FUNC_PIPELINE_END;
43
+ }
44
+
45
+ //-------------------------------------------------------------------------
46
+ // encode()
47
+ //
48
+ // Write the RPC to perform pipeline end operation in the database
49
+ //-------------------------------------------------------------------------
50
+ encode(buf) {
51
+ this.writeFunctionHeader(buf);
52
+ buf.writeUB4(0); // ID (unused)
53
+ }
54
+ }
55
+
56
+ module.exports = EndPipelineMessage;