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
package/lib/thin/pool.js
CHANGED
|
@@ -36,6 +36,7 @@ const thinUtil = require('./util.js');
|
|
|
36
36
|
const {getConnectionInfo} = require('./sqlnet/networkSession.js');
|
|
37
37
|
const crypto = require('crypto');
|
|
38
38
|
const EventEmitter = require('events');
|
|
39
|
+
const Timers = require('timers');
|
|
39
40
|
|
|
40
41
|
class ThinPoolImpl extends PoolImpl {
|
|
41
42
|
|
|
@@ -69,30 +70,33 @@ class ThinPoolImpl extends PoolImpl {
|
|
|
69
70
|
this._privateKey = params.privateKey;
|
|
70
71
|
this._obfuscatedPrivateKey = [];
|
|
71
72
|
this._schedulerJob = null;
|
|
73
|
+
this._poolCloseWaiter = null;
|
|
74
|
+
this._pendingRequests = [];
|
|
75
|
+
|
|
72
76
|
// password obfuscation
|
|
73
77
|
if (this._password !== undefined) {
|
|
74
|
-
|
|
78
|
+
const obj = protocolUtil.setObfuscatedValue(this._password);
|
|
75
79
|
this._password = obj.value;
|
|
76
80
|
this._obfuscatedPassword = obj.obfuscatedValue;
|
|
77
81
|
this._userConfig.password = null;
|
|
78
82
|
}
|
|
79
83
|
// wallet password obfuscation
|
|
80
84
|
if (this._walletPassword !== undefined) {
|
|
81
|
-
|
|
85
|
+
const obj = protocolUtil.setObfuscatedValue(this._walletPassword);
|
|
82
86
|
this._walletPassword = obj.value;
|
|
83
87
|
this._obfuscatedWalletPassword = obj.obfuscatedValue;
|
|
84
88
|
this._userConfig.walletPassword = null;
|
|
85
89
|
}
|
|
86
90
|
// token obfuscation
|
|
87
91
|
if (this._token !== undefined) {
|
|
88
|
-
|
|
92
|
+
const obj = protocolUtil.setObfuscatedValue(this._token);
|
|
89
93
|
this._token = obj.value;
|
|
90
94
|
this._obfuscatedToken = obj.obfuscatedValue;
|
|
91
95
|
this._userConfig.token = null;
|
|
92
96
|
}
|
|
93
97
|
// privateKey obfuscation
|
|
94
98
|
if (this._privateKey !== undefined) {
|
|
95
|
-
|
|
99
|
+
const obj = protocolUtil.setObfuscatedValue(this._privateKey);
|
|
96
100
|
this._privateKey = obj.value;
|
|
97
101
|
this._obfuscatedPrivateKey = obj.obfuscatedValue;
|
|
98
102
|
this._userConfig.privateKey = null;
|
|
@@ -121,8 +125,9 @@ class ThinPoolImpl extends PoolImpl {
|
|
|
121
125
|
this._generateConnectionClass();
|
|
122
126
|
}
|
|
123
127
|
|
|
124
|
-
// create minimum connections
|
|
125
|
-
|
|
128
|
+
// create a background task. It will create minimum connections in the pool
|
|
129
|
+
// and expand the pool as required.
|
|
130
|
+
this.bgThreadFunc();
|
|
126
131
|
}
|
|
127
132
|
|
|
128
133
|
//---------------------------------------------------------------------------
|
|
@@ -131,13 +136,13 @@ class ThinPoolImpl extends PoolImpl {
|
|
|
131
136
|
setAccessToken(params) {
|
|
132
137
|
if (params.token) {
|
|
133
138
|
this._token = params.token;
|
|
134
|
-
|
|
139
|
+
const objToken = protocolUtil.setObfuscatedValue(this._token);
|
|
135
140
|
this._token = objToken.value;
|
|
136
141
|
this._obfuscatedToken = objToken.obfuscatedValue;
|
|
137
142
|
}
|
|
138
143
|
if (params.privateKey) {
|
|
139
144
|
this._privateKey = params.privateKey;
|
|
140
|
-
|
|
145
|
+
const objKey = protocolUtil.setObfuscatedValue(this._privateKey);
|
|
141
146
|
this._privateKey = objKey.value;
|
|
142
147
|
this._obfuscatedPrivateKey = objKey.obfuscatedValue;
|
|
143
148
|
}
|
|
@@ -151,15 +156,21 @@ class ThinPoolImpl extends PoolImpl {
|
|
|
151
156
|
async _getConnAttrs() {
|
|
152
157
|
let accessToken;
|
|
153
158
|
const clonedAttrs = Object.assign({}, this._userConfig);
|
|
159
|
+
// deobfuscate password
|
|
154
160
|
if (clonedAttrs.password === null) {
|
|
155
161
|
clonedAttrs.password = protocolUtil.getDeobfuscatedValue(this._password,
|
|
156
162
|
this._obfuscatedPassword);
|
|
157
163
|
}
|
|
164
|
+
|
|
165
|
+
// deobfuscate wallet password
|
|
158
166
|
if (clonedAttrs.walletPassword === null) {
|
|
159
167
|
clonedAttrs.walletPassword =
|
|
160
168
|
protocolUtil.getDeobfuscatedValue(this._walletPassword,
|
|
161
169
|
this._obfuscatedWalletPassword);
|
|
162
170
|
}
|
|
171
|
+
|
|
172
|
+
// deobfuscate token and private key
|
|
173
|
+
// check for token expiry
|
|
163
174
|
if (clonedAttrs.token === null) {
|
|
164
175
|
clonedAttrs.token =
|
|
165
176
|
protocolUtil.getDeobfuscatedValue(this._token, this._obfuscatedToken);
|
|
@@ -173,7 +184,7 @@ class ThinPoolImpl extends PoolImpl {
|
|
|
173
184
|
errors.throwErr(errors.ERR_TOKEN_HAS_EXPIRED);
|
|
174
185
|
} else {
|
|
175
186
|
// update pool with OAuth2 token
|
|
176
|
-
|
|
187
|
+
const obj = protocolUtil.setObfuscatedValue(clonedAttrs.token);
|
|
177
188
|
this._token = obj.value;
|
|
178
189
|
this._obfuscatedToken = obj.obfuscatedValue;
|
|
179
190
|
}
|
|
@@ -185,11 +196,11 @@ class ThinPoolImpl extends PoolImpl {
|
|
|
185
196
|
errors.throwErr(errors.ERR_TOKEN_HAS_EXPIRED);
|
|
186
197
|
} else {
|
|
187
198
|
// update pool with IAM token and private key
|
|
188
|
-
|
|
199
|
+
const objToken = protocolUtil.setObfuscatedValue(clonedAttrs.token);
|
|
189
200
|
this._token = objToken.value;
|
|
190
201
|
this._obfuscatedToken = objToken.obfuscatedValue;
|
|
191
202
|
|
|
192
|
-
|
|
203
|
+
const objKey = protocolUtil.setObfuscatedValue(clonedAttrs.privateKey);
|
|
193
204
|
this._privateKey = objKey.value;
|
|
194
205
|
this._obfuscatedPrivateKey = objKey.obfuscatedValue;
|
|
195
206
|
}
|
|
@@ -228,13 +239,34 @@ class ThinPoolImpl extends PoolImpl {
|
|
|
228
239
|
//---------------------------------------------------------------------------
|
|
229
240
|
// close pool by destroying available connections
|
|
230
241
|
//---------------------------------------------------------------------------
|
|
231
|
-
async close(
|
|
242
|
+
async close() {
|
|
243
|
+
|
|
244
|
+
// wait till background task for pool expansion is finished; if it is not
|
|
245
|
+
// currently running, wake it up!
|
|
246
|
+
await new Promise((resolve) => {
|
|
247
|
+
this._poolCloseWaiter = resolve;
|
|
248
|
+
if (this.bgWaiter) {
|
|
249
|
+
this.bgWaiter();
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
|
|
232
253
|
// clear scheduled job
|
|
233
254
|
if (this._schedulerJob) {
|
|
234
255
|
clearTimeout(this._schedulerJob);
|
|
235
256
|
this._schedulerJob = null;
|
|
236
257
|
}
|
|
237
|
-
|
|
258
|
+
|
|
259
|
+
// destroy all free connections
|
|
260
|
+
for (const conn of this._freeConnectionList) {
|
|
261
|
+
await this._destroy(conn);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// destroy all used connections
|
|
265
|
+
for (const conn of this._usedConnectionList) {
|
|
266
|
+
await this._destroy(conn);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
this.eventEmitter.removeAllListeners();
|
|
238
270
|
}
|
|
239
271
|
|
|
240
272
|
//---------------------------------------------------------------------------
|
|
@@ -307,25 +339,6 @@ class ThinPoolImpl extends PoolImpl {
|
|
|
307
339
|
return this._stmtCacheSize;
|
|
308
340
|
}
|
|
309
341
|
|
|
310
|
-
//---------------------------------------------------------------------------
|
|
311
|
-
// _growPool()
|
|
312
|
-
//
|
|
313
|
-
// Grows the pool to include the specified number of connections.
|
|
314
|
-
//---------------------------------------------------------------------------
|
|
315
|
-
async _growPool(numConns) {
|
|
316
|
-
const clonedAttrs = await this._getConnAttrs();
|
|
317
|
-
while (numConns > 0) {
|
|
318
|
-
const conn = new ThinConnectionImpl();
|
|
319
|
-
conn._pool = this;
|
|
320
|
-
await conn.connect(clonedAttrs);
|
|
321
|
-
conn._newSession = true;
|
|
322
|
-
conn._dropSess = false;
|
|
323
|
-
conn._lastTimeUsed = Date.now();
|
|
324
|
-
this._freeConnectionList.push(conn);
|
|
325
|
-
numConns--;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
342
|
//---------------------------------------------------------------------------
|
|
330
343
|
// _setScheduler()
|
|
331
344
|
//
|
|
@@ -363,6 +376,94 @@ class ThinPoolImpl extends PoolImpl {
|
|
|
363
376
|
this._setScheduler();
|
|
364
377
|
}
|
|
365
378
|
|
|
379
|
+
//---------------------------------------------------------------------------
|
|
380
|
+
// _getNumConns()
|
|
381
|
+
//
|
|
382
|
+
// get number of connections need to be created
|
|
383
|
+
//---------------------------------------------------------------------------
|
|
384
|
+
_getNumConns() {
|
|
385
|
+
const usedConns = this._freeConnectionList.length + this._usedConnectionList.size;
|
|
386
|
+
// less connections in the pool than poolMin? restore to poolMin
|
|
387
|
+
if (usedConns < this._poolMin) {
|
|
388
|
+
return this._poolMin - usedConns;
|
|
389
|
+
// connections need to be created? create up to poolIncrement without exceeding poolMax
|
|
390
|
+
} else if (this._pendingRequests.length > 0) {
|
|
391
|
+
return Math.min(this._poolIncrement, this._poolMax - usedConns);
|
|
392
|
+
// no pending requests and we are already at poolMin so nothing to do!
|
|
393
|
+
} else {
|
|
394
|
+
return 0;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
//---------------------------------------------------------------------------
|
|
399
|
+
// bgThreadFunc()
|
|
400
|
+
//
|
|
401
|
+
// method which runs in a background thread and is used to create connections.
|
|
402
|
+
// When first started, it creates poolMin connections. After that, it creates
|
|
403
|
+
// poolIncrement connections up to the value of poolMax when needed.
|
|
404
|
+
// The thread terminates automatically when the pool is closed.
|
|
405
|
+
//---------------------------------------------------------------------------
|
|
406
|
+
async bgThreadFunc() {
|
|
407
|
+
|
|
408
|
+
// continue until a close request is received
|
|
409
|
+
while (!this._poolCloseWaiter) {
|
|
410
|
+
// get count for connections to be created
|
|
411
|
+
const numConns = this._getNumConns();
|
|
412
|
+
|
|
413
|
+
// connection creation is going on serially and not concurrently
|
|
414
|
+
for (let i = 0; i < numConns; i++) {
|
|
415
|
+
try {
|
|
416
|
+
// get deobfuscated value
|
|
417
|
+
const config = await this._getConnAttrs();
|
|
418
|
+
const conn = new ThinConnectionImpl();
|
|
419
|
+
conn._pool = this;
|
|
420
|
+
await conn.connect(config);
|
|
421
|
+
conn._newSession = true;
|
|
422
|
+
conn._dropSess = false;
|
|
423
|
+
conn._lastTimeUsed = Date.now();
|
|
424
|
+
this._freeConnectionList.push(conn);
|
|
425
|
+
} catch (err) {
|
|
426
|
+
this._bgErr = err;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
if (this._poolIncrement > 1 && (this._poolMax - this._usedConnectionList.size
|
|
430
|
+
- this._freeConnectionList.length) > 1) {
|
|
431
|
+
this._setScheduler();
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// resolve pending request
|
|
435
|
+
if (this._pendingRequests.length > 0) {
|
|
436
|
+
const payload = this._pendingRequests.shift();
|
|
437
|
+
payload.resolve();
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// give an opportunity for other "threads" to do their work.
|
|
441
|
+
await new Promise((resolve) => Timers.setImmediate(resolve));
|
|
442
|
+
|
|
443
|
+
// break loop when pool is closing
|
|
444
|
+
if (this._poolCloseWaiter) {
|
|
445
|
+
break;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// when pool is closing, break from while loop
|
|
450
|
+
if (this._poolCloseWaiter) {
|
|
451
|
+
break;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// if no pending requests, wait for pending requests to appear!
|
|
455
|
+
if (this._pendingRequests.length == 0 || this._bgErr) {
|
|
456
|
+
await new Promise((resolve) => {
|
|
457
|
+
this.bgWaiter = resolve;
|
|
458
|
+
});
|
|
459
|
+
this.bgWaiter = null;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// notify the closer that the close can actually take place
|
|
464
|
+
this._poolCloseWaiter();
|
|
465
|
+
}
|
|
466
|
+
|
|
366
467
|
//---------------------------------------------------------------------------
|
|
367
468
|
// acquire()
|
|
368
469
|
//
|
|
@@ -410,17 +511,28 @@ class ThinPoolImpl extends PoolImpl {
|
|
|
410
511
|
|
|
411
512
|
// no free connections exist at this point; if less than poolMin
|
|
412
513
|
// connections exist, grow the pool to poolMin again; otherwise, increase
|
|
413
|
-
// the pool by poolIncrement up to poolMax
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
this._setScheduler();
|
|
514
|
+
// the pool by poolIncrement up to poolMax. We are deferring this
|
|
515
|
+
// to the background thread function!
|
|
516
|
+
await new Promise((resolve) => {
|
|
517
|
+
this._pendingRequests.push({resolve: resolve});
|
|
518
|
+
if (this.bgWaiter) {
|
|
519
|
+
// this wakes up the function to do some more work
|
|
520
|
+
this.bgWaiter();
|
|
421
521
|
}
|
|
422
|
-
}
|
|
522
|
+
});
|
|
523
|
+
|
|
524
|
+
if (this._bgErr) {
|
|
525
|
+
const err = this._bgErr;
|
|
526
|
+
this._bgErr = null;
|
|
423
527
|
|
|
528
|
+
// if an error has occurred in the background thread we clear it and then,
|
|
529
|
+
// if there are more pending requests we request the background thread
|
|
530
|
+
// function to try again.
|
|
531
|
+
if (this._pendingRequests.length > 0 && this.bgWaiter) {
|
|
532
|
+
this.bgWaiter();
|
|
533
|
+
}
|
|
534
|
+
throw err;
|
|
535
|
+
}
|
|
424
536
|
// return a connection from the ones that were just built
|
|
425
537
|
const conn = this._freeConnectionList.pop();
|
|
426
538
|
this._usedConnectionList.add(conn);
|
|
@@ -438,33 +550,6 @@ class ThinPoolImpl extends PoolImpl {
|
|
|
438
550
|
this._setScheduler();
|
|
439
551
|
}
|
|
440
552
|
|
|
441
|
-
//---------------------------------------------------------------------------
|
|
442
|
-
// destroyAllNow()
|
|
443
|
-
//
|
|
444
|
-
// called during pool close operation and close any available connection
|
|
445
|
-
// available in connection pool
|
|
446
|
-
//---------------------------------------------------------------------------
|
|
447
|
-
async destroyAllNow(obj) {
|
|
448
|
-
let conn;
|
|
449
|
-
while (this._freeConnectionList.length !== 0) {
|
|
450
|
-
conn = this._freeConnectionList.pop();
|
|
451
|
-
await this._destroy(conn);
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
if (obj.forceClose) {
|
|
455
|
-
for (const item of this._usedConnectionList) {
|
|
456
|
-
await this._destroy(item);
|
|
457
|
-
this._usedConnectionList.delete(item);
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
if (this._usedConnectionList.size !== 0) {
|
|
462
|
-
errors.throwErr(errors.ERR_POOL_HAS_BUSY_CONNECTIONS);
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
this.eventEmitter.removeAllListeners();
|
|
466
|
-
}
|
|
467
|
-
|
|
468
553
|
//---------------------------------------------------------------------------
|
|
469
554
|
// _generateConnectionClass()
|
|
470
555
|
//
|
|
@@ -49,7 +49,7 @@ class BaseBuffer {
|
|
|
49
49
|
this.buf = Buffer.alloc(initializer);
|
|
50
50
|
this.size = 0;
|
|
51
51
|
this.maxSize = initializer;
|
|
52
|
-
} else {
|
|
52
|
+
} else if (initializer) {
|
|
53
53
|
this.buf = initializer;
|
|
54
54
|
this.size = this.maxSize = initializer.length;
|
|
55
55
|
}
|
|
@@ -548,11 +548,12 @@ class BaseBuffer {
|
|
|
548
548
|
// remain in the buffer, the buffer is grown.
|
|
549
549
|
//---------------------------------------------------------------------------
|
|
550
550
|
reserveBytes(numBytes) {
|
|
551
|
-
if (numBytes > this.numBytesLeft())
|
|
551
|
+
if (numBytes > this.numBytesLeft()) {
|
|
552
552
|
this._grow(this.pos + numBytes);
|
|
553
|
-
|
|
553
|
+
}
|
|
554
|
+
const pos = this.pos;
|
|
554
555
|
this.pos += numBytes;
|
|
555
|
-
return
|
|
556
|
+
return pos;
|
|
556
557
|
}
|
|
557
558
|
|
|
558
559
|
//---------------------------------------------------------------------------
|
|
@@ -618,20 +619,20 @@ class BaseBuffer {
|
|
|
618
619
|
//---------------------------------------------------------------------------
|
|
619
620
|
writeBinaryDouble(n) {
|
|
620
621
|
this.writeUInt8(8);
|
|
621
|
-
const
|
|
622
|
-
buf.writeDoubleBE(n);
|
|
623
|
-
if ((buf[
|
|
624
|
-
buf[
|
|
622
|
+
const pos = this.reserveBytes(8);
|
|
623
|
+
this.buf.writeDoubleBE(n, pos);
|
|
624
|
+
if ((this.buf[pos] & 0x80) === 0) {
|
|
625
|
+
this.buf[pos] |= 0x80;
|
|
625
626
|
} else {
|
|
626
627
|
// We complement the bits for a negative number
|
|
627
|
-
buf[
|
|
628
|
-
buf[1] ^= 0xff;
|
|
629
|
-
buf[2] ^= 0xff;
|
|
630
|
-
buf[3] ^= 0xff;
|
|
631
|
-
buf[4] ^= 0xff;
|
|
632
|
-
buf[5] ^= 0xff;
|
|
633
|
-
buf[6] ^= 0xff;
|
|
634
|
-
buf[7] ^= 0xff;
|
|
628
|
+
this.buf[pos] ^= 0xff;
|
|
629
|
+
this.buf[pos + 1] ^= 0xff;
|
|
630
|
+
this.buf[pos + 2] ^= 0xff;
|
|
631
|
+
this.buf[pos + 3] ^= 0xff;
|
|
632
|
+
this.buf[pos + 4] ^= 0xff;
|
|
633
|
+
this.buf[pos + 5] ^= 0xff;
|
|
634
|
+
this.buf[pos + 6] ^= 0xff;
|
|
635
|
+
this.buf[pos + 7] ^= 0xff;
|
|
635
636
|
}
|
|
636
637
|
}
|
|
637
638
|
|
|
@@ -642,16 +643,16 @@ class BaseBuffer {
|
|
|
642
643
|
//---------------------------------------------------------------------------
|
|
643
644
|
writeBinaryFloat(n) {
|
|
644
645
|
this.writeUInt8(4);
|
|
645
|
-
const
|
|
646
|
-
buf.writeFloatBE(n);
|
|
647
|
-
if ((buf[
|
|
648
|
-
buf[
|
|
646
|
+
const pos = this.reserveBytes(4);
|
|
647
|
+
this.buf.writeFloatBE(n, pos);
|
|
648
|
+
if ((this.buf[pos] & 0x80) === 0) {
|
|
649
|
+
this.buf[pos] |= 0x80;
|
|
649
650
|
} else {
|
|
650
651
|
// We complement the bits for a negative number
|
|
651
|
-
buf[
|
|
652
|
-
buf[1] ^= 0xff;
|
|
653
|
-
buf[2] ^= 0xff;
|
|
654
|
-
buf[3] ^= 0xff;
|
|
652
|
+
this.buf[pos] ^= 0xff;
|
|
653
|
+
this.buf[pos + 1] ^= 0xff;
|
|
654
|
+
this.buf[pos + 2] ^= 0xff;
|
|
655
|
+
this.buf[pos + 3] ^= 0xff;
|
|
655
656
|
}
|
|
656
657
|
}
|
|
657
658
|
|
|
@@ -745,31 +746,31 @@ class BaseBuffer {
|
|
|
745
746
|
if (writeLength) {
|
|
746
747
|
this.writeUInt8(length);
|
|
747
748
|
}
|
|
748
|
-
const
|
|
749
|
+
const pos = this.reserveBytes(length);
|
|
749
750
|
if (type === types.DB_TYPE_DATE || type == types.DB_TYPE_TIMESTAMP) {
|
|
750
751
|
const year = date.getFullYear();
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
752
|
+
this.buf[pos] = Math.trunc(year / 100) + 100;
|
|
753
|
+
this.buf[pos + 1] = year % 100 + 100;
|
|
754
|
+
this.buf[pos + 2] = date.getMonth() + 1;
|
|
755
|
+
this.buf[pos + 3] = date.getDate();
|
|
756
|
+
this.buf[pos + 4] = date.getHours() + 1;
|
|
757
|
+
this.buf[pos + 5] = date.getMinutes() + 1;
|
|
758
|
+
this.buf[pos + 6] = date.getSeconds() + 1;
|
|
758
759
|
} else {
|
|
759
760
|
const year = date.getUTCFullYear();
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
761
|
+
this.buf[pos] = Math.trunc(year / 100) + 100;
|
|
762
|
+
this.buf[pos + 1] = year % 100 + 100;
|
|
763
|
+
this.buf[pos + 2] = date.getUTCMonth() + 1;
|
|
764
|
+
this.buf[pos + 3] = date.getUTCDate();
|
|
765
|
+
this.buf[pos + 4] = date.getUTCHours() + 1;
|
|
766
|
+
this.buf[pos + 5] = date.getUTCMinutes() + 1;
|
|
767
|
+
this.buf[pos + 6] = date.getUTCSeconds() + 1;
|
|
767
768
|
}
|
|
768
769
|
if (length > 7) {
|
|
769
|
-
|
|
770
|
+
this.buf.writeInt32BE(fsec, pos + 7);
|
|
770
771
|
if (length > 11) {
|
|
771
|
-
|
|
772
|
-
|
|
772
|
+
this.buf[pos + 11] = constants.TZ_HOUR_OFFSET;
|
|
773
|
+
this.buf[pos + 12] = constants.TZ_MINUTE_OFFSET;
|
|
773
774
|
}
|
|
774
775
|
}
|
|
775
776
|
}
|
|
@@ -843,19 +844,19 @@ class BaseBuffer {
|
|
|
843
844
|
} else if (value.length === 0 && exponent === 0) {
|
|
844
845
|
exponentOnWire = 128;
|
|
845
846
|
}
|
|
846
|
-
|
|
847
|
-
buf[
|
|
848
|
-
buf[
|
|
849
|
-
for (let i = 0
|
|
850
|
-
|
|
847
|
+
let pos = this.reserveBytes(numPairs + 2 + appendSentinel);
|
|
848
|
+
this.buf[pos++] = numPairs + 1 + appendSentinel;
|
|
849
|
+
this.buf[pos++] = exponentOnWire;
|
|
850
|
+
for (let i = 0; i < value.length; i += 2) {
|
|
851
|
+
const base100Digit = Number(value.substring(i, i + 2));
|
|
851
852
|
if (isNegative) {
|
|
852
|
-
buf[pos] = 101 - base100Digit;
|
|
853
|
+
this.buf[pos++] = 101 - base100Digit;
|
|
853
854
|
} else {
|
|
854
|
-
buf[pos] = base100Digit + 1;
|
|
855
|
+
this.buf[pos++] = base100Digit + 1;
|
|
855
856
|
}
|
|
856
857
|
}
|
|
857
858
|
if (appendSentinel) {
|
|
858
|
-
buf[
|
|
859
|
+
this.buf[pos] = 102;
|
|
859
860
|
}
|
|
860
861
|
|
|
861
862
|
}
|
|
@@ -898,8 +899,8 @@ class BaseBuffer {
|
|
|
898
899
|
// Writes a signed 32-bit integer to the buffer in big endian order.
|
|
899
900
|
//---------------------------------------------------------------------------
|
|
900
901
|
writeInt32BE(n) {
|
|
901
|
-
const
|
|
902
|
-
buf.writeInt32BE(n);
|
|
902
|
+
const pos = this.reserveBytes(4);
|
|
903
|
+
this.buf.writeInt32BE(n, pos);
|
|
903
904
|
}
|
|
904
905
|
|
|
905
906
|
//---------------------------------------------------------------------------
|
|
@@ -923,6 +924,24 @@ class BaseBuffer {
|
|
|
923
924
|
}
|
|
924
925
|
}
|
|
925
926
|
|
|
927
|
+
//---------------------------------------------------------------------------
|
|
928
|
+
// writeUB2()
|
|
929
|
+
//
|
|
930
|
+
// Writes an unsigned integer (up to 2 bytes in length) in variable length
|
|
931
|
+
// format to the buffer.
|
|
932
|
+
//---------------------------------------------------------------------------
|
|
933
|
+
writeUB2(value) {
|
|
934
|
+
if (value === 0) {
|
|
935
|
+
this.writeUInt8(0);
|
|
936
|
+
} else if (value <= 0xff) {
|
|
937
|
+
this.writeUInt8(1);
|
|
938
|
+
this.writeUInt8(value);
|
|
939
|
+
} else {
|
|
940
|
+
this.writeUInt8(2);
|
|
941
|
+
this.writeUInt16BE(value);
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
|
|
926
945
|
//---------------------------------------------------------------------------
|
|
927
946
|
// writeUB8()
|
|
928
947
|
//
|
|
@@ -953,8 +972,8 @@ class BaseBuffer {
|
|
|
953
972
|
// Writes an unsigned 8-bit integer to the buffer.
|
|
954
973
|
//---------------------------------------------------------------------------
|
|
955
974
|
writeUInt8(n) {
|
|
956
|
-
const
|
|
957
|
-
buf[
|
|
975
|
+
const pos = this.reserveBytes(1);
|
|
976
|
+
this.buf[pos] = n;
|
|
958
977
|
}
|
|
959
978
|
|
|
960
979
|
//---------------------------------------------------------------------------
|
|
@@ -963,8 +982,8 @@ class BaseBuffer {
|
|
|
963
982
|
// Writes an unsigned 16-bit integer to the buffer in big endian order.
|
|
964
983
|
//---------------------------------------------------------------------------
|
|
965
984
|
writeUInt16BE(n) {
|
|
966
|
-
const
|
|
967
|
-
buf.writeUInt16BE(n);
|
|
985
|
+
const pos = this.reserveBytes(2);
|
|
986
|
+
this.buf.writeUInt16BE(n, pos);
|
|
968
987
|
}
|
|
969
988
|
|
|
970
989
|
//---------------------------------------------------------------------------
|
|
@@ -973,8 +992,8 @@ class BaseBuffer {
|
|
|
973
992
|
// Writes an unsigned 32-bit integer to the buffer in big endian order.
|
|
974
993
|
//---------------------------------------------------------------------------
|
|
975
994
|
writeUInt32BE(n) {
|
|
976
|
-
const
|
|
977
|
-
buf.writeUInt32BE(n);
|
|
995
|
+
const pos = this.reserveBytes(4);
|
|
996
|
+
this.buf.writeUInt32BE(n, pos);
|
|
978
997
|
}
|
|
979
998
|
|
|
980
999
|
//---------------------------------------------------------------------------
|
|
@@ -985,9 +1004,9 @@ class BaseBuffer {
|
|
|
985
1004
|
// higher order bits are simply written as 0.
|
|
986
1005
|
//---------------------------------------------------------------------------
|
|
987
1006
|
writeUInt64BE(n) {
|
|
988
|
-
const
|
|
989
|
-
buf.writeUInt32BE(0);
|
|
990
|
-
buf.writeUInt32BE(n, 4);
|
|
1007
|
+
const pos = this.reserveBytes(8);
|
|
1008
|
+
this.buf.writeUInt32BE(0, pos);
|
|
1009
|
+
this.buf.writeUInt32BE(n, pos + 4);
|
|
991
1010
|
}
|
|
992
1011
|
|
|
993
1012
|
//---------------------------------------------------------------------------
|
|
@@ -996,8 +1015,8 @@ class BaseBuffer {
|
|
|
996
1015
|
// Writes an unsigned 16-bit integer to the buffer in little endian order.
|
|
997
1016
|
//---------------------------------------------------------------------------
|
|
998
1017
|
writeUInt16LE(n) {
|
|
999
|
-
const
|
|
1000
|
-
buf.writeUInt16LE(n);
|
|
1018
|
+
const pos = this.reserveBytes(2);
|
|
1019
|
+
this.buf.writeUInt16LE(n, pos);
|
|
1001
1020
|
}
|
|
1002
1021
|
|
|
1003
1022
|
}
|
|
@@ -1030,7 +1049,7 @@ class GrowableBuffer extends BaseBuffer {
|
|
|
1030
1049
|
if (remainder > 0) {
|
|
1031
1050
|
numBytes += (constants.BUFFER_CHUNK_SIZE - remainder);
|
|
1032
1051
|
}
|
|
1033
|
-
const buf = Buffer.
|
|
1052
|
+
const buf = Buffer.allocUnsafe(numBytes);
|
|
1034
1053
|
this.buf.copy(buf);
|
|
1035
1054
|
this.buf = buf;
|
|
1036
1055
|
this.maxSize = this.size = numBytes;
|
|
@@ -89,10 +89,6 @@ module.exports = {
|
|
|
89
89
|
TNS_PACKET_TYPE_MARKER: 12,
|
|
90
90
|
TNS_PACKET_TYPE_CONTROL: 14,
|
|
91
91
|
|
|
92
|
-
// marker types
|
|
93
|
-
TNS_MARKER_TYPE_BREAK: 1,
|
|
94
|
-
TNS_MARKER_TYPE_RESET: 2,
|
|
95
|
-
|
|
96
92
|
// data types
|
|
97
93
|
TNS_DATA_TYPE_DEFAULT: 0,
|
|
98
94
|
TNS_DATA_TYPE_VARCHAR: 1,
|
|
@@ -429,8 +425,10 @@ module.exports = {
|
|
|
429
425
|
TNS_MSG_TYPE_FLUSH_OUT_BINDS: 19,
|
|
430
426
|
TNS_MSG_TYPE_BIT_VECTOR: 21,
|
|
431
427
|
TNS_MSG_TYPE_SERVER_SIDE_PIGGYBACK: 23,
|
|
432
|
-
TNS_MSG_TYPE_IMPLICIT_RESULTSET: 27,
|
|
433
428
|
TNS_MSG_TYPE_ONEWAY_FN: 26,
|
|
429
|
+
TNS_MSG_TYPE_IMPLICIT_RESULTSET: 27,
|
|
430
|
+
TNS_MSG_TYPE_RENEGOTIATE: 28,
|
|
431
|
+
TNS_MSG_TYPE_COOKIE: 30,
|
|
434
432
|
|
|
435
433
|
// parameter keyword numbers,
|
|
436
434
|
TNS_KEYWORD_NUM_CURRENT_SCHEMA: 168,
|
|
@@ -557,18 +555,9 @@ module.exports = {
|
|
|
557
555
|
TNS_END_TO_END_MODULE: 0x0008,
|
|
558
556
|
|
|
559
557
|
// versions
|
|
560
|
-
TNS_VERSION_DESIRED: 316,
|
|
561
|
-
TNS_VERSION_MINIMUM: 300,
|
|
562
558
|
TNS_VERSION_MIN_ACCEPTED: 315,
|
|
563
559
|
TNS_VERSION_MIN_LARGE_SDU: 315,
|
|
564
560
|
|
|
565
|
-
// other connection constants
|
|
566
|
-
TNS_SERVICE_OPTIONS: 0xc01,
|
|
567
|
-
TNS_PROTOCOL_CHARACTERISTICS: 0x4f98,
|
|
568
|
-
TNS_CONNECT_FLAGS: 0x8080,
|
|
569
|
-
TNS_CAN_RECV_ATTENTION: 0x0400,
|
|
570
|
-
TNS_CHECK_OOB: 0x01,
|
|
571
|
-
|
|
572
561
|
// TTC functions
|
|
573
562
|
TNS_FUNC_AUTH_PHASE_ONE: 118,
|
|
574
563
|
TNS_FUNC_AUTH_PHASE_TWO: 115,
|