oracledb 6.1.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 (61) 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 +57 -40
  13. package/examples/example.js +6 -4
  14. package/lib/connection.js +67 -1
  15. package/lib/dbObject.js +9 -0
  16. package/lib/errors.js +25 -7
  17. package/lib/future.js +53 -0
  18. package/lib/impl/connection.js +56 -0
  19. package/lib/impl/pool.js +5 -3
  20. package/lib/impl/resultset.js +48 -11
  21. package/lib/oracledb.js +34 -14
  22. package/lib/pool.js +10 -0
  23. package/lib/sodaCollection.js +11 -0
  24. package/lib/sodaOperation.js +16 -0
  25. package/lib/thin/connection.js +184 -155
  26. package/lib/thin/dbObject.js +49 -2
  27. package/lib/thin/index.js +1 -1
  28. package/lib/thin/pool.js +3 -2
  29. package/lib/thin/protocol/buffer.js +79 -70
  30. package/lib/thin/protocol/capabilities.js +3 -1
  31. package/lib/thin/protocol/constants.js +31 -14
  32. package/lib/thin/protocol/messages/auth.js +6 -2
  33. package/lib/thin/protocol/messages/base.js +36 -14
  34. package/lib/thin/protocol/messages/dataType.js +8 -5
  35. package/lib/thin/protocol/messages/lobOp.js +7 -8
  36. package/lib/thin/protocol/messages/withData.js +62 -22
  37. package/lib/thin/protocol/oson.js +13 -10
  38. package/lib/thin/protocol/packet.js +6 -5
  39. package/lib/thin/protocol/utils.js +2 -2
  40. package/lib/thin/sqlnet/connStrategy.js +8 -4
  41. package/lib/thin/sqlnet/constants.js +138 -138
  42. package/lib/thin/sqlnet/ezConnectResolver.js +10 -43
  43. package/lib/thin/sqlnet/navNodes.js +7 -7
  44. package/lib/thin/sqlnet/networkSession.js +22 -21
  45. package/lib/thin/sqlnet/ntTcp.js +7 -7
  46. package/lib/thin/sqlnet/packet.js +1 -1
  47. package/lib/thin/statement.js +345 -113
  48. package/lib/thin/util.js +35 -86
  49. package/lib/types.js +6 -1
  50. package/lib/util.js +12 -0
  51. package/lib/version.js +1 -1
  52. package/package.json +1 -1
  53. package/build/Release/oracledb-6.1.0-darwin-x64.node +0 -0
  54. package/build/Release/oracledb-6.1.0-darwin-x64.node-buildinfo.txt +0 -1
  55. package/build/Release/oracledb-6.1.0-js-buildinfo.txt +0 -1
  56. package/build/Release/oracledb-6.1.0-linux-arm64.node +0 -0
  57. package/build/Release/oracledb-6.1.0-linux-arm64.node-buildinfo.txt +0 -1
  58. package/build/Release/oracledb-6.1.0-linux-x64.node +0 -0
  59. package/build/Release/oracledb-6.1.0-linux-x64.node-buildinfo.txt +0 -1
  60. package/build/Release/oracledb-6.1.0-win32-x64.node +0 -0
  61. package/build/Release/oracledb-6.1.0-win32-x64.node-buildinfo.txt +0 -1
@@ -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 {
@@ -367,7 +378,10 @@ class ThinDbObjectImpl extends DbObjectImpl {
367
378
  case types.DB_TYPE_NCHAR:
368
379
  return buf.readStr(constants.CSFRM_NCHAR);
369
380
  case types.DB_TYPE_RAW:
370
- return Buffer.from(buf.readBytesWithLength());
381
+ value = buf.readBytesWithLength();
382
+ if (value !== null)
383
+ value = Buffer.from(value);
384
+ return value;
371
385
  case types.DB_TYPE_BINARY_DOUBLE:
372
386
  return buf.readBinaryDouble();
373
387
  case types.DB_TYPE_BINARY_FLOAT:
@@ -639,4 +653,37 @@ class ThinDbObjectImpl extends DbObjectImpl {
639
653
 
640
654
  }
641
655
 
642
- 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();
@@ -49,7 +49,7 @@ class BaseBuffer {
49
49
  this.buf = Buffer.alloc(initializer);
50
50
  this.size = 0;
51
51
  this.maxSize = initializer;
52
- } else {
52
+ } else if (initializer) {
53
53
  this.buf = initializer;
54
54
  this.size = this.maxSize = initializer.length;
55
55
  }
@@ -548,11 +548,12 @@ class BaseBuffer {
548
548
  // remain in the buffer, the buffer is grown.
549
549
  //---------------------------------------------------------------------------
550
550
  reserveBytes(numBytes) {
551
- if (numBytes > this.numBytesLeft())
551
+ if (numBytes > this.numBytesLeft()) {
552
552
  this._grow(this.pos + numBytes);
553
- const buf = this.buf.subarray(this.pos, this.pos + numBytes);
553
+ }
554
+ const pos = this.pos;
554
555
  this.pos += numBytes;
555
- return buf;
556
+ return pos;
556
557
  }
557
558
 
558
559
  //---------------------------------------------------------------------------
@@ -618,20 +619,20 @@ class BaseBuffer {
618
619
  //---------------------------------------------------------------------------
619
620
  writeBinaryDouble(n) {
620
621
  this.writeUInt8(8);
621
- const buf = this.reserveBytes(8);
622
- buf.writeDoubleBE(n);
623
- if ((buf[0] & 0x80) === 0) {
624
- buf[0] |= 0x80;
622
+ const pos = this.reserveBytes(8);
623
+ this.buf.writeDoubleBE(n, pos);
624
+ if ((this.buf[pos] & 0x80) === 0) {
625
+ this.buf[pos] |= 0x80;
625
626
  } else {
626
627
  // We complement the bits for a negative number
627
- buf[0] ^= 0xff;
628
- buf[1] ^= 0xff;
629
- buf[2] ^= 0xff;
630
- buf[3] ^= 0xff;
631
- buf[4] ^= 0xff;
632
- buf[5] ^= 0xff;
633
- buf[6] ^= 0xff;
634
- buf[7] ^= 0xff;
628
+ this.buf[pos] ^= 0xff;
629
+ this.buf[pos + 1] ^= 0xff;
630
+ this.buf[pos + 2] ^= 0xff;
631
+ this.buf[pos + 3] ^= 0xff;
632
+ this.buf[pos + 4] ^= 0xff;
633
+ this.buf[pos + 5] ^= 0xff;
634
+ this.buf[pos + 6] ^= 0xff;
635
+ this.buf[pos + 7] ^= 0xff;
635
636
  }
636
637
  }
637
638
 
@@ -642,16 +643,16 @@ class BaseBuffer {
642
643
  //---------------------------------------------------------------------------
643
644
  writeBinaryFloat(n) {
644
645
  this.writeUInt8(4);
645
- const buf = this.reserveBytes(4);
646
- buf.writeFloatBE(n);
647
- if ((buf[0] & 0x80) === 0) {
648
- buf[0] |= 0x80;
646
+ const pos = this.reserveBytes(4);
647
+ this.buf.writeFloatBE(n, pos);
648
+ if ((this.buf[pos] & 0x80) === 0) {
649
+ this.buf[pos] |= 0x80;
649
650
  } else {
650
651
  // We complement the bits for a negative number
651
- buf[0] ^= 0xff;
652
- buf[1] ^= 0xff;
653
- buf[2] ^= 0xff;
654
- buf[3] ^= 0xff;
652
+ this.buf[pos] ^= 0xff;
653
+ this.buf[pos + 1] ^= 0xff;
654
+ this.buf[pos + 2] ^= 0xff;
655
+ this.buf[pos + 3] ^= 0xff;
655
656
  }
656
657
  }
657
658
 
@@ -676,15 +677,12 @@ class BaseBuffer {
676
677
  }
677
678
  }
678
679
 
679
- //---------------------------------------------------------------------------
680
- // writeBytesWithLength()
680
+ // _writeRawBytesAndLength()
681
681
  //
682
- // Writes the bytes in the supplied buffer to the buffer, but first writes
683
- // the length. If the length exceeds a fixed value, the value is written in
684
- // chunks instead.
682
+ // Writes the length in the format required before
683
+ // writing the bytes.
685
684
  //---------------------------------------------------------------------------
686
- writeBytesWithLength(value) {
687
- let numBytes = value.length;
685
+ _writeRawBytesAndLength(value, numBytes) {
688
686
  if (numBytes <= constants.TNS_MAX_SHORT_LENGTH) {
689
687
  this.writeUInt8(numBytes);
690
688
  if (numBytes > 0) {
@@ -703,6 +701,17 @@ class BaseBuffer {
703
701
  this.writeUB4(0);
704
702
  }
705
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
+ }
706
715
 
707
716
  //---------------------------------------------------------------------------
708
717
  // writeDbObject()
@@ -745,31 +754,31 @@ class BaseBuffer {
745
754
  if (writeLength) {
746
755
  this.writeUInt8(length);
747
756
  }
748
- const ptr = this.reserveBytes(length);
757
+ const pos = this.reserveBytes(length);
749
758
  if (type === types.DB_TYPE_DATE || type == types.DB_TYPE_TIMESTAMP) {
750
759
  const year = date.getFullYear();
751
- ptr[0] = Math.trunc(year / 100) + 100;
752
- ptr[1] = year % 100 + 100;
753
- ptr[2] = date.getMonth() + 1;
754
- ptr[3] = date.getDate();
755
- ptr[4] = date.getHours() + 1;
756
- ptr[5] = date.getMinutes() + 1;
757
- ptr[6] = date.getSeconds() + 1;
760
+ this.buf[pos] = Math.trunc(year / 100) + 100;
761
+ this.buf[pos + 1] = year % 100 + 100;
762
+ this.buf[pos + 2] = date.getMonth() + 1;
763
+ this.buf[pos + 3] = date.getDate();
764
+ this.buf[pos + 4] = date.getHours() + 1;
765
+ this.buf[pos + 5] = date.getMinutes() + 1;
766
+ this.buf[pos + 6] = date.getSeconds() + 1;
758
767
  } else {
759
768
  const year = date.getUTCFullYear();
760
- ptr[0] = Math.trunc(year / 100) + 100;
761
- ptr[1] = year % 100 + 100;
762
- ptr[2] = date.getUTCMonth() + 1;
763
- ptr[3] = date.getUTCDate();
764
- ptr[4] = date.getUTCHours() + 1;
765
- ptr[5] = date.getUTCMinutes() + 1;
766
- ptr[6] = date.getUTCSeconds() + 1;
769
+ this.buf[pos] = Math.trunc(year / 100) + 100;
770
+ this.buf[pos + 1] = year % 100 + 100;
771
+ this.buf[pos + 2] = date.getUTCMonth() + 1;
772
+ this.buf[pos + 3] = date.getUTCDate();
773
+ this.buf[pos + 4] = date.getUTCHours() + 1;
774
+ this.buf[pos + 5] = date.getUTCMinutes() + 1;
775
+ this.buf[pos + 6] = date.getUTCSeconds() + 1;
767
776
  }
768
777
  if (length > 7) {
769
- ptr.writeInt32BE(fsec, 7);
778
+ this.buf.writeInt32BE(fsec, pos + 7);
770
779
  if (length > 11) {
771
- ptr[11] = constants.TZ_HOUR_OFFSET;
772
- ptr[12] = constants.TZ_MINUTE_OFFSET;
780
+ this.buf[pos + 11] = constants.TZ_HOUR_OFFSET;
781
+ this.buf[pos + 12] = constants.TZ_MINUTE_OFFSET;
773
782
  }
774
783
  }
775
784
  }
@@ -843,19 +852,19 @@ class BaseBuffer {
843
852
  } else if (value.length === 0 && exponent === 0) {
844
853
  exponentOnWire = 128;
845
854
  }
846
- const buf = this.reserveBytes(numPairs + 2 + appendSentinel);
847
- buf[0] = numPairs + 1 + appendSentinel;
848
- buf[1] = exponentOnWire;
849
- for (let i = 0, pos = 2; i < value.length; i += 2, pos++) {
855
+ let pos = this.reserveBytes(numPairs + 2 + appendSentinel);
856
+ this.buf[pos++] = numPairs + 1 + appendSentinel;
857
+ this.buf[pos++] = exponentOnWire;
858
+ for (let i = 0; i < value.length; i += 2) {
850
859
  const base100Digit = Number(value.substring(i, i + 2));
851
860
  if (isNegative) {
852
- buf[pos] = 101 - base100Digit;
861
+ this.buf[pos++] = 101 - base100Digit;
853
862
  } else {
854
- buf[pos] = base100Digit + 1;
863
+ this.buf[pos++] = base100Digit + 1;
855
864
  }
856
865
  }
857
866
  if (appendSentinel) {
858
- buf[buf.length - 1] = 102;
867
+ this.buf[pos] = 102;
859
868
  }
860
869
 
861
870
  }
@@ -898,8 +907,8 @@ class BaseBuffer {
898
907
  // Writes a signed 32-bit integer to the buffer in big endian order.
899
908
  //---------------------------------------------------------------------------
900
909
  writeInt32BE(n) {
901
- const buf = this.reserveBytes(4);
902
- buf.writeInt32BE(n);
910
+ const pos = this.reserveBytes(4);
911
+ this.buf.writeInt32BE(n, pos);
903
912
  }
904
913
 
905
914
  //---------------------------------------------------------------------------
@@ -971,8 +980,8 @@ class BaseBuffer {
971
980
  // Writes an unsigned 8-bit integer to the buffer.
972
981
  //---------------------------------------------------------------------------
973
982
  writeUInt8(n) {
974
- const buf = this.reserveBytes(1);
975
- buf[0] = n;
983
+ const pos = this.reserveBytes(1);
984
+ this.buf[pos] = n;
976
985
  }
977
986
 
978
987
  //---------------------------------------------------------------------------
@@ -981,8 +990,8 @@ class BaseBuffer {
981
990
  // Writes an unsigned 16-bit integer to the buffer in big endian order.
982
991
  //---------------------------------------------------------------------------
983
992
  writeUInt16BE(n) {
984
- const buf = this.reserveBytes(2);
985
- buf.writeUInt16BE(n);
993
+ const pos = this.reserveBytes(2);
994
+ this.buf.writeUInt16BE(n, pos);
986
995
  }
987
996
 
988
997
  //---------------------------------------------------------------------------
@@ -991,8 +1000,8 @@ class BaseBuffer {
991
1000
  // Writes an unsigned 32-bit integer to the buffer in big endian order.
992
1001
  //---------------------------------------------------------------------------
993
1002
  writeUInt32BE(n) {
994
- const buf = this.reserveBytes(4);
995
- buf.writeUInt32BE(n);
1003
+ const pos = this.reserveBytes(4);
1004
+ this.buf.writeUInt32BE(n, pos);
996
1005
  }
997
1006
 
998
1007
  //---------------------------------------------------------------------------
@@ -1003,9 +1012,9 @@ class BaseBuffer {
1003
1012
  // higher order bits are simply written as 0.
1004
1013
  //---------------------------------------------------------------------------
1005
1014
  writeUInt64BE(n) {
1006
- const buf = this.reserveBytes(8);
1007
- buf.writeUInt32BE(0);
1008
- buf.writeUInt32BE(n, 4);
1015
+ const pos = this.reserveBytes(8);
1016
+ this.buf.writeUInt32BE(0, pos);
1017
+ this.buf.writeUInt32BE(n, pos + 4);
1009
1018
  }
1010
1019
 
1011
1020
  //---------------------------------------------------------------------------
@@ -1014,8 +1023,8 @@ class BaseBuffer {
1014
1023
  // Writes an unsigned 16-bit integer to the buffer in little endian order.
1015
1024
  //---------------------------------------------------------------------------
1016
1025
  writeUInt16LE(n) {
1017
- const buf = this.reserveBytes(2);
1018
- buf.writeUInt16LE(n);
1026
+ const pos = this.reserveBytes(2);
1027
+ this.buf.writeUInt16LE(n, pos);
1019
1028
  }
1020
1029
 
1021
1030
  }
@@ -1048,7 +1057,7 @@ class GrowableBuffer extends BaseBuffer {
1048
1057
  if (remainder > 0) {
1049
1058
  numBytes += (constants.BUFFER_CHUNK_SIZE - remainder);
1050
1059
  }
1051
- const buf = Buffer.alloc(numBytes);
1060
+ const buf = Buffer.allocUnsafe(numBytes);
1052
1061
  this.buf.copy(buf);
1053
1062
  this.buf = buf;
1054
1063
  this.maxSize = this.size = numBytes;
@@ -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) {
@@ -448,6 +463,13 @@ class Message {
448
463
  }
449
464
  return writtenBytes;
450
465
  }
466
+
467
+ // Called when an error is encountered during decode of RPC
468
+ saveDeferredErr() {
469
+ if (!this.deferredErr) {
470
+ this.deferredErr = errors.getErr(...arguments);
471
+ }
472
+ }
451
473
  }
452
474
 
453
475
  module.exports = Message;