oracledb 6.0.2 → 6.0.3
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 +15 -17
- package/SECURITY.md +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 +1 -0
- package/build/Release/oracledb-6.0.3-js-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.0.3-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.0.3-linux-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.0.3-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/{oracledb-6.0.2-win32-x64.node → oracledb-6.0.3-win32-x64.node} +0 -0
- package/build/Release/oracledb-6.0.3-win32-x64.node-buildinfo.txt +1 -0
- package/lib/errors.js +5 -4
- package/lib/pool.js +4 -1
- package/lib/settings.js +1 -1
- package/lib/thin/dbObject.js +2 -2
- package/lib/thin/lob.js +2 -2
- package/lib/thin/pool.js +0 -3
- package/lib/thin/protocol/buffer.js +5 -5
- package/lib/thin/protocol/constants.js +5 -4
- package/lib/thin/protocol/messages/auth.js +7 -9
- package/lib/thin/protocol/messages/base.js +10 -10
- package/lib/thin/protocol/messages/execute.js +5 -5
- package/lib/thin/protocol/messages/lobOp.js +3 -3
- package/lib/thin/protocol/messages/withData.js +12 -11
- package/lib/thin/protocol/packet.js +20 -18
- package/lib/thin/protocol/protocol.js +12 -7
- package/lib/thin/sqlnet/connStrategy.js +4 -2
- package/lib/thin/sqlnet/ezConnectResolver.js +9 -5
- package/lib/thin/sqlnet/navNodes.js +3 -3
- package/lib/thin/sqlnet/networkSession.js +10 -10
- package/lib/thin/sqlnet/ntTcp.js +40 -21
- package/lib/thin/sqlnet/packet.js +8 -8
- package/lib/thin/statement.js +1 -0
- package/lib/thin/util.js +21 -0
- package/lib/version.js +1 -1
- package/package.json +1 -1
- package/build/Release/oracledb-6.0.2-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.0.2-darwin-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.2-js-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.2-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.0.2-linux-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.2-linux-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.0.2-win32-x64.node-buildinfo.txt +0 -1
- /package/build/Release/{oracledb-6.0.2-linux-x64.node → oracledb-6.0.3-linux-x64.node} +0 -0
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# node-oracledb version 6.0.
|
|
1
|
+
# node-oracledb version 6.0.3
|
|
2
2
|
|
|
3
3
|
The node-oracledb add-on for Node.js powers high performance Oracle Database
|
|
4
4
|
applications. Applications can be written in TypeScript, or directly in
|
|
5
5
|
JavaScript.
|
|
6
6
|
|
|
7
|
-
Use node-oracledb 6.0.
|
|
7
|
+
Use node-oracledb 6.0.3 to connect Node.js 14.6, or later, to Oracle
|
|
8
8
|
Database. Older versions of node-oracledb may work with older versions of
|
|
9
9
|
Node.js.
|
|
10
10
|
|
|
@@ -20,12 +20,12 @@ See [Getting Started with Node-oracledb][1] and [Quick Start Node-oracledb Insta
|
|
|
20
20
|
|
|
21
21
|
## Documentation
|
|
22
22
|
|
|
23
|
-
See [Documentation for the Oracle Database Node.js Add-on][
|
|
24
|
-
notes][
|
|
23
|
+
See [Documentation for the Oracle Database Node.js Add-on][9] and the [release
|
|
24
|
+
notes][10].
|
|
25
25
|
|
|
26
26
|
## Examples
|
|
27
27
|
|
|
28
|
-
See the [examples][
|
|
28
|
+
See the [examples][7] directory. Start with [examples/example.js][8].
|
|
29
29
|
|
|
30
30
|
## Help
|
|
31
31
|
|
|
@@ -34,19 +34,16 @@ to join Slack][6]).
|
|
|
34
34
|
|
|
35
35
|
## <a name="testing"></a> Tests
|
|
36
36
|
|
|
37
|
-
To run the test suite see [test/README][
|
|
37
|
+
To run the test suite see [test/README][11].
|
|
38
38
|
|
|
39
39
|
## Contributing
|
|
40
40
|
|
|
41
41
|
This project welcomes contributions from the community. Before submitting a
|
|
42
|
-
pull request, please [review our contribution guide][
|
|
43
|
-
|
|
44
|
-
Oracle gratefully acknowledges the contributions to node-oracledb that have
|
|
45
|
-
been made by the community.
|
|
42
|
+
pull request, please [review our contribution guide][12].
|
|
46
43
|
|
|
47
44
|
## Security
|
|
48
45
|
|
|
49
|
-
Please consult the [security guide]
|
|
46
|
+
Please consult the [security guide][13] for our responsible security
|
|
50
47
|
vulnerability disclosure process.
|
|
51
48
|
|
|
52
49
|
## License
|
|
@@ -79,9 +76,10 @@ limitations under the License.
|
|
|
79
76
|
[4]: https://oracle.github.io/node-oracledb
|
|
80
77
|
[5]: https://node-oracledb.slack.com/
|
|
81
78
|
[6]: https://join.slack.com/t/node-oracledb/shared_invite/enQtNDU4Mjc2NzM5OTA2LWMzY2ZlZDY5MDdlMGZiMGRkY2IzYjI5OGU4YTEzZWM5YjQ3ODUzMjcxNWQyNzE4MzM5YjNkYjVmNDk5OWU5NDM
|
|
82
|
-
[
|
|
83
|
-
[
|
|
84
|
-
[
|
|
85
|
-
[
|
|
86
|
-
[
|
|
87
|
-
[
|
|
79
|
+
[7]: https://github.com/oracle/node-oracledb/blob/main/examples
|
|
80
|
+
[8]: https://github.com/oracle/node-oracledb/blob/main/examples/example.js
|
|
81
|
+
[9]: https://node-oracledb.readthedocs.io/en/latest/
|
|
82
|
+
[10]: https://node-oracledb.readthedocs.io/en/latest/release_notes.html
|
|
83
|
+
[11]: https://github.com/oracle/node-oracledb/blob/main/test/README.md
|
|
84
|
+
[12]: https://github.com/oracle/node-oracledb/blob/main/CONTRIBUTING.md
|
|
85
|
+
[13]: https://github.com/oracle/node-oracledb/blob/main/SECURITY.md
|
package/SECURITY.md
CHANGED
|
@@ -21,7 +21,7 @@ security features are welcome on GitHub Issues.
|
|
|
21
21
|
|
|
22
22
|
Security updates will be released on a regular cadence. Many of our projects
|
|
23
23
|
will typically release security fixes in conjunction with the
|
|
24
|
-
|
|
24
|
+
Oracle Critical Patch Update program. Additional
|
|
25
25
|
information, including past advisories, is available on our [security alerts][4]
|
|
26
26
|
page.
|
|
27
27
|
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
oracledb-6.0.3-darwin-x64.node v16.20.0 39d4fe42c06aaccc3feab18cc77fb27025d1fcbb ccbaddf0256153ecfa6702c6ae1a4e5003e3775e Wed, 05 Jul 2023 21:49:52 GMT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
39d4fe42c06aaccc3feab18cc77fb27025d1fcbb
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
oracledb-6.0.3-linux-arm64.node v16.20.0 39d4fe42c06aaccc3feab18cc77fb27025d1fcbb ccbaddf0256153ecfa6702c6ae1a4e5003e3775e Wed, 05 Jul 2023 21:29:48 GMT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
oracledb-6.0.3-linux-x64.node v16.20.0 39d4fe42c06aaccc3feab18cc77fb27025d1fcbb ccbaddf0256153ecfa6702c6ae1a4e5003e3775e Thu, 06 Jul 2023 06:38:15 GMT
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
oracledb-6.0.3-win32-x64.node v16.19.0 39d4fe42c06aaccc3feab18cc77fb27025d1fcbb ccbaddf0256153ecfa6702c6ae1a4e5003e3775e Thu, 06 Jul 2023 06:41:18 GMT
|
package/lib/errors.js
CHANGED
|
@@ -161,7 +161,8 @@ const ERR_INVALID_SID = 519;
|
|
|
161
161
|
const ERR_TNS_NAMES_FILE_MISSING = 520;
|
|
162
162
|
const ERR_CONNECTION_EOF = 521;
|
|
163
163
|
|
|
164
|
-
// define mapping for ODPI-C errors that need to be wrapped
|
|
164
|
+
// define mapping for ODPI-C, OCI & ORA errors that need to be wrapped
|
|
165
|
+
// with NJS errors
|
|
165
166
|
const adjustErrorXref = new Map();
|
|
166
167
|
adjustErrorXref.set("DPI-1010", ERR_CONNECTION_CLOSED);
|
|
167
168
|
adjustErrorXref.set("DPI-1024", [ERR_INVALID_COLL_INDEX_GET, 'at index ([0-9]+) does']);
|
|
@@ -327,7 +328,7 @@ messages.set(ERR_MISSING_CREDENTIALS, // NJS-101
|
|
|
327
328
|
messages.set(ERR_UNEXPECTED_END_OF_DATA, // NJS-102
|
|
328
329
|
'unexpected end of data: want %d bytes but only %d bytes are available');
|
|
329
330
|
messages.set(ERR_UNEXPECTED_MESSAGE_TYPE, // NJS-103
|
|
330
|
-
'unexpected message type %d received');
|
|
331
|
+
'unexpected message type %d received at position %d of packet %d');
|
|
331
332
|
messages.set(ERR_POOL_HAS_BUSY_CONNECTIONS, // NJS-104
|
|
332
333
|
'connection pool cannot be closed because connections are busy');
|
|
333
334
|
messages.set(ERR_NAN_VALUE, // NJS-105
|
|
@@ -343,9 +344,9 @@ messages.set(ERR_INVALID_TYPE_NUM, // NJS-109
|
|
|
343
344
|
messages.set(ERR_INVALID_ORACLE_TYPE_NUM, // NJS-110
|
|
344
345
|
'invalid Oracle type number %d [csfrm: %d]');
|
|
345
346
|
messages.set(ERR_UNEXPECTED_NEGATIVE_INTEGER, // NJS-111
|
|
346
|
-
'internal error: read a negative integer when expecting a positive integer');
|
|
347
|
+
'internal error: read a negative integer when expecting a positive integer at position %d of packet %d');
|
|
347
348
|
messages.set(ERR_INTEGER_TOO_LARGE, // NJS-112
|
|
348
|
-
'internal error: read integer of length %d when expecting integer of no more than length %d');
|
|
349
|
+
'internal error: read integer of length %d when expecting integer of no more than length %d at position %d of packet %d');
|
|
349
350
|
messages.set(ERR_UNEXPECTED_DATA, // NJS-113
|
|
350
351
|
'unexpected data received: %s');
|
|
351
352
|
messages.set(ERR_OSON_FIELD_NAME_LIMITATION, // NJS-114
|
package/lib/pool.js
CHANGED
|
@@ -47,6 +47,7 @@ class Pool extends EventEmitter {
|
|
|
47
47
|
this._timeOfReset = this._createdDate = Date.now();
|
|
48
48
|
this._sessionCallback = undefined;
|
|
49
49
|
this._connRequestQueue = [];
|
|
50
|
+
this._connectionClass = settings.connectionClass;
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
//---------------------------------------------------------------------------
|
|
@@ -376,7 +377,9 @@ class Pool extends EventEmitter {
|
|
|
376
377
|
errors.assertParamValue(nodbUtil.isObject(a1), 1);
|
|
377
378
|
options = this._verifyGetConnectionOptions(a1);
|
|
378
379
|
}
|
|
379
|
-
|
|
380
|
+
|
|
381
|
+
// get connection class value from pool
|
|
382
|
+
options.connectionClass = this._connectionClass;
|
|
380
383
|
|
|
381
384
|
// if pool is draining/closed, throw an appropriate error
|
|
382
385
|
this._checkPoolOpen(true);
|
package/lib/settings.js
CHANGED
|
@@ -69,7 +69,7 @@ class Settings {
|
|
|
69
69
|
// database are returned as though they used the JavaScript time zone
|
|
70
70
|
// setting. TIMESTAMP WITH TIME ZONE and TIMESTAMP WITH LOCAL TIME ZONE data
|
|
71
71
|
// are returned in native JavaScript format (since they contain time zone
|
|
72
|
-
// information).
|
|
72
|
+
// information). This is used only in Thick mode (from node-oracledb 6.0.0).
|
|
73
73
|
//---------------------------------------------------------------------------
|
|
74
74
|
_getDateComponents(useLocal, date) {
|
|
75
75
|
if (useLocal) {
|
package/lib/thin/dbObject.js
CHANGED
|
@@ -362,10 +362,10 @@ class ThinDbObjectImpl extends DbObjectImpl {
|
|
|
362
362
|
return buf.readBinaryInteger();
|
|
363
363
|
case types.DB_TYPE_VARCHAR:
|
|
364
364
|
case types.DB_TYPE_CHAR:
|
|
365
|
-
return buf.readStr(constants.
|
|
365
|
+
return buf.readStr(constants.CSFRM_IMPLICIT);
|
|
366
366
|
case types.DB_TYPE_NVARCHAR:
|
|
367
367
|
case types.DB_TYPE_NCHAR:
|
|
368
|
-
return buf.readStr(constants.
|
|
368
|
+
return buf.readStr(constants.CSFRM_NCHAR);
|
|
369
369
|
case types.DB_TYPE_RAW:
|
|
370
370
|
return Buffer.from(buf.readBytesWithLength());
|
|
371
371
|
case types.DB_TYPE_BINARY_DOUBLE:
|
package/lib/thin/lob.js
CHANGED
|
@@ -121,10 +121,10 @@ class ThinLobImpl extends LobImpl {
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
getCsfrm() {
|
|
124
|
-
if (this.dbType._csfrm !== constants.
|
|
124
|
+
if (this.dbType._csfrm !== constants.CSFRM_NCHAR) {
|
|
125
125
|
if (this._locator[constants.TNS_LOB_LOC_OFFSET_FLAG_3] &
|
|
126
126
|
constants.TNS_LOB_LOC_FLAGS_VAR_LENGTH_CHARSET) {
|
|
127
|
-
return constants.
|
|
127
|
+
return constants.CSFRM_NCHAR;
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
return this.dbType._csfrm;
|
package/lib/thin/pool.js
CHANGED
|
@@ -212,9 +212,6 @@ class ThinPoolImpl extends PoolImpl {
|
|
|
212
212
|
// create new connection and return it
|
|
213
213
|
//---------------------------------------------------------------------------
|
|
214
214
|
async getConnection() {
|
|
215
|
-
if (settings.connectionClass !== '') {
|
|
216
|
-
this._userConfig.connectionClass = settings.connectionClass;
|
|
217
|
-
}
|
|
218
215
|
return await this.acquire();
|
|
219
216
|
}
|
|
220
217
|
|
|
@@ -92,13 +92,13 @@ class BaseBuffer {
|
|
|
92
92
|
return 0;
|
|
93
93
|
} else if (size & 0x80) {
|
|
94
94
|
if (!signed) {
|
|
95
|
-
errors.throwErr(errors.ERR_UNEXPECTED_NEGATIVE_INTEGER);
|
|
95
|
+
errors.throwErr(errors.ERR_UNEXPECTED_NEGATIVE_INTEGER, this.pos, this.packetNum);
|
|
96
96
|
}
|
|
97
97
|
isNegative = true;
|
|
98
98
|
size = size & 0x7f;
|
|
99
99
|
}
|
|
100
100
|
if (size > maxSize) {
|
|
101
|
-
errors.throwErr(errors.ERR_INTEGER_TOO_LARGE, size, maxSize);
|
|
101
|
+
errors.throwErr(errors.ERR_INTEGER_TOO_LARGE, size, maxSize, this.pos, this.packetNum);
|
|
102
102
|
}
|
|
103
103
|
if (skip) {
|
|
104
104
|
this.skipBytes(size);
|
|
@@ -465,7 +465,7 @@ class BaseBuffer {
|
|
|
465
465
|
if (!buf) {
|
|
466
466
|
return null;
|
|
467
467
|
}
|
|
468
|
-
if (csfrm === constants.
|
|
468
|
+
if (csfrm === constants.CSFRM_IMPLICIT)
|
|
469
469
|
return buf.toString();
|
|
470
470
|
|
|
471
471
|
// need a copy of the buffer since swap16() changes the buffer in place and
|
|
@@ -748,7 +748,7 @@ class BaseBuffer {
|
|
|
748
748
|
const ptr = this.reserveBytes(length);
|
|
749
749
|
if (type === types.DB_TYPE_DATE || type == types.DB_TYPE_TIMESTAMP) {
|
|
750
750
|
const year = date.getFullYear();
|
|
751
|
-
ptr[0] = Math.
|
|
751
|
+
ptr[0] = Math.trunc(year / 100) + 100;
|
|
752
752
|
ptr[1] = year % 100 + 100;
|
|
753
753
|
ptr[2] = date.getMonth() + 1;
|
|
754
754
|
ptr[3] = date.getDate();
|
|
@@ -757,7 +757,7 @@ class BaseBuffer {
|
|
|
757
757
|
ptr[6] = date.getSeconds() + 1;
|
|
758
758
|
} else {
|
|
759
759
|
const year = date.getUTCFullYear();
|
|
760
|
-
ptr[0] = Math.
|
|
760
|
+
ptr[0] = Math.trunc(year / 100) + 100;
|
|
761
761
|
ptr[1] = year % 100 + 100;
|
|
762
762
|
ptr[2] = date.getUTCMonth() + 1;
|
|
763
763
|
ptr[3] = date.getUTCDate();
|
|
@@ -40,7 +40,12 @@ module.exports = {
|
|
|
40
40
|
constants.VERSION_MAJOR << 24 |
|
|
41
41
|
constants.VERSION_MINOR << 20 |
|
|
42
42
|
constants.VERSION_PATCH << 12,
|
|
43
|
+
CSFRM_IMPLICIT: constants.CSFRM_IMPLICIT,
|
|
44
|
+
CSFRM_NCHAR: constants.CSFRM_NCHAR,
|
|
43
45
|
DRIVER_NAME: constants.DEFAULT_DRIVER_NAME + ' thn',
|
|
46
|
+
PURITY_DEFAULT: constants.PURITY_DEFAULT,
|
|
47
|
+
PURITY_NEW: constants.PURITY_NEW,
|
|
48
|
+
PURITY_SELF: constants.PURITY_SELF,
|
|
44
49
|
SYSASM: constants.SYSASM,
|
|
45
50
|
SYSBKP: constants.SYSBKP,
|
|
46
51
|
SYSDBA: constants.SYSDBA,
|
|
@@ -88,10 +93,6 @@ module.exports = {
|
|
|
88
93
|
TNS_MARKER_TYPE_BREAK: 1,
|
|
89
94
|
TNS_MARKER_TYPE_RESET: 2,
|
|
90
95
|
|
|
91
|
-
// charset forms
|
|
92
|
-
TNS_CS_IMPLICIT: 1,
|
|
93
|
-
TNS_CS_NCHAR: 2,
|
|
94
|
-
|
|
95
96
|
// data types
|
|
96
97
|
TNS_DATA_TYPE_DEFAULT: 0,
|
|
97
98
|
TNS_DATA_TYPE_VARCHAR: 1,
|
|
@@ -29,12 +29,11 @@
|
|
|
29
29
|
const { Buffer } = require('buffer');
|
|
30
30
|
const constants = require("../constants.js");
|
|
31
31
|
const errors = require("../../../errors.js");
|
|
32
|
-
const os = require("os");
|
|
33
32
|
const process = require("process");
|
|
34
33
|
const ED = require("../encryptDecrypt.js");
|
|
35
34
|
const Message = require("./base.js");
|
|
36
35
|
const util = require("../../util.js");
|
|
37
|
-
|
|
36
|
+
const cInfo = util.CLIENT_INFO;
|
|
38
37
|
const crypto = require('crypto');
|
|
39
38
|
|
|
40
39
|
/**
|
|
@@ -184,11 +183,10 @@ class AuthMessage extends Message {
|
|
|
184
183
|
buf.writeBytesWithLength(Buffer.from(this.username));
|
|
185
184
|
}
|
|
186
185
|
buf.writeKeyValue("AUTH_TERMINAL", "unknown");
|
|
187
|
-
buf.writeKeyValue("AUTH_PROGRAM_NM",
|
|
188
|
-
buf.writeKeyValue("AUTH_MACHINE",
|
|
189
|
-
buf.writeKeyValue("AUTH_PID",
|
|
190
|
-
buf.writeKeyValue("AUTH_SID",
|
|
191
|
-
|
|
186
|
+
buf.writeKeyValue("AUTH_PROGRAM_NM", cInfo.program);
|
|
187
|
+
buf.writeKeyValue("AUTH_MACHINE", cInfo.hostName);
|
|
188
|
+
buf.writeKeyValue("AUTH_PID", cInfo.pid);
|
|
189
|
+
buf.writeKeyValue("AUTH_SID", cInfo.userName);
|
|
192
190
|
} else {
|
|
193
191
|
let numPairs = 0;
|
|
194
192
|
|
|
@@ -302,11 +300,11 @@ class AuthMessage extends Message {
|
|
|
302
300
|
let numParams = buf.readUB2();
|
|
303
301
|
for (let i = 0; i < numParams;i++) {
|
|
304
302
|
buf.skipUB4();
|
|
305
|
-
let key = buf.readStr(constants.
|
|
303
|
+
let key = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
306
304
|
let value = "";
|
|
307
305
|
let numBytes = buf.readUB4();
|
|
308
306
|
if (numBytes > 0) {
|
|
309
|
-
value = buf.readStr(constants.
|
|
307
|
+
value = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
310
308
|
}
|
|
311
309
|
let flag = buf.readUB4();
|
|
312
310
|
if (key === "AUTH_VFR_DATA") {
|
|
@@ -149,7 +149,7 @@ class Message {
|
|
|
149
149
|
for (let i = 0; i < numEntries; i++) {
|
|
150
150
|
buf.skipUB2(); // skip chunk length
|
|
151
151
|
|
|
152
|
-
this.errorInfo.batchErrors[i].message = buf.readStr(constants.
|
|
152
|
+
this.errorInfo.batchErrors[i].message = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
153
153
|
buf.skipBytes(2); // ignore end marker
|
|
154
154
|
}
|
|
155
155
|
}
|
|
@@ -158,7 +158,7 @@ class Message {
|
|
|
158
158
|
this.errorInfo.rowCount = buf.readUB8(); // row number (extended)
|
|
159
159
|
if (this.errorInfo.num !== 0) {
|
|
160
160
|
this.errorOccurred = true;
|
|
161
|
-
this.errorInfo.message = buf.readStr(constants.
|
|
161
|
+
this.errorInfo.message = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
162
162
|
/*
|
|
163
163
|
* Remove ending newline from ORA error message
|
|
164
164
|
*/
|
|
@@ -175,7 +175,7 @@ class Message {
|
|
|
175
175
|
let numBytes = buf.readUB2(); // length of error message
|
|
176
176
|
buf.skipUB2(); // flags
|
|
177
177
|
if (this.errorInfo.num != 0 && numBytes > 0) {
|
|
178
|
-
this.errorInfo.message = buf.readStr(constants.
|
|
178
|
+
this.errorInfo.message = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
179
179
|
}
|
|
180
180
|
this.errorInfo.isWarning = true;
|
|
181
181
|
}
|
|
@@ -215,7 +215,7 @@ class Message {
|
|
|
215
215
|
} else if (messageType === constants.TNS_MSG_TYPE_SERVER_SIDE_PIGGYBACK) {
|
|
216
216
|
this.processServerSidePiggyBack(buf);
|
|
217
217
|
} else {
|
|
218
|
-
errors.throwErr(errors.ERR_UNEXPECTED_MESSAGE_TYPE, messageType);
|
|
218
|
+
errors.throwErr(errors.ERR_UNEXPECTED_MESSAGE_TYPE, messageType, buf.pos, buf.packetNum);
|
|
219
219
|
}
|
|
220
220
|
}
|
|
221
221
|
|
|
@@ -230,8 +230,8 @@ class Message {
|
|
|
230
230
|
|| (opcode === constants.TNS_SERVER_PIGGYBACK_TRACE_EVENT)) {
|
|
231
231
|
// pass
|
|
232
232
|
} else if (opcode === constants.TNS_SERVER_PIGGYBACK_OS_PID_MTS) {
|
|
233
|
-
|
|
234
|
-
buf.
|
|
233
|
+
buf.skipUB2();
|
|
234
|
+
buf.skipBytesChunked();
|
|
235
235
|
} else if (opcode === constants.TNS_SERVER_PIGGYBACK_SYNC) {
|
|
236
236
|
buf.skipUB2(); // skip number of DTYs
|
|
237
237
|
buf.skipUB1(); // skip length of DTYs
|
|
@@ -240,11 +240,11 @@ class Message {
|
|
|
240
240
|
for (let i = 0; i < num_elements; i++) {
|
|
241
241
|
let temp16 = buf.readUB2();
|
|
242
242
|
if (temp16 > 0) { // skip key
|
|
243
|
-
buf.
|
|
243
|
+
buf.skipBytesChunked();
|
|
244
244
|
}
|
|
245
245
|
temp16 = buf.readUB2();
|
|
246
246
|
if (temp16 > 0) { // skip value
|
|
247
|
-
buf.
|
|
247
|
+
buf.skipBytesChunked();
|
|
248
248
|
}
|
|
249
249
|
buf.skipUB2(); // skip flags
|
|
250
250
|
buf.skipUB4(); // skip overall flags
|
|
@@ -271,11 +271,11 @@ class Message {
|
|
|
271
271
|
for (let i = 0; i < num_elements; ++i) {
|
|
272
272
|
let temp16 = buf.readUB2();
|
|
273
273
|
if (temp16 > 0) { // skip key
|
|
274
|
-
buf.
|
|
274
|
+
buf.skipBytesChunked();
|
|
275
275
|
}
|
|
276
276
|
temp16 = buf.readUB2();
|
|
277
277
|
if (temp16 > 0) { // skip value
|
|
278
|
-
buf.
|
|
278
|
+
buf.skipBytesChunked();
|
|
279
279
|
}
|
|
280
280
|
buf.skipUB2(); // skip flags
|
|
281
281
|
}
|
|
@@ -77,21 +77,21 @@ class ExecuteMessage extends MessageWithData {
|
|
|
77
77
|
dmlOptions = constants.TNS_EXEC_OPTION_IMPLICIT_RESULTSET;
|
|
78
78
|
options |= constants.TNS_EXEC_OPTION_EXECUTE;
|
|
79
79
|
}
|
|
80
|
-
if (stmt.cursorId
|
|
80
|
+
if (stmt.cursorId === 0 || stmt.isDdl) {
|
|
81
81
|
options |= constants.TNS_EXEC_OPTION_PARSE;
|
|
82
82
|
}
|
|
83
83
|
if (stmt.isQuery) {
|
|
84
84
|
if (this.parseOnly) {
|
|
85
85
|
options |= constants.TNS_EXEC_OPTION_DESCRIBE;
|
|
86
86
|
} else {
|
|
87
|
-
if (this.options.prefetchRows > 0) {
|
|
88
|
-
options |= constants.TNS_EXEC_OPTION_FETCH;
|
|
89
|
-
}
|
|
90
87
|
if (stmt.cursorId === 0 || stmt.requiresDefine) {
|
|
91
88
|
numIters = this.options.prefetchRows;
|
|
92
89
|
} else {
|
|
93
90
|
numIters = this.options.fetchArraySize;
|
|
94
91
|
}
|
|
92
|
+
if (numIters > 0 && !stmt.noPrefetch) {
|
|
93
|
+
options |= constants.TNS_EXEC_OPTION_FETCH;
|
|
94
|
+
}
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
if (!stmt.isPlSql && !this.parseOnly) {
|
|
@@ -276,7 +276,7 @@ class ExecuteMessage extends MessageWithData {
|
|
|
276
276
|
if (this.currentRow === 0) {
|
|
277
277
|
let stmt = this.statement;
|
|
278
278
|
if (stmt.cursorId !== 0 && !stmt.requiresFullExecute && !this.parseOnly && !stmt.requiresDefine && !stmt.isDdl && !this.batchErrors) {
|
|
279
|
-
if (stmt.isQuery && !stmt.requiresDefine && this.options.prefetchRows > 0) {
|
|
279
|
+
if (stmt.isQuery && !stmt.requiresDefine && !stmt.noPrefetch && this.options.prefetchRows > 0) {
|
|
280
280
|
this.functionCode = constants.TNS_FUNC_REEXECUTE_AND_FETCH;
|
|
281
281
|
} else {
|
|
282
282
|
this.functionCode = constants.TNS_FUNC_REEXECUTE;
|
|
@@ -116,7 +116,7 @@ class LobOpMessage extends Message {
|
|
|
116
116
|
buf.writeBytes(this.destLobImpl._locator);
|
|
117
117
|
}
|
|
118
118
|
if (this.operation === constants.TNS_LOB_OP_CREATE_TEMP) {
|
|
119
|
-
if (this.sourceLobImpl.dbType._csfrm === constants.
|
|
119
|
+
if (this.sourceLobImpl.dbType._csfrm === constants.CSFRM_NCHAR) {
|
|
120
120
|
buf.caps.checkNCharsetId();
|
|
121
121
|
buf.writeUB4(constants.TNS_CHARSET_UTF16);
|
|
122
122
|
} else {
|
|
@@ -128,7 +128,7 @@ class LobOpMessage extends Message {
|
|
|
128
128
|
buf.writeUInt8(constants.TNS_MSG_TYPE_LOB_DATA);
|
|
129
129
|
if (this.sourceLobImpl.dbType._oraTypeNum === constants.TNS_DATA_TYPE_BLOB) {
|
|
130
130
|
data = this.data;
|
|
131
|
-
} else if (this.sourceLobImpl.getCsfrm() === constants.
|
|
131
|
+
} else if (this.sourceLobImpl.getCsfrm() === constants.CSFRM_NCHAR) {
|
|
132
132
|
data = this.data;
|
|
133
133
|
// TODO: avoid conversion back to string, if possible
|
|
134
134
|
// this is since bind data is converted to buffer automatically, but if
|
|
@@ -154,7 +154,7 @@ class LobOpMessage extends Message {
|
|
|
154
154
|
if (data !== null) {
|
|
155
155
|
if (oraTypeNum === constants.TNS_DATA_TYPE_BLOB) {
|
|
156
156
|
data = Buffer.from(data);
|
|
157
|
-
} else if (this.sourceLobImpl.getCsfrm() === constants.
|
|
157
|
+
} else if (this.sourceLobImpl.getCsfrm() === constants.CSFRM_NCHAR) {
|
|
158
158
|
data = Buffer.from(data).swap16().toString('utf16le');
|
|
159
159
|
} else {
|
|
160
160
|
data = data.toString();
|
|
@@ -139,7 +139,7 @@ class MessageWithData extends Message {
|
|
|
139
139
|
|
|
140
140
|
let numBytes = buf.readUB4();
|
|
141
141
|
if (numBytes > 0) {
|
|
142
|
-
buf.
|
|
142
|
+
buf.skipBytesChunked(); // current date
|
|
143
143
|
}
|
|
144
144
|
buf.skipUB4(); // dcbflag
|
|
145
145
|
buf.skipUB4(); // dcbmdbz
|
|
@@ -147,7 +147,7 @@ class MessageWithData extends Message {
|
|
|
147
147
|
buf.skipUB4(); // dcbmxpr
|
|
148
148
|
numBytes = buf.readUB4();
|
|
149
149
|
if (numBytes > 0) {
|
|
150
|
-
buf.
|
|
150
|
+
buf.skipBytesChunked();
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
this.resultSetsToSetup.push(resultSet);
|
|
@@ -190,17 +190,17 @@ class MessageWithData extends Message {
|
|
|
190
190
|
let name;
|
|
191
191
|
numBytes = buf.readUB4();
|
|
192
192
|
if (numBytes > 0) {
|
|
193
|
-
name = buf.readStr(constants.
|
|
193
|
+
name = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
194
194
|
}
|
|
195
195
|
let schema;
|
|
196
196
|
numBytes = buf.readUB4();
|
|
197
197
|
if (numBytes > 0) {
|
|
198
|
-
schema = buf.readStr(constants.
|
|
198
|
+
schema = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
199
199
|
}
|
|
200
200
|
numBytes = buf.readUB4();
|
|
201
201
|
let typeName;
|
|
202
202
|
if (numBytes > 0) {
|
|
203
|
-
typeName = buf.readStr(constants.
|
|
203
|
+
typeName = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
204
204
|
}
|
|
205
205
|
buf.skipUB2(); // column position
|
|
206
206
|
buf.skipUB4(); // uds flag
|
|
@@ -356,7 +356,7 @@ class MessageWithData extends Message {
|
|
|
356
356
|
oraTypeNum === constants.TNS_DATA_TYPE_CHAR ||
|
|
357
357
|
oraTypeNum === constants.TNS_DATA_TYPE_LONG
|
|
358
358
|
) {
|
|
359
|
-
if (csfrm === constants.
|
|
359
|
+
if (csfrm === constants.CSFRM_NCHAR) {
|
|
360
360
|
buf.caps.checkNCharsetId();
|
|
361
361
|
}
|
|
362
362
|
colValue = buf.readStr(csfrm);
|
|
@@ -381,7 +381,7 @@ class MessageWithData extends Message {
|
|
|
381
381
|
colValue = buf.readOracleDate(useLocalTime);
|
|
382
382
|
} else if (oraTypeNum === constants.TNS_DATA_TYPE_ROWID) {
|
|
383
383
|
if (!this.inFetch) {
|
|
384
|
-
colValue = buf.readStr(constants.
|
|
384
|
+
colValue = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
385
385
|
} else {
|
|
386
386
|
let numBytes = buf.readUInt8();
|
|
387
387
|
if (isNullLength(numBytes)) {
|
|
@@ -393,7 +393,7 @@ class MessageWithData extends Message {
|
|
|
393
393
|
}
|
|
394
394
|
} else if (oraTypeNum === constants.TNS_DATA_TYPE_UROWID) {
|
|
395
395
|
if (!this.inFetch) {
|
|
396
|
-
colValue = buf.readStr(constants.
|
|
396
|
+
colValue = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
397
397
|
} else {
|
|
398
398
|
colValue = buf.readURowID();
|
|
399
399
|
}
|
|
@@ -479,7 +479,7 @@ class MessageWithData extends Message {
|
|
|
479
479
|
for (let i = 0; i < numParams; i++) {
|
|
480
480
|
numBytes = buf.readUB2(); // key
|
|
481
481
|
if (numBytes > 0) {
|
|
482
|
-
keyTextValue = buf.readStr(constants.
|
|
482
|
+
keyTextValue = buf.readStr(constants.CSFRM_IMPLICIT);
|
|
483
483
|
}
|
|
484
484
|
numBytes = buf.readUB2(); // value
|
|
485
485
|
if (numBytes > 0) {
|
|
@@ -547,6 +547,7 @@ class MessageWithData extends Message {
|
|
|
547
547
|
variable.maxSize = constants.TNS_MAX_LONG_LENGTH;
|
|
548
548
|
}
|
|
549
549
|
resultSet.statement.requiresDefine = true;
|
|
550
|
+
resultSet.statement.noPrefetch = true;
|
|
550
551
|
}
|
|
551
552
|
}
|
|
552
553
|
}
|
|
@@ -608,7 +609,7 @@ class MessageWithData extends Message {
|
|
|
608
609
|
// NCHAR, NVARCHAR reports ORA-01460: unimplemented or unreasonable
|
|
609
610
|
// conversion requested if maxSize is not multiplied by the
|
|
610
611
|
// bufferSizeFactor
|
|
611
|
-
if (variable.type._csfrm === constants.
|
|
612
|
+
if (variable.type._csfrm === constants.CSFRM_NCHAR) {
|
|
612
613
|
maxSize *= variable.type._bufferSizeFactor;
|
|
613
614
|
}
|
|
614
615
|
if ([constants.TNS_DATA_TYPE_ROWID, constants.TNS_DATA_TYPE_UROWID].includes(oraTypeNum)) {
|
|
@@ -732,7 +733,7 @@ class MessageWithData extends Message {
|
|
|
732
733
|
oraTypeNum === constants.TNS_DATA_TYPE_LONG ||
|
|
733
734
|
oraTypeNum === constants.TNS_DATA_TYPE_RAW ||
|
|
734
735
|
oraTypeNum === constants.TNS_DATA_TYPE_LONG_RAW) {
|
|
735
|
-
if (variable.type._csfrm === constants.
|
|
736
|
+
if (variable.type._csfrm === constants.CSFRM_NCHAR) {
|
|
736
737
|
buf.caps.checkNCharsetId();
|
|
737
738
|
value = Buffer.from(value, constants.TNS_ENCODING_UTF16).swap16();
|
|
738
739
|
} else {
|
|
@@ -254,46 +254,48 @@ class ReadPacket extends BaseBuffer {
|
|
|
254
254
|
* Receives a packet from the adapter.
|
|
255
255
|
*/
|
|
256
256
|
receivePacket() {
|
|
257
|
-
if (this.
|
|
257
|
+
if (this.savedPacketPos === this.savedPackets.length) {
|
|
258
258
|
const packet = this.nsi.syncRecvPacket();
|
|
259
|
-
if (!packet)
|
|
259
|
+
if (!packet || this.nsi.isBreak)
|
|
260
260
|
throw new utils.OutOfPacketsError();
|
|
261
|
-
this.
|
|
261
|
+
this.savedPackets.push(packet);
|
|
262
262
|
}
|
|
263
|
-
this.startPacket(this.
|
|
263
|
+
this.startPacket(this.savedPackets[this.savedPacketPos++]);
|
|
264
264
|
}
|
|
265
265
|
|
|
266
266
|
restorePoint() {
|
|
267
|
-
this.
|
|
268
|
-
this.startPacket(this.
|
|
267
|
+
this.savedPacketPos = 0;
|
|
268
|
+
this.startPacket(this.savedPackets[this.savedPacketPos++]);
|
|
269
269
|
this.pos = this.savedPos;
|
|
270
270
|
}
|
|
271
271
|
|
|
272
272
|
savePoint() {
|
|
273
|
-
if (this.
|
|
274
|
-
this.
|
|
273
|
+
if (this.savedPackets) {
|
|
274
|
+
this.savedPackets = this.savedPackets.splice(this.savedPacketPos - 1);
|
|
275
275
|
} else {
|
|
276
|
-
this.
|
|
276
|
+
this.savedPackets = [this.packet];
|
|
277
277
|
}
|
|
278
|
-
this.
|
|
278
|
+
this.savedPacketPos = 1;
|
|
279
279
|
this.savedPos = this.pos;
|
|
280
280
|
}
|
|
281
281
|
|
|
282
|
-
startPacket(
|
|
283
|
-
this.
|
|
282
|
+
startPacket(packet) {
|
|
283
|
+
this.packet = packet;
|
|
284
|
+
this.buf = packet.buf;
|
|
284
285
|
this.pos = 10; // skip packet heaader and data flags
|
|
285
|
-
this.size = buf.length;
|
|
286
|
+
this.size = packet.buf.length;
|
|
287
|
+
this.packetNum = packet.num;
|
|
286
288
|
}
|
|
287
289
|
|
|
288
290
|
async waitForPackets() {
|
|
289
291
|
const packet = await this.nsi.recvPacket();
|
|
290
|
-
if (!this.
|
|
291
|
-
this.
|
|
292
|
-
this.
|
|
292
|
+
if (!this.savedPackets) {
|
|
293
|
+
this.savedPackets = [packet];
|
|
294
|
+
this.savedPacketPos = 0;
|
|
293
295
|
} else {
|
|
294
|
-
this.
|
|
296
|
+
this.savedPackets.push(packet);
|
|
295
297
|
}
|
|
296
|
-
this.startPacket(this.
|
|
298
|
+
this.startPacket(this.savedPackets[this.savedPacketPos++]);
|
|
297
299
|
}
|
|
298
300
|
|
|
299
301
|
/**
|
|
@@ -71,6 +71,7 @@ class Protocol {
|
|
|
71
71
|
while (true) { // eslint-disable-line
|
|
72
72
|
if (this.nsi.isBreak) {
|
|
73
73
|
await this.resetMessage();
|
|
74
|
+
delete this.readBuf.savedBuffers;
|
|
74
75
|
await this.readBuf.waitForPackets();
|
|
75
76
|
}
|
|
76
77
|
try {
|
|
@@ -78,8 +79,10 @@ class Protocol {
|
|
|
78
79
|
break;
|
|
79
80
|
} catch (err) {
|
|
80
81
|
if (err instanceof utils.OutOfPacketsError) {
|
|
81
|
-
|
|
82
|
-
|
|
82
|
+
if (!this.nsi.isBreak) {
|
|
83
|
+
await this.readBuf.waitForPackets();
|
|
84
|
+
this.readBuf.restorePoint();
|
|
85
|
+
}
|
|
83
86
|
continue;
|
|
84
87
|
}
|
|
85
88
|
throw (err);
|
|
@@ -108,7 +111,7 @@ class Protocol {
|
|
|
108
111
|
this.writeBuf.endRequest();
|
|
109
112
|
}
|
|
110
113
|
|
|
111
|
-
async _recoverFromError(message) {
|
|
114
|
+
async _recoverFromError(caughtErr, message) {
|
|
112
115
|
/*
|
|
113
116
|
* We have NJS error(protocol related) detected during packet write/read
|
|
114
117
|
* operation. Issue a break and reset to clear channel . We receive the
|
|
@@ -121,10 +124,12 @@ class Protocol {
|
|
|
121
124
|
await this.readBuf.waitForPackets();
|
|
122
125
|
message.decode(this.readBuf);
|
|
123
126
|
} catch (err) { // Recovery failed
|
|
124
|
-
// TODO: throw different error indicating that reset failed, probably
|
|
125
|
-
// put inside resetMessage()
|
|
126
127
|
this.nsi.disconnect();
|
|
127
|
-
errors.
|
|
128
|
+
const newErr = errors.getErr(errors.ERR_CONNECTION_CLOSED);
|
|
129
|
+
caughtErr.message = newErr.message +
|
|
130
|
+
"\nError recovery failed: " + err.message +
|
|
131
|
+
"\nOriginal error: " + caughtErr.message;
|
|
132
|
+
throw caughtErr;
|
|
128
133
|
}
|
|
129
134
|
}
|
|
130
135
|
|
|
@@ -150,7 +155,7 @@ class Protocol {
|
|
|
150
155
|
} catch (err) {
|
|
151
156
|
if (!this.connInProgress &&
|
|
152
157
|
err.code !== errors.ERR_CONNECTION_CLOSED_CODE) {
|
|
153
|
-
await this._recoverFromError(message);
|
|
158
|
+
await this._recoverFromError(err, message);
|
|
154
159
|
}
|
|
155
160
|
throw err;
|
|
156
161
|
} finally {
|
|
@@ -28,8 +28,7 @@
|
|
|
28
28
|
|
|
29
29
|
const { NavAddress, NavAddressList, NavDescription, NavDescriptionList } = require("./navNodes.js");
|
|
30
30
|
const { createNVPair } = require("./nvStrToNvPair.js");
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
const errors = require("../../errors.js");
|
|
33
32
|
|
|
34
33
|
/**
|
|
35
34
|
* Class that holds all possible attributes under Description
|
|
@@ -166,6 +165,9 @@ async function createNode(str) {
|
|
|
166
165
|
case "DESCRIPTION_LIST":
|
|
167
166
|
navobj = new NavDescriptionList();
|
|
168
167
|
break;
|
|
168
|
+
default:
|
|
169
|
+
errors.throwErr(errors.ERR_INVALID_CONNECT_STRING_PARAMETERS,
|
|
170
|
+
`unknown top element ${arg}`);
|
|
169
171
|
}
|
|
170
172
|
navobj.initFromNVPair(nvpair);
|
|
171
173
|
let cs = new ConnStrategy();
|
|
@@ -39,8 +39,7 @@ Test Case in oracle_private/ezconnectTest.js
|
|
|
39
39
|
const HOSTNAMES_PATTERN = new RegExp("((?=(?<hostnames>(((\\[[A-z0-9:]+\\])|([A-z0-9][A-z0-9._-]+))[,]?)+)))\\k<hostnames>(:(?<port>\\d+)?)?", 'g');
|
|
40
40
|
|
|
41
41
|
// The EZConnect pattern without the extended settings part.
|
|
42
|
-
const EZ_URL_PATTERN = new RegExp("^((?<protocol>
|
|
43
|
-
+ "(//)?"
|
|
42
|
+
const EZ_URL_PATTERN = new RegExp("^(((?<protocol>[A-z0-9]+):)?//)?"
|
|
44
43
|
+ "(?<hostinfo>(" + HOSTNAMES_PATTERN.source + "(?=([,]|[;]|[/]|[:]|$))([,]|[;])?)+)"
|
|
45
44
|
+ "(/(?<servicename>[A-z0-9][A-z0-9,-.]+)?)"
|
|
46
45
|
+ "?(:(?<servermode>dedicated|shared|pooled))"
|
|
@@ -145,8 +144,9 @@ class EZConnectResolver {
|
|
|
145
144
|
if (protocol == null) {
|
|
146
145
|
if (!(url.includes("//")))
|
|
147
146
|
protocol = 'TCP';
|
|
147
|
+
} else if (protocol.toLowerCase() != 'tcp' && protocol.toLowerCase() != 'tcps') {
|
|
148
|
+
errors.throwErr(errors.ERR_INVALID_EZCONNECT_SYNTAX, 'Unsupported protocol in thin mode', protocol);
|
|
148
149
|
}
|
|
149
|
-
|
|
150
150
|
// Try to get the proxy information from URL properties
|
|
151
151
|
const proxyHost = this.urlProps.get("HTTPS_PROXY");
|
|
152
152
|
const proxyPort = this.urlProps.get("HTTPS_PROXY_PORT");
|
|
@@ -216,8 +216,12 @@ class EZConnectResolver {
|
|
|
216
216
|
let ipcnt = 0;
|
|
217
217
|
let builder = new Array();
|
|
218
218
|
let proxyInfo = '';
|
|
219
|
-
if (proxyHost != null
|
|
220
|
-
|
|
219
|
+
if (proxyHost != null) {
|
|
220
|
+
if (proxyPort != null) {
|
|
221
|
+
proxyInfo = `(HTTPS_PROXY=${proxyHost})(HTTPS_PROXY_PORT=${proxyPort})`;
|
|
222
|
+
} else {
|
|
223
|
+
proxyInfo = `(HTTPS_PROXY=${proxyHost})`;
|
|
224
|
+
}
|
|
221
225
|
}
|
|
222
226
|
|
|
223
227
|
if (protocol == null) protocol = 'TCP';
|
|
@@ -32,6 +32,7 @@ const os = require("os");
|
|
|
32
32
|
const net = require('net');
|
|
33
33
|
const dns = require('dns');
|
|
34
34
|
const dnsPromises = dns.promises;
|
|
35
|
+
const cInfo = require("../util.js").CLIENT_INFO;
|
|
35
36
|
|
|
36
37
|
const SchemaObjectFactoryInterface = {
|
|
37
38
|
ADDR:0,
|
|
@@ -443,7 +444,6 @@ const NavSchemaObject = {
|
|
|
443
444
|
LB: "(LOAD_BALANCE=yes)",
|
|
444
445
|
NFO: "(FAILOVER=false)",
|
|
445
446
|
CD: "(CONNECT_DATA=",
|
|
446
|
-
CID: `(CID=(PROGRAM=nodejs)(HOST=${os.hostname()})(USER=${os.userInfo().username}))`,
|
|
447
447
|
CONID: "(CONNECTION_ID="
|
|
448
448
|
};
|
|
449
449
|
const options = {
|
|
@@ -770,10 +770,10 @@ class NavDescription extends Description {
|
|
|
770
770
|
if (this.connectData == null) {
|
|
771
771
|
this.connectData = "(SERVICE_NAME=)";
|
|
772
772
|
}
|
|
773
|
-
|
|
773
|
+
const cid = `(CID=(PROGRAM=${cInfo.program})(HOST=${cInfo.hostName})(USER=${cInfo.userName}))`;
|
|
774
774
|
cOpts[i].CNdata.push(NavSchemaObject.CD);
|
|
775
775
|
cOpts[i].CNdata.push(this.connectData);
|
|
776
|
-
cOpts[i].CNdata.push(
|
|
776
|
+
cOpts[i].CNdata.push(cid);
|
|
777
777
|
cOpts[i].CNdata.push(")");
|
|
778
778
|
|
|
779
779
|
if (this.SID != null) {
|
|
@@ -165,6 +165,9 @@ class NetworkSession {
|
|
|
165
165
|
* Make the transport level connection
|
|
166
166
|
*/
|
|
167
167
|
async transportConnect(address) {
|
|
168
|
+
if (address.protocol.toUpperCase() == 'TCP' && address.httpsProxy) {
|
|
169
|
+
errors.throwErr(errors.ERR_INVALID_CONNECT_STRING_PARAMETERS, 'https proxy requires protocol as', 'tcps ');
|
|
170
|
+
}
|
|
168
171
|
if (address.protocol && (address.protocol.toUpperCase() == 'TCP' || address.protocol.toUpperCase() == 'TCPS')) {
|
|
169
172
|
this.ntAdapter = new NTTCP(this.sAtts.nt);
|
|
170
173
|
} else {
|
|
@@ -173,8 +176,8 @@ class NetworkSession {
|
|
|
173
176
|
await this.ntAdapter.connect(address);
|
|
174
177
|
this.ntAdapter.startRead();
|
|
175
178
|
this.sAtts.ntCha = this.ntAdapter.cha;
|
|
176
|
-
this.sndDatapkt = new Packet.DataPacket(this.sAtts.
|
|
177
|
-
this.rcvDatapkt = new Packet.DataPacket(this.sAtts.
|
|
179
|
+
this.sndDatapkt = new Packet.DataPacket(this.sAtts.largeSDU);
|
|
180
|
+
this.rcvDatapkt = new Packet.DataPacket(this.sAtts.largeSDU);
|
|
178
181
|
}
|
|
179
182
|
|
|
180
183
|
/**
|
|
@@ -280,17 +283,16 @@ class NetworkSession {
|
|
|
280
283
|
}
|
|
281
284
|
|
|
282
285
|
connectPkt = new Packet.ConnectPacket(redirConnData, this.sAtts, constants.NSPFRDR);
|
|
286
|
+
this.sndDatapkt = new Packet.DataPacket(this.sAtts.largeSDU);
|
|
283
287
|
this._sendConnect(connectPkt);
|
|
284
288
|
}
|
|
285
289
|
}
|
|
286
290
|
|
|
287
291
|
/* Accepted */
|
|
288
292
|
this.connected = true;
|
|
289
|
-
this.
|
|
290
|
-
this.
|
|
291
|
-
this.
|
|
292
|
-
this.sndDatapkt = new Packet.DataPacket(this.sAtts.sdu, this.sAtts.largeSDU);
|
|
293
|
-
this.sndDatapkt.createPacket();
|
|
293
|
+
this.cData = null;
|
|
294
|
+
this.sndDatapkt = new Packet.DataPacket(this.sAtts.largeSDU);
|
|
295
|
+
this.sndDatapkt.createPacket(constants.NSPDADAT); //Currently only used for disconnect
|
|
294
296
|
this.sndDatapkt.offset = this.sndDatapkt.dataPtr;
|
|
295
297
|
this.sndDatapkt.len = this.sndDatapkt.bufLen;
|
|
296
298
|
this.markerPkt = new Packet.MarkerPacket(this.sAtts.largeSDU);
|
|
@@ -466,7 +468,7 @@ class NetworkSession {
|
|
|
466
468
|
let bytesCopied = 0;
|
|
467
469
|
|
|
468
470
|
this.sndDatapkt.dataLen = this.sndDatapkt.offset;
|
|
469
|
-
if (this.sndDatapkt.dataLen < this.sndDatapkt.bufLen) {
|
|
471
|
+
if (this.sndDatapkt.dataLen < this.sndDatapkt.bufLen || !this.sndDatapkt.bufLen) {
|
|
470
472
|
bytesCopied = this.sndDatapkt.fillBuf(userBuf, offset, len);
|
|
471
473
|
len -= bytesCopied;
|
|
472
474
|
offset += bytesCopied;
|
|
@@ -591,7 +593,6 @@ class NetworkSession {
|
|
|
591
593
|
let error = 0;
|
|
592
594
|
if (this.controlPkt.errno) { /* Control pkt already read */
|
|
593
595
|
error = this.controlPkt.errno;
|
|
594
|
-
this.controlPkt.clear(); /* Clear error */
|
|
595
596
|
return (error);
|
|
596
597
|
} else if (!this.getOption(constants.HEALTHCHECK)) {
|
|
597
598
|
return errors.ERR_CONNECTION_CLOSED;
|
|
@@ -602,7 +603,6 @@ class NetworkSession {
|
|
|
602
603
|
if (packet.type == constants.NSPTCNL) {
|
|
603
604
|
this.controlPkt.fromPacket(packet);
|
|
604
605
|
error = this.controlPkt.errno;
|
|
605
|
-
this.controlPkt.clear(); /* Clear error */
|
|
606
606
|
return (error);
|
|
607
607
|
} else {
|
|
608
608
|
this.ntAdapter.packets.unshift(packet); /* Push packet back */
|
package/lib/thin/sqlnet/ntTcp.js
CHANGED
|
@@ -47,6 +47,8 @@ const TCPCHA = 1 << 1 | /* ASYNC support */
|
|
|
47
47
|
1 << 9 | /* Full Duplex support */
|
|
48
48
|
1 << 12; /* SIGPIPE Support */
|
|
49
49
|
|
|
50
|
+
let streamNum = 1;
|
|
51
|
+
|
|
50
52
|
/**
|
|
51
53
|
* Network Transport TCP/TCPS adapter
|
|
52
54
|
* @param {Address} address Destination Address
|
|
@@ -63,6 +65,8 @@ class NTTCP {
|
|
|
63
65
|
this.numPacketsSinceLastWait = 0;
|
|
64
66
|
this.secure = false;
|
|
65
67
|
this.largeSDU = false;
|
|
68
|
+
this.streamNum = streamNum++;
|
|
69
|
+
this.packetNum = 1;
|
|
66
70
|
}
|
|
67
71
|
|
|
68
72
|
/**
|
|
@@ -240,7 +244,8 @@ class NTTCP {
|
|
|
240
244
|
}
|
|
241
245
|
this.stream = null;
|
|
242
246
|
this.connected = false;
|
|
243
|
-
this.
|
|
247
|
+
this.drainWaiter = null;
|
|
248
|
+
this.readWaiter = null;
|
|
244
249
|
}
|
|
245
250
|
|
|
246
251
|
/**
|
|
@@ -318,21 +323,19 @@ class NTTCP {
|
|
|
318
323
|
send(buf) {
|
|
319
324
|
this.checkErr();
|
|
320
325
|
if (process.env.NODE_ORACLEDB_DEBUG_PACKETS)
|
|
321
|
-
this.printPacket(
|
|
326
|
+
this.printPacket(`Sending packet ${this.packetNum} on stream ${this.streamNum}`, buf);
|
|
322
327
|
const result = this.stream.write(buf, (err) => {
|
|
323
328
|
if (err) {
|
|
324
329
|
this.savedErr = err;
|
|
325
330
|
this.err = true;
|
|
326
|
-
|
|
327
|
-
this.waiter();
|
|
328
|
-
this.waiter = null;
|
|
329
|
-
}
|
|
331
|
+
this._notifyWaiters();
|
|
330
332
|
}
|
|
331
333
|
});
|
|
332
334
|
if (!result) {
|
|
333
335
|
this.needsDrain = true;
|
|
334
336
|
}
|
|
335
337
|
this.numPacketsSinceLastWait++;
|
|
338
|
+
this.packetNum++;
|
|
336
339
|
}
|
|
337
340
|
|
|
338
341
|
/**
|
|
@@ -352,7 +355,9 @@ class NTTCP {
|
|
|
352
355
|
async pauseWrite() {
|
|
353
356
|
this.checkErr();
|
|
354
357
|
if (this.needsDrain) {
|
|
355
|
-
await new Promise((resolve) =>
|
|
358
|
+
await new Promise((resolve) => {
|
|
359
|
+
this.drainWaiter = resolve;
|
|
360
|
+
});
|
|
356
361
|
this.checkErr();
|
|
357
362
|
} else {
|
|
358
363
|
await new Promise((resolve) => Timers.setImmediate(resolve));
|
|
@@ -394,15 +399,16 @@ class NTTCP {
|
|
|
394
399
|
const packet = {
|
|
395
400
|
buf: tempBuf.subarray(0, len),
|
|
396
401
|
type: tempBuf[4],
|
|
397
|
-
flags: tempBuf[5]
|
|
402
|
+
flags: tempBuf[5],
|
|
403
|
+
num : this.packetNum++
|
|
398
404
|
};
|
|
399
405
|
this.packets.push(packet);
|
|
400
|
-
if (this.
|
|
401
|
-
this.
|
|
402
|
-
this.
|
|
406
|
+
if (this.readWaiter) {
|
|
407
|
+
this.readWaiter();
|
|
408
|
+
this.readWaiter = null;
|
|
403
409
|
}
|
|
404
410
|
if (process.env.NODE_ORACLEDB_DEBUG_PACKETS)
|
|
405
|
-
this.printPacket(
|
|
411
|
+
this.printPacket(`Receiving packet ${packet.num} on stream ${this.streamNum}`, packet.buf);
|
|
406
412
|
|
|
407
413
|
// if the packet consumed all of the bytes (most common scenario), then
|
|
408
414
|
// simply clear the temporary buffer; otherwise, retain whatever bytes
|
|
@@ -436,7 +442,7 @@ class NTTCP {
|
|
|
436
442
|
if (this.packets.length === 0) {
|
|
437
443
|
this.checkErr();
|
|
438
444
|
await new Promise((resolve) => {
|
|
439
|
-
this.
|
|
445
|
+
this.readWaiter = resolve;
|
|
440
446
|
this.numPacketsSinceLastWait = 0;
|
|
441
447
|
});
|
|
442
448
|
this.checkErr();
|
|
@@ -472,26 +478,25 @@ class NTTCP {
|
|
|
472
478
|
this.stream.on('error', (err) => {
|
|
473
479
|
this.savedErr = err;
|
|
474
480
|
this.err = true;
|
|
475
|
-
|
|
476
|
-
this.waiter();
|
|
477
|
-
this.waiter = null;
|
|
478
|
-
}
|
|
481
|
+
this._notifyWaiters();
|
|
479
482
|
});
|
|
480
483
|
|
|
481
484
|
this.stream.on('end', () => {
|
|
482
485
|
this.err = true;
|
|
483
|
-
|
|
484
|
-
this.waiter();
|
|
485
|
-
this.waiter = null;
|
|
486
|
-
}
|
|
486
|
+
this._notifyWaiters();
|
|
487
487
|
});
|
|
488
488
|
|
|
489
489
|
this.stream.on('close', () => {
|
|
490
490
|
this.connected = false;
|
|
491
|
+
this._notifyWaiters();
|
|
491
492
|
});
|
|
492
493
|
|
|
493
494
|
this.stream.on('drain', () => {
|
|
494
495
|
this.needsDrain = false;
|
|
496
|
+
if (this.drainWaiter) {
|
|
497
|
+
this.drainWaiter();
|
|
498
|
+
this.drainWaiter = null;
|
|
499
|
+
}
|
|
495
500
|
});
|
|
496
501
|
|
|
497
502
|
}
|
|
@@ -516,6 +521,20 @@ class NTTCP {
|
|
|
516
521
|
}
|
|
517
522
|
}
|
|
518
523
|
|
|
524
|
+
/**
|
|
525
|
+
* Notify the waiters (drain and read) and reset them, if applicable.
|
|
526
|
+
*/
|
|
527
|
+
_notifyWaiters() {
|
|
528
|
+
if (this.drainWaiter) {
|
|
529
|
+
this.drainWaiter();
|
|
530
|
+
this.drainWaiter = null;
|
|
531
|
+
}
|
|
532
|
+
if (this.readWaiter) {
|
|
533
|
+
this.readWaiter();
|
|
534
|
+
this.readWaiter = null;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
519
538
|
}
|
|
520
539
|
|
|
521
540
|
module.exports = NTTCP;
|
|
@@ -52,7 +52,7 @@ function ConnectPacket(connectData, sAtts, flags = 0) {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
/* Building Connect Packet */
|
|
55
|
-
this.buf = Buffer.
|
|
55
|
+
this.buf = Buffer.allocUnsafe(size).fill(0);
|
|
56
56
|
this.buf.writeUInt16BE(size, constants.NSPHDLEN);
|
|
57
57
|
this.buf.writeUInt8(flags, constants.NSPHDFLGS);
|
|
58
58
|
this.buf.writeUInt8(constants.NSPTCN, constants.NSPHDTYP);
|
|
@@ -142,24 +142,24 @@ function ConnectPacket(connectData, sAtts, flags = 0) {
|
|
|
142
142
|
* @param {int} size of Data Packet
|
|
143
143
|
* @param {boolean} isLargeSDU Large SDU
|
|
144
144
|
*/
|
|
145
|
-
function DataPacket(
|
|
145
|
+
function DataPacket(isLargeSDU) {
|
|
146
146
|
this.dataPtr = 0; /* data offset start */
|
|
147
147
|
this.dataLen = 0; /* data offset end */
|
|
148
|
-
this.bufLen = size; /* Length of buffer */
|
|
149
148
|
this.offset = 0; /* Offset for buffer read/write (fastpath) */
|
|
150
149
|
this.len = 0; /* Length of buffer read/write (fastpath) */
|
|
150
|
+
this.bufLen = 0; /* Length of buffer */
|
|
151
151
|
|
|
152
152
|
/**
|
|
153
153
|
* Create the Data Packet(Internal)
|
|
154
154
|
*/
|
|
155
|
-
this.createPacket = function() {
|
|
155
|
+
this.createPacket = function(len) {
|
|
156
156
|
/* Building Data Packet */
|
|
157
157
|
this.dataPtr = constants.NSPDADAT;
|
|
158
158
|
this.dataLen = constants.NSPDADAT;
|
|
159
|
-
|
|
160
|
-
this.buf = Buffer.alloc(size);
|
|
159
|
+
this.buf = Buffer.allocUnsafe(len).fill(0);
|
|
161
160
|
this.buf.writeUInt8(0, constants.NSPHDFLGS);
|
|
162
161
|
this.buf.writeUInt8(constants.NSPTDA, constants.NSPHDTYP);
|
|
162
|
+
this.bufLen = len; /* Length of buffer */
|
|
163
163
|
};
|
|
164
164
|
|
|
165
165
|
/**
|
|
@@ -173,7 +173,7 @@ function DataPacket(size, isLargeSDU) {
|
|
|
173
173
|
let bytes2Copy;
|
|
174
174
|
|
|
175
175
|
if (!this.buf) {
|
|
176
|
-
this.createPacket();
|
|
176
|
+
this.createPacket(len + constants.NSPDADAT); //Currently NS data packets are being used only in the connect/disconnect phase
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
if (len > this.bufLen - this.dataLen) {
|
|
@@ -377,7 +377,7 @@ function ControlPacket() {
|
|
|
377
377
|
} else if (err1 == NSESENDMESG) {
|
|
378
378
|
this.errno = err1;
|
|
379
379
|
this.notifLen = err2;
|
|
380
|
-
this.notif = Buffer.
|
|
380
|
+
this.notif = Buffer.allocUnsafe(err2 + 1).fill(0);
|
|
381
381
|
this.buf.copy(this.notif, 0, constants.NSPCTLDAT + 12, constants.NSPCTLDAT + 12 + err2);
|
|
382
382
|
} else {
|
|
383
383
|
this.errno = err1;
|
package/lib/thin/statement.js
CHANGED
package/lib/thin/util.js
CHANGED
|
@@ -28,6 +28,26 @@
|
|
|
28
28
|
|
|
29
29
|
const constants = require('../constants');
|
|
30
30
|
const errors = require('../errors.js');
|
|
31
|
+
const os = require('os');
|
|
32
|
+
|
|
33
|
+
//---------------------------------------------------------------------------
|
|
34
|
+
// populateClientInfo()
|
|
35
|
+
//
|
|
36
|
+
// Populates client process information
|
|
37
|
+
//---------------------------------------------------------------------------
|
|
38
|
+
function populateClientInfo() {
|
|
39
|
+
this.program = process.argv0;
|
|
40
|
+
this.terminal = "unknown";
|
|
41
|
+
this.pid = process.pid.toString();
|
|
42
|
+
try {
|
|
43
|
+
this.userName = os.userInfo().username;
|
|
44
|
+
} catch {
|
|
45
|
+
this.userName = "unknown";
|
|
46
|
+
}
|
|
47
|
+
this.hostName = os.hostname();
|
|
48
|
+
}
|
|
49
|
+
// Initialize client data on startup.
|
|
50
|
+
const CLIENT_INFO = new populateClientInfo();
|
|
31
51
|
|
|
32
52
|
//---------------------------------------------------------------------------
|
|
33
53
|
// getMetadataMany(sql)
|
|
@@ -280,6 +300,7 @@ function checkCredentials(params) {
|
|
|
280
300
|
module.exports = {
|
|
281
301
|
getMetadataMany,
|
|
282
302
|
cleanSql,
|
|
303
|
+
CLIENT_INFO,
|
|
283
304
|
getExecuteOutBinds,
|
|
284
305
|
getExecuteManyOutBinds,
|
|
285
306
|
getOutBinds,
|
package/lib/version.js
CHANGED
package/package.json
CHANGED
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
oracledb-6.0.2-darwin-x64.node v18.16.0 5caec79c2095133bc3d39b0e08d0d7a7952a4352 ccbaddf0256153ecfa6702c6ae1a4e5003e3775e Tue, 20 Jun 2023 15:14:06 GMT
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
5caec79c2095133bc3d39b0e08d0d7a7952a4352
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
oracledb-6.0.2-linux-arm64.node v14.16.0 5caec79c2095133bc3d39b0e08d0d7a7952a4352 ccbaddf0256153ecfa6702c6ae1a4e5003e3775e Tue, 20 Jun 2023 16:56:30 GMT
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
oracledb-6.0.2-linux-x64.node v16.20.0 5caec79c2095133bc3d39b0e08d0d7a7952a4352 ccbaddf0256153ecfa6702c6ae1a4e5003e3775e Tue, 20 Jun 2023 15:29:14 GMT
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
oracledb-6.0.2-win32-x64.node v16.19.0 5caec79c2095133bc3d39b0e08d0d7a7952a4352 ccbaddf0256153ecfa6702c6ae1a4e5003e3775e Tue, 20 Jun 2023 15:13:50 GMT
|
|
File without changes
|