oracledb 6.8.0 → 6.10.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 (85) hide show
  1. package/README.md +39 -3
  2. package/build/Release/oracledb-6.10.0-darwin-arm64.node +0 -0
  3. package/build/Release/oracledb-6.10.0-darwin-arm64.node-buildinfo.txt +1 -0
  4. package/build/Release/oracledb-6.10.0-darwin-x64.node +0 -0
  5. package/build/Release/oracledb-6.10.0-darwin-x64.node-buildinfo.txt +1 -0
  6. package/build/Release/oracledb-6.10.0-js-buildinfo.txt +1 -0
  7. package/build/Release/oracledb-6.10.0-linux-arm64.node +0 -0
  8. package/build/Release/oracledb-6.10.0-linux-arm64.node-buildinfo.txt +1 -0
  9. package/build/Release/oracledb-6.10.0-linux-x64.node +0 -0
  10. package/build/Release/oracledb-6.10.0-linux-x64.node-buildinfo.txt +1 -0
  11. package/build/Release/oracledb-6.10.0-win32-x64.node +0 -0
  12. package/build/Release/oracledb-6.10.0-win32-x64.node-buildinfo.txt +1 -0
  13. package/lib/aqDeqOptions.js +18 -1
  14. package/lib/aqMessage.js +10 -1
  15. package/lib/aqQueue.js +10 -6
  16. package/lib/configProviders/file.js +72 -0
  17. package/lib/connection.js +93 -4
  18. package/lib/dbObject.js +34 -4
  19. package/lib/errors.js +70 -35
  20. package/lib/impl/aqDeqOptions.js +10 -1
  21. package/lib/impl/connection.js +9 -0
  22. package/lib/impl/datahandlers/buffer.js +49 -0
  23. package/lib/impl/datahandlers/oson.js +7 -2
  24. package/lib/impl/pool.js +10 -1
  25. package/lib/impl/resultset.js +5 -4
  26. package/lib/impl/sodaDocument.js +5 -14
  27. package/lib/lob.js +9 -1
  28. package/lib/oracledb.js +152 -30
  29. package/lib/pool.js +199 -147
  30. package/lib/poolStatistics.js +4 -2
  31. package/lib/sodaCollection.js +12 -8
  32. package/lib/sodaDatabase.js +35 -8
  33. package/lib/sodaDocument.js +24 -6
  34. package/lib/sodaOperation.js +7 -6
  35. package/lib/thin/aq.js +475 -0
  36. package/lib/thin/connection.js +171 -14
  37. package/lib/thin/dbObject.js +8 -6
  38. package/lib/thin/lob.js +2 -3
  39. package/lib/thin/pool.js +105 -28
  40. package/lib/thin/protocol/capabilities.js +10 -4
  41. package/lib/thin/protocol/constants.js +90 -1
  42. package/lib/thin/protocol/encryptDecrypt.js +2 -2
  43. package/lib/thin/protocol/messages/aqArray.js +238 -0
  44. package/lib/thin/protocol/messages/aqBase.js +305 -0
  45. package/lib/thin/protocol/messages/aqDeq.js +164 -0
  46. package/lib/thin/protocol/messages/aqEnq.js +135 -0
  47. package/lib/thin/protocol/messages/auth.js +25 -27
  48. package/lib/thin/protocol/messages/base.js +98 -9
  49. package/lib/thin/protocol/messages/dataType.js +2 -1
  50. package/lib/thin/protocol/messages/execute.js +46 -4
  51. package/lib/thin/protocol/messages/lobOp.js +5 -22
  52. package/lib/thin/protocol/messages/logOff.js +0 -1
  53. package/lib/thin/protocol/messages/sessionRelease.js +0 -1
  54. package/lib/thin/protocol/messages/transactionSwitch.js +12 -4
  55. package/lib/thin/protocol/messages/withData.js +3 -3
  56. package/lib/thin/protocol/packet.js +6 -5
  57. package/lib/thin/protocol/protocol.js +2 -1
  58. package/lib/thin/sqlnet/connStrategy.js +2 -1
  59. package/lib/thin/sqlnet/navNodes.js +1 -1
  60. package/lib/thin/sqlnet/networkSession.js +10 -4
  61. package/lib/thin/sqlnet/packet.js +2 -1
  62. package/lib/thin/sqlnet/sessionAtts.js +2 -3
  63. package/lib/types.js +6 -11
  64. package/lib/util.js +72 -11
  65. package/lib/version.js +1 -1
  66. package/package/install.js +3 -3
  67. package/package/prunebinaries.js +6 -12
  68. package/package.json +2 -2
  69. package/{lib/configProviders/azure.js → plugins/configProviders/azure/index.js} +73 -63
  70. package/plugins/configProviders/azurevault/index.js +84 -0
  71. package/{lib → plugins}/configProviders/base.js +13 -3
  72. package/{lib/configProviders/ociobject.js → plugins/configProviders/ociobject/index.js} +43 -78
  73. package/plugins/configProviders/ocivault/index.js +100 -0
  74. package/plugins/token/extensionOci/index.js +71 -35
  75. package/build/Release/oracledb-6.8.0-darwin-arm64.node +0 -0
  76. package/build/Release/oracledb-6.8.0-darwin-arm64.node-buildinfo.txt +0 -1
  77. package/build/Release/oracledb-6.8.0-darwin-x64.node +0 -0
  78. package/build/Release/oracledb-6.8.0-darwin-x64.node-buildinfo.txt +0 -1
  79. package/build/Release/oracledb-6.8.0-js-buildinfo.txt +0 -1
  80. package/build/Release/oracledb-6.8.0-linux-arm64.node +0 -0
  81. package/build/Release/oracledb-6.8.0-linux-arm64.node-buildinfo.txt +0 -1
  82. package/build/Release/oracledb-6.8.0-linux-x64.node +0 -0
  83. package/build/Release/oracledb-6.8.0-linux-x64.node-buildinfo.txt +0 -1
  84. package/build/Release/oracledb-6.8.0-win32-x64.node +0 -0
  85. package/build/Release/oracledb-6.8.0-win32-x64.node-buildinfo.txt +0 -1
@@ -0,0 +1,305 @@
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
+ //-----------------------------------------------------------------------------
28
+ // aqBase.js
29
+ //
30
+ // This file defines the base class for messages that are sent to the
31
+ // database and the responses that are received by the client for enqueuing and
32
+ // dequeuing AQ messages.
33
+ //-----------------------------------------------------------------------------
34
+
35
+ 'use strict';
36
+
37
+ const constants = require("../constants.js");
38
+ const errors = require("../../../errors.js");
39
+ const BaseMessage = require("./base.js");
40
+ const { ThinDbObjectImpl } = require("../../dbObject.js");
41
+ const oson = require('../../../impl/datahandlers/oson.js');
42
+
43
+ class AqBaseMessage extends BaseMessage {
44
+
45
+ constructor(connImpl) {
46
+ super(connImpl);
47
+ this.queueImpl = null;
48
+ this.deqOptionsImpl = null;
49
+ this.enqOptionsImpl = null;
50
+ this.noMsgFound = false;
51
+ }
52
+
53
+ //--------------------------------------------------------------------------
54
+ // _processDate()
55
+ //
56
+ // Processes a date found in the buffer.
57
+ //--------------------------------------------------------------------------
58
+ _processDate(buf) {
59
+ const numBytes = buf.readUB4();
60
+ if (numBytes > 0)
61
+ return buf.readOracleDate(true);
62
+ }
63
+
64
+ //--------------------------------------------------------------------------
65
+ // _processErrorInfo()
66
+ //
67
+ // Process error information from the buffer. If the error that indicates
68
+ // that no messages were received is detected, the error is cleared and
69
+ // the flag set so that the dequeue can handle that case.
70
+ //--------------------------------------------------------------------------
71
+ processErrorInfo(buf) {
72
+ super.processErrorInfo(buf);
73
+ if (this.errorInfo.num === constants.TNS_ERR_NO_MESSAGES_FOUND) {
74
+ this.errorInfo.num = 0;
75
+ this.errorOccurred = false;
76
+ this.noMsgFound = true;
77
+ }
78
+ }
79
+
80
+ //--------------------------------------------------------------------------
81
+ // _processExtensions()
82
+ //
83
+ // Processes extensions to the message property object returned by the
84
+ // database.
85
+ //--------------------------------------------------------------------------
86
+ _processExtensions(buf, propsImpl) {
87
+ const numExtensions = buf.readUB4();
88
+ if (numExtensions > 0) {
89
+ buf.skipUB1();
90
+ for (let i = 0; i < numExtensions; i++) {
91
+ const textValue = buf.readBytesAndLength();
92
+ const binaryValue = buf.readBytesAndLength();
93
+ const value = textValue || binaryValue;
94
+ const keyword = buf.readUB2();
95
+ if (value) {
96
+ if (keyword === constants.TNS_AQ_EXT_KEYWORD_AGENT_NAME) {
97
+ propsImpl.senderAgentName = value;
98
+ } else if (keyword === constants.TNS_AQ_EXT_KEYWORD_AGENT_ADDRESS) {
99
+ propsImpl.senderAgentAddress = value;
100
+ } else if (keyword === constants.TNS_AQ_EXT_KEYWORD_AGENT_PROTOCOL) {
101
+ propsImpl.senderAgentProtocol = value[0];
102
+ } else if (keyword === constants.TNS_AQ_EXT_KEYWORD_ORIGINAL_MSGID) {
103
+ propsImpl.originalMsgId = value;
104
+ }
105
+ }
106
+ }
107
+ }
108
+ }
109
+
110
+ //--------------------------------------------------------------------------
111
+ // _processMsgId()
112
+ //
113
+ // Reads a message id from the buffer and returns it.
114
+ //--------------------------------------------------------------------------
115
+ _processMsgId(buf) {
116
+ return Buffer.from(buf.readBytes(constants.TNS_AQ_MESSAGE_ID_LENGTH));
117
+ }
118
+
119
+ //--------------------------------------------------------------------------
120
+ // _processMsgProps()
121
+ //
122
+ // Processes a message property object returned by the database.
123
+ //--------------------------------------------------------------------------
124
+ _processMsgProps(buf, propsImpl) {
125
+ propsImpl.priority = buf.readSB4();
126
+ propsImpl.delay = buf.readSB4();
127
+ propsImpl.expiration = buf.readSB4();
128
+ propsImpl.correlation = buf.readStrAndLength();
129
+ propsImpl.numAttempts = buf.readSB4();
130
+ propsImpl.exceptionQueue = buf.readStrAndLength();
131
+ propsImpl.state = buf.readSB4();
132
+ propsImpl.enqTime = this._processDate(buf);
133
+ propsImpl.enqTxnId = buf.readBytesAndLength();
134
+ this._processExtensions(buf, propsImpl);
135
+ const temp32 = buf.readUB4(); // user properties
136
+ if (temp32 > 0) {
137
+ errors.throwErr(errors.ERR_NOT_IMPLEMENTED);
138
+ }
139
+ buf.skipUB4(); // csn
140
+ buf.skipUB4(); // dsn
141
+ const flags = buf.readUB4();
142
+ if (flags === constants.TNS_KPD_AQ_BUFMSG) {
143
+ propsImpl.deliveryMode = constants.TNS_AQ_MSG_BUFFERED;
144
+ } else {
145
+ propsImpl.deliveryMode = constants.TNS_AQ_MSG_PERSISTENT;
146
+ }
147
+ if (buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_21_1) {
148
+ buf.skipUB4(); // shard number
149
+ }
150
+ }
151
+
152
+ //--------------------------------------------------------------------------
153
+ // _processPayload()
154
+ //
155
+ // Processes the payload for an enqueued message returned by the database.
156
+ //--------------------------------------------------------------------------
157
+ _processPayload(buf) {
158
+ const payloadData = buf.readDbObject();
159
+ if (this.queueImpl.payloadTypeClass) {
160
+ const obj = new this.queueImpl.payloadTypeClass();
161
+ const objImpl = new ThinDbObjectImpl(this.queueImpl.payloadTypeClass,
162
+ payloadData.packedData);
163
+ if (payloadData) {
164
+ objImpl.toid = payloadData.toid;
165
+ objImpl.oid = payloadData.oid;
166
+ }
167
+ obj._impl = objImpl;
168
+ return obj;
169
+ } else {
170
+ if (payloadData.packedData) {
171
+ const payload = Buffer.from(payloadData.packedData.slice(4));
172
+ if (this.queueImpl.isJson) {
173
+ const decoder = new oson.OsonDecoder(payload);
174
+ return decoder.decode();
175
+ }
176
+ return payload;
177
+ } else if (!this.queueImpl.isJson) {
178
+ return Buffer.alloc(0);
179
+ }
180
+ }
181
+ }
182
+
183
+ //--------------------------------------------------------------------------
184
+ // _processRecipients()
185
+ //
186
+ // Process recipients for a message.
187
+ //--------------------------------------------------------------------------
188
+ _processRecipients(buf) {
189
+ const numRecipients = buf.readUB4();
190
+ if (numRecipients > 0)
191
+ errors.throwNotImplemented('aq recipients');
192
+ return [];
193
+ }
194
+
195
+ //--------------------------------------------------------------------------
196
+ // _writeMsgProps()
197
+ //
198
+ // Write a message property object to the buffer.
199
+ //--------------------------------------------------------------------------
200
+ _writeMsgProps(buf, propsImpl) {
201
+ buf.writeSB4(propsImpl.priority);
202
+ buf.writeSB4(propsImpl.delay);
203
+ buf.writeSB4(propsImpl.expiration);
204
+ this._writeValueWithLength(buf, propsImpl.correlation);
205
+ buf.writeUB4(0); // number of attempts
206
+ this._writeValueWithLength(buf, propsImpl.exceptionQueue);
207
+ buf.writeUB4(propsImpl.state);
208
+ buf.writeUB4(0); // enqueue time length
209
+ this._writeValueWithLength(buf, propsImpl.enqTxnId);
210
+ buf.writeUB4(4); // number of extensions
211
+ buf.writeUInt8(0x0e); // unknown extra byte
212
+
213
+ this._writeKeywordValuePair(buf, null, null,
214
+ constants.TNS_AQ_EXT_KEYWORD_AGENT_NAME);
215
+ this._writeKeywordValuePair(buf, null, null,
216
+ constants.TNS_AQ_EXT_KEYWORD_AGENT_ADDRESS);
217
+ this._writeKeywordValuePair(buf, null, Buffer.from([0x00]),
218
+ constants.TNS_AQ_EXT_KEYWORD_AGENT_PROTOCOL);
219
+ this._writeKeywordValuePair(buf, null, null,
220
+ constants.TNS_AQ_EXT_KEYWORD_ORIGINAL_MSGID);
221
+
222
+ buf.writeUB4(0); // user property
223
+ buf.writeUB4(0); // cscn
224
+ buf.writeUB4(0); // dscn
225
+ buf.writeUB4(0); // flags
226
+ if (buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_21_1) {
227
+ buf.writeUB4(0xffffffff); // shard id
228
+ }
229
+ }
230
+
231
+ //--------------------------------------------------------------------------
232
+ // _writePayload()
233
+ //
234
+ // Writes the payload of the message property object to the buffer.
235
+ //--------------------------------------------------------------------------
236
+ _writePayload(buf, propsImpl) {
237
+ if (this.queueImpl.isJson) {
238
+ buf.writeOson(propsImpl.payload, this.connection._osonMaxFieldNameSize,
239
+ false);
240
+ } else if (this.queueImpl.payloadTypeClass) {
241
+ buf.writeDbObject(propsImpl.payload);
242
+ } else {
243
+ buf.writeBytes(propsImpl.payload);
244
+ }
245
+ }
246
+
247
+ //--------------------------------------------------------------------------
248
+ // _writeRecipients()
249
+ //
250
+ // Write the recipient list of the message property object to the buffer.
251
+ //--------------------------------------------------------------------------
252
+ _writeRecipients(buf, propsImpl) {
253
+ let index = 0;
254
+ for (const recipient of propsImpl.recipients) {
255
+ this._writeKeywordValuePair(buf, recipient, null, index);
256
+ this._writeKeywordValuePair(buf, null, null, index + 1);
257
+ this._writeKeywordValuePair(buf, null, Buffer.from([0x00]), index + 2);
258
+ index += 3;
259
+ }
260
+ }
261
+
262
+ //--------------------------------------------------------------------------
263
+ // _writeValueWithLength()
264
+ //
265
+ // Write a string to the buffer, prefixed by a length.
266
+ //--------------------------------------------------------------------------
267
+ _writeValueWithLength(buf, value) {
268
+ if (!value) {
269
+ buf.writeUB4(0);
270
+ } else {
271
+ const valueBytes = Buffer.isBuffer(value) ?
272
+ value : Buffer.from(value, 'utf-8');
273
+ buf.writeUB4(valueBytes.length);
274
+ buf.writeBytesWithLength(valueBytes);
275
+ }
276
+ }
277
+
278
+ //--------------------------------------------------------------------------
279
+ // _writeKeywordValuePair()
280
+ //
281
+ // Writes a keyword value pair to the buffer.
282
+ //--------------------------------------------------------------------------
283
+ _writeKeywordValuePair(buf, textValue, binaryValue, keyword) {
284
+ let textValueBytes;
285
+ if (!textValue) {
286
+ buf.writeUB4(0);
287
+ } else {
288
+ textValueBytes = Buffer.from(textValue);
289
+ buf.writeUB4(textValueBytes.length);
290
+ buf.writeBytesWithLength(textValueBytes);
291
+ }
292
+ if (!binaryValue) {
293
+ buf.writeUB4(0);
294
+ } else {
295
+ buf.writeUB4(binaryValue.length);
296
+ buf.writeBytesWithLength(binaryValue);
297
+ }
298
+
299
+ buf.writeUB2(keyword);
300
+ }
301
+
302
+ }
303
+
304
+
305
+ module.exports = AqBaseMessage;
@@ -0,0 +1,164 @@
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
+ //-----------------------------------------------------------------------------
28
+ // aqDeq.js
29
+ //
30
+ // This file defines the messages that are sent to the database and the
31
+ // responses that are received by the client for dequeuing an AQ message.
32
+ //-----------------------------------------------------------------------------
33
+
34
+ 'use strict';
35
+
36
+ const AqBaseMessage = require("./aqBase.js");
37
+ const constants = require("../constants.js");
38
+
39
+ class AqDeqMessage extends AqBaseMessage {
40
+
41
+ constructor(connImpl) {
42
+ super(connImpl);
43
+ this.functionCode = constants.TNS_FUNC_AQ_DEQ;
44
+ this.propsImpl = null;
45
+ }
46
+
47
+ //--------------------------------------------------------------------------
48
+ // processReturnParameter()
49
+ //
50
+ // Process the return parameters of the AQ Dequeue request.
51
+ //--------------------------------------------------------------------------
52
+ processReturnParameter(buf) {
53
+ const numBytes = buf.readUB4();
54
+ if (numBytes > 0) {
55
+ this._processMsgProps(buf, this.propsImpl);
56
+ this.propsImpl.recipients = this._processRecipients(buf);
57
+ this.propsImpl.payload = this._processPayload(buf);
58
+ this.propsImpl.msgId = this._processMsgId(buf);
59
+ }
60
+ }
61
+
62
+ //--------------------------------------------------------------------------
63
+ // _writeMessageBody()
64
+ //
65
+ // Writes the body of the message to the buffer.
66
+ //--------------------------------------------------------------------------
67
+ encode(buf) {
68
+ const queueNameBytes = Buffer.from(this.queueImpl.name, 'utf-8');
69
+ const consumerNameBytes = this.deqOptionsImpl.consumerName ?
70
+ Buffer.from(this.deqOptionsImpl.consumerName, 'utf-8') : null;
71
+ const correlationBytes = this.deqOptionsImpl.correlation ?
72
+ Buffer.from(this.deqOptionsImpl.correlation, 'utf-8') : null;
73
+ const conditionBytes = this.deqOptionsImpl.condition ?
74
+ Buffer.from(this.deqOptionsImpl.condition, 'utf-8') : null;
75
+ let msgIdBytes = this.deqOptionsImpl.msgId ?
76
+ this.deqOptionsImpl.msgId.slice(0, 16) : null;
77
+ const deliveryMode = this.deqOptionsImpl.deliveryMode;
78
+ let deqFlags = 0;
79
+
80
+ if (msgIdBytes && msgIdBytes.length < 16) {
81
+ msgIdBytes = Buffer.concat([msgIdBytes,
82
+ Buffer.alloc(16 - msgIdBytes.length)]);
83
+ }
84
+
85
+ if (deliveryMode === constants.TNS_AQ_MSG_BUFFERED) {
86
+ deqFlags |= constants.TNS_KPD_AQ_BUFMSG;
87
+ } else if (deliveryMode === constants.TNS_AQ_MSG_PERSISTENT_OR_BUFFERED) {
88
+ deqFlags |= constants.TNS_KPD_AQ_EITHER;
89
+ }
90
+
91
+ this.writeFunctionHeader(buf);
92
+ buf.writeUInt8(1); // queue name (ptr)
93
+ buf.writeUB4(queueNameBytes.length); // queue name len
94
+ buf.writeUInt8(1); // message properties
95
+ buf.writeUInt8(1); // msg props len
96
+ buf.writeUInt8(1); // recipient list
97
+ buf.writeUInt8(1); // recipient list len
98
+ if (consumerNameBytes) {
99
+ buf.writeUInt8(1); // consumer name
100
+ buf.writeUB4(consumerNameBytes.length);
101
+ } else {
102
+ buf.writeUInt8(0); // consumer name
103
+ buf.writeUB4(0); // consumer name len
104
+ }
105
+ buf.writeSB4(this.deqOptionsImpl.mode); // dequeue mode
106
+ buf.writeSB4(this.deqOptionsImpl.navigation); // navigation
107
+ buf.writeSB4(this.deqOptionsImpl.visibility); // visibility
108
+ buf.writeSB4(this.deqOptionsImpl.wait); // wait
109
+ if (msgIdBytes) {
110
+ buf.writeUInt8(1); // select mesg id
111
+ buf.writeUB4(constants.TNS_AQ_MESSAGE_ID_LENGTH); // mesg id len
112
+ } else {
113
+ buf.writeUInt8(0); // select mesg id
114
+ buf.writeUB4(0); // select mesg id len
115
+ }
116
+ if (correlationBytes) {
117
+ buf.writeUInt8(1); // correlation id
118
+ buf.writeUB4(correlationBytes.length); // correlation id len
119
+ } else {
120
+ buf.writeUInt8(0); // correlation id
121
+ buf.writeUB4(0); // correlation id len
122
+ }
123
+ buf.writeUInt8(1); // toid of payload
124
+ buf.writeUB4(16); // toid len
125
+ buf.writeUB2(constants.TNS_AQ_MESSAGE_VERSION);
126
+ buf.writeUInt8(1); // payload
127
+ buf.writeUInt8(1); // return msg id
128
+ buf.writeUB4(constants.TNS_AQ_MESSAGE_ID_LENGTH);
129
+ buf.writeUB4(deqFlags); // dequeue flags
130
+ if (conditionBytes) {
131
+ buf.writeUInt8(1); // condition (pointer)
132
+ buf.writeUB4(conditionBytes.length); // condition len
133
+ } else {
134
+ buf.writeUInt8(0); // condition
135
+ buf.writeUB4(0); // condition len
136
+ }
137
+ buf.writeUInt8(0); // extensions
138
+ buf.writeUB4(0); // number of extensions
139
+ if (buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_20_1) {
140
+ buf.writeUInt8(0); // JSON payload
141
+ }
142
+ if (buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_21_1) {
143
+ buf.writeUB4(0xffffffff); // shard id
144
+ }
145
+
146
+ buf.writeBytesWithLength(queueNameBytes);
147
+ if (consumerNameBytes) {
148
+ buf.writeBytesWithLength(consumerNameBytes);
149
+ }
150
+ if (msgIdBytes) {
151
+ buf.writeBytes(msgIdBytes);
152
+ }
153
+ if (correlationBytes) {
154
+ buf.writeBytesWithLength(correlationBytes);
155
+ }
156
+ buf.writeBytes(this.queueImpl.payloadToid);
157
+ if (conditionBytes) {
158
+ buf.writeBytesWithLength(conditionBytes);
159
+ }
160
+ }
161
+
162
+ }
163
+
164
+ module.exports = AqDeqMessage;
@@ -0,0 +1,135 @@
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
+ //-----------------------------------------------------------------------------
28
+ // aqEnq.js
29
+ //
30
+ // This file defines the messages that are sent to the database and the
31
+ // responses that are received by the client for enqueuing an AQ message.
32
+ //-----------------------------------------------------------------------------
33
+
34
+ 'use strict';
35
+
36
+ const AqBaseMessage = require("./aqBase.js");
37
+ const constants = require("../constants.js");
38
+
39
+ class AqEnqMessage extends AqBaseMessage {
40
+
41
+ constructor(connImpl) {
42
+ super(connImpl);
43
+ this.functionCode = constants.TNS_FUNC_AQ_ENQ;
44
+ this.propsImpl = null;
45
+ }
46
+
47
+ //--------------------------------------------------------------------------
48
+ // processReturnParameter()
49
+ //
50
+ // Process the return parameters for the AQ enqueue request.
51
+ //--------------------------------------------------------------------------
52
+ processReturnParameter(buf) {
53
+ this.propsImpl.msgId = this._processMsgId(buf);
54
+ buf.skipUB2(); // extensions length
55
+ }
56
+
57
+ //--------------------------------------------------------------------------
58
+ // encode()
59
+ //
60
+ // Writes the body of the message to the buffer.
61
+ //--------------------------------------------------------------------------
62
+ encode(buf) {
63
+ const queueNameBytes = Buffer.from(this.queueImpl.name, 'utf-8');
64
+ let enqFlags = 0;
65
+
66
+ if (this.enqOptionsImpl.deliveryMode === constants.TNS_AQ_MSG_BUFFERED) {
67
+ enqFlags |= constants.TNS_KPD_AQ_BUFMSG;
68
+ }
69
+
70
+ this.writeFunctionHeader(buf);
71
+ buf.writeUInt8(1); // queue name (ptr)
72
+ buf.writeUB4(queueNameBytes.length); // queue name len
73
+ this._writeMsgProps(buf, this.propsImpl);
74
+ if (!this.propsImpl.recipients) {
75
+ buf.writeUInt8(0); // recipients (ptr)
76
+ buf.writeUB4(0); // no. of key/value pairs
77
+ } else {
78
+ buf.writeUInt8(1); // recipients (ptr)
79
+ buf.writeUB4(3 * this.propsImpl.recipients.length);
80
+ }
81
+ buf.writeUB4(this.enqOptionsImpl.visibility);
82
+ buf.writeUInt8(0); // relative msg id
83
+ buf.writeUB4(0); // relative msg len
84
+ buf.writeUB4(0); // sequence deviation
85
+ buf.writeUInt8(1); // TOID of payload (ptr)
86
+ buf.writeUB4(16); // TOID of payload len
87
+ buf.writeUB2(constants.TNS_AQ_MESSAGE_VERSION);
88
+ if (this.queueImpl.isJson) {
89
+ buf.writeUInt8(0); // payload (ptr)
90
+ buf.writeUInt8(0); // RAW payload (ptr)
91
+ buf.writeUB4(0); // RAW payload len
92
+ } else if (this.queueImpl.payloadTypeClass) {
93
+ buf.writeUInt8(1); // payload (ptr)
94
+ buf.writeUInt8(0); // RAW payload (ptr)
95
+ buf.writeUB4(0); // RAW payload len
96
+ } else {
97
+ buf.writeUInt8(0); // payload (ptr)
98
+ buf.writeUInt8(1); // RAW payload (ptr)
99
+ buf.writeUB4(this.propsImpl.payload.length);
100
+ }
101
+ buf.writeUInt8(1); // return msg id (ptr)
102
+ buf.writeUB4(constants.TNS_AQ_MESSAGE_ID_LENGTH); // return msg id len
103
+ buf.writeUB4(enqFlags); // enqueue flags
104
+ buf.writeUInt8(0); // extensions 1 (ptr)
105
+ buf.writeUB4(0); // number of extensions 1
106
+ buf.writeUInt8(0); // extensions 2 (ptr)
107
+ buf.writeUB4(0); // number of extensions 2
108
+ buf.writeUInt8(0); // source sequence number
109
+ buf.writeUB4(0); // source sequence len
110
+ buf.writeUInt8(0); // max sequence number
111
+ buf.writeUB4(0); // max sequence len
112
+ buf.writeUInt8(0); // output ack len
113
+ buf.writeUInt8(0); // correlation (ptr)
114
+ buf.writeUB4(0); // correlation len
115
+ buf.writeUInt8(0); // sender name (ptr)
116
+ buf.writeUB4(0); // sender name len
117
+ buf.writeUInt8(0); // sender address (ptr)
118
+ buf.writeUB4(0); // sender address len
119
+ buf.writeUInt8(0); // sender charset id
120
+ buf.writeUInt8(0); // sender ncharset id
121
+ if (buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_20_1) {
122
+ buf.writeUInt8(this.queueImpl.isJson ? 1 : 0); // JSON payload (ptr)
123
+ }
124
+
125
+ buf.writeBytesWithLength(queueNameBytes);
126
+ if (this.propsImpl.recipients) {
127
+ this._writeRecipients(buf, this.propsImpl);
128
+ }
129
+ buf.writeBytes(this.queueImpl.payloadToid);
130
+ this._writePayload(buf, this.propsImpl);
131
+ }
132
+
133
+ }
134
+
135
+ module.exports = AqEnqMessage;
@@ -114,6 +114,7 @@ class AuthMessage extends Message {
114
114
  } else if (process.env.ORA_EDITION) {
115
115
  this.edition = process.env.ORA_EDITION;
116
116
  }
117
+ this.appContext = config.appContext;
117
118
  this.setAuthMode(config);
118
119
  }
119
120
 
@@ -247,6 +248,9 @@ class AuthMessage extends Message {
247
248
  if (this.edition) {
248
249
  numPairs += 1;
249
250
  }
251
+ if (this.appContext) {
252
+ numPairs += this.appContext.length * 3;
253
+ }
250
254
  if (this.schemaUser.length !== 0) {
251
255
  numPairs += 1;
252
256
  }
@@ -319,6 +323,15 @@ class AuthMessage extends Message {
319
323
  if (this.edition) {
320
324
  buf.writeKeyValue("AUTH_ORA_EDITION", this.edition);
321
325
  }
326
+ if (this.appContext) {
327
+ // NOTE: these keys require a trailing null character as the server
328
+ // expects it!
329
+ for (const entry of this.appContext) {
330
+ buf.writeKeyValue("AUTH_APPCTX_NSPACE\0", entry[0]);
331
+ buf.writeKeyValue("AUTH_APPCTX_ATTR\0", entry[1]);
332
+ buf.writeKeyValue("AUTH_APPCTX_VALUE\0", entry[2]);
333
+ }
334
+ }
322
335
 
323
336
  }
324
337
  }
@@ -342,34 +355,19 @@ class AuthMessage extends Message {
342
355
  }
343
356
  if (this.functionCode === constants.TNS_FUNC_AUTH_PHASE_ONE) {
344
357
  this.functionCode = constants.TNS_FUNC_AUTH_PHASE_TWO;
345
- } else {
346
- let releaseNum;
347
- let updateNum;
348
- let portReleaseNum;
349
- let portUpdateNum;
350
-
351
- this.conn.dbDomain = this.sessionData['AUTH_SC_DB_DOMAIN'];
352
- this.conn.dbName = this.sessionData['AUTH_DBNAME'];
353
- this.conn.maxOpenCursors = Number(this.sessionData['AUTH_MAX_OPEN_CURSORS'] || 0);
354
- this.conn.serviceName = this.sessionData['AUTH_SC_SERVICE_NAME'];
355
- this.conn.instanceName = this.sessionData['AUTH_INSTANCENAME'];
356
- this.conn.maxIdentifierLength = Number(this.sessionData['AUTH_MAX_IDEN_LENGTH'] || 30);
357
- const fullVersionNum = Number(this.sessionData['AUTH_VERSION_NO']);
358
- const versionNum = (fullVersionNum >> 24) & 0xFF;
359
- this.conn.warning = this.warning;
360
- if (buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_18_1_EXT_1) {
361
- releaseNum = (fullVersionNum >> 16) & 0xFF;
362
- updateNum = (fullVersionNum >> 12) & 0x0F;
363
- portReleaseNum = (fullVersionNum >> 4) & 0xFF;
364
- portUpdateNum = fullVersionNum & 0x0F;
365
- } else {
366
- releaseNum = (fullVersionNum >> 20) & 0x0F;
367
- updateNum = (fullVersionNum >> 12) & 0xFF;
368
- portReleaseNum = (fullVersionNum >> 8) & 0x0F;
369
- portUpdateNum = fullVersionNum & 0xFF;
358
+ } else if (!this.changePassword && this.comboKey) {
359
+ const value = this.sessionData.AUTH_SVR_RESPONSE;
360
+ let response;
361
+ if (value) {
362
+ const encodedResponse = Buffer.from(value, "hex");
363
+ response = ED.decrypt(this.comboKey, encodedResponse);
364
+ }
365
+ if (
366
+ !response ||
367
+ !response.subarray(16, 32).equals(Buffer.from("SERVER_TO_CLIENT"))
368
+ ) {
369
+ errors.throwErr(errors.ERR_INVALID_SERVER_RESPONSE);
370
370
  }
371
- this.conn.serverVersionString = versionNum + '.' + releaseNum + '.' + updateNum + '.' + portReleaseNum + '.' + portUpdateNum;
372
- this.conn.serverVersion = versionNum * 100000000 + releaseNum * 1000000 + updateNum * 10000 + portReleaseNum * 100 + portUpdateNum * 1;
373
371
  }
374
372
  }
375
373