oracledb 6.9.0 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +1 -1
- package/NOTICE.txt +1 -1
- package/README.md +9 -9
- package/build/Release/oracledb-7.0.0-darwin-arm64.node +0 -0
- package/build/Release/oracledb-7.0.0-darwin-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-7.0.0-js-buildinfo.txt +1 -0
- package/build/Release/oracledb-7.0.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-7.0.0-linux-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-7.0.0-linux-x64.node +0 -0
- package/build/Release/oracledb-7.0.0-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-7.0.0-win32-x64.node +0 -0
- package/build/Release/oracledb-7.0.0-win32-x64.node-buildinfo.txt +1 -0
- package/eslint.config.js +39 -0
- package/lib/aqDeqOptions.js +18 -1
- package/lib/aqQueue.js +10 -6
- package/lib/connection.js +418 -39
- package/lib/dbObject.js +25 -4
- package/lib/endUserSecurityContext.js +176 -0
- package/lib/errors.js +99 -8
- package/lib/impl/aqDeqOptions.js +10 -1
- package/lib/impl/connection.js +76 -2
- package/lib/impl/datahandlers/buffer.js +68 -5
- package/lib/impl/datahandlers/oson.js +7 -2
- package/lib/impl/datahandlers/vector.js +25 -5
- package/lib/impl/lob.js +9 -0
- package/lib/impl/parserHelpers.js +443 -0
- package/lib/impl/resultset.js +1 -1
- package/lib/impl/sodaDocument.js +5 -14
- package/lib/lob.js +27 -14
- package/lib/obfuscation.js +97 -0
- package/lib/oracledb.js +163 -49
- package/lib/parser.js +204 -0
- package/lib/pipeline.js +113 -0
- package/lib/pool.js +203 -147
- package/lib/poolStatistics.js +1 -1
- package/lib/resultset.js +42 -21
- package/lib/settings.js +1 -0
- 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 +518 -54
- package/lib/thin/dbObject.js +7 -1
- package/lib/thin/lob.js +20 -1
- package/lib/thin/pool.js +42 -62
- package/lib/thin/protocol/capabilities.js +21 -4
- package/lib/thin/protocol/constants.js +143 -2
- package/lib/thin/protocol/encryptDecrypt.js +45 -10
- 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 +18 -28
- package/lib/thin/protocol/messages/base.js +245 -4
- package/lib/thin/protocol/messages/dataType.js +8 -3
- package/lib/thin/protocol/messages/directPathLoadStream.js +377 -0
- package/lib/thin/protocol/messages/directPathOp.js +65 -0
- package/lib/thin/protocol/messages/directPathPrepare.js +158 -0
- package/lib/thin/protocol/messages/endPipeline.js +56 -0
- package/lib/thin/protocol/messages/execute.js +9 -7
- package/lib/thin/protocol/messages/index.js +9 -1
- package/lib/thin/protocol/messages/protocol.js +2 -2
- package/lib/thin/protocol/messages/withData.js +10 -142
- package/lib/thin/protocol/packet.js +120 -28
- package/lib/thin/protocol/protocol.js +110 -25
- package/lib/thin/protocol/utils.js +1 -26
- package/lib/thin/resultSet.js +13 -19
- package/lib/thin/sqlnet/ezConnectResolver.js +2 -2
- package/lib/thin/sqlnet/networkSession.js +63 -41
- package/lib/thin/sqlnet/ntTcp.js +24 -0
- package/lib/thin/sqlnet/nvStrToNvPair.js +50 -25
- package/lib/thin/sqlnet/packet.js +25 -4
- package/lib/thin/sqlnet/paramParser.js +10 -7
- package/lib/thin/statementCache.js +2 -4
- package/lib/traceHandler.js +59 -2
- package/lib/transformer.js +8 -3
- package/lib/types.js +36 -22
- package/lib/util.js +6 -19
- package/lib/version.js +3 -3
- package/package/install.js +5 -5
- package/package/prunebinaries.js +1 -1
- package/package.json +1 -1
- package/plugins/configProviders/awsCommon.js +125 -0
- package/plugins/configProviders/awss3/index.js +138 -0
- package/plugins/configProviders/awssecretsmanager/index.js +147 -0
- package/plugins/configProviders/azure/index.js +7 -5
- package/plugins/token/extensionAzure/index.js +0 -1
- package/plugins/token/extensionOci/index.js +0 -1
- 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
package/lib/thin/connection.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2022,
|
|
1
|
+
// Copyright (c) 2022, 2026, Oracle and/or its affiliates.
|
|
2
2
|
|
|
3
3
|
//-----------------------------------------------------------------------------
|
|
4
4
|
//
|
|
@@ -42,6 +42,7 @@ const types = require('../types.js');
|
|
|
42
42
|
const errors = require("../errors.js");
|
|
43
43
|
const messages = require('./protocol/messages');
|
|
44
44
|
const StatementCache = require('./statementCache.js');
|
|
45
|
+
const { ThinQueueImpl } = require('./aq.js');
|
|
45
46
|
|
|
46
47
|
const finalizationRegistry = new global.FinalizationRegistry((heldValue) => {
|
|
47
48
|
heldValue.disconnect();
|
|
@@ -52,6 +53,29 @@ class TDSBuffer extends BaseBuffer {
|
|
|
52
53
|
|
|
53
54
|
class ThinConnectionImpl extends ConnectionImpl {
|
|
54
55
|
|
|
56
|
+
static _createNamespace(nameSpaceName) {
|
|
57
|
+
return {
|
|
58
|
+
nameSpaceName,
|
|
59
|
+
keyValues: [],
|
|
60
|
+
pendingClear: false
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
static _mergeKeyValues(namespace, keyValues) {
|
|
65
|
+
const mergedKeyValues = namespace.keyValues.slice();
|
|
66
|
+
for (const entry of keyValues) {
|
|
67
|
+
const entryKey = Object.keys(entry)[0];
|
|
68
|
+
const existingIndex = mergedKeyValues.findIndex((existingEntry) =>
|
|
69
|
+
Object.prototype.hasOwnProperty.call(existingEntry, entryKey));
|
|
70
|
+
if (existingIndex !== -1) {
|
|
71
|
+
mergedKeyValues.splice(existingIndex, 1);
|
|
72
|
+
}
|
|
73
|
+
mergedKeyValues.push(entry);
|
|
74
|
+
}
|
|
75
|
+
namespace.keyValues = mergedKeyValues;
|
|
76
|
+
namespace.pendingClear = false;
|
|
77
|
+
}
|
|
78
|
+
|
|
55
79
|
/**
|
|
56
80
|
* Terminates the connection
|
|
57
81
|
*
|
|
@@ -59,6 +83,7 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
59
83
|
*/
|
|
60
84
|
async close() {
|
|
61
85
|
try {
|
|
86
|
+
this.clearEndUserSecurityContext();
|
|
62
87
|
if (this._protocol.txnInProgress) {
|
|
63
88
|
if (this.tpcContext) {
|
|
64
89
|
const message = this.createTpcRollbackMessage();
|
|
@@ -81,7 +106,7 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
81
106
|
}
|
|
82
107
|
this.nscon.disconnect();
|
|
83
108
|
}
|
|
84
|
-
} catch
|
|
109
|
+
} catch {
|
|
85
110
|
// immediate close of open socket on failure
|
|
86
111
|
// exception won't be thrown to user
|
|
87
112
|
this.nscon.disconnect(sqlNetConstants.NSFIMM);
|
|
@@ -165,12 +190,8 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
165
190
|
}
|
|
166
191
|
}
|
|
167
192
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
//
|
|
171
|
-
// Calls the RPC that executes a SQL statement and returns the results.
|
|
172
|
-
//---------------------------------------------------------------------------
|
|
173
|
-
async _execute(statement, numIters, binds, options, executeManyFlag) {
|
|
193
|
+
async _getExecuteMessage(statement, numIters, binds, options,
|
|
194
|
+
executeManyFlag, internalTempLobs = []) {
|
|
174
195
|
|
|
175
196
|
// Throw error if executeMany is not called on a DML statement or PL/SQL
|
|
176
197
|
if (executeManyFlag && statement.isQuery) {
|
|
@@ -194,7 +215,7 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
194
215
|
}
|
|
195
216
|
|
|
196
217
|
for (let i = 0; i < binds.length; i++) {
|
|
197
|
-
await this._bind(statement, binds[i], i + 1);
|
|
218
|
+
await this._bind(statement, binds[i], i + 1, internalTempLobs);
|
|
198
219
|
}
|
|
199
220
|
if (statement.isPlSql && (options.batchErrors || options.dmlRowCounts)) {
|
|
200
221
|
errors.throwErr(errors.ERR_EXEC_MODE_ONLY_FOR_DML);
|
|
@@ -205,6 +226,18 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
205
226
|
message.numExecs = numIters;
|
|
206
227
|
message.arrayDmlRowCounts = options.dmlRowCounts;
|
|
207
228
|
message.batchErrors = options.batchErrors;
|
|
229
|
+
return message;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
//---------------------------------------------------------------------------
|
|
233
|
+
// _execute()
|
|
234
|
+
//
|
|
235
|
+
// Calls the RPC that executes a SQL statement and returns the results.
|
|
236
|
+
//---------------------------------------------------------------------------
|
|
237
|
+
async _execute(statement, numIters, binds, options, executeManyFlag, internalTempLobs = []) {
|
|
238
|
+
|
|
239
|
+
const message = await this._getExecuteMessage(statement, numIters, binds,
|
|
240
|
+
options, executeManyFlag, internalTempLobs);
|
|
208
241
|
|
|
209
242
|
// if a PL/SQL statement requires a full execute, perform only a single
|
|
210
243
|
// iteration in order to allow the determination of input/output binds
|
|
@@ -226,14 +259,124 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
226
259
|
}
|
|
227
260
|
|
|
228
261
|
// if a define is required, send an additional request to the database
|
|
229
|
-
|
|
230
|
-
statement.requiresFullExecute = true;
|
|
231
|
-
await this._protocol._processMessage(message);
|
|
232
|
-
statement.requiresFullExecute = false;
|
|
233
|
-
statement.requiresDefine = false;
|
|
234
|
-
}
|
|
262
|
+
await this._handleDefines(statement, message);
|
|
235
263
|
|
|
236
264
|
// process results
|
|
265
|
+
return this._processExecuteResult(statement, numIters, options,
|
|
266
|
+
executeManyFlag, message);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
//---------------------------------------------------------------------------
|
|
270
|
+
// _sendMessagesForPipeline()
|
|
271
|
+
//
|
|
272
|
+
// Sends the messages for the pipeline to the database for processing.
|
|
273
|
+
// This is async function only because of await adapter.pauseWrite()
|
|
274
|
+
// which is used to slow down writing to network socket.
|
|
275
|
+
//---------------------------------------------------------------------------
|
|
276
|
+
async _sendMessagesForPipeline(messages, continueOnError) {
|
|
277
|
+
for (const messageObj of messages) {
|
|
278
|
+
if (messageObj.pipelineResultImpl.error)
|
|
279
|
+
continue;
|
|
280
|
+
const message = messageObj.message;
|
|
281
|
+
const opType = messageObj.pipelineResultImpl.op.opType;
|
|
282
|
+
try {
|
|
283
|
+
if (['execute', 'executeMany', 'fetchOne', 'fetchMany',
|
|
284
|
+
'fetchAll'].includes(opType)) {
|
|
285
|
+
const statement = messageObj.statement;
|
|
286
|
+
if (statement.isPlSql && (statement.cursorId === 0 ||
|
|
287
|
+
statement.requiresFullExecute)) {
|
|
288
|
+
message.numExecs = 1;
|
|
289
|
+
message.noImplicitRelease = true;
|
|
290
|
+
await this._protocol._encodeMessage(message);
|
|
291
|
+
message.requiresSingleExecute = true;
|
|
292
|
+
} else if (message.numExecs > 0) {
|
|
293
|
+
await this._protocol._encodeMessage(message);
|
|
294
|
+
}
|
|
295
|
+
} else if (opType === 'commit')
|
|
296
|
+
await this._protocol._encodeMessage(message);
|
|
297
|
+
} catch (err) {
|
|
298
|
+
this._returnStatement(messageObj.statement);
|
|
299
|
+
if (!continueOnError) {
|
|
300
|
+
throw (err);
|
|
301
|
+
}
|
|
302
|
+
messageObj.pipelineResultImpl.error = err;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
//---------------------------------------------------------------------------
|
|
308
|
+
// _createMessagesForPipelineOp()
|
|
309
|
+
//
|
|
310
|
+
// Creates a single message for a pipeline operation.
|
|
311
|
+
//---------------------------------------------------------------------------
|
|
312
|
+
async _createMessagesForPipelineOp(conn, operation) {
|
|
313
|
+
const opType = operation.opType;
|
|
314
|
+
if (opType === 'commit') {
|
|
315
|
+
errors.assert(conn._impl, errors.ERR_INVALID_CONNECTION);
|
|
316
|
+
return { message: new messages.CommitMessage(this) };
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
let processedArgs;
|
|
320
|
+
switch (opType) {
|
|
321
|
+
case 'execute':
|
|
322
|
+
processedArgs = await conn._processExecuteArgs(operation.statement,
|
|
323
|
+
operation.parameters, operation.options);
|
|
324
|
+
break;
|
|
325
|
+
case 'executeMany':
|
|
326
|
+
processedArgs = await conn._processExecuteManyArgs(operation.statement,
|
|
327
|
+
operation.parameters, operation.options);
|
|
328
|
+
break;
|
|
329
|
+
case 'fetchOne':
|
|
330
|
+
case 'fetchMany':
|
|
331
|
+
case 'fetchAll': {
|
|
332
|
+
const options = {
|
|
333
|
+
...operation.options,
|
|
334
|
+
fetchTypeHandler: conn._createFetchTypeHandler(operation.fetchLobs)
|
|
335
|
+
};
|
|
336
|
+
processedArgs = await conn._processExecuteArgs(operation.statement,
|
|
337
|
+
operation.parameters, options);
|
|
338
|
+
break;
|
|
339
|
+
}
|
|
340
|
+
default:
|
|
341
|
+
errors.throwErr(errors.ERR_PIPELINE_OPERATION_NOT_SUPPORTED, opType);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const {sql, numIters, binds, options, executeManyFlag} = processedArgs;
|
|
345
|
+
return await this._prepareForExecute(sql, numIters, binds, options,
|
|
346
|
+
executeManyFlag);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
//---------------------------------------------------------------------------
|
|
350
|
+
// _createMessagesForPipeline()
|
|
351
|
+
//
|
|
352
|
+
// Creates a list of messages for the pipeline and returns them after they
|
|
353
|
+
// have been submitted to the database for processing.
|
|
354
|
+
//---------------------------------------------------------------------------
|
|
355
|
+
async _createMessagesForPipeline(conn, resultsImpl, continueOnError) {
|
|
356
|
+
const messagesForPipeline = [];
|
|
357
|
+
let tokenNum = 1;
|
|
358
|
+
for (const resultImpl of resultsImpl) {
|
|
359
|
+
let messageObj;
|
|
360
|
+
try {
|
|
361
|
+
messageObj = await this._createMessagesForPipelineOp(conn,
|
|
362
|
+
resultImpl.op);
|
|
363
|
+
} catch (err) {
|
|
364
|
+
if (!continueOnError)
|
|
365
|
+
throw (err);
|
|
366
|
+
resultImpl.error = err;
|
|
367
|
+
continue;
|
|
368
|
+
}
|
|
369
|
+
messageObj.message.pipelineMessage = true;
|
|
370
|
+
messageObj.pipelineResultImpl = resultImpl;
|
|
371
|
+
messageObj.message.tokenNum = tokenNum;
|
|
372
|
+
tokenNum++;
|
|
373
|
+
messagesForPipeline.push(messageObj);
|
|
374
|
+
}
|
|
375
|
+
return messagesForPipeline;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
_processExecuteResult(statement, numIters, options, executeManyFlag,
|
|
379
|
+
message) {
|
|
237
380
|
const result = {};
|
|
238
381
|
if (message.warning) {
|
|
239
382
|
result.warning = message.warning;
|
|
@@ -283,6 +426,164 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
283
426
|
return result;
|
|
284
427
|
}
|
|
285
428
|
|
|
429
|
+
//---------------------------------------------------------------------------
|
|
430
|
+
// _completePipelineOp()
|
|
431
|
+
//
|
|
432
|
+
// Completes a particular pipeline operation.
|
|
433
|
+
//---------------------------------------------------------------------------
|
|
434
|
+
async _completePipelineOp(messageObj, conn) {
|
|
435
|
+
const message = messageObj.message;
|
|
436
|
+
const opType = messageObj.pipelineResultImpl.op.opType;
|
|
437
|
+
|
|
438
|
+
// Post-processing of pipeline message happen once after reading response
|
|
439
|
+
// of all the operations is completed in the first phase.
|
|
440
|
+
await message.postProcess();
|
|
441
|
+
await this._protocol._processCallStatus(message);
|
|
442
|
+
|
|
443
|
+
if (opType === 'commit')
|
|
444
|
+
return;
|
|
445
|
+
|
|
446
|
+
if (['execute', 'executeMany', 'fetchOne', 'fetchMany',
|
|
447
|
+
'fetchAll'].includes(opType)) {
|
|
448
|
+
const statement = messageObj.statement;
|
|
449
|
+
const numIters = messageObj.numIters;
|
|
450
|
+
const options = messageObj.options;
|
|
451
|
+
const executeManyFlag = messageObj.executeManyFlag;
|
|
452
|
+
try {
|
|
453
|
+
|
|
454
|
+
// for PL/SQL blocks that required a single execute, perform any
|
|
455
|
+
// remaining executes now
|
|
456
|
+
if (message.requiresSingleExecute) {
|
|
457
|
+
statement.requiresFullExecute = false;
|
|
458
|
+
message.numExecs = numIters - 1;
|
|
459
|
+
message.offset = 1;
|
|
460
|
+
message.noImplicitRelease = false;
|
|
461
|
+
if (message.numExecs > 0) {
|
|
462
|
+
await this._protocol._processMessage(message);
|
|
463
|
+
statement.requiresFullExecute = false;
|
|
464
|
+
}
|
|
465
|
+
message.requiresSingleExecute = false;
|
|
466
|
+
} else {
|
|
467
|
+
statement.requiresFullExecute = false;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
// resend the message if that is required (for operations that fetch
|
|
471
|
+
// LOBS, for example)
|
|
472
|
+
await this._handleDefines(statement, message);
|
|
473
|
+
|
|
474
|
+
// process results
|
|
475
|
+
messageObj.resultTemp = this._processExecuteResult(statement, numIters,
|
|
476
|
+
options, executeManyFlag, message);
|
|
477
|
+
} catch (err) {
|
|
478
|
+
this._returnStatement(messageObj.statement);
|
|
479
|
+
throw (err);
|
|
480
|
+
} finally {
|
|
481
|
+
for (const lob of messageObj.internalTempLobs) {
|
|
482
|
+
this._tempLobsToClose.push(lob._locator);
|
|
483
|
+
this._tempLobsTotalSize += lob._locator.length;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
if (opType === 'executeMany')
|
|
487
|
+
await conn._transformExecuteManyResult(messageObj.resultTemp,
|
|
488
|
+
messageObj.options);
|
|
489
|
+
else if (opType === 'execute') {
|
|
490
|
+
await conn._handleFetchForExecuteInPipeline(messageObj.resultTemp, messageObj.options);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
if (['fetchOne', 'fetchMany', 'fetchAll'].includes(opType)) {
|
|
494
|
+
// fetch rows
|
|
495
|
+
await conn._transformExecuteResult(messageObj.resultTemp,
|
|
496
|
+
messageObj.options, messageObj.pipelineResultImpl.op);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
//---------------------------------------------------------------------------
|
|
502
|
+
// _completePipelineOps()
|
|
503
|
+
//
|
|
504
|
+
// Completes any pipeline operations that have not actually completed.
|
|
505
|
+
// This could be due to the fact that LOBs were fetched or a fetch all
|
|
506
|
+
// operation has more rows to fetch.
|
|
507
|
+
//---------------------------------------------------------------------------
|
|
508
|
+
async _completePipelineOps(messagesForPipeline, conn, continueOnError) {
|
|
509
|
+
for (const messageObj of messagesForPipeline) {
|
|
510
|
+
const resultImpl = messageObj.pipelineResultImpl;
|
|
511
|
+
if (resultImpl.error)
|
|
512
|
+
continue;
|
|
513
|
+
try {
|
|
514
|
+
await this._completePipelineOp(messageObj, conn);
|
|
515
|
+
if (!messageObj.pipelineResultImpl.error) {
|
|
516
|
+
messageObj.pipelineResultImpl.result = messageObj.resultTemp;
|
|
517
|
+
}
|
|
518
|
+
} catch (err) {
|
|
519
|
+
this._returnStatement(messageObj.statement);
|
|
520
|
+
if (!continueOnError) {
|
|
521
|
+
throw (err);
|
|
522
|
+
}
|
|
523
|
+
messageObj.pipelineResultImpl.error = err;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
// Returns whether the connection supports pipelining. Currently this is
|
|
529
|
+
// only supported with Oracle Database 23ai and later.
|
|
530
|
+
supportsPipelining() {
|
|
531
|
+
return this.nscon.pipeliningSupport;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
//---------------------------------------------------------------------------
|
|
535
|
+
// runPipelineWithPipelining()
|
|
536
|
+
//
|
|
537
|
+
// Run the pipeline with pipelining when the database supports it.
|
|
538
|
+
//---------------------------------------------------------------------------
|
|
539
|
+
async runPipelineWithPipelining(conn, resultsImpl, continueOnError) {
|
|
540
|
+
this.pipelineMode = continueOnError ?
|
|
541
|
+
constants.TNS_PIPELINE_MODE_CONTINUE_ON_ERROR :
|
|
542
|
+
constants.TNS_PIPELINE_MODE_ABORT_ON_ERROR;
|
|
543
|
+
this.nscon.pipelineEnabled = true;
|
|
544
|
+
|
|
545
|
+
// Create all pipeline messages
|
|
546
|
+
const messagesForPipeline = await this._createMessagesForPipeline(conn,
|
|
547
|
+
resultsImpl, continueOnError);
|
|
548
|
+
try {
|
|
549
|
+
this._protocol.readBuf.resetPackets();
|
|
550
|
+
|
|
551
|
+
// Encode all messages
|
|
552
|
+
await this._sendMessagesForPipeline(messagesForPipeline,
|
|
553
|
+
continueOnError);
|
|
554
|
+
|
|
555
|
+
// endPipeline message
|
|
556
|
+
const endMessage = new messages.EndPipelineMessage(this);
|
|
557
|
+
|
|
558
|
+
// Decode responses for all operation messages, then process the final
|
|
559
|
+
// end-pipeline response and cleanup any remaining response packets.
|
|
560
|
+
await this._protocol.endPipeline(messagesForPipeline,
|
|
561
|
+
endMessage, this, continueOnError);
|
|
562
|
+
|
|
563
|
+
// Complete post processing of results (and deferred operations in
|
|
564
|
+
// non-pipeline mode)
|
|
565
|
+
await this._completePipelineOps(messagesForPipeline, conn,
|
|
566
|
+
continueOnError);
|
|
567
|
+
|
|
568
|
+
return conn._buildPipelineResults(resultsImpl);
|
|
569
|
+
} finally {
|
|
570
|
+
this.pipelineMode = 0;
|
|
571
|
+
this.nscon.pipelineEnabled = false;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
//---------------------------------------------------------------------------
|
|
576
|
+
// runPipelineWithoutPipelining()
|
|
577
|
+
//
|
|
578
|
+
// Run the pipeline without pipelining when the database doesn't support
|
|
579
|
+
// pipelining. Call timeouts are disabled for consistency with when
|
|
580
|
+
// run with pipelining.
|
|
581
|
+
//---------------------------------------------------------------------------
|
|
582
|
+
async runPipelineWithoutPipelining(conn, resultsImpl, continueOnError) {
|
|
583
|
+
return await conn._runPipelineWithoutPipelining(resultsImpl,
|
|
584
|
+
continueOnError);
|
|
585
|
+
}
|
|
586
|
+
|
|
286
587
|
//---------------------------------------------------------------------------
|
|
287
588
|
// _parseTDSAttr()
|
|
288
589
|
//
|
|
@@ -781,6 +1082,42 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
781
1082
|
return (this._pool) ? true : false;
|
|
782
1083
|
}
|
|
783
1084
|
|
|
1085
|
+
_postConnect(authMessage) {
|
|
1086
|
+
let releaseNum;
|
|
1087
|
+
let updateNum;
|
|
1088
|
+
let portReleaseNum;
|
|
1089
|
+
let portUpdateNum;
|
|
1090
|
+
|
|
1091
|
+
this.dbDomain = authMessage.sessionData['AUTH_SC_DB_DOMAIN'];
|
|
1092
|
+
this.dbName = authMessage.sessionData['AUTH_SC_DBUNIQUE_NAME'];
|
|
1093
|
+
this.dbUniqueName = authMessage.sessionData['AUTH_SC_REAL_DBUNIQUE_NAME'];
|
|
1094
|
+
this.maxOpenCursors = Number(authMessage.sessionData['AUTH_MAX_OPEN_CURSORS'] || 0);
|
|
1095
|
+
this.serviceName = authMessage.sessionData['AUTH_SC_SERVICE_NAME'];
|
|
1096
|
+
this.instanceName = authMessage.sessionData['AUTH_INSTANCENAME'];
|
|
1097
|
+
this.maxIdentifierLength = Number(authMessage.sessionData['AUTH_MAX_IDEN_LENGTH'] || 30);
|
|
1098
|
+
const fullVersionNum = Number(authMessage.sessionData['AUTH_VERSION_NO']);
|
|
1099
|
+
const versionNum = (fullVersionNum >> 24) & 0xFF;
|
|
1100
|
+
this.warning = authMessage.warning;
|
|
1101
|
+
if (this._protocol.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_18_1_EXT_1) {
|
|
1102
|
+
releaseNum = (fullVersionNum >> 16) & 0xFF;
|
|
1103
|
+
updateNum = (fullVersionNum >> 12) & 0x0F;
|
|
1104
|
+
portReleaseNum = (fullVersionNum >> 4) & 0xFF;
|
|
1105
|
+
portUpdateNum = fullVersionNum & 0x0F;
|
|
1106
|
+
} else {
|
|
1107
|
+
releaseNum = (fullVersionNum >> 20) & 0x0F;
|
|
1108
|
+
updateNum = (fullVersionNum >> 12) & 0xFF;
|
|
1109
|
+
portReleaseNum = (fullVersionNum >> 8) & 0x0F;
|
|
1110
|
+
portUpdateNum = fullVersionNum & 0xFF;
|
|
1111
|
+
}
|
|
1112
|
+
this.serverVersionString = versionNum + '.' + releaseNum + '.' + updateNum + '.' + portReleaseNum + '.' + portUpdateNum;
|
|
1113
|
+
this.serverVersion = versionNum * 100000000 + releaseNum * 1000000 + updateNum * 10000 + portReleaseNum * 100 + portUpdateNum * 1;
|
|
1114
|
+
|
|
1115
|
+
// Set pdbName only from Oracle Database version 12.2 onwards.
|
|
1116
|
+
if (this.serverVersion >= 1202000000) {
|
|
1117
|
+
this.pdbName = authMessage.sessionData.AUTH_DBNAME;
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
|
|
784
1121
|
/**
|
|
785
1122
|
*
|
|
786
1123
|
* @param {object} params Configuration of the connection
|
|
@@ -822,51 +1159,52 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
822
1159
|
this.comboKey = null; // used in changePassword API
|
|
823
1160
|
this.tpcContext = null;
|
|
824
1161
|
this._sessionlessData = null;
|
|
1162
|
+
this._nameSpaceMap = new Map();
|
|
825
1163
|
|
|
826
1164
|
this.nscon = new nsi();
|
|
827
1165
|
finalizationRegistry.register(this, this.nscon);
|
|
828
1166
|
await this.nscon.connect(params);
|
|
829
1167
|
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
serverType = params._connInfo[0];
|
|
833
|
-
this.serviceName = params._connInfo[2];
|
|
834
|
-
this.purity = params._connInfo[3] | constants.PURITY_DEFAULT;
|
|
835
|
-
this.sid = params._connInfo[4];
|
|
836
|
-
} else {
|
|
837
|
-
serverType = this.nscon.getOption(sqlNetConstants.SERVERTYPE);
|
|
838
|
-
this.serviceName = this.nscon.getOption(sqlNetConstants.SVCNAME);
|
|
839
|
-
this.sid = this.nscon.getOption(sqlNetConstants.SID);
|
|
840
|
-
this.purity = this.nscon.getOption(sqlNetConstants.PURITY) | constants.PURITY_DEFAULT;
|
|
841
|
-
}
|
|
842
|
-
if (serverType) {
|
|
843
|
-
this._drcpEnabled = serverType.toLowerCase() === 'pooled';
|
|
844
|
-
}
|
|
845
|
-
this.remoteAddress = this.nscon.getOption(sqlNetConstants.REMOTEADDR);
|
|
846
|
-
this.connectionClass = params.connectionClass;
|
|
847
|
-
|
|
848
|
-
/*
|
|
849
|
-
* if drcp is used, use purity = NEW as the default purity for
|
|
850
|
-
* standalone connections and purity = SELF for connections that belong
|
|
851
|
-
* to a pool
|
|
852
|
-
*/
|
|
853
|
-
if (this.purity === constants.PURITY_DEFAULT && this._drcpEnabled) {
|
|
1168
|
+
try {
|
|
1169
|
+
let serverType;
|
|
854
1170
|
if (this.isPooled()) {
|
|
855
|
-
|
|
1171
|
+
serverType = params._connInfo[0];
|
|
1172
|
+
this.serviceName = params._connInfo[2];
|
|
1173
|
+
this.purity = params._connInfo[3] | constants.PURITY_DEFAULT;
|
|
1174
|
+
this.sid = params._connInfo[4];
|
|
856
1175
|
} else {
|
|
857
|
-
|
|
1176
|
+
serverType = this.nscon.getOption(sqlNetConstants.SERVERTYPE);
|
|
1177
|
+
this.serviceName = this.nscon.getOption(sqlNetConstants.SVCNAME);
|
|
1178
|
+
this.sid = this.nscon.getOption(sqlNetConstants.SID);
|
|
1179
|
+
this.purity = this.nscon.getOption(sqlNetConstants.PURITY) | constants.PURITY_DEFAULT;
|
|
1180
|
+
}
|
|
1181
|
+
if (serverType) {
|
|
1182
|
+
this._drcpEnabled = serverType.toLowerCase() === 'pooled';
|
|
1183
|
+
}
|
|
1184
|
+
this.remoteAddress = this.nscon.getOption(sqlNetConstants.REMOTEADDR);
|
|
1185
|
+
this.connectionClass = params.connectionClass;
|
|
1186
|
+
|
|
1187
|
+
/*
|
|
1188
|
+
* if drcp is used, use purity = NEW as the default purity for
|
|
1189
|
+
* standalone connections and purity = SELF for connections that belong
|
|
1190
|
+
* to a pool
|
|
1191
|
+
*/
|
|
1192
|
+
if (this.purity === constants.PURITY_DEFAULT && this._drcpEnabled) {
|
|
1193
|
+
if (this.isPooled()) {
|
|
1194
|
+
this.purity = constants.PURITY_SELF;
|
|
1195
|
+
} else {
|
|
1196
|
+
this.purity = constants.PURITY_NEW;
|
|
1197
|
+
}
|
|
858
1198
|
}
|
|
859
|
-
}
|
|
860
1199
|
|
|
861
|
-
|
|
1200
|
+
this._protocol = new Protocol(this);
|
|
862
1201
|
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
1202
|
+
// check if the protocol version supported by the database is high
|
|
1203
|
+
// enough; if not, reject the connection immediately
|
|
1204
|
+
if (this._protocol.caps.protocolVersion < constants.TNS_VERSION_MIN_ACCEPTED) {
|
|
1205
|
+
errors.throwErr(errors.ERR_SERVER_VERSION_NOT_SUPPORTED);
|
|
1206
|
+
}
|
|
868
1207
|
|
|
869
|
-
try {
|
|
870
1208
|
const protocolMessage = new messages.ProtocolMessage(this);
|
|
871
1209
|
const dataTypeMessage = new messages.DataTypeMessage(this);
|
|
872
1210
|
const authMessage = new messages.AuthMessage(this, params);
|
|
@@ -895,6 +1233,7 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
895
1233
|
if (!params.externalAuth) { // non-token Authentication
|
|
896
1234
|
await this._protocol._processMessage(authMessage); // OAUTH
|
|
897
1235
|
}
|
|
1236
|
+
this._postConnect(authMessage);
|
|
898
1237
|
} catch (err) {
|
|
899
1238
|
this.nscon.disconnect();
|
|
900
1239
|
throw err;
|
|
@@ -924,7 +1263,8 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
924
1263
|
// option is true
|
|
925
1264
|
//---------------------------------------------------------------------------
|
|
926
1265
|
_prepare(sql, options) {
|
|
927
|
-
const
|
|
1266
|
+
const forceNew = Boolean(options.fetchTypeMap);
|
|
1267
|
+
const statement = this._getStatement(sql, options.keepInStmtCache, forceNew);
|
|
928
1268
|
statement.bufferRowIndex = 0;
|
|
929
1269
|
statement.bufferRowCount = 0;
|
|
930
1270
|
statement.lastRowIndex = 0;
|
|
@@ -935,7 +1275,7 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
935
1275
|
//---------------------------------------------------------------------------
|
|
936
1276
|
// Binds the values by user to the statement object
|
|
937
1277
|
//---------------------------------------------------------------------------
|
|
938
|
-
async _bind(stmt, variable, pos = 0) {
|
|
1278
|
+
async _bind(stmt, variable, pos = 0, internalTempLobs = []) {
|
|
939
1279
|
const bindInfoDict = stmt.bindInfoDict;
|
|
940
1280
|
const bindInfoList = stmt.bindInfoList;
|
|
941
1281
|
|
|
@@ -946,6 +1286,8 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
946
1286
|
* the user expects to get it
|
|
947
1287
|
*/
|
|
948
1288
|
if (stmt.isPlSql && variable.maxSize > 32767) {
|
|
1289
|
+
if (this.pipelineMode)
|
|
1290
|
+
errors.throwErr(errors.ERR_PIPELINE_LARGE_BUFFERS_NOT_SUPPORTED);
|
|
949
1291
|
if (variable.type === types.DB_TYPE_RAW ||
|
|
950
1292
|
variable.type === types.DB_TYPE_LONG_RAW) {
|
|
951
1293
|
variable.type = types.DB_TYPE_BLOB;
|
|
@@ -977,6 +1319,7 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
977
1319
|
if (val && val.length > 0) {
|
|
978
1320
|
const lobImpl = new ThinLobImpl();
|
|
979
1321
|
await lobImpl.create(this, variable.type);
|
|
1322
|
+
internalTempLobs.push(lobImpl);
|
|
980
1323
|
await lobImpl.write(1, val);
|
|
981
1324
|
variable.values[index] = lobImpl;
|
|
982
1325
|
} else {
|
|
@@ -1064,6 +1407,15 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
1064
1407
|
}
|
|
1065
1408
|
}
|
|
1066
1409
|
|
|
1410
|
+
async _handleDefines(statement, message) {
|
|
1411
|
+
if (statement.requiresDefine && statement.sql) {
|
|
1412
|
+
statement.requiresFullExecute = true;
|
|
1413
|
+
await this._protocol._processMessage(message);
|
|
1414
|
+
statement.requiresDefine = false;
|
|
1415
|
+
statement.requiresFullExecute = false;
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1067
1419
|
//---------------------------------------------------------------------------
|
|
1068
1420
|
// execute()
|
|
1069
1421
|
//
|
|
@@ -1071,15 +1423,31 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
1071
1423
|
//---------------------------------------------------------------------------
|
|
1072
1424
|
async execute(sql, numIters, binds, options, executeManyFlag) {
|
|
1073
1425
|
const statement = this._prepare(sql, options);
|
|
1426
|
+
const internalTempLobs = [];
|
|
1074
1427
|
try {
|
|
1075
1428
|
return await this._execute(statement, numIters, binds, options,
|
|
1076
|
-
executeManyFlag);
|
|
1429
|
+
executeManyFlag, internalTempLobs);
|
|
1077
1430
|
} catch (err) {
|
|
1078
1431
|
this._returnStatement(statement);
|
|
1079
1432
|
throw err;
|
|
1433
|
+
} finally {
|
|
1434
|
+
// Add to freelist which will be sent in piggyback fashion
|
|
1435
|
+
for (const lob of internalTempLobs) {
|
|
1436
|
+
this._tempLobsToClose.push(lob._locator);
|
|
1437
|
+
this._tempLobsTotalSize += lob._locator.length;
|
|
1438
|
+
}
|
|
1080
1439
|
}
|
|
1081
1440
|
}
|
|
1082
1441
|
|
|
1442
|
+
async _prepareForExecute(sql, numIters, binds, options, executeManyFlag) {
|
|
1443
|
+
const statement = this._prepare(sql, options);
|
|
1444
|
+
const internalTempLobs = [];
|
|
1445
|
+
const message = await this._getExecuteMessage(statement, numIters, binds,
|
|
1446
|
+
options, executeManyFlag, internalTempLobs);
|
|
1447
|
+
return {statement, numIters, options, executeManyFlag, internalTempLobs,
|
|
1448
|
+
message};
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1083
1451
|
//---------------------------------------------------------------------------
|
|
1084
1452
|
// Get the statement object from the statement cache for the SQL if it exists
|
|
1085
1453
|
// else prepare a new statement object for the SQL. If a statement is already
|
|
@@ -1089,9 +1457,9 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
1089
1457
|
// cache) since it is unknown at this point whether the original session or a
|
|
1090
1458
|
// new session is going to be used.
|
|
1091
1459
|
//---------------------------------------------------------------------------
|
|
1092
|
-
_getStatement(sql, cacheStatement = false) {
|
|
1460
|
+
_getStatement(sql, cacheStatement = false, forceNew = false) {
|
|
1093
1461
|
return this.statementCache.getStatement(sql, cacheStatement,
|
|
1094
|
-
this._drcpEstablishSession);
|
|
1462
|
+
forceNew || this._drcpEstablishSession);
|
|
1095
1463
|
}
|
|
1096
1464
|
|
|
1097
1465
|
//---------------------------------------------------------------------------
|
|
@@ -1415,6 +1783,20 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
1415
1783
|
return this.dbName;
|
|
1416
1784
|
}
|
|
1417
1785
|
|
|
1786
|
+
//---------------------------------------------------------------------------
|
|
1787
|
+
// Returns the name of a container associated with the connection.
|
|
1788
|
+
//---------------------------------------------------------------------------
|
|
1789
|
+
getPdbName() {
|
|
1790
|
+
return this.pdbName;
|
|
1791
|
+
}
|
|
1792
|
+
|
|
1793
|
+
//---------------------------------------------------------------------------
|
|
1794
|
+
// Returns the Oracle Database unique name associated with the connection.
|
|
1795
|
+
//---------------------------------------------------------------------------
|
|
1796
|
+
getDbUniqueName() {
|
|
1797
|
+
return this.dbUniqueName;
|
|
1798
|
+
}
|
|
1799
|
+
|
|
1418
1800
|
//---------------------------------------------------------------------------
|
|
1419
1801
|
// Returns maximum number of cursors that can be opened in one session.
|
|
1420
1802
|
//---------------------------------------------------------------------------
|
|
@@ -1450,5 +1832,87 @@ class ThinConnectionImpl extends ConnectionImpl {
|
|
|
1450
1832
|
getWarning() {
|
|
1451
1833
|
return this.warning;
|
|
1452
1834
|
}
|
|
1835
|
+
|
|
1836
|
+
//---------------------------------------------------------------------------
|
|
1837
|
+
// getQueue()
|
|
1838
|
+
//
|
|
1839
|
+
// Returns a queue for use with advanced queuing.
|
|
1840
|
+
//---------------------------------------------------------------------------
|
|
1841
|
+
getQueue(name, payloadTypeClass, payloadType) {
|
|
1842
|
+
return new ThinQueueImpl(this, name, payloadTypeClass, payloadType);
|
|
1843
|
+
}
|
|
1844
|
+
|
|
1845
|
+
// Queue key/value pairs to be sent to the server.
|
|
1846
|
+
// If the namespace already has pending entries, merge and replace by key.
|
|
1847
|
+
appContext(namespaceName, keyValues) {
|
|
1848
|
+
const existingNamespace = this._nameSpaceMap.get(namespaceName);
|
|
1849
|
+
|
|
1850
|
+
// If namespace doesn't exist or was cleared, just initialize it
|
|
1851
|
+
if (!existingNamespace || existingNamespace.pendingClear) {
|
|
1852
|
+
const ns = existingNamespace || ThinConnectionImpl._createNamespace(namespaceName);
|
|
1853
|
+
ns.pendingClear = false;
|
|
1854
|
+
ns.keyValues = keyValues;
|
|
1855
|
+
this._nameSpaceMap.set(namespaceName, ns);
|
|
1856
|
+
return;
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1859
|
+
ThinConnectionImpl._mergeKeyValues(existingNamespace, keyValues);
|
|
1860
|
+
}
|
|
1861
|
+
|
|
1862
|
+
// This will clear all context on the server.
|
|
1863
|
+
// If the nameSpaceName exists , it updates else creates a new entry with clear flag set.
|
|
1864
|
+
clearAppContext(namespaceName) {
|
|
1865
|
+
const ns = ThinConnectionImpl._createNamespace(namespaceName);
|
|
1866
|
+
ns.pendingClear = true;
|
|
1867
|
+
this._nameSpaceMap.set(namespaceName, ns);
|
|
1868
|
+
}
|
|
1869
|
+
|
|
1870
|
+
//---------------------------------------------------------------------------
|
|
1871
|
+
// directPathLoad()
|
|
1872
|
+
// Implements direct path loading into a table.
|
|
1873
|
+
//---------------------------------------------------------------------------
|
|
1874
|
+
async directPathLoad(schemaName, tableName, columnNames, data) {
|
|
1875
|
+
const prepareMessage = new messages.DirectPathPrepareMessage(this);
|
|
1876
|
+
prepareMessage.schemaName = schemaName;
|
|
1877
|
+
prepareMessage.tableName = tableName;
|
|
1878
|
+
prepareMessage.columnNames = columnNames;
|
|
1879
|
+
await this._protocol._processMessage(prepareMessage);
|
|
1880
|
+
|
|
1881
|
+
const opMessage = new messages.DirectPathOpMessage(this);
|
|
1882
|
+
opMessage.prepare(prepareMessage.cursorId, constants.TNS_DP_OP_ABORT);
|
|
1883
|
+
|
|
1884
|
+
try {
|
|
1885
|
+
const loadMessage = new messages.DirectPathLoadStreamMessage(this);
|
|
1886
|
+
loadMessage.prepare(prepareMessage.cursorId, data, prepareMessage.columnMetadata);
|
|
1887
|
+
await this._protocol._processMessage(loadMessage);
|
|
1888
|
+
opMessage.opCode = constants.TNS_DP_OP_FINISH;
|
|
1889
|
+
} finally {
|
|
1890
|
+
await this._protocol._processMessage(opMessage);
|
|
1891
|
+
}
|
|
1892
|
+
}
|
|
1893
|
+
|
|
1894
|
+
//---------------------------------------------------------------------------
|
|
1895
|
+
// setEndUserSecurityContext()
|
|
1896
|
+
//
|
|
1897
|
+
// Set the End Security Context.
|
|
1898
|
+
//---------------------------------------------------------------------------
|
|
1899
|
+
setEndUserSecurityContext(context) {
|
|
1900
|
+
if (!this._protocol.caps.supportsEndUserSecurityContext) {
|
|
1901
|
+
errors.throwErr(errors.ERR_UNSUPPORTED_DEEP_DATA_SECURITY_FEATURE);
|
|
1902
|
+
}
|
|
1903
|
+
|
|
1904
|
+
if (this.securityContext && this.securityContext !== context) {
|
|
1905
|
+
this.securityContext.clearEncodedPayload();
|
|
1906
|
+
}
|
|
1907
|
+
this.securityContext = context;
|
|
1908
|
+
}
|
|
1909
|
+
|
|
1910
|
+
clearEndUserSecurityContext() {
|
|
1911
|
+
if (this.securityContext) {
|
|
1912
|
+
this.securityContext.clearEncodedPayload();
|
|
1913
|
+
}
|
|
1914
|
+
this.securityContext = null;
|
|
1915
|
+
}
|
|
1916
|
+
|
|
1453
1917
|
}
|
|
1454
1918
|
module.exports = ThinConnectionImpl;
|