Skip to content

Commit

Permalink
Internal code changes, example and test case additions
Browse files Browse the repository at this point in the history
  • Loading branch information
sharadraju committed Oct 5, 2023
1 parent b175843 commit 61d42a8
Show file tree
Hide file tree
Showing 11 changed files with 563 additions and 118 deletions.
2 changes: 2 additions & 0 deletions doc/src/release_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ Common Changes
Thin Mode Changes
++++++++++++++++++

#) Internal performance optimizations for network buffer and packet handling

#) Ensure that the database port is passed as a number to the network connection.
See `Issue #1600 <https://github.com/oracle/node-oracledb/issues/1600>`__
and `PR #1601 <https://github.com/oracle/node-oracledb/pull/1601>`__
Expand Down
21 changes: 7 additions & 14 deletions examples/dbconfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
* to the database. Production applications should consider using
* External Authentication to avoid hard coded credentials.
*
* To create a database user see
* To create a database user, see
* https://blogs.oracle.com/sql/post/how-to-create-users-grant-them-privileges-and-remove-them-in-oracle-database
*
* Applications can set the connectString value to an Easy Connect
Expand All @@ -46,8 +46,8 @@
* Commonly just the host_name and service_name are needed
* e.g. "localhost/orclpdb1" or "example.com/XEPDB1"
*
* The Easy Connect syntax was enhanced in Oracle Database 19c to
* allow more options, refer to the documentation:
* The Easy Connect syntax supports lots of options. To know more, please
* refer to the latest Oracle documentation on Easy Connect syntax:
* https://www.oracle.com/pls/topic/lookup?ctx=dblatest&id=GUID-B0437826-43C1-49EC-A94D-B650B6A4A6EE
*
* If using a tnsnames.ora file, the file can be in a default
Expand All @@ -66,17 +66,10 @@
* creating a pool should not be set when externalAuth is true.
*
* TROUBLESHOOTING
* Errors like:
* ORA-12541: TNS:no listener
* or
* ORA-12154: TNS:could not resolve the connect identifier specified
* indicate connectString is invalid.
*
* The error:
* ORA-12514: TNS:listener does not currently know of requested in connect descriptor
* indicates connectString is invalid. You are reaching a computer
* with Oracle installed but the service name isn't known.
* Use 'lsnrctl services' on the database server to find available services
* Refer to the Error Handling section in node-oracledb documentation
* to understand the different types of errors in both the Thin and Thick
* modes of node-oracledb:
* https://node-oracledb.readthedocs.io/en/latest/user_guide/exception_handling.html#errors-in-thin-and-thick-modes
*
*****************************************************************************/

Expand Down
2 changes: 1 addition & 1 deletion lib/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -1074,7 +1074,7 @@ class Connection extends EventEmitter {
//
// Returns the health status of the connection. If this function returns
// false, the caller should close the connection.
// ---------------------------------------------------------------------------
//---------------------------------------------------------------------------
isHealthy() {
return (this._impl !== undefined && !this._closing &&
this._impl.isHealthy());
Expand Down
127 changes: 64 additions & 63 deletions lib/thin/protocol/buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class BaseBuffer {
this.buf = Buffer.alloc(initializer);
this.size = 0;
this.maxSize = initializer;
} else {
} else if (initializer) {
this.buf = initializer;
this.size = this.maxSize = initializer.length;
}
Expand Down Expand Up @@ -548,11 +548,12 @@ class BaseBuffer {
// remain in the buffer, the buffer is grown.
//---------------------------------------------------------------------------
reserveBytes(numBytes) {
if (numBytes > this.numBytesLeft())
if (numBytes > this.numBytesLeft()) {
this._grow(this.pos + numBytes);
const buf = this.buf.subarray(this.pos, this.pos + numBytes);
}
const pos = this.pos;
this.pos += numBytes;
return buf;
return pos;
}

//---------------------------------------------------------------------------
Expand Down Expand Up @@ -618,20 +619,20 @@ class BaseBuffer {
//---------------------------------------------------------------------------
writeBinaryDouble(n) {
this.writeUInt8(8);
const buf = this.reserveBytes(8);
buf.writeDoubleBE(n);
if ((buf[0] & 0x80) === 0) {
buf[0] |= 0x80;
const pos = this.reserveBytes(8);
this.buf.writeDoubleBE(n, pos);
if ((this.buf[pos] & 0x80) === 0) {
this.buf[pos] |= 0x80;
} else {
// We complement the bits for a negative number
buf[0] ^= 0xff;
buf[1] ^= 0xff;
buf[2] ^= 0xff;
buf[3] ^= 0xff;
buf[4] ^= 0xff;
buf[5] ^= 0xff;
buf[6] ^= 0xff;
buf[7] ^= 0xff;
this.buf[pos] ^= 0xff;
this.buf[pos + 1] ^= 0xff;
this.buf[pos + 2] ^= 0xff;
this.buf[pos + 3] ^= 0xff;
this.buf[pos + 4] ^= 0xff;
this.buf[pos + 5] ^= 0xff;
this.buf[pos + 6] ^= 0xff;
this.buf[pos + 7] ^= 0xff;
}
}

Expand All @@ -642,16 +643,16 @@ class BaseBuffer {
//---------------------------------------------------------------------------
writeBinaryFloat(n) {
this.writeUInt8(4);
const buf = this.reserveBytes(4);
buf.writeFloatBE(n);
if ((buf[0] & 0x80) === 0) {
buf[0] |= 0x80;
const pos = this.reserveBytes(4);
this.buf.writeFloatBE(n, pos);
if ((this.buf[pos] & 0x80) === 0) {
this.buf[pos] |= 0x80;
} else {
// We complement the bits for a negative number
buf[0] ^= 0xff;
buf[1] ^= 0xff;
buf[2] ^= 0xff;
buf[3] ^= 0xff;
this.buf[pos] ^= 0xff;
this.buf[pos + 1] ^= 0xff;
this.buf[pos + 2] ^= 0xff;
this.buf[pos + 3] ^= 0xff;
}
}

Expand Down Expand Up @@ -745,31 +746,31 @@ class BaseBuffer {
if (writeLength) {
this.writeUInt8(length);
}
const ptr = this.reserveBytes(length);
const pos = this.reserveBytes(length);
if (type === types.DB_TYPE_DATE || type == types.DB_TYPE_TIMESTAMP) {
const year = date.getFullYear();
ptr[0] = Math.trunc(year / 100) + 100;
ptr[1] = year % 100 + 100;
ptr[2] = date.getMonth() + 1;
ptr[3] = date.getDate();
ptr[4] = date.getHours() + 1;
ptr[5] = date.getMinutes() + 1;
ptr[6] = date.getSeconds() + 1;
this.buf[pos] = Math.trunc(year / 100) + 100;
this.buf[pos + 1] = year % 100 + 100;
this.buf[pos + 2] = date.getMonth() + 1;
this.buf[pos + 3] = date.getDate();
this.buf[pos + 4] = date.getHours() + 1;
this.buf[pos + 5] = date.getMinutes() + 1;
this.buf[pos + 6] = date.getSeconds() + 1;
} else {
const year = date.getUTCFullYear();
ptr[0] = Math.trunc(year / 100) + 100;
ptr[1] = year % 100 + 100;
ptr[2] = date.getUTCMonth() + 1;
ptr[3] = date.getUTCDate();
ptr[4] = date.getUTCHours() + 1;
ptr[5] = date.getUTCMinutes() + 1;
ptr[6] = date.getUTCSeconds() + 1;
this.buf[pos] = Math.trunc(year / 100) + 100;
this.buf[pos + 1] = year % 100 + 100;
this.buf[pos + 2] = date.getUTCMonth() + 1;
this.buf[pos + 3] = date.getUTCDate();
this.buf[pos + 4] = date.getUTCHours() + 1;
this.buf[pos + 5] = date.getUTCMinutes() + 1;
this.buf[pos + 6] = date.getUTCSeconds() + 1;
}
if (length > 7) {
ptr.writeInt32BE(fsec, 7);
this.buf.writeInt32BE(fsec, pos + 7);
if (length > 11) {
ptr[11] = constants.TZ_HOUR_OFFSET;
ptr[12] = constants.TZ_MINUTE_OFFSET;
this.buf[pos + 11] = constants.TZ_HOUR_OFFSET;
this.buf[pos + 12] = constants.TZ_MINUTE_OFFSET;
}
}
}
Expand Down Expand Up @@ -843,19 +844,19 @@ class BaseBuffer {
} else if (value.length === 0 && exponent === 0) {
exponentOnWire = 128;
}
const buf = this.reserveBytes(numPairs + 2 + appendSentinel);
buf[0] = numPairs + 1 + appendSentinel;
buf[1] = exponentOnWire;
for (let i = 0, pos = 2; i < value.length; i += 2, pos++) {
let pos = this.reserveBytes(numPairs + 2 + appendSentinel);
this.buf[pos++] = numPairs + 1 + appendSentinel;
this.buf[pos++] = exponentOnWire;
for (let i = 0; i < value.length; i += 2) {
const base100Digit = Number(value.substring(i, i + 2));
if (isNegative) {
buf[pos] = 101 - base100Digit;
this.buf[pos++] = 101 - base100Digit;
} else {
buf[pos] = base100Digit + 1;
this.buf[pos++] = base100Digit + 1;
}
}
if (appendSentinel) {
buf[buf.length - 1] = 102;
this.buf[pos] = 102;
}

}
Expand Down Expand Up @@ -898,8 +899,8 @@ class BaseBuffer {
// Writes a signed 32-bit integer to the buffer in big endian order.
//---------------------------------------------------------------------------
writeInt32BE(n) {
const buf = this.reserveBytes(4);
buf.writeInt32BE(n);
const pos = this.reserveBytes(4);
this.buf.writeInt32BE(n, pos);
}

//---------------------------------------------------------------------------
Expand Down Expand Up @@ -971,8 +972,8 @@ class BaseBuffer {
// Writes an unsigned 8-bit integer to the buffer.
//---------------------------------------------------------------------------
writeUInt8(n) {
const buf = this.reserveBytes(1);
buf[0] = n;
const pos = this.reserveBytes(1);
this.buf[pos] = n;
}

//---------------------------------------------------------------------------
Expand All @@ -981,8 +982,8 @@ class BaseBuffer {
// Writes an unsigned 16-bit integer to the buffer in big endian order.
//---------------------------------------------------------------------------
writeUInt16BE(n) {
const buf = this.reserveBytes(2);
buf.writeUInt16BE(n);
const pos = this.reserveBytes(2);
this.buf.writeUInt16BE(n, pos);
}

//---------------------------------------------------------------------------
Expand All @@ -991,8 +992,8 @@ class BaseBuffer {
// Writes an unsigned 32-bit integer to the buffer in big endian order.
//---------------------------------------------------------------------------
writeUInt32BE(n) {
const buf = this.reserveBytes(4);
buf.writeUInt32BE(n);
const pos = this.reserveBytes(4);
this.buf.writeUInt32BE(n, pos);
}

//---------------------------------------------------------------------------
Expand All @@ -1003,9 +1004,9 @@ class BaseBuffer {
// higher order bits are simply written as 0.
//---------------------------------------------------------------------------
writeUInt64BE(n) {
const buf = this.reserveBytes(8);
buf.writeUInt32BE(0);
buf.writeUInt32BE(n, 4);
const pos = this.reserveBytes(8);
this.buf.writeUInt32BE(0, pos);
this.buf.writeUInt32BE(n, pos + 4);
}

//---------------------------------------------------------------------------
Expand All @@ -1014,8 +1015,8 @@ class BaseBuffer {
// Writes an unsigned 16-bit integer to the buffer in little endian order.
//---------------------------------------------------------------------------
writeUInt16LE(n) {
const buf = this.reserveBytes(2);
buf.writeUInt16LE(n);
const pos = this.reserveBytes(2);
this.buf.writeUInt16LE(n, pos);
}

}
Expand Down Expand Up @@ -1048,7 +1049,7 @@ class GrowableBuffer extends BaseBuffer {
if (remainder > 0) {
numBytes += (constants.BUFFER_CHUNK_SIZE - remainder);
}
const buf = Buffer.alloc(numBytes);
const buf = Buffer.allocUnsafe(numBytes);
this.buf.copy(buf);
this.buf = buf;
this.maxSize = this.size = numBytes;
Expand Down
23 changes: 13 additions & 10 deletions lib/thin/protocol/oson.js
Original file line number Diff line number Diff line change
Expand Up @@ -416,10 +416,11 @@ class OsonTreeSegment extends GrowableBuffer {
//---------------------------------------------------------------------------
_encodeArray(value, fnamesSeg) {
this._encodeContainer(constants.TNS_JSON_TYPE_ARRAY, value.length);
let offsetsBufPos = 0;
const offsetsBuf = this.reserveBytes(value.length * 4);
const len = value.length * 4;
const pos = this.reserveBytes(len);
let offsetsBufPos = pos;
for (const element of value) {
offsetsBuf.writeUInt32BE(this.pos, offsetsBufPos);
this.buf.writeUInt32BE(this.pos, offsetsBufPos);
offsetsBufPos += 4;
this.encodeNode(element, fnamesSeg);
}
Expand Down Expand Up @@ -456,19 +457,21 @@ class OsonTreeSegment extends GrowableBuffer {
_encodeObject(value, fnamesSeg) {
const numChildren = value.values.length;
this._encodeContainer(constants.TNS_JSON_TYPE_OBJECT, numChildren);
let fieldIdOffset = 0;
let valueOffset = numChildren * fnamesSeg.fieldIdSize;
const buf = this.reserveBytes(numChildren * (fnamesSeg.fieldIdSize + 4));
const len = numChildren * (fnamesSeg.fieldIdSize + 4);
const pos = this.reserveBytes(len);
let fieldIdOffset = pos;
let valueOffset = pos + (numChildren * fnamesSeg.fieldIdSize);

for (let i = 0; i < value.fields.length; i++) {
const fieldName = fnamesSeg.fieldNamesMap.get(value.fields[i]);
if (fnamesSeg.fieldIdSize == 1) {
buf[fieldIdOffset] = fieldName.fieldId;
this.buf[fieldIdOffset] = fieldName.fieldId;
} else if (fnamesSeg.fieldIdSize == 2) {
buf.writeUInt16BE(fieldName.fieldId, fieldIdOffset);
this.buf.writeUInt16BE(fieldName.fieldId, fieldIdOffset);
} else {
buf.writeUInt32BE(fieldName.fieldId, fieldIdOffset);
this.buf.writeUInt32BE(fieldName.fieldId, fieldIdOffset);
}
buf.writeUInt32BE(this.pos, valueOffset);
this.buf.writeUInt32BE(this.pos, valueOffset);
fieldIdOffset += fnamesSeg.fieldIdSize;
valueOffset += 4;
this.encodeNode(value.values[i], fnamesSeg);
Expand Down
11 changes: 6 additions & 5 deletions lib/thin/protocol/packet.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ const errors = require("../../errors.js");

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


/**
* Class used for byte chunks used in the ChunkedBytesBuffer.
*/
Expand All @@ -52,7 +51,7 @@ class BytesChunk {
if (remainder > 0) {
this.allocLen += (constants.CHUNKED_BYTES_CHUNK_SIZE - remainder);
}
this.buf = Buffer.alloc(this.allocLen);
this.buf = Buffer.allocUnsafe(this.allocLen);
this.actualLen = 0;
}

Expand Down Expand Up @@ -133,15 +132,17 @@ class ChunkedBytesBuffer {
*
* @class ReadPacket
*/

class ReadPacket extends BaseBuffer {

/**
* Constructor.
* @param {Object} adapter used for sending/receiving data
* @param {Object} capabilities
*/

constructor(nsi, caps) {
super(nsi.sAtts.sdu);
super();
this.nsi = nsi;
this.caps = caps;
this.chunkedBytesBuf = new ChunkedBytesBuffer();
Expand Down Expand Up @@ -228,7 +229,7 @@ class ReadPacket extends BaseBuffer {
if (inChunkedRead) {
buf = this.chunkedBytesBuf.getBuf(numBytes);
} else {
buf = Buffer.alloc(numBytes);
buf = Buffer.allocUnsafe(numBytes);
}

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

const outputValue = Buffer.alloc(outputLen);
const outputValue = Buffer.allocUnsafe(outputLen);
inputLen -= 1;
outputValue[0] = 42;
outputOffset += 1;
Expand Down
Loading

0 comments on commit 61d42a8

Please sign in to comment.