oracledb 6.5.1 → 6.7.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.7.0-darwin-arm64.node +0 -0
- package/build/Release/oracledb-6.7.0-darwin-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.7.0-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.7.0-darwin-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.7.0-js-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.7.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.7.0-linux-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.7.0-linux-x64.node +0 -0
- package/build/Release/oracledb-6.7.0-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.7.0-win32-x64.node +0 -0
- package/build/Release/oracledb-6.7.0-win32-x64.node-buildinfo.txt +1 -0
- package/examples/README.md +4 -0
- package/lib/configProviders/azure.js +178 -0
- package/lib/configProviders/base.js +85 -0
- package/lib/configProviders/ociobject.js +211 -0
- package/lib/connection.js +97 -14
- package/lib/constants.js +1 -0
- package/lib/errors.js +68 -6
- package/lib/impl/aqQueue.js +2 -1
- package/lib/impl/base.js +45 -0
- package/lib/impl/connection.js +53 -0
- package/lib/impl/datahandlers/constants.js +3 -1
- package/lib/impl/datahandlers/vector.js +24 -9
- package/lib/impl/lob.js +29 -1
- package/lib/impl/pool.js +15 -0
- package/lib/impl/resultset.js +28 -2
- package/lib/impl/sodaCollection.js +2 -1
- package/lib/impl/sodaDatabase.js +2 -1
- package/lib/impl/sodaDocCursor.js +2 -1
- package/lib/impl/sodaOperation.js +2 -1
- package/lib/lob.js +55 -3
- package/lib/oracledb.js +246 -7
- package/lib/pool.js +14 -5
- package/lib/settings.js +1 -0
- package/lib/thin/connection.js +304 -29
- package/lib/thin/dbObject.js +4 -0
- package/lib/thin/lob.js +193 -1
- package/lib/thin/pool.js +18 -0
- package/lib/thin/protocol/capabilities.js +2 -0
- package/lib/thin/protocol/constants.js +29 -1
- package/lib/thin/protocol/messages/auth.js +12 -6
- package/lib/thin/protocol/messages/base.js +3 -0
- package/lib/thin/protocol/messages/index.js +5 -1
- package/lib/thin/protocol/messages/lobOp.js +17 -5
- package/lib/thin/protocol/messages/sessionRelease.js +1 -0
- package/lib/thin/protocol/messages/transactionChangeState.js +99 -0
- package/lib/thin/protocol/messages/transactionSwitch.js +139 -0
- package/lib/thin/protocol/messages/withData.js +21 -6
- package/lib/thin/protocol/protocol.js +23 -0
- package/lib/thin/sqlnet/connStrategy.js +9 -1
- package/lib/thin/sqlnet/constants.js +2 -0
- package/lib/thin/sqlnet/navNodes.js +14 -2
- package/lib/thin/sqlnet/networkSession.js +11 -10
- package/lib/thin/sqlnet/ntTcp.js +1 -1
- package/lib/thin/sqlnet/paramParser.js +87 -50
- package/lib/thin/sqlnet/sessionAtts.js +14 -2
- package/lib/thin/util.js +4 -3
- package/lib/traceHandler.js +133 -0
- package/lib/transformer.js +1 -2
- package/lib/types.js +1 -1
- package/lib/util.js +213 -35
- package/lib/version.js +2 -2
- package/package.json +1 -1
- package/build/Release/oracledb-6.5.1-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.5.1-darwin-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.5.1-js-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.5.1-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.5.1-linux-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.5.1-linux-x64.node +0 -0
- package/build/Release/oracledb-6.5.1-linux-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.5.1-win32-x64.node +0 -0
- package/build/Release/oracledb-6.5.1-win32-x64.node-buildinfo.txt +0 -1
package/lib/thin/lob.js
CHANGED
|
@@ -31,6 +31,7 @@ const LobImpl = require('../impl/lob.js');
|
|
|
31
31
|
const constants = require('./protocol/constants.js');
|
|
32
32
|
const LobOpMessage = require('./protocol/messages/lobOp.js');
|
|
33
33
|
const errors = require('../errors.js');
|
|
34
|
+
const types = require('../types.js');
|
|
34
35
|
|
|
35
36
|
class ThinLobImpl extends LobImpl {
|
|
36
37
|
|
|
@@ -54,15 +55,31 @@ class ThinLobImpl extends LobImpl {
|
|
|
54
55
|
await this.conn._protocol._processMessage(message);
|
|
55
56
|
if (options.operation === constants.TNS_LOB_OP_READ) {
|
|
56
57
|
return (message.data) ? message.data : null;
|
|
58
|
+
} else if (
|
|
59
|
+
options.operation === constants.TNS_LOB_OP_FILE_EXISTS ||
|
|
60
|
+
options.operation === constants.TNS_LOB_OP_FILE_ISOPEN
|
|
61
|
+
) {
|
|
62
|
+
return message.boolFlag;
|
|
57
63
|
} else {
|
|
58
64
|
return message.amount;
|
|
59
65
|
}
|
|
60
66
|
}
|
|
61
67
|
|
|
68
|
+
//---------------------------------------------------------------------------
|
|
69
|
+
// getChunkSize()
|
|
70
|
+
//
|
|
71
|
+
// Internal method for returning the chunk size of the LOB.
|
|
72
|
+
//---------------------------------------------------------------------------
|
|
62
73
|
getChunkSize() {
|
|
63
74
|
return this._chunkSize;
|
|
64
75
|
}
|
|
65
76
|
|
|
77
|
+
//---------------------------------------------------------------------------
|
|
78
|
+
// _getChunkSizeAsync()
|
|
79
|
+
//
|
|
80
|
+
// Internal method for returning the chunk size of the LOB fetched from
|
|
81
|
+
// the database.
|
|
82
|
+
//---------------------------------------------------------------------------
|
|
66
83
|
async _getChunkSizeAsync() {
|
|
67
84
|
this.checkConn();
|
|
68
85
|
const options = {
|
|
@@ -73,29 +90,76 @@ class ThinLobImpl extends LobImpl {
|
|
|
73
90
|
this._chunkSize = this._pieceSize = await this._sendMessage(options);
|
|
74
91
|
}
|
|
75
92
|
|
|
93
|
+
//---------------------------------------------------------------------------
|
|
94
|
+
// getLength()
|
|
95
|
+
//
|
|
96
|
+
// Internal method for returning the length of a LOB.
|
|
97
|
+
//---------------------------------------------------------------------------
|
|
76
98
|
getLength() {
|
|
77
99
|
return this._length;
|
|
78
100
|
}
|
|
79
101
|
|
|
102
|
+
//---------------------------------------------------------------------------
|
|
103
|
+
// getPieceSize()
|
|
104
|
+
//
|
|
105
|
+
// Internal method returning the size to use for each piece that is
|
|
106
|
+
// transferred when reading from the LOB.
|
|
107
|
+
//---------------------------------------------------------------------------
|
|
80
108
|
getPieceSize() {
|
|
81
109
|
return this._pieceSize;
|
|
82
110
|
}
|
|
83
111
|
|
|
112
|
+
//---------------------------------------------------------------------------
|
|
113
|
+
// setPieceSize()
|
|
114
|
+
//
|
|
115
|
+
// Internal method to set the pieceSize for LOBs.
|
|
116
|
+
//---------------------------------------------------------------------------
|
|
84
117
|
setPieceSize(value) {
|
|
85
118
|
this._pieceSize = value;
|
|
86
119
|
}
|
|
87
120
|
|
|
121
|
+
//---------------------------------------------------------------------------
|
|
122
|
+
// getType()
|
|
123
|
+
//
|
|
124
|
+
// Internal method returning the datatype of LOBs.
|
|
125
|
+
//---------------------------------------------------------------------------
|
|
88
126
|
getType() {
|
|
89
127
|
return this.dbType;
|
|
90
128
|
}
|
|
91
129
|
|
|
130
|
+
//---------------------------------------------------------------------------
|
|
131
|
+
// getData()
|
|
132
|
+
//
|
|
133
|
+
// Internal method returning the data obtained from the database.
|
|
134
|
+
//---------------------------------------------------------------------------
|
|
92
135
|
async getData(offset = 1, len = this._length) {
|
|
136
|
+
let shouldClose = false;
|
|
93
137
|
if (!len) {
|
|
94
138
|
len = this._length;
|
|
95
139
|
}
|
|
96
|
-
|
|
140
|
+
if (this.dbType === types.DB_TYPE_BFILE) {
|
|
141
|
+
if (!await this.isFileOpen()) {
|
|
142
|
+
shouldClose = true;
|
|
143
|
+
await this.openFile();
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
let data;
|
|
147
|
+
// if read fails and BFILE was opened by application, we close it.
|
|
148
|
+
try {
|
|
149
|
+
data = await this.read(offset, len);
|
|
150
|
+
} finally {
|
|
151
|
+
if (shouldClose) {
|
|
152
|
+
await this.closeFile();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return data;
|
|
97
156
|
}
|
|
98
157
|
|
|
158
|
+
//---------------------------------------------------------------------------
|
|
159
|
+
// read()
|
|
160
|
+
//
|
|
161
|
+
// Internal method for reading a portion (or all) of the data in the LOB.
|
|
162
|
+
//---------------------------------------------------------------------------
|
|
99
163
|
async read(offset, length) {
|
|
100
164
|
this.checkConn();
|
|
101
165
|
const options = {
|
|
@@ -108,6 +172,11 @@ class ThinLobImpl extends LobImpl {
|
|
|
108
172
|
return await this._sendMessage(options);
|
|
109
173
|
}
|
|
110
174
|
|
|
175
|
+
//---------------------------------------------------------------------------
|
|
176
|
+
// write()
|
|
177
|
+
//
|
|
178
|
+
// Internal method for writing data to the LOB object.
|
|
179
|
+
//---------------------------------------------------------------------------
|
|
111
180
|
async write(offset, data) {
|
|
112
181
|
this.checkConn();
|
|
113
182
|
const options = {
|
|
@@ -120,6 +189,11 @@ class ThinLobImpl extends LobImpl {
|
|
|
120
189
|
this._length += data.length;
|
|
121
190
|
}
|
|
122
191
|
|
|
192
|
+
//---------------------------------------------------------------------------
|
|
193
|
+
// getCsfrm()
|
|
194
|
+
//
|
|
195
|
+
// Return the character set encoding used by the LOB.
|
|
196
|
+
//---------------------------------------------------------------------------
|
|
123
197
|
getCsfrm() {
|
|
124
198
|
if (this.dbType._csfrm !== constants.CSFRM_NCHAR) {
|
|
125
199
|
if (this._locator[constants.TNS_LOB_LOC_OFFSET_FLAG_3] &
|
|
@@ -155,11 +229,60 @@ class ThinLobImpl extends LobImpl {
|
|
|
155
229
|
await this._getChunkSizeAsync();
|
|
156
230
|
}
|
|
157
231
|
|
|
232
|
+
//---------------------------------------------------------------------------
|
|
233
|
+
// fileExists()
|
|
234
|
+
//
|
|
235
|
+
// Internal method for returning whether the file referenced by a BFILE
|
|
236
|
+
// exists.
|
|
237
|
+
//---------------------------------------------------------------------------
|
|
238
|
+
async fileExists() {
|
|
239
|
+
this.checkConn();
|
|
240
|
+
const options = {
|
|
241
|
+
operation: constants.TNS_LOB_OP_FILE_EXISTS,
|
|
242
|
+
sourceLobImpl: this,
|
|
243
|
+
};
|
|
244
|
+
return await this._sendMessage(options);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
//---------------------------------------------------------------------------
|
|
248
|
+
// getDirFileName()
|
|
249
|
+
//
|
|
250
|
+
// Internal method for returning the directory alias and name of the file
|
|
251
|
+
// referenced by a BFILE
|
|
252
|
+
//---------------------------------------------------------------------------
|
|
253
|
+
getDirFileName() {
|
|
254
|
+
const dirNameOffset = constants.TNS_LOB_LOC_FIXED_OFFSET + 2;
|
|
255
|
+
const dirNameLen = this._locator.readUInt16BE(
|
|
256
|
+
constants.TNS_LOB_LOC_FIXED_OFFSET
|
|
257
|
+
);
|
|
258
|
+
const fileNameOffset = constants.TNS_LOB_LOC_FIXED_OFFSET + dirNameLen + 4;
|
|
259
|
+
const fileNameLen = this._locator.readUInt16BE(
|
|
260
|
+
dirNameOffset + dirNameLen
|
|
261
|
+
);
|
|
262
|
+
const dirName = this._locator.slice(
|
|
263
|
+
dirNameOffset, dirNameOffset + dirNameLen
|
|
264
|
+
).toString();
|
|
265
|
+
const fileName = this._locator.slice(
|
|
266
|
+
fileNameOffset, fileNameOffset + fileNameLen
|
|
267
|
+
).toString();
|
|
268
|
+
return { dirName: dirName, fileName: fileName };
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
//---------------------------------------------------------------------------
|
|
272
|
+
// checkConn()
|
|
273
|
+
//
|
|
274
|
+
// Internal method to check the connection.
|
|
275
|
+
//---------------------------------------------------------------------------
|
|
158
276
|
checkConn() {
|
|
159
277
|
if (!this.conn.nscon.connected)
|
|
160
278
|
errors.throwErr(errors.ERR_INVALID_CONNECTION);
|
|
161
279
|
}
|
|
162
280
|
|
|
281
|
+
//---------------------------------------------------------------------------
|
|
282
|
+
// close()
|
|
283
|
+
//
|
|
284
|
+
// Internal method to close the LOBs using piggyback mechanism.
|
|
285
|
+
//---------------------------------------------------------------------------
|
|
163
286
|
close() {
|
|
164
287
|
this.checkConn();
|
|
165
288
|
if (this._isTempLob) {
|
|
@@ -169,6 +292,25 @@ class ThinLobImpl extends LobImpl {
|
|
|
169
292
|
}
|
|
170
293
|
}
|
|
171
294
|
|
|
295
|
+
//---------------------------------------------------------------------------
|
|
296
|
+
// closeFile()
|
|
297
|
+
//
|
|
298
|
+
// Internal method to close the opened file for BFILE LOBs.
|
|
299
|
+
//---------------------------------------------------------------------------
|
|
300
|
+
async closeFile() {
|
|
301
|
+
this.checkConn();
|
|
302
|
+
const options = {
|
|
303
|
+
operation: constants.TNS_LOB_OP_FILE_CLOSE,
|
|
304
|
+
sourceLobImpl: this,
|
|
305
|
+
};
|
|
306
|
+
await this._sendMessage(options);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
//---------------------------------------------------------------------------
|
|
310
|
+
// init()
|
|
311
|
+
//
|
|
312
|
+
// Internal method to initialize LOBs.
|
|
313
|
+
//---------------------------------------------------------------------------
|
|
172
314
|
init(conn, locator, dbType, len, chunkSize) {
|
|
173
315
|
this.dirtyLength = false;
|
|
174
316
|
this.conn = conn;
|
|
@@ -184,6 +326,56 @@ class ThinLobImpl extends LobImpl {
|
|
|
184
326
|
this._pieceSize = chunkSize;
|
|
185
327
|
}
|
|
186
328
|
|
|
329
|
+
//---------------------------------------------------------------------------
|
|
330
|
+
// isFileOpen()
|
|
331
|
+
//
|
|
332
|
+
// Internal method to check if the file is already open.
|
|
333
|
+
//---------------------------------------------------------------------------
|
|
334
|
+
async isFileOpen() {
|
|
335
|
+
const options = {
|
|
336
|
+
operation: constants.TNS_LOB_OP_FILE_ISOPEN,
|
|
337
|
+
sourceLobImpl: this
|
|
338
|
+
};
|
|
339
|
+
await this._sendMessage(options);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
//---------------------------------------------------------------------------
|
|
343
|
+
// openFile()
|
|
344
|
+
//
|
|
345
|
+
// Internal method for opening file (BFILE).
|
|
346
|
+
//---------------------------------------------------------------------------
|
|
347
|
+
async openFile() {
|
|
348
|
+
this.checkConn();
|
|
349
|
+
const options = {
|
|
350
|
+
operation: constants.TNS_LOB_OP_FILE_OPEN,
|
|
351
|
+
sourceLobImpl: this,
|
|
352
|
+
amount: constants.TNS_LOB_OPEN_READ_ONLY,
|
|
353
|
+
sendAmount: true
|
|
354
|
+
};
|
|
355
|
+
return await this._sendMessage(options);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
//---------------------------------------------------------------------------
|
|
359
|
+
// setDirFileName()
|
|
360
|
+
//
|
|
361
|
+
// Internal method for setting the directory alias and name of the file
|
|
362
|
+
// referenced by a BFILE
|
|
363
|
+
//---------------------------------------------------------------------------
|
|
364
|
+
setDirFileName(dirObject) {
|
|
365
|
+
const dirNameLen = Buffer.byteLength(dirObject.dirName);
|
|
366
|
+
const dirNameOffset = constants.TNS_LOB_LOC_FIXED_OFFSET + 2;
|
|
367
|
+
const fileNameOffset = dirNameOffset + dirNameLen + 2;
|
|
368
|
+
const fileNameLen = Buffer.byteLength(dirObject.fileName);
|
|
369
|
+
const newLocLen = fileNameOffset + fileNameLen;
|
|
370
|
+
const newLocator = Buffer.allocUnsafe(newLocLen);
|
|
371
|
+
this._locator.copy(newLocator, 0, 0, constants.TNS_LOB_LOC_FIXED_OFFSET + 1);
|
|
372
|
+
newLocator.writeUInt16BE(dirNameLen, constants.TNS_LOB_LOC_FIXED_OFFSET);
|
|
373
|
+
newLocator.write(dirObject.dirName, dirNameOffset);
|
|
374
|
+
newLocator.writeInt16BE(fileNameLen, dirNameOffset + dirNameLen);
|
|
375
|
+
newLocator.write(dirObject.fileName, fileNameOffset);
|
|
376
|
+
this._locator = newLocator;
|
|
377
|
+
}
|
|
378
|
+
|
|
187
379
|
}
|
|
188
380
|
|
|
189
381
|
module.exports = ThinLobImpl;
|
package/lib/thin/pool.js
CHANGED
|
@@ -44,6 +44,9 @@ class ThinPoolImpl extends PoolImpl {
|
|
|
44
44
|
if (!params.homogeneous) {
|
|
45
45
|
errors.throwErr(errors.ERR_NOT_IMPLEMENTED, 'Heterogeneous Pooling');
|
|
46
46
|
}
|
|
47
|
+
if (!params.connectString) {
|
|
48
|
+
errors.throwErr(errors.ERR_EMPTY_CONNECT_STRING);
|
|
49
|
+
}
|
|
47
50
|
thinUtil.checkCredentials(params);
|
|
48
51
|
|
|
49
52
|
this._availableObjects = [];
|
|
@@ -64,6 +67,7 @@ class ThinPoolImpl extends PoolImpl {
|
|
|
64
67
|
this._usedConnectionList = new Set();
|
|
65
68
|
this._password = params.password;
|
|
66
69
|
this._walletPassword = params.walletPassword;
|
|
70
|
+
this._walletContent = params.walletContent;
|
|
67
71
|
this._obfuscatedPassword = [];
|
|
68
72
|
this._obfuscatedWalletPassword = [];
|
|
69
73
|
this._token = params.token;
|
|
@@ -88,6 +92,13 @@ class ThinPoolImpl extends PoolImpl {
|
|
|
88
92
|
this._obfuscatedWalletPassword = obj.obfuscatedValue;
|
|
89
93
|
this._userConfig.walletPassword = null;
|
|
90
94
|
}
|
|
95
|
+
// wallet content obfuscation
|
|
96
|
+
if (this._walletContent !== undefined) {
|
|
97
|
+
const obj = protocolUtil.setObfuscatedValue(this._walletContent);
|
|
98
|
+
this._walletContent = obj.value;
|
|
99
|
+
this._obfuscatedWalletContent = obj.obfuscatedValue;
|
|
100
|
+
this._userConfig.walletConent = null;
|
|
101
|
+
}
|
|
91
102
|
// token obfuscation
|
|
92
103
|
if (this._token !== undefined) {
|
|
93
104
|
const obj = protocolUtil.setObfuscatedValue(this._token);
|
|
@@ -172,6 +183,13 @@ class ThinPoolImpl extends PoolImpl {
|
|
|
172
183
|
this._obfuscatedWalletPassword);
|
|
173
184
|
}
|
|
174
185
|
|
|
186
|
+
// deobfuscate wallet content
|
|
187
|
+
if (clonedAttrs.walletContent === null) {
|
|
188
|
+
clonedAttrs.walletContent =
|
|
189
|
+
protocolUtil.getDeobfuscatedValue(this._walletContent,
|
|
190
|
+
this._obfuscatedWalletContent);
|
|
191
|
+
}
|
|
192
|
+
|
|
175
193
|
// deobfuscate token and private key
|
|
176
194
|
// check for token expiry
|
|
177
195
|
if (clonedAttrs.token === null) {
|
|
@@ -118,6 +118,8 @@ class Capabilities {
|
|
|
118
118
|
constants.TNS_CCAP_CTB_IMPLICIT_POOL;
|
|
119
119
|
this.compileCaps[constants.TNS_CCAP_TTC5] =
|
|
120
120
|
constants.TNS_CCAP_VECTOR_SUPPORT;
|
|
121
|
+
this.compileCaps[constants.TNS_CCAP_VECTOR_FEATURES] =
|
|
122
|
+
constants.TNS_CCAP_VECTOR_FEATURE_BINARY;
|
|
121
123
|
}
|
|
122
124
|
|
|
123
125
|
initRuntimeCaps() {
|
|
@@ -492,12 +492,17 @@ module.exports = {
|
|
|
492
492
|
TNS_LOB_OP_CLOSE: 0x10000,
|
|
493
493
|
TNS_LOB_OP_IS_OPEN: 0x11000,
|
|
494
494
|
TNS_LOB_OP_ARRAY: 0x80000,
|
|
495
|
+
TNS_LOB_OP_FILE_OPEN: 0x0100,
|
|
496
|
+
TNS_LOB_OP_FILE_CLOSE: 0x0200,
|
|
497
|
+
TNS_LOB_OP_FILE_ISOPEN: 0x0400,
|
|
498
|
+
TNS_LOB_OP_FILE_EXISTS: 0x0800,
|
|
495
499
|
|
|
496
500
|
// LOB locator constants
|
|
497
501
|
TNS_LOB_LOC_OFFSET_FLAG_1: 4,
|
|
498
502
|
TNS_LOB_LOC_OFFSET_FLAG_3: 6,
|
|
499
503
|
TNS_LOB_LOC_OFFSET_FLAG_4: 7,
|
|
500
504
|
TNS_LOB_QLOCATOR_VERSION: 4,
|
|
505
|
+
TNS_LOB_LOC_FIXED_OFFSET: 16,
|
|
501
506
|
|
|
502
507
|
// LOB locator flags (byte 1)
|
|
503
508
|
TNS_LOB_LOC_FLAGS_BLOB: 0x01,
|
|
@@ -513,6 +518,7 @@ module.exports = {
|
|
|
513
518
|
|
|
514
519
|
// other LOB constants
|
|
515
520
|
TNS_LOB_OPEN_READ_WRITE: 2,
|
|
521
|
+
TNS_LOB_OPEN_READ_ONLY: 11,
|
|
516
522
|
TNS_LOB_PREFETCH_FLAG: 0x2000000,
|
|
517
523
|
|
|
518
524
|
// base JSON constants
|
|
@@ -548,6 +554,8 @@ module.exports = {
|
|
|
548
554
|
TNS_FUNC_SESSION_RELEASE: 163,
|
|
549
555
|
TNS_FUNC_SESSION_STATE: 176, // piggyback fn
|
|
550
556
|
TNS_FUNC_CANCEL_ALL: 120, // piggyback fn
|
|
557
|
+
TNS_FUNC_TPC_TXN_SWITCH: 103,
|
|
558
|
+
TNS_FUNC_TPC_TXN_CHANGE_STATE: 104,
|
|
551
559
|
|
|
552
560
|
// character sets and encodings
|
|
553
561
|
TNS_CHARSET_UTF8: 873,
|
|
@@ -578,7 +586,8 @@ module.exports = {
|
|
|
578
586
|
TNS_CCAP_TTC4: 40,
|
|
579
587
|
TNS_CCAP_LOB2: 42,
|
|
580
588
|
TNS_CCAP_TTC5: 44,
|
|
581
|
-
|
|
589
|
+
TNS_CCAP_VECTOR_FEATURES: 52,
|
|
590
|
+
TNS_CCAP_MAX: 53,
|
|
582
591
|
|
|
583
592
|
// compile time capability values
|
|
584
593
|
TNS_CCAP_SQL_VERSION_MAX: 6,
|
|
@@ -634,6 +643,7 @@ module.exports = {
|
|
|
634
643
|
TNS_CCAP_LOB2_2GB_PREFETCH: 0x04,
|
|
635
644
|
TNS_CCAP_CTB_IMPLICIT_POOL: 0x08,
|
|
636
645
|
TNS_CCAP_VECTOR_SUPPORT: 0x08,
|
|
646
|
+
TNS_CCAP_VECTOR_FEATURE_BINARY: 0x01,
|
|
637
647
|
|
|
638
648
|
// runtime capability indices
|
|
639
649
|
TNS_RCAP_COMPAT: 0,
|
|
@@ -660,6 +670,24 @@ module.exports = {
|
|
|
660
670
|
TNS_EOCS_FLAGS_TXN_IN_PROGRESS: 0x00000002,
|
|
661
671
|
TNS_EOCS_FLAGS_SESS_RELEASE: 0x00008000,
|
|
662
672
|
|
|
673
|
+
// transaction switching op codes
|
|
674
|
+
TNS_TPC_TXN_START: 0x01,
|
|
675
|
+
TNS_TPC_TXN_DETACH: 0x02,
|
|
676
|
+
|
|
677
|
+
// transaction change state op codes
|
|
678
|
+
TNS_TPC_TXN_COMMIT: 0x01,
|
|
679
|
+
TNS_TPC_TXN_ABORT: 0x02,
|
|
680
|
+
TNS_TPC_TXN_PREPARE: 0x03,
|
|
681
|
+
TNS_TPC_TXN_FORGET: 0x04,
|
|
682
|
+
|
|
683
|
+
// transaction states
|
|
684
|
+
TNS_TPC_TXN_STATE_PREPARE: 0,
|
|
685
|
+
TNS_TPC_TXN_STATE_REQUIRES_COMMIT: 1,
|
|
686
|
+
TNS_TPC_TXN_STATE_COMMITTED: 2,
|
|
687
|
+
TNS_TPC_TXN_STATE_ABORTED: 3,
|
|
688
|
+
TNS_TPC_TXN_STATE_READ_ONLY: 4,
|
|
689
|
+
TNS_TPC_TXN_STATE_FORGOTTEN: 5,
|
|
690
|
+
|
|
663
691
|
// other constants
|
|
664
692
|
TNS_ESCAPE_CHAR: 253,
|
|
665
693
|
TNS_LONG_LENGTH_INDICATOR: dataHandlerConstants.TNS_LONG_LENGTH_INDICATOR,
|
|
@@ -102,6 +102,11 @@ class AuthMessage extends Message {
|
|
|
102
102
|
}
|
|
103
103
|
this.serviceName = this.conn.serviceName;
|
|
104
104
|
this.remoteAddress = this.conn.remoteAddress;
|
|
105
|
+
this.driverName = config.driverName;
|
|
106
|
+
this.machine = config.machine;
|
|
107
|
+
this.osUser = config.osUser;
|
|
108
|
+
this.program = config.program;
|
|
109
|
+
this.terminal = config.terminal;
|
|
105
110
|
this.setAuthMode(config);
|
|
106
111
|
}
|
|
107
112
|
|
|
@@ -181,11 +186,11 @@ class AuthMessage extends Message {
|
|
|
181
186
|
if (this.userByteLen > 0) {
|
|
182
187
|
buf.writeBytesWithLength(Buffer.from(this.username));
|
|
183
188
|
}
|
|
184
|
-
buf.writeKeyValue("AUTH_TERMINAL", cInfo.terminal);
|
|
185
|
-
buf.writeKeyValue("AUTH_PROGRAM_NM", cInfo.program);
|
|
186
|
-
buf.writeKeyValue("AUTH_MACHINE", cInfo.hostName);
|
|
189
|
+
buf.writeKeyValue("AUTH_TERMINAL", this.terminal ?? cInfo.terminal);
|
|
190
|
+
buf.writeKeyValue("AUTH_PROGRAM_NM", this.program ?? cInfo.program);
|
|
191
|
+
buf.writeKeyValue("AUTH_MACHINE", this.machine ?? cInfo.hostName);
|
|
187
192
|
buf.writeKeyValue("AUTH_PID", cInfo.pid);
|
|
188
|
-
buf.writeKeyValue("AUTH_SID", cInfo.userName);
|
|
193
|
+
buf.writeKeyValue("AUTH_SID", this.osUser ?? cInfo.userName);
|
|
189
194
|
} else {
|
|
190
195
|
let numPairs = 0;
|
|
191
196
|
|
|
@@ -253,7 +258,8 @@ class AuthMessage extends Message {
|
|
|
253
258
|
}
|
|
254
259
|
if (!this.changePassword) {
|
|
255
260
|
buf.writeKeyValue("SESSION_CLIENT_CHARSET", "873");
|
|
256
|
-
buf.writeKeyValue("SESSION_CLIENT_DRIVER_NAME",
|
|
261
|
+
buf.writeKeyValue("SESSION_CLIENT_DRIVER_NAME",
|
|
262
|
+
this.driverName ?? constants.DRIVER_NAME);
|
|
257
263
|
buf.writeKeyValue("SESSION_CLIENT_VERSION",
|
|
258
264
|
constants.CLIENT_VERSION.toString());
|
|
259
265
|
buf.writeKeyValue("AUTH_ALTER_SESSION", this.getAlterTimezoneStatement(), 1);
|
|
@@ -321,7 +327,7 @@ class AuthMessage extends Message {
|
|
|
321
327
|
let portUpdateNum;
|
|
322
328
|
|
|
323
329
|
this.conn.dbDomain = this.sessionData['AUTH_SC_DB_DOMAIN'];
|
|
324
|
-
this.conn.dbName = this.sessionData['
|
|
330
|
+
this.conn.dbName = this.sessionData['AUTH_DBNAME'];
|
|
325
331
|
this.conn.maxOpenCursors = Number(this.sessionData['AUTH_MAX_OPEN_CURSORS'] || 0);
|
|
326
332
|
this.conn.serviceName = this.sessionData['AUTH_SC_SERVICE_NAME'];
|
|
327
333
|
this.conn.instanceName = this.sessionData['AUTH_INSTANCENAME'];
|
|
@@ -296,6 +296,9 @@ class Message {
|
|
|
296
296
|
this._writeCurrentSchemaPiggyback(buf);
|
|
297
297
|
}
|
|
298
298
|
if (this.connection.statementCache._cursorsToClose.size > 0 && !this.connection._drcpEstablishSession) {
|
|
299
|
+
// skip closing cursors when '_drcpEstablishSession = true' Since we don't know whether the same session
|
|
300
|
+
// is in use. We can not send the information across until after the session information has been returned
|
|
301
|
+
// (on the first round trip).
|
|
299
302
|
this.writeCloseCursorsPiggyBack(buf);
|
|
300
303
|
}
|
|
301
304
|
if (
|
|
@@ -38,6 +38,8 @@ const ProtocolMessage = require('./protocol.js');
|
|
|
38
38
|
const RollbackMessage = require('./rollback.js');
|
|
39
39
|
const SessionReleaseMessage = require('./sessionRelease.js');
|
|
40
40
|
const FastAuthMessage = require('./fastAuth.js');
|
|
41
|
+
const TransactionChangeStateMessage = require('./transactionChangeState.js');
|
|
42
|
+
const TransactionSwitchMessage = require('./transactionSwitch.js');
|
|
41
43
|
|
|
42
44
|
module.exports = {
|
|
43
45
|
AuthMessage,
|
|
@@ -51,5 +53,7 @@ module.exports = {
|
|
|
51
53
|
PingMessage,
|
|
52
54
|
ProtocolMessage,
|
|
53
55
|
RollbackMessage,
|
|
54
|
-
SessionReleaseMessage
|
|
56
|
+
SessionReleaseMessage,
|
|
57
|
+
TransactionChangeStateMessage,
|
|
58
|
+
TransactionSwitchMessage
|
|
55
59
|
};
|
|
@@ -90,8 +90,13 @@ class LobOpMessage extends Message {
|
|
|
90
90
|
buf.writeUInt8(0);
|
|
91
91
|
}
|
|
92
92
|
buf.writeUInt8(0);
|
|
93
|
-
|
|
94
|
-
|
|
93
|
+
const operations = [
|
|
94
|
+
constants.TNS_LOB_OP_CREATE_TEMP,
|
|
95
|
+
constants.TNS_LOB_OP_IS_OPEN,
|
|
96
|
+
constants.TNS_LOB_OP_FILE_EXISTS,
|
|
97
|
+
constants.TNS_LOB_OP_FILE_ISOPEN,
|
|
98
|
+
];
|
|
99
|
+
if (operations.includes(this.operation)) {
|
|
95
100
|
buf.writeUInt8(1);
|
|
96
101
|
} else {
|
|
97
102
|
buf.writeUInt8(0);
|
|
@@ -152,7 +157,10 @@ class LobOpMessage extends Message {
|
|
|
152
157
|
const oraTypeNum = this.sourceLobImpl.dbType._oraTypeNum;
|
|
153
158
|
let data = buf.readBytesWithLength();
|
|
154
159
|
if (data !== null) {
|
|
155
|
-
if (
|
|
160
|
+
if (
|
|
161
|
+
oraTypeNum === constants.TNS_DATA_TYPE_BLOB ||
|
|
162
|
+
oraTypeNum === constants.TNS_DATA_TYPE_BFILE
|
|
163
|
+
) {
|
|
156
164
|
data = Buffer.from(data);
|
|
157
165
|
} else if (this.sourceLobImpl.getCsfrm() === constants.CSFRM_NCHAR) {
|
|
158
166
|
data = Buffer.from(data).swap16().toString('utf16le');
|
|
@@ -189,8 +197,12 @@ class LobOpMessage extends Message {
|
|
|
189
197
|
} else if (this.sendAmount) {
|
|
190
198
|
this.amount = buf.readSB8();
|
|
191
199
|
}
|
|
192
|
-
if (
|
|
193
|
-
|
|
200
|
+
if (
|
|
201
|
+
this.operation === constants.TNS_LOB_OP_IS_OPEN
|
|
202
|
+
|| this.operation === constants.TNS_LOB_OP_FILE_EXISTS
|
|
203
|
+
|| this.operation === constants.TNS_LOB_OP_FILE_ISOPEN
|
|
204
|
+
) {
|
|
205
|
+
temp8 = buf.readUInt8();
|
|
194
206
|
this.boolFlag = temp8 > 0;
|
|
195
207
|
}
|
|
196
208
|
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// Copyright (c) 2024, Oracle and/or its affiliates.
|
|
2
|
+
|
|
3
|
+
//-----------------------------------------------------------------------------
|
|
4
|
+
//
|
|
5
|
+
// This software is dual-licensed to you under the Universal Permissive License
|
|
6
|
+
// (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
|
7
|
+
// 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
|
8
|
+
// either license.
|
|
9
|
+
//
|
|
10
|
+
// If you elect to accept the software under the Apache License, Version 2.0,
|
|
11
|
+
// the following applies:
|
|
12
|
+
//
|
|
13
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
14
|
+
// you may not use this file except in compliance with the License.
|
|
15
|
+
// You may obtain a copy of the License at
|
|
16
|
+
//
|
|
17
|
+
// https://www.apache.org/licenses/LICENSE-2.0
|
|
18
|
+
//
|
|
19
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
20
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
21
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
22
|
+
// See the License for the specific language governing permissions and
|
|
23
|
+
// limitations under the License.
|
|
24
|
+
//
|
|
25
|
+
//-----------------------------------------------------------------------------
|
|
26
|
+
|
|
27
|
+
'use strict';
|
|
28
|
+
|
|
29
|
+
const Message = require("./base.js");
|
|
30
|
+
const constants = require("../constants.js");
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Used for two-phase commit (TPC) transaction change state: commit, rollback,
|
|
34
|
+
* forget, etc.
|
|
35
|
+
*
|
|
36
|
+
* @class TransactionChangeStateMessage
|
|
37
|
+
* @extends {Message}
|
|
38
|
+
*/
|
|
39
|
+
class TransactionChangeStateMessage extends Message {
|
|
40
|
+
|
|
41
|
+
constructor(connImpl) {
|
|
42
|
+
super(connImpl);
|
|
43
|
+
this.functionCode = constants.TNS_FUNC_TPC_TXN_CHANGE_STATE;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
processReturnParameter(buf) {
|
|
47
|
+
// process the parameters returned by the datatabase
|
|
48
|
+
this.state = buf.readUB4();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
encode(buf) {
|
|
52
|
+
// writes the message to the database
|
|
53
|
+
// acquire data to send to the server
|
|
54
|
+
let xidBytes;
|
|
55
|
+
if (this.xid) {
|
|
56
|
+
xidBytes = Buffer.alloc(128);
|
|
57
|
+
this.xid.globalTransactionId.copy(xidBytes);
|
|
58
|
+
this.xid.branchQualifier.copy(xidBytes,
|
|
59
|
+
this.xid.globalTransactionId.length);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
this.writeFunctionHeader(buf);
|
|
63
|
+
buf.writeUB4(this.operation);
|
|
64
|
+
if (this.context) {
|
|
65
|
+
buf.writeUInt8(1);
|
|
66
|
+
buf.writeUB4(this.context.length);
|
|
67
|
+
} else {
|
|
68
|
+
buf.writeUInt8(0);
|
|
69
|
+
buf.writeUB4(0);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (this.xid) {
|
|
73
|
+
buf.writeUB4(this.xid.formatId);
|
|
74
|
+
buf.writeUB4(this.xid.globalTransactionId.length);
|
|
75
|
+
buf.writeUB4(this.xid.branchQualifier.length);
|
|
76
|
+
buf.writeUInt8(1);
|
|
77
|
+
buf.writeUB4(xidBytes.length);
|
|
78
|
+
} else {
|
|
79
|
+
buf.writeUB4(0);
|
|
80
|
+
buf.writeUB4(0);
|
|
81
|
+
buf.writeUB4(0);
|
|
82
|
+
buf.writeUInt8(0);
|
|
83
|
+
buf.writeUB4(0);
|
|
84
|
+
}
|
|
85
|
+
buf.writeUB4(0);
|
|
86
|
+
buf.writeUB4(this.state);
|
|
87
|
+
buf.writeUInt8(1);
|
|
88
|
+
buf.writeUB4(this.flags);
|
|
89
|
+
|
|
90
|
+
if (this.context) {
|
|
91
|
+
buf.writeBytes(this.context);
|
|
92
|
+
}
|
|
93
|
+
if (this.xid) {
|
|
94
|
+
buf.writeBytes(xidBytes);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
module.exports = TransactionChangeStateMessage;
|