oracledb 6.0.3 → 6.2.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.2.0-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.2.0-darwin-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.2.0-js-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.2.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.2.0-linux-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.2.0-linux-x64.node +0 -0
- package/build/Release/oracledb-6.2.0-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.2.0-win32-x64.node +0 -0
- package/build/Release/oracledb-6.2.0-win32-x64.node-buildinfo.txt +1 -0
- package/examples/dbconfig.js +7 -14
- package/examples/example.js +0 -1
- package/lib/aqQueue.js +40 -26
- package/lib/connection.js +16 -4
- package/lib/dbObject.js +9 -0
- package/lib/errors.js +17 -13
- package/lib/impl/connection.js +9 -0
- package/lib/impl/resultset.js +7 -4
- package/lib/oracledb.js +26 -18
- package/lib/pool.js +7 -1
- package/lib/sodaCollection.js +12 -1
- package/lib/sodaOperation.js +16 -0
- package/lib/thin/connection.js +229 -182
- package/lib/thin/dbObject.js +4 -1
- package/lib/thin/pool.js +153 -68
- package/lib/thin/protocol/buffer.js +83 -64
- package/lib/thin/protocol/constants.js +3 -14
- package/lib/thin/protocol/encryptDecrypt.js +17 -17
- package/lib/thin/protocol/messages/auth.js +21 -23
- package/lib/thin/protocol/messages/base.js +29 -45
- package/lib/thin/protocol/messages/connectionCookie.js +76 -0
- package/lib/thin/protocol/messages/dataType.js +13 -9
- package/lib/thin/protocol/messages/execute.js +7 -7
- package/lib/thin/protocol/messages/index.js +2 -0
- package/lib/thin/protocol/messages/protocol.js +31 -20
- package/lib/thin/protocol/messages/withData.js +58 -47
- package/lib/thin/protocol/oson.js +17 -14
- package/lib/thin/protocol/packet.js +36 -14
- package/lib/thin/protocol/utils.js +2 -2
- package/lib/thin/resultSet.js +6 -6
- package/lib/thin/sqlnet/connStrategy.js +130 -5
- package/lib/thin/sqlnet/constants.js +2 -0
- package/lib/thin/sqlnet/ezConnectResolver.js +29 -61
- package/lib/thin/sqlnet/navNodes.js +34 -27
- package/lib/thin/sqlnet/networkSession.js +46 -47
- package/lib/thin/sqlnet/ntTcp.js +30 -14
- package/lib/thin/sqlnet/nvStrToNvPair.js +16 -16
- package/lib/thin/sqlnet/packet.js +10 -3
- package/lib/thin/sqlnet/paramParser.js +9 -9
- package/lib/thin/sqlnet/sessionAtts.js +4 -0
- package/lib/thin/statement.js +345 -113
- package/lib/thin/util.js +23 -86
- package/lib/transformer.js +3 -1
- package/lib/util.js +4 -13
- package/lib/version.js +2 -2
- package/package.json +1 -1
- package/build/Release/oracledb-6.0.3-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.0.3-darwin-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.3-js-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.3-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.0.3-linux-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.3-linux-x64.node +0 -0
- package/build/Release/oracledb-6.0.3-linux-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.3-win32-x64.node +0 -0
- package/build/Release/oracledb-6.0.3-win32-x64.node-buildinfo.txt +0 -1
|
@@ -50,9 +50,9 @@ class EncryptDecrypt {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
_encrypt(key, val, padding) {
|
|
53
|
-
|
|
53
|
+
const block_size = 16;
|
|
54
54
|
const iv = Buffer.alloc(block_size, 0);
|
|
55
|
-
|
|
55
|
+
const n = block_size - (val.length % block_size);
|
|
56
56
|
const nv = Buffer.alloc(n, n);
|
|
57
57
|
if (n > 0) {
|
|
58
58
|
if (padding) {
|
|
@@ -73,15 +73,15 @@ class EncryptDecrypt {
|
|
|
73
73
|
|
|
74
74
|
// Encrypt password and newPassword using comboKey
|
|
75
75
|
_setEncryptedPasswordBuffers(passwordBytes, newPasswordBytes, comboKey, authObj) {
|
|
76
|
-
|
|
76
|
+
const salt = Buffer.alloc(16);
|
|
77
77
|
crypto.randomFillSync(salt, 0, 16);
|
|
78
|
-
|
|
78
|
+
const temp = Buffer.concat([salt, passwordBytes]);
|
|
79
79
|
authObj.encodedPassword = this._encrypt(comboKey, temp);
|
|
80
80
|
temp.fill(0);
|
|
81
81
|
authObj.encodedPassword = authObj.encodedPassword.slice().toString('hex').toUpperCase();
|
|
82
82
|
|
|
83
83
|
if (newPasswordBytes) {
|
|
84
|
-
|
|
84
|
+
const newPasswordWithSalt = Buffer.concat([salt, newPasswordBytes]);
|
|
85
85
|
authObj.encodedNewPassword = this._encrypt(comboKey, newPasswordWithSalt);
|
|
86
86
|
newPasswordWithSalt.fill(0);
|
|
87
87
|
authObj.encodedNewPassword = authObj.encodedNewPassword.slice().toString('hex').toUpperCase();
|
|
@@ -106,10 +106,10 @@ class EncryptDecrypt {
|
|
|
106
106
|
let keyLen = 32;
|
|
107
107
|
let hashAlg = 'sha512';
|
|
108
108
|
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
const verifierData = Buffer.from(sessionData['AUTH_VFR_DATA'], 'hex');
|
|
110
|
+
const encodedServerKey = Buffer.from(sessionData['AUTH_SESSKEY'], 'hex');
|
|
111
111
|
let iterations = Number(sessionData['AUTH_PBKDF2_VGEN_COUNT']);
|
|
112
|
-
|
|
112
|
+
const passwordBytes = Buffer.from(password, 'utf8');
|
|
113
113
|
let passwordHash;
|
|
114
114
|
let passwordKey;
|
|
115
115
|
|
|
@@ -117,18 +117,18 @@ class EncryptDecrypt {
|
|
|
117
117
|
algorithm = 'aes-192-cbc';
|
|
118
118
|
keyLen = 24;
|
|
119
119
|
hashAlg = 'sha1';
|
|
120
|
-
|
|
120
|
+
const h = crypto.createHash(hashAlg);
|
|
121
121
|
h.update(passwordBytes);
|
|
122
122
|
h.update(verifierData);
|
|
123
|
-
|
|
123
|
+
const ph = h.digest();
|
|
124
124
|
passwordHash = Buffer.alloc(ph.length + 4);
|
|
125
125
|
ph.copy(passwordHash, 0, 0, ph.length);
|
|
126
126
|
} else {
|
|
127
127
|
algorithm = 'aes-256-cbc';
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
const temp = Buffer.from('AUTH_PBKDF2_SPEEDY_KEY', 'utf8');
|
|
129
|
+
const salt = Buffer.concat([verifierData, temp]);
|
|
130
130
|
passwordKey = crypto.pbkdf2Sync(passwordBytes, salt, iterations, 64, 'sha512');
|
|
131
|
-
|
|
131
|
+
const h = crypto.createHash(hashAlg);
|
|
132
132
|
h.update(passwordKey);
|
|
133
133
|
h.update(verifierData);
|
|
134
134
|
passwordHash = h.digest().slice(0, keyLen);
|
|
@@ -163,10 +163,10 @@ class EncryptDecrypt {
|
|
|
163
163
|
iterations, keyLen, 'sha512');
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
-
|
|
166
|
+
const salt = Buffer.alloc(16);
|
|
167
167
|
if (!verifier11G) {
|
|
168
168
|
crypto.randomFillSync(salt, 0, 16);
|
|
169
|
-
|
|
169
|
+
const temp = Buffer.concat([salt, passwordKey]);
|
|
170
170
|
authObj.speedyKey = this._encrypt(authObj.comboKey, temp);
|
|
171
171
|
authObj.speedyKey = authObj.speedyKey.slice(0, 80).toString('hex').toUpperCase();
|
|
172
172
|
}
|
|
@@ -184,7 +184,7 @@ class EncryptDecrypt {
|
|
|
184
184
|
}
|
|
185
185
|
|
|
186
186
|
updatePasswordsWithComboKey(password, newPassword, comboKey, authObj) {
|
|
187
|
-
|
|
187
|
+
const passwordBytes = Buffer.from(password, 'utf8');
|
|
188
188
|
let newPasswordBytes;
|
|
189
189
|
if (newPassword) {
|
|
190
190
|
newPasswordBytes = Buffer.from(newPassword, 'utf8');
|
|
@@ -193,5 +193,5 @@ class EncryptDecrypt {
|
|
|
193
193
|
}
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
-
|
|
196
|
+
const encryptDecryptInst = new EncryptDecrypt();
|
|
197
197
|
module.exports = encryptDecryptInst;
|
|
@@ -103,32 +103,32 @@ class AuthMessage extends Message {
|
|
|
103
103
|
}
|
|
104
104
|
this.serviceName = this.conn.serviceName;
|
|
105
105
|
this.remoteAddress = this.conn.remoteAddress;
|
|
106
|
-
this.setAuthMode();
|
|
106
|
+
this.setAuthMode(config);
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
setAuthMode() {
|
|
109
|
+
setAuthMode(config) {
|
|
110
110
|
if (!this.newPassword) {
|
|
111
111
|
this.authMode = constants.TNS_AUTH_MODE_LOGON;
|
|
112
112
|
}
|
|
113
|
-
if (
|
|
113
|
+
if (config.privilege & constants.SYSDBA) {
|
|
114
114
|
this.authMode |= constants.TNS_AUTH_MODE_SYSDBA;
|
|
115
115
|
}
|
|
116
|
-
if (
|
|
116
|
+
if (config.privilege & constants.SYSOPER) {
|
|
117
117
|
this.authMode |= constants.TNS_AUTH_MODE_SYSOPER;
|
|
118
118
|
}
|
|
119
|
-
if (
|
|
119
|
+
if (config.privilege & constants.SYSASM) {
|
|
120
120
|
this.authMode |= constants.TNS_AUTH_MODE_SYSASM;
|
|
121
121
|
}
|
|
122
|
-
if (
|
|
122
|
+
if (config.privilege & constants.SYSBKP) {
|
|
123
123
|
this.authMode |= constants.TNS_AUTH_MODE_SYSBKP;
|
|
124
124
|
}
|
|
125
|
-
if (
|
|
125
|
+
if (config.privilege & constants.SYSDG) {
|
|
126
126
|
this.authMode |= constants.TNS_AUTH_MODE_SYSDGD;
|
|
127
127
|
}
|
|
128
|
-
if (
|
|
128
|
+
if (config.privilege & constants.SYSKM) {
|
|
129
129
|
this.authMode |= constants.TNS_AUTH_MODE_SYSKMT;
|
|
130
130
|
}
|
|
131
|
-
if (
|
|
131
|
+
if (config.privilege & constants.SYSRAC) {
|
|
132
132
|
this.authMode |= constants.TNS_AUTH_MODE_SYSRAC;
|
|
133
133
|
}
|
|
134
134
|
if (this.privateKey) {
|
|
@@ -221,7 +221,7 @@ class AuthMessage extends Message {
|
|
|
221
221
|
if (this.privateKey) {
|
|
222
222
|
numPairs += 2;
|
|
223
223
|
}
|
|
224
|
-
if (this.conn.
|
|
224
|
+
if (this.conn.connectionClass) {
|
|
225
225
|
numPairs += 1;
|
|
226
226
|
}
|
|
227
227
|
if (this.conn.purity) {
|
|
@@ -268,8 +268,8 @@ class AuthMessage extends Message {
|
|
|
268
268
|
if (this.encodedNewPassword) {
|
|
269
269
|
buf.writeKeyValue("AUTH_NEWPASSWORD", this.encodedNewPassword);
|
|
270
270
|
}
|
|
271
|
-
if (this.conn.
|
|
272
|
-
buf.writeKeyValue("AUTH_KPPL_CONN_CLASS", this.conn.
|
|
271
|
+
if (this.conn.connectionClass) {
|
|
272
|
+
buf.writeKeyValue("AUTH_KPPL_CONN_CLASS", this.conn.connectionClass);
|
|
273
273
|
}
|
|
274
274
|
if (this.conn.purity) {
|
|
275
275
|
buf.writeKeyValue("AUTH_KPPL_PURITY", '' + this.conn.purity);
|
|
@@ -278,11 +278,11 @@ class AuthMessage extends Message {
|
|
|
278
278
|
const currentDate = new Date();
|
|
279
279
|
const currentDateFormatted = currentDate.toGMTString();
|
|
280
280
|
|
|
281
|
-
|
|
281
|
+
const header = "date: " + currentDateFormatted + "\n" +
|
|
282
282
|
"(request-target): " + this.serviceName + "\n" +
|
|
283
283
|
"host: " + this.remoteAddress;
|
|
284
284
|
|
|
285
|
-
|
|
285
|
+
const signature = crypto.createSign('RSA-SHA256')
|
|
286
286
|
.update(header)
|
|
287
287
|
.sign(this.privateKey, 'base64');
|
|
288
288
|
|
|
@@ -297,16 +297,16 @@ class AuthMessage extends Message {
|
|
|
297
297
|
}
|
|
298
298
|
|
|
299
299
|
processReturnParameter(buf) {
|
|
300
|
-
|
|
300
|
+
const numParams = buf.readUB2();
|
|
301
301
|
for (let i = 0; i < numParams;i++) {
|
|
302
302
|
buf.skipUB4();
|
|
303
|
-
|
|
303
|
+
const key = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
304
304
|
let value = "";
|
|
305
|
-
|
|
305
|
+
const numBytes = buf.readUB4();
|
|
306
306
|
if (numBytes > 0) {
|
|
307
307
|
value = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
308
308
|
}
|
|
309
|
-
|
|
309
|
+
const flag = buf.readUB4();
|
|
310
310
|
if (key === "AUTH_VFR_DATA") {
|
|
311
311
|
this.verifierType = flag;
|
|
312
312
|
}
|
|
@@ -316,16 +316,14 @@ class AuthMessage extends Message {
|
|
|
316
316
|
if (this.functionCode === constants.TNS_FUNC_AUTH_PHASE_ONE) {
|
|
317
317
|
this.functionCode = constants.TNS_FUNC_AUTH_PHASE_TWO;
|
|
318
318
|
} else {
|
|
319
|
-
let versionNum;
|
|
320
319
|
let releaseNum;
|
|
321
320
|
let updateNum;
|
|
322
321
|
let portReleaseNum;
|
|
323
322
|
let portUpdateNum;
|
|
324
323
|
|
|
325
|
-
this.conn.
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
versionNum = (fullVersionNum >> 24) & 0xFF;
|
|
324
|
+
this.conn.instanceName = this.sessionData['AUTH_INSTANCENAME'];
|
|
325
|
+
const fullVersionNum = Number(this.sessionData['AUTH_VERSION_NO']);
|
|
326
|
+
const versionNum = (fullVersionNum >> 24) & 0xFF;
|
|
329
327
|
if (buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_18_1_EXT_1) {
|
|
330
328
|
releaseNum = (fullVersionNum >> 16) & 0xFF;
|
|
331
329
|
updateNum = (fullVersionNum >> 12) & 0x0F;
|
|
@@ -30,37 +30,13 @@ const { Buffer } = require('buffer');
|
|
|
30
30
|
const constants = require("../constants.js");
|
|
31
31
|
const errors = require("../../../errors.js");
|
|
32
32
|
|
|
33
|
-
class OracleErrorInfo {
|
|
34
|
-
constructor() {
|
|
35
|
-
this.num = 0;
|
|
36
|
-
this.cursorId = 0;
|
|
37
|
-
this.pos = 0;
|
|
38
|
-
this.rowCount = 0;
|
|
39
|
-
this.message = "";
|
|
40
|
-
this.rowID = null;
|
|
41
|
-
this.batchErrors;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
class Error {
|
|
46
|
-
constructor(num, message = "", context = "", isRecoverable = false, isWarning = false, code = 0, offset = 0) {
|
|
47
|
-
this.num = num;
|
|
48
|
-
this.message = message;
|
|
49
|
-
this.context = context;
|
|
50
|
-
this.isRecoverable = isRecoverable;
|
|
51
|
-
this.isWarning = isWarning;
|
|
52
|
-
this.code = code;
|
|
53
|
-
this.offset = offset;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
33
|
/**
|
|
58
34
|
*
|
|
59
35
|
* Base class for all the RPC messages to support encode/decode functions
|
|
60
36
|
*/
|
|
61
37
|
class Message {
|
|
62
38
|
constructor(connection) {
|
|
63
|
-
this.errorInfo =
|
|
39
|
+
this.errorInfo = {};
|
|
64
40
|
this.connection = connection;
|
|
65
41
|
this.messageType = constants.TNS_MSG_TYPE_FUNCTION;
|
|
66
42
|
this.functionCode = 0;
|
|
@@ -106,7 +82,7 @@ class Message {
|
|
|
106
82
|
buf.skipUB1(); // call number
|
|
107
83
|
buf.skipUB2(); // padding
|
|
108
84
|
buf.skipUB4(); // success iters
|
|
109
|
-
|
|
85
|
+
const numBytes = buf.readUB4(); // oerrdd (logical rowid)
|
|
110
86
|
if (numBytes > 0) {
|
|
111
87
|
buf.skipBytesChunked();
|
|
112
88
|
}
|
|
@@ -114,12 +90,12 @@ class Message {
|
|
|
114
90
|
let numEntries = buf.readUB2(); // batch error codes array
|
|
115
91
|
if (numEntries > 0) {
|
|
116
92
|
this.errorInfo.batchErrors = [];
|
|
117
|
-
|
|
93
|
+
const firstByte = buf.readUInt8();
|
|
118
94
|
for (let i = 0; i < numEntries; i++) {
|
|
119
95
|
if (firstByte === constants.TNS_LONG_LENGTH_INDICATOR) {
|
|
120
96
|
buf.skipUB4(); // chunk length ignored
|
|
121
97
|
}
|
|
122
|
-
|
|
98
|
+
const errorCode = buf.readUB2();
|
|
123
99
|
this.errorInfo.batchErrors.push(new Error(errorCode));
|
|
124
100
|
}
|
|
125
101
|
if (firstByte === constants.TNS_LONG_LENGTH_INDICATOR) {
|
|
@@ -130,7 +106,7 @@ class Message {
|
|
|
130
106
|
// batch error offset
|
|
131
107
|
numEntries = buf.readUB2(); // batch error row offset array
|
|
132
108
|
if (numEntries > 0) {
|
|
133
|
-
|
|
109
|
+
const firstByte = buf.readUInt8();
|
|
134
110
|
for (let i = 0; i < numEntries; i++) {
|
|
135
111
|
if (firstByte === constants.TNS_LONG_LENGTH_INDICATOR) {
|
|
136
112
|
buf.skipUB4(); // chunk length ignored
|
|
@@ -172,7 +148,7 @@ class Message {
|
|
|
172
148
|
|
|
173
149
|
processWarningInfo(buf) {
|
|
174
150
|
this.errorInfo.num = buf.readUB2(); // error number
|
|
175
|
-
|
|
151
|
+
const numBytes = buf.readUB2(); // length of error message
|
|
176
152
|
buf.skipUB2(); // flags
|
|
177
153
|
if (this.errorInfo.num != 0 && numBytes > 0) {
|
|
178
154
|
this.errorInfo.message = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
@@ -224,18 +200,19 @@ class Message {
|
|
|
224
200
|
if (opcode === constants.TNS_SERVER_PIGGYBACK_LTXID) {
|
|
225
201
|
const num_bytes = buf.readUB4();
|
|
226
202
|
if (num_bytes > 0) {
|
|
227
|
-
buf.
|
|
203
|
+
buf.skipBytesChunked();
|
|
228
204
|
}
|
|
229
205
|
} else if ((opcode === constants.TNS_SERVER_PIGGYBACK_QUERY_CACHE_INVALIDATION)
|
|
230
206
|
|| (opcode === constants.TNS_SERVER_PIGGYBACK_TRACE_EVENT)) {
|
|
231
207
|
// pass
|
|
232
208
|
} else if (opcode === constants.TNS_SERVER_PIGGYBACK_OS_PID_MTS) {
|
|
233
|
-
buf.
|
|
234
|
-
buf.
|
|
209
|
+
const numDtys = buf.readUB2();
|
|
210
|
+
buf.skipUB1();
|
|
211
|
+
buf.skipBytes(numDtys);
|
|
235
212
|
} else if (opcode === constants.TNS_SERVER_PIGGYBACK_SYNC) {
|
|
236
213
|
buf.skipUB2(); // skip number of DTYs
|
|
237
214
|
buf.skipUB1(); // skip length of DTYs
|
|
238
|
-
const num_elements = buf.
|
|
215
|
+
const num_elements = buf.readUB4();
|
|
239
216
|
buf.skipBytes(1); // skip length
|
|
240
217
|
for (let i = 0; i < num_elements; i++) {
|
|
241
218
|
let temp16 = buf.readUB2();
|
|
@@ -247,20 +224,20 @@ class Message {
|
|
|
247
224
|
buf.skipBytesChunked();
|
|
248
225
|
}
|
|
249
226
|
buf.skipUB2(); // skip flags
|
|
250
|
-
buf.skipUB4(); // skip overall flags
|
|
251
227
|
}
|
|
228
|
+
buf.skipUB4(); // skip overall flags
|
|
252
229
|
} else if (opcode === constants.TNS_SERVER_PIGGYBACK_EXT_SYNC) {
|
|
253
230
|
buf.skipUB2();
|
|
254
231
|
buf.skipUB1();
|
|
255
232
|
} else if (opcode === constants.TNS_SERVER_PIGGYBACK_AC_REPLAY_CONTEXT) {
|
|
256
233
|
buf.skipUB2(); // skip number of DTYs
|
|
257
|
-
buf.skipUB1(
|
|
234
|
+
buf.skipUB1(); // skip length of DTYs
|
|
258
235
|
buf.skipUB4(); // skip flags
|
|
259
236
|
buf.skipUB4(); // skip error code
|
|
260
237
|
buf.skipUB1(); // skip queue
|
|
261
238
|
const num_bytes = buf.readUB4(); // skip replay context
|
|
262
239
|
if (num_bytes > 0) {
|
|
263
|
-
buf.
|
|
240
|
+
buf.skipBytesChunked();
|
|
264
241
|
}
|
|
265
242
|
} else if (opcode === constants.TNS_SERVER_PIGGYBACK_SESS_RET) {
|
|
266
243
|
buf.skipUB2();
|
|
@@ -283,7 +260,7 @@ class Message {
|
|
|
283
260
|
const flags = buf.readUB4(); // session flags
|
|
284
261
|
if (flags & constants.TNS_SESSGET_SESSION_CHANGED) {
|
|
285
262
|
if (this.connection._drcpEstablishSession) {
|
|
286
|
-
this.connection.
|
|
263
|
+
this.connection.resetStatementCache();
|
|
287
264
|
}
|
|
288
265
|
}
|
|
289
266
|
this.connection._drcpEstablishSession = false;
|
|
@@ -335,8 +312,8 @@ class Message {
|
|
|
335
312
|
}
|
|
336
313
|
|
|
337
314
|
writeCloseTempLobsPiggyback(buf) {
|
|
338
|
-
|
|
339
|
-
|
|
315
|
+
const lobsToClose = this.connection._tempLobsToClose;
|
|
316
|
+
const opCode = constants.TNS_LOB_OP_FREE_TEMP | constants.TNS_LOB_OP_ARRAY;
|
|
340
317
|
|
|
341
318
|
this.writePiggybackHeader(buf, constants.TNS_FUNC_LOB_OP);
|
|
342
319
|
|
|
@@ -406,9 +383,9 @@ class Message {
|
|
|
406
383
|
buf.writeUInt8(0); // pointer (cidser)
|
|
407
384
|
buf.writeUB4(flags);
|
|
408
385
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
386
|
+
const clientIdentifierBytes = this.writeEndEndTraceValue(buf, this.connection._clientIdentifier, this.connection._clientIdentifierModified);
|
|
387
|
+
const moduleBytes = this.writeEndEndTraceValue(buf, this.connection._module, this.connection._moduleModified);
|
|
388
|
+
const actionBytes = this.writeEndEndTraceValue(buf, this.connection._action, this.connection._actionModified);
|
|
412
389
|
|
|
413
390
|
// write unsupported bits
|
|
414
391
|
buf.writeUInt8(0); // pointer (cideci)
|
|
@@ -416,13 +393,13 @@ class Message {
|
|
|
416
393
|
buf.writeUInt8(0); // cidcct
|
|
417
394
|
buf.writeUB4(0); // cidecs
|
|
418
395
|
|
|
419
|
-
|
|
396
|
+
const clientInfoBytes = this.writeEndEndTraceValue(buf, this.connection._clientInfo, this.connection._clientInfoModified);
|
|
420
397
|
// write unsupported bits
|
|
421
398
|
buf.writeUInt8(0); // pointer (cideci)
|
|
422
399
|
buf.writeUB4(0); // length (cideci)
|
|
423
400
|
buf.writeUInt8(0); // cidcct
|
|
424
401
|
buf.writeUB4(0); // cidecs
|
|
425
|
-
|
|
402
|
+
const dbOpBytes = this.writeEndEndTraceValue(buf, this.connection._dbOp, this.connection._dbOpModified);
|
|
426
403
|
|
|
427
404
|
// write strings
|
|
428
405
|
if (this.connection._clientIdentifierModified && this.connection._clientIdentifier) {
|
|
@@ -471,6 +448,13 @@ class Message {
|
|
|
471
448
|
}
|
|
472
449
|
return writtenBytes;
|
|
473
450
|
}
|
|
451
|
+
|
|
452
|
+
// Called when an error is encountered during decode of RPC
|
|
453
|
+
saveDeferredErr() {
|
|
454
|
+
if (!this.deferredErr) {
|
|
455
|
+
this.deferredErr = errors.getErr(...arguments);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
474
458
|
}
|
|
475
459
|
|
|
476
460
|
module.exports = Message;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// Copyright (c) 2023 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 constants = require("../constants.js");
|
|
30
|
+
const Message = require("./base.js");
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Executes a Fast Negotiation RPC function.
|
|
34
|
+
* It sends Protocol Negotiation, Cookie Message, Datatype Negotiation
|
|
35
|
+
* and OSESS Key RPC in single round trip.
|
|
36
|
+
*
|
|
37
|
+
* @class ConnectionCookieMessage
|
|
38
|
+
* @extends {Message}
|
|
39
|
+
*/
|
|
40
|
+
class ConnectionCookieMessage extends Message {
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Serializes the ConnectionCookieMessage function arguments
|
|
44
|
+
*
|
|
45
|
+
* @param {object} buf input arguments
|
|
46
|
+
*/
|
|
47
|
+
encode(buf) {
|
|
48
|
+
this.protocolMessage.encode(buf);
|
|
49
|
+
buf.writeUInt8(constants.TNS_MSG_TYPE_COOKIE);
|
|
50
|
+
buf.writeUInt8(1); // cookie version
|
|
51
|
+
buf.writeUInt8(this.cookie.protocolVersion);
|
|
52
|
+
buf.writeUInt16LE(this.cookie.charsetID);
|
|
53
|
+
buf.writeUInt8(this.cookie.flags);
|
|
54
|
+
buf.writeUInt16LE(this.cookie.ncharsetID);
|
|
55
|
+
buf.writeBytesWithLength(this.cookie.serverBanner);
|
|
56
|
+
buf.writeBytesWithLength(this.cookie.compileCaps);
|
|
57
|
+
buf.writeBytesWithLength(this.cookie.runtimeCaps);
|
|
58
|
+
this.dataTypeMessage.encode(buf);
|
|
59
|
+
this.authMessage.encode(buf);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
processMessage(buf, messageType) {
|
|
63
|
+
if (messageType === constants.TNS_MSG_TYPE_RENEGOTIATE) {
|
|
64
|
+
this.cookie.populated = false;
|
|
65
|
+
} else if (messageType === constants.TNS_MSG_TYPE_PROTOCOL) {
|
|
66
|
+
this.protocolMessage.processMessage(buf, messageType);
|
|
67
|
+
} else if (messageType === constants.TNS_MSG_TYPE_DATA_TYPES) {
|
|
68
|
+
this.dataTypeMessage.processMessage(buf, messageType);
|
|
69
|
+
} else {
|
|
70
|
+
this.authMessage.processMessage(buf, messageType);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
module.exports = ConnectionCookieMessage;
|
|
@@ -38,14 +38,18 @@ const Message = require("./base.js");
|
|
|
38
38
|
*/
|
|
39
39
|
class DataTypeMessage extends Message {
|
|
40
40
|
|
|
41
|
-
processMessage(buf) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
41
|
+
processMessage(buf, messageType) {
|
|
42
|
+
if (messageType === constants.TNS_MSG_TYPE_DATA_TYPES) {
|
|
43
|
+
while (true) { // eslint-disable-line
|
|
44
|
+
const dataType = buf.readUInt16BE();
|
|
45
|
+
if (dataType === 0)
|
|
46
|
+
break;
|
|
47
|
+
const convDataType = buf.readUInt16BE();
|
|
48
|
+
if (convDataType !== 0)
|
|
49
|
+
buf.skipBytes(4);
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
super.processMessage(buf, messageType);
|
|
49
53
|
}
|
|
50
54
|
}
|
|
51
55
|
|
|
@@ -57,7 +61,7 @@ class DataTypeMessage extends Message {
|
|
|
57
61
|
constants.TNS_ENCODING_CONV_LENGTH);
|
|
58
62
|
buf.writeBytesWithLength(buf.caps.compileCaps);
|
|
59
63
|
buf.writeBytesWithLength(buf.caps.runtimeCaps);
|
|
60
|
-
for (
|
|
64
|
+
for (const val of dataTypes) {
|
|
61
65
|
buf.writeUInt16BE(val[0]);
|
|
62
66
|
buf.writeUInt16BE(val[1]);
|
|
63
67
|
buf.writeUInt16BE(val[2]);
|
|
@@ -65,8 +65,8 @@ class ExecuteMessage extends MessageWithData {
|
|
|
65
65
|
let numParams = 0;
|
|
66
66
|
let numIters = 1;
|
|
67
67
|
// Configuring the options field thats send to the server
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
const stmt = this.statement;
|
|
69
|
+
const params = stmt.bindInfoList;
|
|
70
70
|
|
|
71
71
|
if (!stmt.requiresDefine && !this.parseOnly && params) {
|
|
72
72
|
numParams = params.length;
|
|
@@ -223,7 +223,7 @@ class ExecuteMessage extends MessageWithData {
|
|
|
223
223
|
// Write the message header for a re-execute and return the bind parameters.
|
|
224
224
|
//-------------------------------------------------------------------------
|
|
225
225
|
writeReExecuteMessage(buf) {
|
|
226
|
-
|
|
226
|
+
const stmt = this.statement;
|
|
227
227
|
let params = stmt.bindInfoList;
|
|
228
228
|
let execFlag1 = 0, execFlag2 = 0, numIters;
|
|
229
229
|
if (params !== undefined) {
|
|
@@ -236,7 +236,7 @@ class ExecuteMessage extends MessageWithData {
|
|
|
236
236
|
});
|
|
237
237
|
}
|
|
238
238
|
|
|
239
|
-
|
|
239
|
+
const tmpparams = [];
|
|
240
240
|
params.forEach(info => {
|
|
241
241
|
if (info.bindDir !== constants.TNS_BIND_DIR_OUTPUT && !info.isReturnBind) {
|
|
242
242
|
tmpparams.push(info);
|
|
@@ -274,9 +274,9 @@ class ExecuteMessage extends MessageWithData {
|
|
|
274
274
|
|
|
275
275
|
// no rows have yet been sent so the header information needs to be sent
|
|
276
276
|
if (this.currentRow === 0) {
|
|
277
|
-
|
|
278
|
-
if (stmt.cursorId !== 0 && !stmt.requiresFullExecute && !this.parseOnly && !stmt.requiresDefine && !stmt.isDdl && !this.batchErrors) {
|
|
279
|
-
if (stmt.isQuery &&
|
|
277
|
+
const stmt = this.statement;
|
|
278
|
+
if (stmt.cursorId !== 0 && !stmt.requiresFullExecute && !this.parseOnly && !stmt.requiresDefine && !stmt.noPrefetch && !stmt.isDdl && !this.batchErrors) {
|
|
279
|
+
if (stmt.isQuery && this.options.prefetchRows > 0) {
|
|
280
280
|
this.functionCode = constants.TNS_FUNC_REEXECUTE_AND_FETCH;
|
|
281
281
|
} else {
|
|
282
282
|
this.functionCode = constants.TNS_FUNC_REEXECUTE;
|
|
@@ -37,10 +37,12 @@ const PingMessage = require('./ping.js');
|
|
|
37
37
|
const ProtocolMessage = require('./protocol.js');
|
|
38
38
|
const RollbackMessage = require('./rollback.js');
|
|
39
39
|
const SessionReleaseMessage = require('./sessionRelease.js');
|
|
40
|
+
const ConnectionCookieMessage = require('./connectionCookie.js');
|
|
40
41
|
|
|
41
42
|
module.exports = {
|
|
42
43
|
AuthMessage,
|
|
43
44
|
CommitMessage,
|
|
45
|
+
ConnectionCookieMessage,
|
|
44
46
|
DataTypeMessage,
|
|
45
47
|
ExecuteMessage,
|
|
46
48
|
FetchMessage,
|
|
@@ -50,26 +50,37 @@ class ProtocolMessage extends Message {
|
|
|
50
50
|
buf.writeUInt8(0);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
53
|
+
processMessage(buf, messageType) {
|
|
54
|
+
if (messageType === constants.TNS_MSG_TYPE_PROTOCOL) {
|
|
55
|
+
this.processProtocolInfo(buf);
|
|
56
|
+
} else {
|
|
57
|
+
super.processMessage(buf, messageType);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
processProtocolInfo(buf) {
|
|
62
|
+
this.serverVersion = buf.readUInt8();
|
|
63
|
+
buf.skipUB1();
|
|
64
|
+
this.serverBanner = buf.readNullTerminatedBytes(48);
|
|
65
|
+
buf.caps.charSetID = buf.readUInt16LE();
|
|
66
|
+
this.serverFlags = buf.readUInt8();
|
|
67
|
+
const num_elem = buf.readUInt16LE();
|
|
68
|
+
if (num_elem > 0) { // skip elements
|
|
69
|
+
buf.skipBytes(num_elem * 5);
|
|
70
|
+
}
|
|
71
|
+
const fdoLen = buf.readUInt16BE();
|
|
72
|
+
const fdo = buf.readBytes(fdoLen);
|
|
73
|
+
const ix = 6 + fdo[5] + fdo[6];
|
|
74
|
+
buf.caps.nCharsetId = (fdo[ix + 3] << 8) + fdo[ix + 4];
|
|
75
|
+
const serverCompileCaps = buf.readBytesWithLength();
|
|
76
|
+
if (serverCompileCaps) {
|
|
77
|
+
this.serverCompileCaps = Buffer.from(serverCompileCaps);
|
|
78
|
+
buf.caps.adjustForServerCompileCaps(this.serverCompileCaps);
|
|
79
|
+
}
|
|
80
|
+
const serverRunTimeCaps = buf.readBytesWithLength();
|
|
81
|
+
if (serverRunTimeCaps) {
|
|
82
|
+
this.serverRunTimeCaps = Buffer.from(serverRunTimeCaps);
|
|
83
|
+
buf.caps.adjustForServerRuntimeCaps(this.serverRunTimeCaps);
|
|
73
84
|
}
|
|
74
85
|
}
|
|
75
86
|
|