oracledb 6.2.0 → 6.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +2 -2
  2. package/build/Release/oracledb-6.3.0-darwin-x64.node +0 -0
  3. package/build/Release/oracledb-6.3.0-darwin-x64.node-buildinfo.txt +1 -0
  4. package/build/Release/oracledb-6.3.0-js-buildinfo.txt +1 -0
  5. package/build/Release/oracledb-6.3.0-linux-arm64.node +0 -0
  6. package/build/Release/oracledb-6.3.0-linux-arm64.node-buildinfo.txt +1 -0
  7. package/build/Release/oracledb-6.3.0-linux-x64.node +0 -0
  8. package/build/Release/oracledb-6.3.0-linux-x64.node-buildinfo.txt +1 -0
  9. package/build/Release/oracledb-6.3.0-win32-x64.node +0 -0
  10. package/build/Release/oracledb-6.3.0-win32-x64.node-buildinfo.txt +1 -0
  11. package/examples/README.md +26 -8
  12. package/examples/dbconfig.js +50 -26
  13. package/examples/example.js +6 -4
  14. package/lib/connection.js +66 -0
  15. package/lib/errors.js +18 -0
  16. package/lib/future.js +53 -0
  17. package/lib/impl/connection.js +56 -0
  18. package/lib/impl/pool.js +5 -3
  19. package/lib/impl/resultset.js +48 -11
  20. package/lib/oracledb.js +23 -8
  21. package/lib/pool.js +10 -0
  22. package/lib/thin/connection.js +46 -2
  23. package/lib/thin/dbObject.js +45 -1
  24. package/lib/thin/index.js +1 -1
  25. package/lib/thin/pool.js +3 -2
  26. package/lib/thin/protocol/buffer.js +15 -7
  27. package/lib/thin/protocol/capabilities.js +3 -1
  28. package/lib/thin/protocol/constants.js +31 -14
  29. package/lib/thin/protocol/messages/auth.js +6 -2
  30. package/lib/thin/protocol/messages/base.js +29 -14
  31. package/lib/thin/protocol/messages/dataType.js +8 -5
  32. package/lib/thin/protocol/messages/lobOp.js +7 -8
  33. package/lib/thin/protocol/messages/withData.js +53 -18
  34. package/lib/thin/protocol/utils.js +1 -1
  35. package/lib/thin/sqlnet/connStrategy.js +8 -4
  36. package/lib/thin/sqlnet/constants.js +138 -138
  37. package/lib/thin/sqlnet/navNodes.js +5 -5
  38. package/lib/thin/sqlnet/networkSession.js +9 -2
  39. package/lib/thin/sqlnet/ntTcp.js +7 -7
  40. package/lib/thin/statement.js +1 -1
  41. package/lib/thin/util.js +15 -4
  42. package/lib/types.js +6 -1
  43. package/lib/util.js +8 -0
  44. package/lib/version.js +1 -1
  45. package/package.json +1 -1
  46. package/build/Release/oracledb-6.2.0-darwin-x64.node +0 -0
  47. package/build/Release/oracledb-6.2.0-darwin-x64.node-buildinfo.txt +0 -1
  48. package/build/Release/oracledb-6.2.0-js-buildinfo.txt +0 -1
  49. package/build/Release/oracledb-6.2.0-linux-arm64.node +0 -0
  50. package/build/Release/oracledb-6.2.0-linux-arm64.node-buildinfo.txt +0 -1
  51. package/build/Release/oracledb-6.2.0-linux-x64.node +0 -0
  52. package/build/Release/oracledb-6.2.0-linux-x64.node-buildinfo.txt +0 -1
  53. package/build/Release/oracledb-6.2.0-win32-x64.node +0 -0
  54. package/build/Release/oracledb-6.2.0-win32-x64.node-buildinfo.txt +0 -1
package/lib/oracledb.js CHANGED
@@ -48,6 +48,7 @@ const AqDeqOptions = require('./aqDeqOptions.js');
48
48
  const AqEnqOptions = require('./aqEnqOptions.js');
49
49
  const AqMessage = require('./aqMessage.js');
50
50
  const AqQueue = require('./aqQueue.js');
51
+ const future = require('./future.js');
51
52
  const BaseDbObject = require('./dbObject.js');
52
53
  const Connection = require('./connection.js');
53
54
  const Lob = require('./lob.js');
@@ -471,9 +472,10 @@ async function _verifyOptions(options, inCreatePool) {
471
472
  let accessToken;
472
473
  if (typeof options.accessToken === 'function') {
473
474
  outOptions.accessTokenFn = options.accessToken;
474
- accessToken = await options.accessToken(false);
475
+ outOptions.accessTokenConfig = options.accessTokenConfig;
476
+ accessToken = await options.accessToken(false, options.accessTokenConfig);
475
477
  if (!nodbUtil.isTokenValid(accessToken)) {
476
- accessToken = await options.accessToken(true);
478
+ accessToken = await options.accessToken(true, options.accessTokenConfig);
477
479
  }
478
480
  } else {
479
481
  accessToken = options.accessToken;
@@ -482,9 +484,7 @@ async function _verifyOptions(options, inCreatePool) {
482
484
  errors.ERR_TOKEN_HAS_EXPIRED);
483
485
  if (accessToken.privateKey !== undefined) {
484
486
  errors.assert(typeof accessToken.privateKey === 'string', errors.ERR_TOKEN_BASED_AUTH);
485
- accessToken.privateKey = accessToken.privateKey.replace(/\n/g, '');
486
- accessToken.privateKey = accessToken.privateKey.replace('-----BEGIN PRIVATE KEY-----', '');
487
- accessToken.privateKey = accessToken.privateKey.replace('-----END PRIVATE KEY-----', '');
487
+ accessToken.privateKey = nodbUtil.denormalizePrivateKey(accessToken.privateKey);
488
488
  }
489
489
 
490
490
  // store token and privatekey
@@ -497,9 +497,20 @@ async function _verifyOptions(options, inCreatePool) {
497
497
 
498
498
  }
499
499
 
500
- // Check external Auth config
501
- if (outOptions.token === undefined && outOptions.externalAuth && (outOptions.user || outOptions.password)) {
502
- errors.throwErr(errors.ERR_WRONG_CRED_FOR_EXTAUTH);
500
+ // Check external Auth config.
501
+ // Allow Session User enclosed in [] for proxy authentication.
502
+ if (outOptions.token === undefined && outOptions.externalAuth) {
503
+ if (outOptions.password) {
504
+ errors.throwErr(errors.ERR_WRONG_CRED_FOR_EXTAUTH);
505
+ }
506
+ if (outOptions.user) {
507
+ if (inCreatePool) {
508
+ errors.throwErr(errors.ERR_WRONG_CRED_FOR_EXTAUTH);
509
+ } else if (outOptions.user[0] !== '[' || outOptions.user.slice(-1) !== ']') {
510
+ // username is not enclosed in [].
511
+ errors.throwErr(errors.ERR_WRONG_USER_FORMAT_EXTAUTH_PROXY);
512
+ }
513
+ }
503
514
  }
504
515
 
505
516
  return outOptions;
@@ -868,6 +879,7 @@ module.exports = {
868
879
  DB_TYPE_TIMESTAMP_LTZ: types.DB_TYPE_TIMESTAMP_LTZ,
869
880
  DB_TYPE_TIMESTAMP_TZ: types.DB_TYPE_TIMESTAMP_TZ,
870
881
  DB_TYPE_VARCHAR: types.DB_TYPE_VARCHAR,
882
+ DB_TYPE_XMLTYPE: types.DB_TYPE_XMLTYPE,
871
883
 
872
884
  // fetchInfo type defaulting
873
885
  DEFAULT: constants.DEFAULT,
@@ -1013,6 +1025,9 @@ module.exports = {
1013
1025
  ARRAY: constants.OUT_FORMAT_ARRAY,
1014
1026
  OBJECT: constants.OUT_FORMAT_OBJECT,
1015
1027
 
1028
+ // Instances
1029
+ future,
1030
+
1016
1031
  // property getters
1017
1032
  get autoCommit() {
1018
1033
  return settings.autoCommit;
package/lib/pool.js CHANGED
@@ -192,10 +192,20 @@ class Pool extends EventEmitter {
192
192
  outOptions.user = options.username;
193
193
  }
194
194
 
195
+ if (this.externalAuth &&
196
+ outOptions.user && (outOptions.user[0] !== '['
197
+ || outOptions.user.slice(-1) !== ']')) {
198
+ // username is not enclosed in [].
199
+ errors.throwErr(errors.ERR_WRONG_USER_FORMAT_EXTAUTH_PROXY);
200
+ }
201
+
195
202
  // password must be a string
196
203
  if (options.password !== undefined) {
197
204
  errors.assertParamPropValue(typeof options.password === 'string', 1,
198
205
  "password");
206
+ if (this.externalAuth) {
207
+ errors.throwErr(errors.ERR_WRONG_CRED_FOR_EXTAUTH);
208
+ }
199
209
  outOptions.password = options.password;
200
210
  }
201
211
 
@@ -32,7 +32,7 @@ const ThinResultSetImpl = require('./resultSet.js');
32
32
  const ThinLobImpl = require("./lob.js");
33
33
  const Protocol = require("./protocol/protocol.js");
34
34
  const { BaseBuffer } = require('./protocol/buffer.js');
35
- const {NetworkSession:nsi} = require("./sqlnet/networkSession.js");
35
+ const {NetworkSession: nsi} = require("./sqlnet/networkSession.js");
36
36
  const { Statement } = require("./statement");
37
37
  const thinUtil = require('./util');
38
38
  const sqlNetConstants = require('./sqlnet/constants.js');
@@ -206,6 +206,9 @@ class ThinConnectionImpl extends ConnectionImpl {
206
206
 
207
207
  // process results
208
208
  const result = {};
209
+ if (message.warning) {
210
+ result.warning = message.warning;
211
+ }
209
212
  if (statement.numQueryVars > 0) {
210
213
  result.resultSet = message.resultSet;
211
214
  } else {
@@ -1085,6 +1088,47 @@ class ThinConnectionImpl extends ConnectionImpl {
1085
1088
  getInstanceName() {
1086
1089
  return this.instanceName;
1087
1090
  }
1088
- }
1089
1091
 
1092
+ //---------------------------------------------------------------------------
1093
+ // Returns the Oracle Database domain name associated with the connection.
1094
+ //---------------------------------------------------------------------------
1095
+ getDbDomain() {
1096
+ return this.dbDomain;
1097
+ }
1098
+
1099
+ //---------------------------------------------------------------------------
1100
+ // Returns the Oracle Database name associated with the connection.
1101
+ //---------------------------------------------------------------------------
1102
+ getDbName() {
1103
+ return this.dbName;
1104
+ }
1105
+
1106
+ //---------------------------------------------------------------------------
1107
+ // Returns maximum number of cursors that can be opened in one session.
1108
+ //---------------------------------------------------------------------------
1109
+ getMaxOpenCursors() {
1110
+ return this.maxOpenCursors;
1111
+ }
1112
+
1113
+ //---------------------------------------------------------------------------
1114
+ // Returns the Oracle Database service name associated with the connection.
1115
+ //---------------------------------------------------------------------------
1116
+ getServiceName() {
1117
+ return this.serviceName;
1118
+ }
1119
+
1120
+ //---------------------------------------------------------------------------
1121
+ // Returns boolean based on this._protocol.txnInProgress value.
1122
+ //---------------------------------------------------------------------------
1123
+ getTransactionInProgress() {
1124
+ return this._protocol.txnInProgress === constants.TNS_TXN_IN_PROGRESS;
1125
+ }
1126
+
1127
+ //---------------------------------------------------------------------------
1128
+ // Returns the warning object.
1129
+ //---------------------------------------------------------------------------
1130
+ getWarning() {
1131
+ return this.warning;
1132
+ }
1133
+ }
1090
1134
  module.exports = ThinConnectionImpl;
@@ -32,6 +32,7 @@ const errors = require('../errors.js');
32
32
  const types = require('../types.js');
33
33
  const DbObjectImpl = require('../impl/dbObject.js');
34
34
  const { GrowableBuffer } = require('./protocol/buffer.js');
35
+ const ThinLobImpl = require('./lob.js');
35
36
 
36
37
  class DbObjectPickleBuffer extends GrowableBuffer {
37
38
 
@@ -125,6 +126,16 @@ class DbObjectPickleBuffer extends GrowableBuffer {
125
126
  }
126
127
  }
127
128
 
129
+ //---------------------------------------------------------------------------
130
+ // _writeRawBytesAndLength()
131
+ //
132
+ // Writes the length in the format required before
133
+ // writing the bytes.
134
+ //---------------------------------------------------------------------------
135
+ _writeRawBytesAndLength(value, numBytes) {
136
+ this.writeLength(numBytes);
137
+ this.writeBytes(value);
138
+ }
128
139
  }
129
140
 
130
141
  class ThinDbObjectImpl extends DbObjectImpl {
@@ -642,4 +653,37 @@ class ThinDbObjectImpl extends DbObjectImpl {
642
653
 
643
654
  }
644
655
 
645
- module.exports = ThinDbObjectImpl;
656
+ //---------------------------------------------------------------------------
657
+ // readXML()
658
+ //
659
+ // Decodes the raw Bytes to XML string or LOB object.
660
+ //
661
+ //---------------------------------------------------------------------------
662
+ function readXML(conn, buf) {
663
+ let colValue;
664
+
665
+ const xmlObj = new DbObjectPickleBuffer(buf);
666
+ const tempobj = {};
667
+ xmlObj.readHeader(tempobj);
668
+ xmlObj.skipBytes(1);
669
+ const xmlflag = xmlObj.readUInt32BE();
670
+ if (xmlflag & constants.TNS_XML_TYPE_FLAG_SKIP_NEXT_4) {
671
+ xmlObj.skipBytes(4);
672
+ }
673
+ const numBytesLeft = xmlObj.numBytesLeft();
674
+ const ptr = xmlObj.readBytes(numBytesLeft);
675
+ if (xmlflag & constants.TNS_XML_TYPE_STRING) {
676
+ colValue = ptr.toString();
677
+ } else if (xmlflag & constants.TNS_XML_TYPE_LOB) {
678
+ const lobImpl = new ThinLobImpl();
679
+ const locator = Buffer.from(ptr);
680
+ lobImpl.init(conn, locator, types.DB_TYPE_CLOB, 0, 0);
681
+ colValue = lobImpl;
682
+ } else {
683
+ // We only support String and Clob type.
684
+ errors.throwErr(errors.ERR_UNEXPECTED_XML_TYPE, xmlflag);
685
+ }
686
+ return colValue;
687
+ }
688
+
689
+ module.exports = { ThinDbObjectImpl, readXML };
package/lib/thin/index.js CHANGED
@@ -30,7 +30,7 @@ const ThinConnectionImpl = require('./connection.js');
30
30
  const ThinResultSetImpl = require('./resultSet.js');
31
31
  const ThinPoolImpl = require('./pool.js');
32
32
  const ThinLobImpl = require('./lob.js');
33
- const ThinDbObjectImpl = require('./dbObject.js');
33
+ const { ThinDbObjectImpl } = require('./dbObject.js');
34
34
 
35
35
  const impl = require('../impl');
36
36
  impl.ConnectionImpl = ThinConnectionImpl;
package/lib/thin/pool.js CHANGED
@@ -102,6 +102,7 @@ class ThinPoolImpl extends PoolImpl {
102
102
  this._userConfig.privateKey = null;
103
103
  }
104
104
  this._accessTokenFn = params.accessTokenFn;
105
+ this._accessTokenConfig = params.accessTokenConfig;
105
106
  this._isDRCPEnabled = false;
106
107
  this.eventEmitter = new EventEmitter();
107
108
  // listener to remove dead or idle connections
@@ -176,7 +177,7 @@ class ThinPoolImpl extends PoolImpl {
176
177
  protocolUtil.getDeobfuscatedValue(this._token, this._obfuscatedToken);
177
178
  if (util.isTokenExpired(clonedAttrs.token)) {
178
179
  if (typeof this._accessTokenFn === 'function') {
179
- accessToken = await this._accessTokenFn(true);
180
+ accessToken = await this._accessTokenFn(true, this._accessTokenConfig);
180
181
  if (typeof accessToken === 'string') {
181
182
  clonedAttrs.token = accessToken;
182
183
  if (util.isTokenExpired(clonedAttrs.token)) {
@@ -199,7 +200,6 @@ class ThinPoolImpl extends PoolImpl {
199
200
  const objToken = protocolUtil.setObfuscatedValue(clonedAttrs.token);
200
201
  this._token = objToken.value;
201
202
  this._obfuscatedToken = objToken.obfuscatedValue;
202
-
203
203
  const objKey = protocolUtil.setObfuscatedValue(clonedAttrs.privateKey);
204
204
  this._privateKey = objKey.value;
205
205
  this._obfuscatedPrivateKey = objKey.obfuscatedValue;
@@ -541,6 +541,7 @@ class ThinPoolImpl extends PoolImpl {
541
541
 
542
542
  // release connection to connection pool
543
543
  release(conn) {
544
+ conn.warning = undefined;
544
545
  this._usedConnectionList.delete(conn);
545
546
  if (conn.nscon.connected) {
546
547
  conn._lastTimeUsed = Date.now();
@@ -677,15 +677,12 @@ class BaseBuffer {
677
677
  }
678
678
  }
679
679
 
680
- //---------------------------------------------------------------------------
681
- // writeBytesWithLength()
680
+ // _writeRawBytesAndLength()
682
681
  //
683
- // Writes the bytes in the supplied buffer to the buffer, but first writes
684
- // the length. If the length exceeds a fixed value, the value is written in
685
- // chunks instead.
682
+ // Writes the length in the format required before
683
+ // writing the bytes.
686
684
  //---------------------------------------------------------------------------
687
- writeBytesWithLength(value) {
688
- let numBytes = value.length;
685
+ _writeRawBytesAndLength(value, numBytes) {
689
686
  if (numBytes <= constants.TNS_MAX_SHORT_LENGTH) {
690
687
  this.writeUInt8(numBytes);
691
688
  if (numBytes > 0) {
@@ -704,6 +701,17 @@ class BaseBuffer {
704
701
  this.writeUB4(0);
705
702
  }
706
703
  }
704
+ //---------------------------------------------------------------------------
705
+ // writeBytesWithLength()
706
+ //
707
+ // Writes the bytes in the supplied buffer to the buffer, but first writes
708
+ // the length. If the length exceeds a fixed value, the value is written in
709
+ // chunks instead.
710
+ //---------------------------------------------------------------------------
711
+ writeBytesWithLength(value) {
712
+ const numBytes = value.length;
713
+ this._writeRawBytesAndLength(value, numBytes);
714
+ }
707
715
 
708
716
  //---------------------------------------------------------------------------
709
717
  // writeDbObject()
@@ -89,7 +89,9 @@ class Capabilities {
89
89
  this.compileCaps[constants.TNS_CCAP_DBF_VERSION] =
90
90
  constants.TNS_CCAP_DBF_VERSION_MAX;
91
91
  this.compileCaps[constants.TNS_CCAP_LOB] =
92
- constants.TNS_CCAP_LOB_UB8_SIZE | constants.TNS_CCAP_LOB_ENCS | constants.TNS_CCAP_LOB_PREFETCH;
92
+ constants.TNS_CCAP_LOB_UB8_SIZE | constants.TNS_CCAP_LOB_ENCS
93
+ | constants.TNS_CCAP_LOB_PREFETCH | constants.TNS_CCAP_LOB_TEMP_SIZE
94
+ | constants.TNS_CCAP_LOB_12C | constants.TNS_CCAP_LOB_PREFETCH_DATA;
93
95
  this.compileCaps[constants.TNS_CCAP_UB2_DTY] = 1;
94
96
  this.compileCaps[constants.TNS_CCAP_LOB2] =
95
97
  constants.TNS_CCAP_LOB2_QUASI | constants.TNS_CCAP_LOB2_2GB_PREFETCH;
@@ -56,14 +56,14 @@ module.exports = {
56
56
 
57
57
  // authentication modes
58
58
  AUTH_MODE_DEFAULT: 0,
59
- AUTH_MODE_PRELIM : 0x00000008,
60
- AUTH_MODE_SYSASM : 0x00008000,
61
- AUTH_MODE_SYSBKP : 0x00020000,
62
- AUTH_MODE_SYSDBA : 0x00000002,
63
- AUTH_MODE_SYSDGD : 0x00040000,
64
- AUTH_MODE_SYSKMT : 0x00080000,
65
- AUTH_MODE_SYSOPER: 0x00000004,
66
- AUTH_MODE_SYSRAC : 0x00100000,
59
+ AUTH_MODE_PRELIM: 0x00000008,
60
+ AUTH_MODE_SYSASM: 0x00008000,
61
+ AUTH_MODE_SYSBKP: 0x00020000,
62
+ AUTH_MODE_SYSDBA: 0x00000002,
63
+ AUTH_MODE_SYSDGD: 0x00040000,
64
+ AUTH_MODE_SYSKMT: 0x00080000,
65
+ AUTH_MODE_SYSOPER: 0x00000004,
66
+ AUTH_MODE_SYSRAC: 0x00100000,
67
67
 
68
68
  // TTC authentication modes
69
69
  TNS_AUTH_MODE_LOGON: 0x00000001,
@@ -120,7 +120,7 @@ module.exports = {
120
120
  TNS_DATA_TYPE_AUA: 36 + 256,
121
121
  TNS_DATA_TYPE_RXH7: 37 + 256,
122
122
  TNS_DATA_TYPE_NA6: 38 + 256,
123
- TNS_DATA_TYPE_OAC: 39,
123
+ TNS_DATA_TYPE_OAC9: 39,
124
124
  TNS_DATA_TYPE_AMS: 40,
125
125
  TNS_DATA_TYPE_BRN: 41,
126
126
  TNS_DATA_TYPE_BRP: 42 + 256,
@@ -194,7 +194,7 @@ module.exports = {
194
194
  TNS_DATA_TYPE_RSET: 116,
195
195
  TNS_DATA_TYPE_CWD: 117,
196
196
  TNS_DATA_TYPE_JSON: 119,
197
- TNS_DATA_TYPE_NEW_OAC: 120,
197
+ TNS_DATA_TYPE_OAC122: 120,
198
198
  TNS_DATA_TYPE_UD12: 124 + 256,
199
199
  TNS_DATA_TYPE_AL8: 125 + 256,
200
200
  TNS_DATA_TYPE_LFOP: 126 + 256,
@@ -381,7 +381,7 @@ module.exports = {
381
381
  TNS_DATA_TYPE_XSNSOP2: 604,
382
382
  TNS_DATA_TYPE_XSNS2: 605,
383
383
  TNS_DATA_TYPE_IMPLRES: 611,
384
- TNS_DATA_TYPE_OER: 612,
384
+ TNS_DATA_TYPE_OER19: 612,
385
385
  TNS_DATA_TYPE_UB1ARRAY: 613,
386
386
  TNS_DATA_TYPE_SESSSTATE: 614,
387
387
  TNS_DATA_TYPE_AC_REPLAY: 615,
@@ -400,8 +400,11 @@ module.exports = {
400
400
  TNS_DATA_TYPE_CHUNKINFO: 636,
401
401
  TNS_DATA_TYPE_SCN: 637,
402
402
  TNS_DATA_TYPE_SCN8: 638,
403
- TNS_DATA_TYPE_UDS: 639,
403
+ TNS_DATA_TYPE_UD21: 639,
404
404
  TNS_DATA_TYPE_TNP: 640,
405
+ TNS_DATA_TYPE_OAC: 646,
406
+ TNS_DATA_TYPE_OER: 652,
407
+ TNS_DATA_TYPE_UDS: 663,
405
408
 
406
409
  // data type representations
407
410
  TNS_TYPE_REP_NATIVE: 0,
@@ -622,7 +625,12 @@ module.exports = {
622
625
  TNS_CCAP_FIELD_VERSION_21_1: 16,
623
626
  TNS_CCAP_FIELD_VERSION_23_1: 17,
624
627
  TNS_CCAP_FIELD_VERSION_23_1_EXT_1: 18,
625
- TNS_CCAP_FIELD_VERSION_MAX: 18,
628
+ TNS_CCAP_FIELD_VERSION_23_1_EXT_2: 19,
629
+ TNS_CCAP_FIELD_VERSION_23_1_EXT_3: 20,
630
+ TNS_CCAP_FIELD_VERSION_23_1_EXT_4: 21,
631
+ TNS_CCAP_FIELD_VERSION_23_1_EXT_5: 22,
632
+ TNS_CCAP_FIELD_VERSION_23_1_EXT_6: 23,
633
+ TNS_CCAP_FIELD_VERSION_MAX: 23,
626
634
  TNS_CCAP_O5LOGON: 8,
627
635
  TNS_CCAP_O5LOGON_NP: 2,
628
636
  TNS_CCAP_O7LOGON: 32,
@@ -642,7 +650,10 @@ module.exports = {
642
650
  TNS_CCAP_KEEP_OUT_ORDER: 0x80,
643
651
  TNS_CCAP_LOB_UB8_SIZE: 0x01,
644
652
  TNS_CCAP_LOB_ENCS: 0x02,
653
+ TNS_CCAP_LOB_PREFETCH_DATA: 0x04,
654
+ TNS_CCAP_LOB_TEMP_SIZE: 0x08,
645
655
  TNS_CCAP_LOB_PREFETCH: 0x40,
656
+ TNS_CCAP_LOB_12C: 0x80,
646
657
  TNS_CCAP_DRCP: 0x10,
647
658
  TNS_CCAP_ZLNP: 0x04,
648
659
  TNS_CCAP_INBAND_NOTIFICATION: 0x04,
@@ -667,6 +678,9 @@ module.exports = {
667
678
  /** MultiRound SHA-512. */
668
679
  TNS_VERIFIER_TYPE_12C: 0x4815,
669
680
 
681
+ // UDS flags
682
+ TNS_UDS_FLAGS_IS_JSON: 0x00000100,
683
+
670
684
  // other constants
671
685
  TNS_MAX_SHORT_LENGTH: 252,
672
686
  TNS_ESCAPE_CHAR: 253,
@@ -743,6 +757,9 @@ module.exports = {
743
757
  TNS_ERR_NO_DATA_FOUND: 1403,
744
758
  TNS_ERR_SESSION_SHUTDOWN: 12572,
745
759
 
760
+ // warnings
761
+ TNS_WARN_COMPILATION_CREATE: 0x20,
762
+
746
763
  // other constants
747
764
  PACKET_HEADER_SIZE: 8,
748
765
  NUMBER_AS_TEXT_CHARS: 172,
@@ -750,6 +767,6 @@ module.exports = {
750
767
  BUFFER_CHUNK_SIZE: 65536,
751
768
  CHUNKED_BYTES_CHUNK_SIZE: 65536,
752
769
 
753
- TNS_BASE64_ALPHABET_ARRAY: Buffer.from('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'),
770
+ TNS_BASE64_ALPHABET_ARRAY: Buffer.from('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'),
754
771
  TNS_EXTENT_OID: Buffer.from('00000000000000000000000000010001', 'hex')
755
772
  };
@@ -98,8 +98,7 @@ class AuthMessage extends Message {
98
98
  this.functionCode = constants.TNS_FUNC_AUTH_PHASE_TWO;
99
99
  this.privateKey = config.privateKey;
100
100
  if (this.privateKey) {
101
- this.privateKey = '-----BEGIN PRIVATE KEY-----\n' + this.privateKey;
102
- this.privateKey = this.privateKey + '\n' + '-----END PRIVATE KEY-----';
101
+ this.privateKey = util.normalizePrivateKey(this.privateKey);
103
102
  }
104
103
  this.serviceName = this.conn.serviceName;
105
104
  this.remoteAddress = this.conn.remoteAddress;
@@ -321,9 +320,14 @@ class AuthMessage extends Message {
321
320
  let portReleaseNum;
322
321
  let portUpdateNum;
323
322
 
323
+ this.conn.dbDomain = this.sessionData['AUTH_SC_DB_DOMAIN'];
324
+ this.conn.dbName = this.sessionData['AUTH_SC_DBUNIQUE_NAME'];
325
+ this.conn.maxOpenCursors = Number(this.sessionData['AUTH_MAX_OPEN_CURSORS']);
326
+ this.conn.serviceName = this.sessionData['AUTH_SC_SERVICE_NAME'];
324
327
  this.conn.instanceName = this.sessionData['AUTH_INSTANCENAME'];
325
328
  const fullVersionNum = Number(this.sessionData['AUTH_VERSION_NO']);
326
329
  const versionNum = (fullVersionNum >> 24) & 0xFF;
330
+ this.conn.warning = this.warning;
327
331
  if (buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_18_1_EXT_1) {
328
332
  releaseNum = (fullVersionNum >> 16) & 0xFF;
329
333
  updateNum = (fullVersionNum >> 12) & 0x0F;
@@ -44,9 +44,9 @@ class Message {
44
44
  this.flushOutBinds = false;
45
45
  this.endToEndSeqNum = 0;
46
46
  this.errorOccurred = false;
47
- this.isWarning = false;
48
47
  this.flushOutBinds = false;
49
48
  this.processedError = false;
49
+ this.warning = undefined;
50
50
  }
51
51
 
52
52
  preProcess() { }
@@ -69,13 +69,16 @@ class Message {
69
69
  buf.skipUB2(); // array elem error
70
70
  buf.skipUB2(); // array elem error
71
71
  this.errorInfo.cursorId = buf.readUB2(); // cursor id
72
- this.errorInfo.pos = buf.readUB2(); // error position
73
- buf.skipUB1(); // sql type
72
+ const errorPos = buf.readSB2(); // error position
73
+ buf.skipUB1(); // sql type (19c and earlier)
74
74
  buf.skipUB1(); // fatal ?
75
- buf.skipUB2(); // flags
76
- buf.skipUB2(); // user cursor options
75
+ buf.skipUB1(); // flags
76
+ buf.skipUB1(); // user cursor options
77
77
  buf.skipUB1(); // UPI parameter
78
- buf.skipUB1(); // warning flag
78
+ const warnFlag = buf.readUInt8(); // warning flag
79
+ if (warnFlag & constants.TNS_WARN_COMPILATION_CREATE) {
80
+ this.warning = errors.getErr(errors.WRN_COMPILATION_CREATE);
81
+ }
79
82
  this.errorInfo.rowID = buf.readRowID(); // rowid
80
83
  buf.skipUB4(); // OS error
81
84
  buf.skipUB1(); // statement error
@@ -132,28 +135,40 @@ class Message {
132
135
 
133
136
  this.errorInfo.num = buf.readUB4(); // error number (extended)
134
137
  this.errorInfo.rowCount = buf.readUB8(); // row number (extended)
138
+
139
+ // fields added in Oracle Database 20c
140
+ if (buf.caps.ttcFieldVersion >= constants.TNS_CCAP_FIELD_VERSION_20_1) {
141
+ buf.skipUB4(); // sql type
142
+ buf.skipUB4(); // server checksum
143
+ }
144
+
145
+ // error message
135
146
  if (this.errorInfo.num !== 0) {
136
147
  this.errorOccurred = true;
148
+ if (errorPos >= 0) {
149
+ this.errorInfo.pos = errorPos;
150
+ }
137
151
  this.errorInfo.message = buf.readStr(constants.CSFRM_IMPLICIT);
138
152
  /*
139
153
  * Remove ending newline from ORA error message
140
154
  */
141
- this.errorInfo.message = this.errorInfo.message.replace(/\n+$/, "");
155
+ this.errorInfo.message = this.errorInfo.message.trim();
142
156
  }
143
- this.errorInfo.isWarning = false;
144
157
  this.processedError = true;
145
158
  }
146
159
 
147
160
  processReturnParameter() { }
148
161
 
149
162
  processWarningInfo(buf) {
150
- this.errorInfo.num = buf.readUB2(); // error number
151
- const numBytes = buf.readUB2(); // length of error message
152
- buf.skipUB2(); // flags
153
- if (this.errorInfo.num != 0 && numBytes > 0) {
154
- this.errorInfo.message = buf.readStr(constants.CSFRM_IMPLICIT);
163
+ const errNum = buf.readUB2(); // warning number
164
+ const numBytes = buf.readUB2(); // length of warning message
165
+ buf.skipUB2(); // flags
166
+ if (errNum != 0 && numBytes > 0) {
167
+ // get message string and remove the ending newline.
168
+ const message = buf.readStr(constants.CSFRM_IMPLICIT).trim();
169
+ this.warning = new Error(message);
170
+ this.warning.errorNum = errNum;
155
171
  }
156
- this.errorInfo.isWarning = true;
157
172
  }
158
173
 
159
174
  hasMoreData(buf) {
@@ -81,7 +81,7 @@ const dataTypes = [
81
81
  [constants.TNS_DATA_TYPE_LONG_RAW, constants.TNS_DATA_TYPE_LONG_RAW, constants.TNS_TYPE_REP_UNIVERSAL],
82
82
  [constants.TNS_DATA_TYPE_UB2, constants.TNS_DATA_TYPE_UB2, constants.TNS_TYPE_REP_UNIVERSAL],
83
83
  [constants.TNS_DATA_TYPE_UB4, constants.TNS_DATA_TYPE_UB4, constants.TNS_TYPE_REP_UNIVERSAL],
84
- [constants.TNS_DATA_TYPE_SB1, constants.TNS_DATA_TYPE_SB1, constants.TNS_TYPE_REP_UNIVERSAL],
84
+ [constants.TNS_DATA_TYPE_SB1, constants.TNS_DATA_TYPE_SB1, constants.TNS_TYPE_REP_ORACLE],
85
85
  [constants.TNS_DATA_TYPE_SB2, constants.TNS_DATA_TYPE_SB2, constants.TNS_TYPE_REP_UNIVERSAL],
86
86
  [constants.TNS_DATA_TYPE_SB4, constants.TNS_DATA_TYPE_SB4, constants.TNS_TYPE_REP_UNIVERSAL],
87
87
  [constants.TNS_DATA_TYPE_SWORD, constants.TNS_DATA_TYPE_SWORD, constants.TNS_TYPE_REP_UNIVERSAL],
@@ -93,7 +93,7 @@ const dataTypes = [
93
93
  [constants.TNS_DATA_TYPE_AMS, constants.TNS_DATA_TYPE_AMS, constants.TNS_TYPE_REP_UNIVERSAL],
94
94
  [constants.TNS_DATA_TYPE_BRN, constants.TNS_DATA_TYPE_BRN, constants.TNS_TYPE_REP_UNIVERSAL],
95
95
  [constants.TNS_DATA_TYPE_CWD, constants.TNS_DATA_TYPE_CWD, constants.TNS_TYPE_REP_UNIVERSAL],
96
- [constants.TNS_DATA_TYPE_NEW_OAC, constants.TNS_DATA_TYPE_NEW_OAC, constants.TNS_TYPE_REP_UNIVERSAL],
96
+ [constants.TNS_DATA_TYPE_OAC122, constants.TNS_DATA_TYPE_OAC122, constants.TNS_TYPE_REP_UNIVERSAL],
97
97
  [constants.TNS_DATA_TYPE_OER8, constants.TNS_DATA_TYPE_OER8, constants.TNS_TYPE_REP_UNIVERSAL],
98
98
  [constants.TNS_DATA_TYPE_FUN, constants.TNS_DATA_TYPE_FUN, constants.TNS_TYPE_REP_UNIVERSAL],
99
99
  [constants.TNS_DATA_TYPE_AUA, constants.TNS_DATA_TYPE_AUA, constants.TNS_TYPE_REP_UNIVERSAL],
@@ -294,7 +294,7 @@ const dataTypes = [
294
294
  [constants.TNS_DATA_TYPE_PDN, constants.TNS_DATA_TYPE_NUMBER, constants.TNS_TYPE_REP_ORACLE],
295
295
  [constants.TNS_DATA_TYPE_VCS, constants.TNS_DATA_TYPE_VARCHAR, constants.TNS_TYPE_REP_UNIVERSAL],
296
296
  [constants.TNS_DATA_TYPE_VBI, constants.TNS_DATA_TYPE_VARCHAR, constants.TNS_TYPE_REP_UNIVERSAL],
297
- [constants.TNS_DATA_TYPE_OAC, constants.TNS_DATA_TYPE_NEW_OAC, constants.TNS_TYPE_REP_UNIVERSAL],
297
+ [constants.TNS_DATA_TYPE_OAC9, constants.TNS_DATA_TYPE_OAC9, constants.TNS_TYPE_REP_UNIVERSAL],
298
298
  [constants.TNS_DATA_TYPE_UIN, constants.TNS_DATA_TYPE_NUMBER, constants.TNS_TYPE_REP_ORACLE],
299
299
  [constants.TNS_DATA_TYPE_SLS, constants.TNS_DATA_TYPE_NUMBER, constants.TNS_TYPE_REP_ORACLE],
300
300
  [constants.TNS_DATA_TYPE_LVC, constants.TNS_DATA_TYPE_VARCHAR, constants.TNS_TYPE_REP_UNIVERSAL],
@@ -360,7 +360,7 @@ const dataTypes = [
360
360
  [constants.TNS_DATA_TYPE_AC_REPLAY, constants.TNS_DATA_TYPE_AC_REPLAY, constants.TNS_TYPE_REP_UNIVERSAL],
361
361
  [constants.TNS_DATA_TYPE_AC_CONT, constants.TNS_DATA_TYPE_AC_CONT, constants.TNS_TYPE_REP_UNIVERSAL],
362
362
  [constants.TNS_DATA_TYPE_IMPLRES, constants.TNS_DATA_TYPE_IMPLRES, constants.TNS_TYPE_REP_UNIVERSAL],
363
- [constants.TNS_DATA_TYPE_OER, constants.TNS_DATA_TYPE_OER, constants.TNS_TYPE_REP_UNIVERSAL],
363
+ [constants.TNS_DATA_TYPE_OER19, constants.TNS_DATA_TYPE_OER19, constants.TNS_TYPE_REP_UNIVERSAL],
364
364
  [constants.TNS_DATA_TYPE_TXT, constants.TNS_DATA_TYPE_TXT, constants.TNS_TYPE_REP_UNIVERSAL],
365
365
  [constants.TNS_DATA_TYPE_XSSESSNS, constants.TNS_DATA_TYPE_XSSESSNS, constants.TNS_TYPE_REP_UNIVERSAL],
366
366
  [constants.TNS_DATA_TYPE_XSATTOP, constants.TNS_DATA_TYPE_XSATTOP, constants.TNS_TYPE_REP_UNIVERSAL],
@@ -388,8 +388,11 @@ const dataTypes = [
388
388
  [constants.TNS_DATA_TYPE_SCN, constants.TNS_DATA_TYPE_SCN, constants.TNS_TYPE_REP_UNIVERSAL],
389
389
  [constants.TNS_DATA_TYPE_SCN8, constants.TNS_DATA_TYPE_SCN8, constants.TNS_TYPE_REP_UNIVERSAL],
390
390
  [constants.TNS_DATA_TYPE_CHUNKINFO, constants.TNS_DATA_TYPE_CHUNKINFO, constants.TNS_TYPE_REP_UNIVERSAL],
391
+ [constants.TNS_DATA_TYPE_UD21, constants.TNS_DATA_TYPE_UD21, constants.TNS_TYPE_REP_UNIVERSAL],
391
392
  [constants.TNS_DATA_TYPE_UDS, constants.TNS_DATA_TYPE_UDS, constants.TNS_TYPE_REP_UNIVERSAL],
392
- [constants.TNS_DATA_TYPE_TNP, constants.TNS_DATA_TYPE_TNP, constants.TNS_TYPE_REP_UNIVERSAL]
393
+ [constants.TNS_DATA_TYPE_TNP, constants.TNS_DATA_TYPE_TNP, constants.TNS_TYPE_REP_UNIVERSAL],
394
+ [constants.TNS_DATA_TYPE_OER, constants.TNS_DATA_TYPE_OER, constants.TNS_TYPE_REP_UNIVERSAL],
395
+ [constants.TNS_DATA_TYPE_OAC, constants.TNS_DATA_TYPE_OAC, constants.TNS_TYPE_REP_UNIVERSAL]
393
396
  ];
394
397
 
395
398
  module.exports = DataTypeMessage;
@@ -169,7 +169,7 @@ class LobOpMessage extends Message {
169
169
  processReturnParameter(buf) {
170
170
  let lobArray;
171
171
  let locator;
172
- let temp16;
172
+ let temp8;
173
173
  let numBytes;
174
174
  if (this.sourceLobImpl !== null) {
175
175
  numBytes = this.sourceLobImpl._locator.length;
@@ -184,15 +184,14 @@ class LobOpMessage extends Message {
184
184
  locator.copy(this.destLobImpl._locator);
185
185
  }
186
186
  if (this.operation === constants.TNS_LOB_OP_CREATE_TEMP) {
187
- buf.skipUB2();
188
- }
189
- if (this.sendAmount) {
187
+ buf.skipUB2(); // skip character set
188
+ buf.skipBytes(3); // skip trailing flags, amount
189
+ } else if (this.sendAmount) {
190
190
  this.amount = buf.readSB8();
191
191
  }
192
- if (this.operation === constants.TNS_LOB_OP_CREATE_TEMP
193
- || this.operation === constants.TNS_LOB_OP_IS_OPEN) {
194
- temp16 = buf.readUB2();
195
- this.boolFlag = temp16 > 0;
192
+ if (this.operation === constants.TNS_LOB_OP_IS_OPEN) {
193
+ temp8 = buf.readUB1();
194
+ this.boolFlag = temp8 > 0;
196
195
  }
197
196
  }
198
197