oracledb 6.9.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.
- package/README.md +2 -2
- package/build/Release/oracledb-6.10.0-darwin-arm64.node +0 -0
- package/build/Release/oracledb-6.10.0-darwin-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.10.0-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.10.0-darwin-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.10.0-js-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.10.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.10.0-linux-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.10.0-linux-x64.node +0 -0
- package/build/Release/oracledb-6.10.0-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.10.0-win32-x64.node +0 -0
- package/build/Release/oracledb-6.10.0-win32-x64.node-buildinfo.txt +1 -0
- package/lib/aqDeqOptions.js +18 -1
- package/lib/aqQueue.js +10 -6
- package/lib/connection.js +6 -2
- package/lib/dbObject.js +25 -4
- package/lib/errors.js +14 -4
- package/lib/impl/aqDeqOptions.js +10 -1
- package/lib/impl/datahandlers/buffer.js +49 -0
- package/lib/impl/datahandlers/oson.js +7 -2
- package/lib/impl/sodaDocument.js +5 -14
- package/lib/oracledb.js +23 -14
- package/lib/pool.js +187 -146
- package/lib/poolStatistics.js +1 -1
- package/lib/sodaCollection.js +12 -8
- package/lib/sodaDatabase.js +35 -8
- package/lib/sodaDocument.js +24 -6
- package/lib/sodaOperation.js +7 -6
- package/lib/thin/aq.js +475 -0
- package/lib/thin/connection.js +54 -4
- package/lib/thin/protocol/capabilities.js +3 -1
- package/lib/thin/protocol/constants.js +61 -0
- package/lib/thin/protocol/encryptDecrypt.js +2 -2
- package/lib/thin/protocol/messages/aqArray.js +238 -0
- package/lib/thin/protocol/messages/aqBase.js +305 -0
- package/lib/thin/protocol/messages/aqDeq.js +164 -0
- package/lib/thin/protocol/messages/aqEnq.js +135 -0
- package/lib/thin/protocol/messages/auth.js +12 -27
- package/lib/thin/protocol/messages/withData.js +3 -3
- package/lib/thin/protocol/packet.js +6 -5
- package/lib/thin/sqlnet/networkSession.js +1 -1
- package/lib/types.js +6 -6
- package/lib/util.js +0 -13
- package/lib/version.js +1 -1
- package/package.json +1 -1
- package/plugins/configProviders/azure/index.js +3 -0
- package/build/Release/oracledb-6.9.0-darwin-arm64.node +0 -0
- package/build/Release/oracledb-6.9.0-darwin-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.9.0-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.9.0-darwin-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.9.0-js-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.9.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.9.0-linux-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.9.0-linux-x64.node +0 -0
- package/build/Release/oracledb-6.9.0-linux-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.9.0-win32-x64.node +0 -0
- package/build/Release/oracledb-6.9.0-win32-x64.node-buildinfo.txt +0 -1
|
@@ -559,6 +559,9 @@ module.exports = {
|
|
|
559
559
|
TNS_FUNC_CANCEL_ALL: 120, // piggyback fn
|
|
560
560
|
TNS_FUNC_TPC_TXN_SWITCH: 103,
|
|
561
561
|
TNS_FUNC_TPC_TXN_CHANGE_STATE: 104,
|
|
562
|
+
TNS_FUNC_AQ_ENQ: 121,
|
|
563
|
+
TNS_FUNC_AQ_DEQ: 122,
|
|
564
|
+
TNS_FUNC_ARRAY_AQ: 145,
|
|
562
565
|
|
|
563
566
|
// character sets and encodings
|
|
564
567
|
TNS_CHARSET_UTF8: 873,
|
|
@@ -574,6 +577,7 @@ module.exports = {
|
|
|
574
577
|
TNS_CCAP_CTB_FEATURE_BACKPORT: 5,
|
|
575
578
|
TNS_CCAP_FIELD_VERSION: 7,
|
|
576
579
|
TNS_CCAP_SERVER_DEFINE_CONV: 8,
|
|
580
|
+
TNS_CCAP_DEQUEUE_WITH_SELECTOR: 9,
|
|
577
581
|
TNS_CCAP_TTC1: 15,
|
|
578
582
|
TNS_CCAP_OCI1: 16,
|
|
579
583
|
TNS_CCAP_TDS_VERSION: 17,
|
|
@@ -648,6 +652,7 @@ module.exports = {
|
|
|
648
652
|
TNS_CCAP_LOB2_QUASI: 0x01,
|
|
649
653
|
TNS_CCAP_LOB2_2GB_PREFETCH: 0x04,
|
|
650
654
|
TNS_CCAP_CTB_IMPLICIT_POOL: 0x08,
|
|
655
|
+
TNS_CCAP_CTB_OAUTH_MSG_ON_ERR: 0x10,
|
|
651
656
|
TNS_CCAP_VECTOR_SUPPORT: 0x08,
|
|
652
657
|
TNS_CCAP_VECTOR_FEATURE_BINARY: 0x01,
|
|
653
658
|
TNS_CCAP_VECTOR_FEATURE_SPARSE: 0x02,
|
|
@@ -716,6 +721,61 @@ module.exports = {
|
|
|
716
721
|
TNS_TPC_TRANS_TRANSACTION_ID_SYNC_CLIENT: 0x02,
|
|
717
722
|
TNS_TPC_TRANS_TRANSACTION_ID_SYNC_TXEND_XA: 0x03,
|
|
718
723
|
|
|
724
|
+
// AQ Delivery modes
|
|
725
|
+
TNS_AQ_MSG_PERSISTENT: constants.AQ_MSG_DELIV_MODE_PERSISTENT,
|
|
726
|
+
TNS_AQ_MSG_BUFFERED: constants.AQ_MSG_DELIV_MODE_BUFFERED,
|
|
727
|
+
TNS_AQ_MSG_PERSISTENT_OR_BUFFERED: constants.AQ_MSG_DELIV_MODE_PERSISTENT_OR_BUFFERED,
|
|
728
|
+
|
|
729
|
+
// AQ dequeue modes
|
|
730
|
+
TNS_AQ_DEQ_BROWSE: 1,
|
|
731
|
+
TNS_AQ_DEQ_LOCKED: 2,
|
|
732
|
+
TNS_AQ_DEQ_REMOVE: 3,
|
|
733
|
+
TNS_AQ_DEQ_REMOVE_NODATA: 4,
|
|
734
|
+
|
|
735
|
+
// AQ dequeue navigation modes
|
|
736
|
+
TNS_AQ_DEQ_FIRST_MSG: 1,
|
|
737
|
+
TNS_AQ_DEQ_NEXT_MSG: 3,
|
|
738
|
+
TNS_AQ_DEQ_NEXT_TRANSACTION: 2,
|
|
739
|
+
|
|
740
|
+
// AQ dequeue visibility modes
|
|
741
|
+
TNS_AQ_DEQ_IMMEDIATE: 1,
|
|
742
|
+
TNS_AQ_DEQ_ON_COMMIT: 2,
|
|
743
|
+
|
|
744
|
+
// AQ dequeue wait modes
|
|
745
|
+
TNS_AQ_DEQ_NO_WAIT: 0,
|
|
746
|
+
TNS_AQ_DEQ_WAIT_FOREVER: 0xFFFFFFFF,
|
|
747
|
+
|
|
748
|
+
// AQ enqueue visibility modes
|
|
749
|
+
TNS_AQ_ENQ_IMMEDIATE: 1,
|
|
750
|
+
TNS_AQ_ENQ_ON_COMMIT: 2,
|
|
751
|
+
|
|
752
|
+
// AQ message states
|
|
753
|
+
TNS_AQ_MSG_EXPIRED: 3,
|
|
754
|
+
TNS_AQ_MSG_PROCESSED: 2,
|
|
755
|
+
TNS_AQ_MSG_READY: 0,
|
|
756
|
+
TNS_AQ_MSG_WAITING: 1,
|
|
757
|
+
|
|
758
|
+
// AQ other constants
|
|
759
|
+
TNS_AQ_MSG_NO_DELAY: 0,
|
|
760
|
+
TNS_AQ_MSG_NO_EXPIRATION: -1,
|
|
761
|
+
TNS_AQ_ARRAY_ENQ: 0x01,
|
|
762
|
+
TNS_AQ_ARRAY_DEQ: 0x02,
|
|
763
|
+
TNS_AQ_ARRAY_FLAGS_RETURN_MESSAGE_ID: 0x01,
|
|
764
|
+
TNS_TTC_ENQ_STREAMING_ENABLED: 0x00000001,
|
|
765
|
+
TNS_TTC_ENQ_STREAMING_DISABLED: 0x00000000,
|
|
766
|
+
|
|
767
|
+
// AQ flags
|
|
768
|
+
TNS_KPD_AQ_BUFMSG: 0x02,
|
|
769
|
+
TNS_KPD_AQ_EITHER: 0x10,
|
|
770
|
+
|
|
771
|
+
TNS_AQ_MESSAGE_ID_LENGTH: 16,
|
|
772
|
+
TNS_AQ_MESSAGE_VERSION: 1,
|
|
773
|
+
|
|
774
|
+
TNS_AQ_EXT_KEYWORD_AGENT_NAME: 64,
|
|
775
|
+
TNS_AQ_EXT_KEYWORD_AGENT_ADDRESS: 65,
|
|
776
|
+
TNS_AQ_EXT_KEYWORD_AGENT_PROTOCOL: 66,
|
|
777
|
+
TNS_AQ_EXT_KEYWORD_ORIGINAL_MSGID: 69,
|
|
778
|
+
|
|
719
779
|
|
|
720
780
|
// other constants
|
|
721
781
|
TNS_ESCAPE_CHAR: 253,
|
|
@@ -788,6 +848,7 @@ module.exports = {
|
|
|
788
848
|
TNS_ERR_INVALID_SID: 12505,
|
|
789
849
|
TNS_ERR_NO_DATA_FOUND: 1403,
|
|
790
850
|
TNS_ERR_SESSION_SHUTDOWN: 12572,
|
|
851
|
+
TNS_ERR_NO_MESSAGES_FOUND: 25228,
|
|
791
852
|
|
|
792
853
|
// warnings
|
|
793
854
|
TNS_WARN_COMPILATION_CREATE: 0x20,
|
|
@@ -40,7 +40,7 @@ class EncryptDecrypt {
|
|
|
40
40
|
|
|
41
41
|
// Key length is dependent on the algorithm. In this case for aes192, it is
|
|
42
42
|
// 24 bytes (192 bits).
|
|
43
|
-
|
|
43
|
+
decrypt(key, val) {
|
|
44
44
|
const iv = Buffer.alloc(16, 0); // Initialization vector, same is used in server
|
|
45
45
|
const decipher = crypto.createDecipheriv(algorithm, key, iv);
|
|
46
46
|
decipher.setAutoPadding(false);
|
|
@@ -138,7 +138,7 @@ class EncryptDecrypt {
|
|
|
138
138
|
if (newPassword) {
|
|
139
139
|
newPasswordBytes = Buffer.from(newPassword, 'utf8');
|
|
140
140
|
}
|
|
141
|
-
const sessionKeyParta = this.
|
|
141
|
+
const sessionKeyParta = this.decrypt(passwordHash, encodedServerKey);
|
|
142
142
|
const sessionKeyPartb = Buffer.alloc(sessionKeyParta.length);
|
|
143
143
|
crypto.randomFillSync(sessionKeyPartb);
|
|
144
144
|
const encodedClientKey = this._encrypt(passwordHash, sessionKeyPartb);
|
|
@@ -0,0 +1,238 @@
|
|
|
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
|
+
// aqArray.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 and dequeuing
|
|
32
|
+
// an array of AQ messages.
|
|
33
|
+
//-----------------------------------------------------------------------------
|
|
34
|
+
|
|
35
|
+
'use strict';
|
|
36
|
+
|
|
37
|
+
const AqBaseMessage = require("./aqBase.js");
|
|
38
|
+
const constants = require("../constants.js");
|
|
39
|
+
const errors = require("../../../errors.js");
|
|
40
|
+
|
|
41
|
+
class AqArrayMessage extends AqBaseMessage {
|
|
42
|
+
|
|
43
|
+
constructor(connImpl) {
|
|
44
|
+
super(connImpl);
|
|
45
|
+
this.functionCode = constants.TNS_FUNC_ARRAY_AQ;
|
|
46
|
+
this.numIters = 0;
|
|
47
|
+
this.propsImpls = [];
|
|
48
|
+
this.noMsgFound = false;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
//--------------------------------------------------------------------------
|
|
52
|
+
// processReturnParameter()
|
|
53
|
+
//
|
|
54
|
+
// Process the return parameters of the AQ array enqueue/dequeue request.
|
|
55
|
+
// We recieve all the msg details in deq and in case of enq the msgIds.
|
|
56
|
+
//--------------------------------------------------------------------------
|
|
57
|
+
processReturnParameter(buf) {
|
|
58
|
+
const numIters = buf.readUB4();
|
|
59
|
+
for (let i = 0; i < numIters; i++) {
|
|
60
|
+
const propsImpl = this.propsImpls[i];
|
|
61
|
+
let temp16 = buf.readUB2();
|
|
62
|
+
if (temp16 > 0) {
|
|
63
|
+
buf.skipUB1();
|
|
64
|
+
this._processMsgProps(buf, propsImpl);
|
|
65
|
+
}
|
|
66
|
+
propsImpl.recipients = this._processRecipients(buf);
|
|
67
|
+
temp16 = buf.readUB2();
|
|
68
|
+
if (temp16 > 0) {
|
|
69
|
+
propsImpl.payload = this._processPayload(buf);
|
|
70
|
+
}
|
|
71
|
+
const msgId = buf.readBytesAndLength();// msgIds array
|
|
72
|
+
if (this.operation === constants.TNS_AQ_ARRAY_ENQ) {
|
|
73
|
+
for (let j = 0; j < this.propsImpls.length; j++) {
|
|
74
|
+
this.propsImpls[j].msgId = Buffer.from(msgId.slice(j * 16, (j + 1) * 16));
|
|
75
|
+
}
|
|
76
|
+
} else {
|
|
77
|
+
propsImpl.msgId = Buffer.from(msgId);
|
|
78
|
+
}
|
|
79
|
+
temp16 = buf.readUB2(); // extensions len
|
|
80
|
+
if (temp16 > 0) {
|
|
81
|
+
errors.throwErr(errors.ERR_NOT_IMPLEMENTED);
|
|
82
|
+
}
|
|
83
|
+
buf.skipUB2(); // output ack
|
|
84
|
+
}
|
|
85
|
+
if (this.operation === constants.TNS_AQ_ARRAY_ENQ) {
|
|
86
|
+
this.numIters = buf.readUB4();
|
|
87
|
+
} else {
|
|
88
|
+
this.numIters = numIters;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
//--------------------------------------------------------------------------
|
|
93
|
+
// _writeArrayDeq()
|
|
94
|
+
//
|
|
95
|
+
// Writes to the buffer the fields specific to the array dequeue of AQ
|
|
96
|
+
// messages.
|
|
97
|
+
//--------------------------------------------------------------------------
|
|
98
|
+
_writeArrayDeq(buf) {
|
|
99
|
+
let consumerNameBytes = null;
|
|
100
|
+
let correlationBytes = null;
|
|
101
|
+
let conditionBytes = null;
|
|
102
|
+
const queueNameBytes = Buffer.from(this.queueImpl.name);
|
|
103
|
+
const deliveryMode = this.deqOptionsImpl.deliveryMode;
|
|
104
|
+
let flags = 0;
|
|
105
|
+
|
|
106
|
+
if (deliveryMode === constants.TNS_AQ_MSG_BUFFERED) {
|
|
107
|
+
flags |= constants.TNS_KPD_AQ_BUFMSG;
|
|
108
|
+
} else if (deliveryMode === constants.TNS_AQ_MSG_PERSISTENT_OR_BUFFERED) {
|
|
109
|
+
flags |= constants.TNS_KPD_AQ_EITHER;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (this.deqOptionsImpl.consumerName) {
|
|
113
|
+
consumerNameBytes = Buffer.from(this.deqOptionsImpl.consumerName, 'utf-8');
|
|
114
|
+
}
|
|
115
|
+
if (this.deqOptionsImpl.condition) {
|
|
116
|
+
conditionBytes = Buffer.from(this.deqOptionsImpl.condition, 'utf-8');
|
|
117
|
+
}
|
|
118
|
+
if (this.deqOptionsImpl.correlation) {
|
|
119
|
+
correlationBytes = Buffer.from(this.deqOptionsImpl.correlation, 'utf-8');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
for (const propsImpl of this.propsImpls) {
|
|
123
|
+
buf.writeUB4(queueNameBytes.length);
|
|
124
|
+
buf.writeBytesWithLength(queueNameBytes);
|
|
125
|
+
this._writeMsgProps(buf, propsImpl);
|
|
126
|
+
buf.writeUB4(0); // num recipients
|
|
127
|
+
this._writeValueWithLength(buf, consumerNameBytes);
|
|
128
|
+
buf.writeSB4(this.deqOptionsImpl.mode);
|
|
129
|
+
buf.writeSB4(this.deqOptionsImpl.navigation);
|
|
130
|
+
buf.writeSB4(this.deqOptionsImpl.visibility);
|
|
131
|
+
buf.writeSB4(this.deqOptionsImpl.wait);
|
|
132
|
+
this._writeValueWithLength(buf, this.deqOptionsImpl.msgid);
|
|
133
|
+
this._writeValueWithLength(buf, correlationBytes);
|
|
134
|
+
this._writeValueWithLength(buf, conditionBytes);
|
|
135
|
+
buf.writeUB4(0); // extensions
|
|
136
|
+
buf.writeUB4(0); // rel msg id
|
|
137
|
+
buf.writeSB4(0); // seq deviation
|
|
138
|
+
buf.writeUB4(16); // toid length
|
|
139
|
+
buf.writeBytesWithLength(this.queueImpl.payloadToid);
|
|
140
|
+
buf.writeUB2(constants.TNS_AQ_MESSAGE_VERSION);
|
|
141
|
+
buf.writeUB4(0); // payload length
|
|
142
|
+
buf.writeUB4(0); // raw pay length
|
|
143
|
+
buf.writeUB4(0);
|
|
144
|
+
buf.writeUB4(flags); // deliveryMode flag
|
|
145
|
+
buf.writeUB4(0); // extensions len
|
|
146
|
+
buf.writeUB4(0); // source seq len
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
//--------------------------------------------------------------------------
|
|
151
|
+
// _writeArrayEnq()
|
|
152
|
+
//
|
|
153
|
+
// Writes input parameters in case of array enqueue.
|
|
154
|
+
//--------------------------------------------------------------------------
|
|
155
|
+
_writeArrayEnq(buf) {
|
|
156
|
+
const queueNameBytes = Buffer.from(this.queueImpl.name);
|
|
157
|
+
const deliveryMode = this.enqOptionsImpl.deliveryMode;
|
|
158
|
+
let flags = 0;
|
|
159
|
+
|
|
160
|
+
if (deliveryMode === constants.TNS_AQ_MSG_BUFFERED) {
|
|
161
|
+
flags |= constants.TNS_KPD_AQ_BUFMSG;
|
|
162
|
+
} else if (deliveryMode === constants.TNS_AQ_MSG_PERSISTENT_OR_BUFFERED) {
|
|
163
|
+
flags |= constants.TNS_KPD_AQ_EITHER;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
buf.writeUB4(0); // rel msgid len
|
|
167
|
+
buf.writeUInt8(constants.TNS_MSG_TYPE_ROW_HEADER);
|
|
168
|
+
buf.writeUB4(queueNameBytes.length);
|
|
169
|
+
buf.writeBytesWithLength(queueNameBytes);
|
|
170
|
+
buf.writeBytes(this.queueImpl.payloadToid);
|
|
171
|
+
buf.writeUB2(constants.TNS_AQ_MESSAGE_VERSION);
|
|
172
|
+
buf.writeUB4(flags);
|
|
173
|
+
|
|
174
|
+
for (const propsImpl of this.propsImpls) {
|
|
175
|
+
buf.writeUInt8(constants.TNS_MSG_TYPE_ROW_DATA);
|
|
176
|
+
buf.writeUB4(flags); // aqi flags
|
|
177
|
+
this._writeMsgProps(buf, propsImpl);
|
|
178
|
+
if (propsImpl.recipients === null || propsImpl.recipients.length === 0) {
|
|
179
|
+
buf.writeUB4(0); // num recipients
|
|
180
|
+
} else {
|
|
181
|
+
buf.writeUB4(3 * propsImpl.recipients.length);
|
|
182
|
+
this._writeRecipients(buf, propsImpl);
|
|
183
|
+
}
|
|
184
|
+
buf.writeSB4(this.enqOptionsImpl.visibility);
|
|
185
|
+
buf.writeUB4(0); // relative msg id
|
|
186
|
+
buf.writeSB4(0); // seq deviation
|
|
187
|
+
if (!this.queueImpl.payloadTypeClass && !this.queueImpl.isJson) {
|
|
188
|
+
buf.writeUB4(propsImpl.payload.length);
|
|
189
|
+
}
|
|
190
|
+
this._writePayload(buf, propsImpl);
|
|
191
|
+
}
|
|
192
|
+
buf.writeUInt8(constants.TNS_MSG_TYPE_STATUS);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
//--------------------------------------------------------------------------
|
|
196
|
+
// _writeMessageBody()
|
|
197
|
+
//
|
|
198
|
+
// Writes the body of the message to the buffer.
|
|
199
|
+
//--------------------------------------------------------------------------
|
|
200
|
+
encode(buf) {
|
|
201
|
+
this.writeFunctionHeader(buf);
|
|
202
|
+
if (this.operation === constants.TNS_AQ_ARRAY_ENQ) {
|
|
203
|
+
buf.writeUInt8(0); // input params
|
|
204
|
+
buf.writeUB4(0); // length
|
|
205
|
+
} else {
|
|
206
|
+
buf.writeUInt8(1);
|
|
207
|
+
buf.writeUB4(this.numIters);
|
|
208
|
+
}
|
|
209
|
+
buf.writeUB4(constants.TNS_AQ_ARRAY_FLAGS_RETURN_MESSAGE_ID);
|
|
210
|
+
if (this.operation === constants.TNS_AQ_ARRAY_ENQ) {
|
|
211
|
+
buf.writeUInt8(1); // output params
|
|
212
|
+
buf.writeUInt8(0); // length
|
|
213
|
+
} else {
|
|
214
|
+
buf.writeUInt8(1);
|
|
215
|
+
buf.writeUInt8(1);
|
|
216
|
+
}
|
|
217
|
+
buf.writeSB4(this.operation);
|
|
218
|
+
if (this.operation === constants.TNS_AQ_ARRAY_ENQ) {
|
|
219
|
+
buf.writeUInt8(1); // num iters (pointer)
|
|
220
|
+
} else {
|
|
221
|
+
buf.writeUInt8(0);
|
|
222
|
+
}
|
|
223
|
+
if (buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_21_1) {
|
|
224
|
+
buf.writeUB4(0xffff); // shard id
|
|
225
|
+
}
|
|
226
|
+
if (this.operation === constants.TNS_AQ_ARRAY_ENQ) {
|
|
227
|
+
buf.writeUB4(this.numIters);
|
|
228
|
+
}
|
|
229
|
+
if (this.operation === constants.TNS_AQ_ARRAY_ENQ) {
|
|
230
|
+
this._writeArrayEnq(buf);
|
|
231
|
+
} else {
|
|
232
|
+
this._writeArrayDeq(buf);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
module.exports = AqArrayMessage;
|
|
@@ -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;
|