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.
Files changed (43) hide show
  1. package/README.md +15 -17
  2. package/SECURITY.md +1 -1
  3. package/build/Release/oracledb-6.0.3-darwin-x64.node +0 -0
  4. package/build/Release/oracledb-6.0.3-darwin-x64.node-buildinfo.txt +1 -0
  5. package/build/Release/oracledb-6.0.3-js-buildinfo.txt +1 -0
  6. package/build/Release/oracledb-6.0.3-linux-arm64.node +0 -0
  7. package/build/Release/oracledb-6.0.3-linux-arm64.node-buildinfo.txt +1 -0
  8. package/build/Release/oracledb-6.0.3-linux-x64.node-buildinfo.txt +1 -0
  9. package/build/Release/{oracledb-6.0.2-win32-x64.node → oracledb-6.0.3-win32-x64.node} +0 -0
  10. package/build/Release/oracledb-6.0.3-win32-x64.node-buildinfo.txt +1 -0
  11. package/lib/errors.js +5 -4
  12. package/lib/pool.js +4 -1
  13. package/lib/settings.js +1 -1
  14. package/lib/thin/dbObject.js +2 -2
  15. package/lib/thin/lob.js +2 -2
  16. package/lib/thin/pool.js +0 -3
  17. package/lib/thin/protocol/buffer.js +5 -5
  18. package/lib/thin/protocol/constants.js +5 -4
  19. package/lib/thin/protocol/messages/auth.js +7 -9
  20. package/lib/thin/protocol/messages/base.js +10 -10
  21. package/lib/thin/protocol/messages/execute.js +5 -5
  22. package/lib/thin/protocol/messages/lobOp.js +3 -3
  23. package/lib/thin/protocol/messages/withData.js +12 -11
  24. package/lib/thin/protocol/packet.js +20 -18
  25. package/lib/thin/protocol/protocol.js +12 -7
  26. package/lib/thin/sqlnet/connStrategy.js +4 -2
  27. package/lib/thin/sqlnet/ezConnectResolver.js +9 -5
  28. package/lib/thin/sqlnet/navNodes.js +3 -3
  29. package/lib/thin/sqlnet/networkSession.js +10 -10
  30. package/lib/thin/sqlnet/ntTcp.js +40 -21
  31. package/lib/thin/sqlnet/packet.js +8 -8
  32. package/lib/thin/statement.js +1 -0
  33. package/lib/thin/util.js +21 -0
  34. package/lib/version.js +1 -1
  35. package/package.json +1 -1
  36. package/build/Release/oracledb-6.0.2-darwin-x64.node +0 -0
  37. package/build/Release/oracledb-6.0.2-darwin-x64.node-buildinfo.txt +0 -1
  38. package/build/Release/oracledb-6.0.2-js-buildinfo.txt +0 -1
  39. package/build/Release/oracledb-6.0.2-linux-arm64.node +0 -0
  40. package/build/Release/oracledb-6.0.2-linux-arm64.node-buildinfo.txt +0 -1
  41. package/build/Release/oracledb-6.0.2-linux-x64.node-buildinfo.txt +0 -1
  42. package/build/Release/oracledb-6.0.2-win32-x64.node-buildinfo.txt +0 -1
  43. /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.2
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.2 to connect Node.js 14.6, or later, to Oracle
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][32] and the [release
24
- notes][33].
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][30] directory. Start with [examples/example.js][31].
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][34].
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][35].
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](./SECURITY.md) for our responsible security
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
- [30]: https://github.com/oracle/node-oracledb/blob/main/examples
83
- [31]: https://github.com/oracle/node-oracledb/blob/main/examples/example.js
84
- [32]: https://node-oracledb.readthedocs.io/en/latest/
85
- [33]: https://node-oracledb.readthedocs.io/en/latest/release_notes.html
86
- [34]: https://github.com/oracle/node-oracledb/blob/main/test/README.md
87
- [35]: https://github.com/oracle/node-oracledb/blob/main/CONTRIBUTING.md
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
- [Oracle Critical Patch Update][3] program. Additional
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
 
@@ -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
@@ -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
@@ -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 with NJS errors
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
- settings.addToOptions(options, "connectionClass");
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) {
@@ -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.TNS_CS_IMPLICIT);
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.TNS_CS_NCHAR);
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.TNS_CS_NCHAR) {
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.TNS_CS_NCHAR;
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.TNS_CS_IMPLICIT)
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.floor(year / 100) + 100;
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.floor(year / 100) + 100;
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", process.argv0);
188
- buf.writeKeyValue("AUTH_MACHINE", os.hostname());
189
- buf.writeKeyValue("AUTH_PID", process.pid.toString());
190
- buf.writeKeyValue("AUTH_SID", os.userInfo().username);
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.TNS_CS_IMPLICIT);
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.TNS_CS_IMPLICIT);
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.TNS_CS_IMPLICIT);
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.TNS_CS_IMPLICIT);
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.TNS_CS_IMPLICIT);
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
- const nb = buf.readUB2();
234
- buf.skipBytes(nb + 1);
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.skipBytes(temp16 + 1);
243
+ buf.skipBytesChunked();
244
244
  }
245
245
  temp16 = buf.readUB2();
246
246
  if (temp16 > 0) { // skip value
247
- buf.skipBytes(temp16 + 1);
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.skipBytes(temp16 + 1);
274
+ buf.skipBytesChunked();
275
275
  }
276
276
  temp16 = buf.readUB2();
277
277
  if (temp16 > 0) { // skip value
278
- buf.skipBytes(temp16 + 1);
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 == 0 || stmt.isDdl) {
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.TNS_CS_NCHAR) {
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.TNS_CS_NCHAR) {
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.TNS_CS_NCHAR) {
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.skipBytes(numBytes + 1); // current date
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.skipBytes(numBytes + 1);
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.TNS_CS_IMPLICIT);
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.TNS_CS_IMPLICIT);
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.TNS_CS_IMPLICIT);
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.TNS_CS_NCHAR) {
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.TNS_CS_IMPLICIT);
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.TNS_CS_IMPLICIT);
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.TNS_CS_IMPLICIT);
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.TNS_CS_NCHAR) {
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.TNS_CS_NCHAR) {
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.savedBufferPos === this.savedBuffers.length) {
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.savedBuffers.push(packet.buf);
261
+ this.savedPackets.push(packet);
262
262
  }
263
- this.startPacket(this.savedBuffers[this.savedBufferPos++]);
263
+ this.startPacket(this.savedPackets[this.savedPacketPos++]);
264
264
  }
265
265
 
266
266
  restorePoint() {
267
- this.savedBufferPos = 0;
268
- this.startPacket(this.savedBuffers[this.savedBufferPos++]);
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.savedBuffers) {
274
- this.savedBuffers = this.savedBuffers.splice(this.savedBufferPos - 1);
273
+ if (this.savedPackets) {
274
+ this.savedPackets = this.savedPackets.splice(this.savedPacketPos - 1);
275
275
  } else {
276
- this.savedBuffers = [this.buf];
276
+ this.savedPackets = [this.packet];
277
277
  }
278
- this.savedBufferPos = 1;
278
+ this.savedPacketPos = 1;
279
279
  this.savedPos = this.pos;
280
280
  }
281
281
 
282
- startPacket(buf) {
283
- this.buf = buf;
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.savedBuffers) {
291
- this.savedBuffers = [packet.buf];
292
- this.savedBufferPos = 0;
292
+ if (!this.savedPackets) {
293
+ this.savedPackets = [packet];
294
+ this.savedPacketPos = 0;
293
295
  } else {
294
- this.savedBuffers.push(packet.buf);
296
+ this.savedPackets.push(packet);
295
297
  }
296
- this.startPacket(this.savedBuffers[this.savedBufferPos++]);
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
- await this.readBuf.waitForPackets();
82
- this.readBuf.restorePoint();
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.throwErr(errors.ERR_CONNECTION_CLOSED);
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>tcp|tcps):)?"
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 && proxyPort != null) {
220
- proxyInfo = `(HTTPS_PROXY=${proxyHost})(HTTPS_PROXY_PORT=${proxyPort})`;
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(NavSchemaObject.CID);
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.sdu, this.sAtts.largeSDU);
177
- this.rcvDatapkt = new Packet.DataPacket(this.sAtts.sdu, this.sAtts.largeSDU);
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.rcvDatapkt = new Packet.DataPacket(this.sAtts.sdu, this.sAtts.largeSDU);
290
- this.rcvDatapkt.offset = this.rcvDatapkt.dataPtr;
291
- this.rcvDatapkt.len = this.rcvDatapkt.dataPtr;
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 */
@@ -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.waiter = null;
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("Sending packet", buf);
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
- if (this.waiter) {
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) => this.stream.once('drain', 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.waiter) {
401
- this.waiter();
402
- this.waiter = null;
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("Receiving packet", packet.buf);
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.waiter = resolve;
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
- if (this.waiter) {
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
- if (this.waiter) {
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.alloc(size);
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(size, isLargeSDU) {
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.alloc(err2 + 1);
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;
@@ -93,6 +93,7 @@ class Statement {
93
93
  this.queryVars = [];
94
94
  this.bindInfoDict = new Map();
95
95
  this.requiresFullExecute = false;
96
+ this.noPrefetch = false;
96
97
  this.returnToCache = false;
97
98
  this.numColumns = 0;
98
99
  this.lastRowIndex;
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
@@ -31,6 +31,6 @@
31
31
  module.exports = {
32
32
  VERSION_MAJOR: 6,
33
33
  VERSION_MINOR: 0,
34
- VERSION_PATCH: 2,
34
+ VERSION_PATCH: 3,
35
35
  VERSION_SUFFIX: ''
36
36
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oracledb",
3
- "version": "6.0.2",
3
+ "version": "6.0.3",
4
4
  "description": "A Node.js module for Oracle Database access from JavaScript and TypeScript",
5
5
  "license": "(Apache-2.0 OR UPL-1.0)",
6
6
  "homepage": "http://oracle.github.io/node-oracledb/",
@@ -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
@@ -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