Skip to content

Commit 61d42a8

Browse files
committed
Internal code changes, example and test case additions
1 parent b175843 commit 61d42a8

File tree

11 files changed

+563
-118
lines changed

11 files changed

+563
-118
lines changed

doc/src/release_notes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ Common Changes
1919
Thin Mode Changes
2020
++++++++++++++++++
2121

22+
#) Internal performance optimizations for network buffer and packet handling
23+
2224
#) Ensure that the database port is passed as a number to the network connection.
2325
See `Issue #1600 <https://github.com/oracle/node-oracledb/issues/1600>`__
2426
and `PR #1601 <https://github.com/oracle/node-oracledb/pull/1601>`__

examples/dbconfig.js

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
* to the database. Production applications should consider using
3131
* External Authentication to avoid hard coded credentials.
3232
*
33-
* To create a database user see
33+
* To create a database user, see
3434
* https://blogs.oracle.com/sql/post/how-to-create-users-grant-them-privileges-and-remove-them-in-oracle-database
3535
*
3636
* Applications can set the connectString value to an Easy Connect
@@ -46,8 +46,8 @@
4646
* Commonly just the host_name and service_name are needed
4747
* e.g. "localhost/orclpdb1" or "example.com/XEPDB1"
4848
*
49-
* The Easy Connect syntax was enhanced in Oracle Database 19c to
50-
* allow more options, refer to the documentation:
49+
* The Easy Connect syntax supports lots of options. To know more, please
50+
* refer to the latest Oracle documentation on Easy Connect syntax:
5151
* https://www.oracle.com/pls/topic/lookup?ctx=dblatest&id=GUID-B0437826-43C1-49EC-A94D-B650B6A4A6EE
5252
*
5353
* If using a tnsnames.ora file, the file can be in a default
@@ -66,17 +66,10 @@
6666
* creating a pool should not be set when externalAuth is true.
6767
*
6868
* TROUBLESHOOTING
69-
* Errors like:
70-
* ORA-12541: TNS:no listener
71-
* or
72-
* ORA-12154: TNS:could not resolve the connect identifier specified
73-
* indicate connectString is invalid.
74-
*
75-
* The error:
76-
* ORA-12514: TNS:listener does not currently know of requested in connect descriptor
77-
* indicates connectString is invalid. You are reaching a computer
78-
* with Oracle installed but the service name isn't known.
79-
* Use 'lsnrctl services' on the database server to find available services
69+
* Refer to the Error Handling section in node-oracledb documentation
70+
* to understand the different types of errors in both the Thin and Thick
71+
* modes of node-oracledb:
72+
* https://node-oracledb.readthedocs.io/en/latest/user_guide/exception_handling.html#errors-in-thin-and-thick-modes
8073
*
8174
*****************************************************************************/
8275

lib/connection.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1074,7 +1074,7 @@ class Connection extends EventEmitter {
10741074
//
10751075
// Returns the health status of the connection. If this function returns
10761076
// false, the caller should close the connection.
1077-
// ---------------------------------------------------------------------------
1077+
//---------------------------------------------------------------------------
10781078
isHealthy() {
10791079
return (this._impl !== undefined && !this._closing &&
10801080
this._impl.isHealthy());

lib/thin/protocol/buffer.js

Lines changed: 64 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class BaseBuffer {
4949
this.buf = Buffer.alloc(initializer);
5050
this.size = 0;
5151
this.maxSize = initializer;
52-
} else {
52+
} else if (initializer) {
5353
this.buf = initializer;
5454
this.size = this.maxSize = initializer.length;
5555
}
@@ -548,11 +548,12 @@ class BaseBuffer {
548548
// remain in the buffer, the buffer is grown.
549549
//---------------------------------------------------------------------------
550550
reserveBytes(numBytes) {
551-
if (numBytes > this.numBytesLeft())
551+
if (numBytes > this.numBytesLeft()) {
552552
this._grow(this.pos + numBytes);
553-
const buf = this.buf.subarray(this.pos, this.pos + numBytes);
553+
}
554+
const pos = this.pos;
554555
this.pos += numBytes;
555-
return buf;
556+
return pos;
556557
}
557558

558559
//---------------------------------------------------------------------------
@@ -618,20 +619,20 @@ class BaseBuffer {
618619
//---------------------------------------------------------------------------
619620
writeBinaryDouble(n) {
620621
this.writeUInt8(8);
621-
const buf = this.reserveBytes(8);
622-
buf.writeDoubleBE(n);
623-
if ((buf[0] & 0x80) === 0) {
624-
buf[0] |= 0x80;
622+
const pos = this.reserveBytes(8);
623+
this.buf.writeDoubleBE(n, pos);
624+
if ((this.buf[pos] & 0x80) === 0) {
625+
this.buf[pos] |= 0x80;
625626
} else {
626627
// We complement the bits for a negative number
627-
buf[0] ^= 0xff;
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;
635636
}
636637
}
637638

@@ -642,16 +643,16 @@ class BaseBuffer {
642643
//---------------------------------------------------------------------------
643644
writeBinaryFloat(n) {
644645
this.writeUInt8(4);
645-
const buf = this.reserveBytes(4);
646-
buf.writeFloatBE(n);
647-
if ((buf[0] & 0x80) === 0) {
648-
buf[0] |= 0x80;
646+
const pos = this.reserveBytes(4);
647+
this.buf.writeFloatBE(n, pos);
648+
if ((this.buf[pos] & 0x80) === 0) {
649+
this.buf[pos] |= 0x80;
649650
} else {
650651
// We complement the bits for a negative number
651-
buf[0] ^= 0xff;
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;
655656
}
656657
}
657658

@@ -745,31 +746,31 @@ class BaseBuffer {
745746
if (writeLength) {
746747
this.writeUInt8(length);
747748
}
748-
const ptr = this.reserveBytes(length);
749+
const pos = this.reserveBytes(length);
749750
if (type === types.DB_TYPE_DATE || type == types.DB_TYPE_TIMESTAMP) {
750751
const year = date.getFullYear();
751-
ptr[0] = Math.trunc(year / 100) + 100;
752-
ptr[1] = year % 100 + 100;
753-
ptr[2] = date.getMonth() + 1;
754-
ptr[3] = date.getDate();
755-
ptr[4] = date.getHours() + 1;
756-
ptr[5] = date.getMinutes() + 1;
757-
ptr[6] = date.getSeconds() + 1;
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;
758759
} else {
759760
const year = date.getUTCFullYear();
760-
ptr[0] = Math.trunc(year / 100) + 100;
761-
ptr[1] = year % 100 + 100;
762-
ptr[2] = date.getUTCMonth() + 1;
763-
ptr[3] = date.getUTCDate();
764-
ptr[4] = date.getUTCHours() + 1;
765-
ptr[5] = date.getUTCMinutes() + 1;
766-
ptr[6] = date.getUTCSeconds() + 1;
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;
767768
}
768769
if (length > 7) {
769-
ptr.writeInt32BE(fsec, 7);
770+
this.buf.writeInt32BE(fsec, pos + 7);
770771
if (length > 11) {
771-
ptr[11] = constants.TZ_HOUR_OFFSET;
772-
ptr[12] = constants.TZ_MINUTE_OFFSET;
772+
this.buf[pos + 11] = constants.TZ_HOUR_OFFSET;
773+
this.buf[pos + 12] = constants.TZ_MINUTE_OFFSET;
773774
}
774775
}
775776
}
@@ -843,19 +844,19 @@ class BaseBuffer {
843844
} else if (value.length === 0 && exponent === 0) {
844845
exponentOnWire = 128;
845846
}
846-
const buf = this.reserveBytes(numPairs + 2 + appendSentinel);
847-
buf[0] = numPairs + 1 + appendSentinel;
848-
buf[1] = exponentOnWire;
849-
for (let i = 0, pos = 2; i < value.length; i += 2, pos++) {
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) {
850851
const base100Digit = Number(value.substring(i, i + 2));
851852
if (isNegative) {
852-
buf[pos] = 101 - base100Digit;
853+
this.buf[pos++] = 101 - base100Digit;
853854
} else {
854-
buf[pos] = base100Digit + 1;
855+
this.buf[pos++] = base100Digit + 1;
855856
}
856857
}
857858
if (appendSentinel) {
858-
buf[buf.length - 1] = 102;
859+
this.buf[pos] = 102;
859860
}
860861

861862
}
@@ -898,8 +899,8 @@ class BaseBuffer {
898899
// Writes a signed 32-bit integer to the buffer in big endian order.
899900
//---------------------------------------------------------------------------
900901
writeInt32BE(n) {
901-
const buf = this.reserveBytes(4);
902-
buf.writeInt32BE(n);
902+
const pos = this.reserveBytes(4);
903+
this.buf.writeInt32BE(n, pos);
903904
}
904905

905906
//---------------------------------------------------------------------------
@@ -971,8 +972,8 @@ class BaseBuffer {
971972
// Writes an unsigned 8-bit integer to the buffer.
972973
//---------------------------------------------------------------------------
973974
writeUInt8(n) {
974-
const buf = this.reserveBytes(1);
975-
buf[0] = n;
975+
const pos = this.reserveBytes(1);
976+
this.buf[pos] = n;
976977
}
977978

978979
//---------------------------------------------------------------------------
@@ -981,8 +982,8 @@ class BaseBuffer {
981982
// Writes an unsigned 16-bit integer to the buffer in big endian order.
982983
//---------------------------------------------------------------------------
983984
writeUInt16BE(n) {
984-
const buf = this.reserveBytes(2);
985-
buf.writeUInt16BE(n);
985+
const pos = this.reserveBytes(2);
986+
this.buf.writeUInt16BE(n, pos);
986987
}
987988

988989
//---------------------------------------------------------------------------
@@ -991,8 +992,8 @@ class BaseBuffer {
991992
// Writes an unsigned 32-bit integer to the buffer in big endian order.
992993
//---------------------------------------------------------------------------
993994
writeUInt32BE(n) {
994-
const buf = this.reserveBytes(4);
995-
buf.writeUInt32BE(n);
995+
const pos = this.reserveBytes(4);
996+
this.buf.writeUInt32BE(n, pos);
996997
}
997998

998999
//---------------------------------------------------------------------------
@@ -1003,9 +1004,9 @@ class BaseBuffer {
10031004
// higher order bits are simply written as 0.
10041005
//---------------------------------------------------------------------------
10051006
writeUInt64BE(n) {
1006-
const buf = this.reserveBytes(8);
1007-
buf.writeUInt32BE(0);
1008-
buf.writeUInt32BE(n, 4);
1007+
const pos = this.reserveBytes(8);
1008+
this.buf.writeUInt32BE(0, pos);
1009+
this.buf.writeUInt32BE(n, pos + 4);
10091010
}
10101011

10111012
//---------------------------------------------------------------------------
@@ -1014,8 +1015,8 @@ class BaseBuffer {
10141015
// Writes an unsigned 16-bit integer to the buffer in little endian order.
10151016
//---------------------------------------------------------------------------
10161017
writeUInt16LE(n) {
1017-
const buf = this.reserveBytes(2);
1018-
buf.writeUInt16LE(n);
1018+
const pos = this.reserveBytes(2);
1019+
this.buf.writeUInt16LE(n, pos);
10191020
}
10201021

10211022
}
@@ -1048,7 +1049,7 @@ class GrowableBuffer extends BaseBuffer {
10481049
if (remainder > 0) {
10491050
numBytes += (constants.BUFFER_CHUNK_SIZE - remainder);
10501051
}
1051-
const buf = Buffer.alloc(numBytes);
1052+
const buf = Buffer.allocUnsafe(numBytes);
10521053
this.buf.copy(buf);
10531054
this.buf = buf;
10541055
this.maxSize = this.size = numBytes;

lib/thin/protocol/oson.js

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -416,10 +416,11 @@ class OsonTreeSegment extends GrowableBuffer {
416416
//---------------------------------------------------------------------------
417417
_encodeArray(value, fnamesSeg) {
418418
this._encodeContainer(constants.TNS_JSON_TYPE_ARRAY, value.length);
419-
let offsetsBufPos = 0;
420-
const offsetsBuf = this.reserveBytes(value.length * 4);
419+
const len = value.length * 4;
420+
const pos = this.reserveBytes(len);
421+
let offsetsBufPos = pos;
421422
for (const element of value) {
422-
offsetsBuf.writeUInt32BE(this.pos, offsetsBufPos);
423+
this.buf.writeUInt32BE(this.pos, offsetsBufPos);
423424
offsetsBufPos += 4;
424425
this.encodeNode(element, fnamesSeg);
425426
}
@@ -456,19 +457,21 @@ class OsonTreeSegment extends GrowableBuffer {
456457
_encodeObject(value, fnamesSeg) {
457458
const numChildren = value.values.length;
458459
this._encodeContainer(constants.TNS_JSON_TYPE_OBJECT, numChildren);
459-
let fieldIdOffset = 0;
460-
let valueOffset = numChildren * fnamesSeg.fieldIdSize;
461-
const buf = this.reserveBytes(numChildren * (fnamesSeg.fieldIdSize + 4));
460+
const len = numChildren * (fnamesSeg.fieldIdSize + 4);
461+
const pos = this.reserveBytes(len);
462+
let fieldIdOffset = pos;
463+
let valueOffset = pos + (numChildren * fnamesSeg.fieldIdSize);
464+
462465
for (let i = 0; i < value.fields.length; i++) {
463466
const fieldName = fnamesSeg.fieldNamesMap.get(value.fields[i]);
464467
if (fnamesSeg.fieldIdSize == 1) {
465-
buf[fieldIdOffset] = fieldName.fieldId;
468+
this.buf[fieldIdOffset] = fieldName.fieldId;
466469
} else if (fnamesSeg.fieldIdSize == 2) {
467-
buf.writeUInt16BE(fieldName.fieldId, fieldIdOffset);
470+
this.buf.writeUInt16BE(fieldName.fieldId, fieldIdOffset);
468471
} else {
469-
buf.writeUInt32BE(fieldName.fieldId, fieldIdOffset);
472+
this.buf.writeUInt32BE(fieldName.fieldId, fieldIdOffset);
470473
}
471-
buf.writeUInt32BE(this.pos, valueOffset);
474+
this.buf.writeUInt32BE(this.pos, valueOffset);
472475
fieldIdOffset += fnamesSeg.fieldIdSize;
473476
valueOffset += 4;
474477
this.encodeNode(value.values[i], fnamesSeg);

lib/thin/protocol/packet.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ const errors = require("../../errors.js");
3535

3636
const TNS_BASE64_ALPHABET_ARRAY = Buffer.from("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", 'utf8');
3737

38-
3938
/**
4039
* Class used for byte chunks used in the ChunkedBytesBuffer.
4140
*/
@@ -52,7 +51,7 @@ class BytesChunk {
5251
if (remainder > 0) {
5352
this.allocLen += (constants.CHUNKED_BYTES_CHUNK_SIZE - remainder);
5453
}
55-
this.buf = Buffer.alloc(this.allocLen);
54+
this.buf = Buffer.allocUnsafe(this.allocLen);
5655
this.actualLen = 0;
5756
}
5857

@@ -133,15 +132,17 @@ class ChunkedBytesBuffer {
133132
*
134133
* @class ReadPacket
135134
*/
135+
136136
class ReadPacket extends BaseBuffer {
137137

138138
/**
139139
* Constructor.
140140
* @param {Object} adapter used for sending/receiving data
141141
* @param {Object} capabilities
142142
*/
143+
143144
constructor(nsi, caps) {
144-
super(nsi.sAtts.sdu);
145+
super();
145146
this.nsi = nsi;
146147
this.caps = caps;
147148
this.chunkedBytesBuf = new ChunkedBytesBuffer();
@@ -228,7 +229,7 @@ class ReadPacket extends BaseBuffer {
228229
if (inChunkedRead) {
229230
buf = this.chunkedBytesBuf.getBuf(numBytes);
230231
} else {
231-
buf = Buffer.alloc(numBytes);
232+
buf = Buffer.allocUnsafe(numBytes);
232233
}
233234

234235
// copy the bytes to the buffer from the remainder of this packet
@@ -341,7 +342,7 @@ class ReadPacket extends BaseBuffer {
341342
outputLen += 3;
342343
}
343344

344-
const outputValue = Buffer.alloc(outputLen);
345+
const outputValue = Buffer.allocUnsafe(outputLen);
345346
inputLen -= 1;
346347
outputValue[0] = 42;
347348
outputOffset += 1;

0 commit comments

Comments
 (0)