oracledb 6.5.0 → 6.6.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 (59) hide show
  1. package/README.md +2 -2
  2. package/build/Release/oracledb-6.6.0-darwin-arm64.node +0 -0
  3. package/build/Release/oracledb-6.6.0-darwin-arm64.node-buildinfo.txt +1 -0
  4. package/build/Release/oracledb-6.6.0-darwin-x64.node +0 -0
  5. package/build/Release/oracledb-6.6.0-darwin-x64.node-buildinfo.txt +1 -0
  6. package/build/Release/oracledb-6.6.0-js-buildinfo.txt +1 -0
  7. package/build/Release/oracledb-6.6.0-linux-arm64.node +0 -0
  8. package/build/Release/oracledb-6.6.0-linux-arm64.node-buildinfo.txt +1 -0
  9. package/build/Release/oracledb-6.6.0-linux-x64.node +0 -0
  10. package/build/Release/oracledb-6.6.0-linux-x64.node-buildinfo.txt +1 -0
  11. package/build/Release/oracledb-6.6.0-win32-x64.node +0 -0
  12. package/build/Release/oracledb-6.6.0-win32-x64.node-buildinfo.txt +1 -0
  13. package/examples/README.md +4 -0
  14. package/lib/configProviders/azure.js +167 -0
  15. package/lib/configProviders/base.js +99 -0
  16. package/lib/configProviders/ociobject.js +203 -0
  17. package/lib/connection.js +28 -12
  18. package/lib/constants.js +1 -0
  19. package/lib/errors.js +68 -1
  20. package/lib/impl/datahandlers/buffer.js +2 -2
  21. package/lib/impl/datahandlers/constants.js +3 -1
  22. package/lib/impl/datahandlers/vector.js +24 -9
  23. package/lib/impl/lob.js +27 -0
  24. package/lib/impl/resultset.js +26 -1
  25. package/lib/lob.js +52 -1
  26. package/lib/oracledb.js +61 -34
  27. package/lib/pool.js +7 -0
  28. package/lib/thin/connection.js +232 -16
  29. package/lib/thin/dbObject.js +4 -0
  30. package/lib/thin/lob.js +193 -1
  31. package/lib/thin/pool.js +15 -0
  32. package/lib/thin/protocol/capabilities.js +2 -0
  33. package/lib/thin/protocol/constants.js +30 -1
  34. package/lib/thin/protocol/messages/index.js +5 -1
  35. package/lib/thin/protocol/messages/lobOp.js +17 -5
  36. package/lib/thin/protocol/messages/transactionChangeState.js +99 -0
  37. package/lib/thin/protocol/messages/transactionSwitch.js +139 -0
  38. package/lib/thin/protocol/messages/withData.js +37 -8
  39. package/lib/thin/protocol/protocol.js +4 -0
  40. package/lib/thin/sqlnet/networkSession.js +2 -1
  41. package/lib/thin/sqlnet/packet.js +3 -1
  42. package/lib/thin/sqlnet/paramParser.js +87 -50
  43. package/lib/thin/sqlnet/sessionAtts.js +13 -1
  44. package/lib/thin/statement.js +4 -0
  45. package/lib/thin/statementCache.js +5 -0
  46. package/lib/transformer.js +1 -2
  47. package/lib/types.js +1 -1
  48. package/lib/util.js +62 -2
  49. package/lib/version.js +1 -1
  50. package/package.json +1 -1
  51. package/build/Release/oracledb-6.5.0-darwin-x64.node +0 -0
  52. package/build/Release/oracledb-6.5.0-darwin-x64.node-buildinfo.txt +0 -1
  53. package/build/Release/oracledb-6.5.0-js-buildinfo.txt +0 -1
  54. package/build/Release/oracledb-6.5.0-linux-arm64.node +0 -0
  55. package/build/Release/oracledb-6.5.0-linux-arm64.node-buildinfo.txt +0 -1
  56. package/build/Release/oracledb-6.5.0-linux-x64.node +0 -0
  57. package/build/Release/oracledb-6.5.0-linux-x64.node-buildinfo.txt +0 -1
  58. package/build/Release/oracledb-6.5.0-win32-x64.node +0 -0
  59. package/build/Release/oracledb-6.5.0-win32-x64.node-buildinfo.txt +0 -1
package/lib/errors.js CHANGED
@@ -31,6 +31,17 @@ const util = require('util');
31
31
  // define error prefix for all messages
32
32
  const ERR_PREFIX = "NJS";
33
33
 
34
+ const ERR_INTEGRITY_ERROR_CODES = [
35
+ 1, // unique constraint violated
36
+ 1400, // cannot insert NULL
37
+ 1438, // value larger than specified precision
38
+ 2290, // check constraint violated
39
+ 2291, // integrity constraint violated - parent key not found
40
+ 2292, // integrity constraint violated - child record found
41
+ 21525, // attribute or collection element violated its constraints
42
+ 40479, // internal JSON serializer error
43
+ ];
44
+
34
45
  // define error number constants (used in JavaScript library)
35
46
  const ERR_INVALID_POOL = 2;
36
47
  const ERR_INVALID_CONNECTION = 3;
@@ -145,6 +156,13 @@ const ERR_VECTOR_VERSION_NOT_SUPPORTED = 145;
145
156
  const ERR_OBJECT_IS_NOT_A_COLLECTION = 146;
146
157
  const ERR_CURSOR_HAS_BEEN_CLOSED = 147;
147
158
  const ERR_DML_RETURNING_DUP_BINDS = 149;
159
+ const ERR_INVALID_TPC_BEGIN_FLAGS = 150;
160
+ const ERR_INVALID_TPC_END_FLAGS = 151;
161
+ const ERR_UNKNOWN_TRANSACTION_STATE = 152;
162
+ const ERR_INVALID_TRANSACTION_SIZE = 153;
163
+ const ERR_INVALID_BRANCH_SIZE = 154;
164
+ const ERR_OPERATION_NOT_SUPPORTED_ON_BFILE = 155;
165
+ const ERR_OPERATION_ONLY_SUPPORTED_ON_BFILE = 156;
148
166
 
149
167
  // Oracle Net layer errors start from 500
150
168
  const ERR_CONNECTION_CLOSED = 500;
@@ -168,6 +186,13 @@ const ERR_INVALID_SERVICE_NAME = 518;
168
186
  const ERR_INVALID_SID = 519;
169
187
  const ERR_TNS_NAMES_FILE_MISSING = 520;
170
188
  const ERR_CONNECTION_EOF = 521;
189
+ const ERR_AZURE_CONFIG_PROVIDER_AUTH_FAILED = 522;
190
+ const ERR_CONFIG_PROVIDER_FAILED_TO_RETRIEVE_CONFIG = 523;
191
+ const ERR_CONFIG_PROVIDER_NOT_SUPPORTED = 524;
192
+ const ERR_CONFIG_PROVIDER_LOAD_FAILED = 525;
193
+ const ERR_OCIOBJECT_CONFIG_PROVIDER_AUTH_FAILED = 526;
194
+ const ERR_AZURE_VAULT_AUTH_FAILED = 527;
195
+ const ERR_AZURE_SERVICE_PRINCIPAL_AUTH_FAILED = 528;
171
196
 
172
197
  // Oracle SUCCESS_WITH_INFO warning start from 700
173
198
  const WRN_COMPILATION_CREATE = 700;
@@ -423,6 +448,20 @@ messages.set(ERR_CURSOR_HAS_BEEN_CLOSED, // NJS-147
423
448
  'cursor has been closed by the database');
424
449
  messages.set(ERR_DML_RETURNING_DUP_BINDS, // NJS-149
425
450
  'the bind variable placeholder "%s" cannot be used both before and after the RETURNING clause in a DML RETURNING statement');
451
+ messages.set(ERR_INVALID_TPC_BEGIN_FLAGS, // NJS-150
452
+ 'invalid flags for tpcBegin() in Two Phase Commit');
453
+ messages.set(ERR_INVALID_TPC_END_FLAGS, // NJS-151
454
+ 'invalid flags for tpcEnd() in Two Phase Commit');
455
+ messages.set(ERR_UNKNOWN_TRANSACTION_STATE, // NJS-152
456
+ 'internal error: unknown transaction state {state} in Two Phase Commit');
457
+ messages.set(ERR_INVALID_TRANSACTION_SIZE, // NJS-153
458
+ 'size of the transaction ID is %d and cannot exceed 64');
459
+ messages.set(ERR_INVALID_BRANCH_SIZE, // NJS-154
460
+ 'size of the branch ID is %d and cannot exceed 64');
461
+ messages.set(ERR_OPERATION_NOT_SUPPORTED_ON_BFILE, // NJS-155
462
+ 'operation is not supported on BFILE LOBs');
463
+ messages.set(ERR_OPERATION_ONLY_SUPPORTED_ON_BFILE, // NJS-156
464
+ 'operation is only supported on BFILE LOBs');
426
465
 
427
466
  // Oracle Net layer errors
428
467
 
@@ -468,7 +507,20 @@ messages.set(ERR_TNS_NAMES_FILE_MISSING, // NJS-520
468
507
  'cannot connect to Oracle Database. File tnsnames.ora not found in %s');
469
508
  messages.set(ERR_CONNECTION_EOF, // NJS-521
470
509
  'connection to host %s port %d received end-of-file on communication channel. (CONNECTION_ID=%s)');
471
-
510
+ messages.set(ERR_AZURE_CONFIG_PROVIDER_AUTH_FAILED, // NJS-522
511
+ 'Azure Authentication Failed: The authentication parameter value %s may be incorrect');
512
+ messages.set(ERR_CONFIG_PROVIDER_FAILED_TO_RETRIEVE_CONFIG, // NJS-523
513
+ 'Failed to retrieve configuration from Centralized Configuration Provider:\n %s');
514
+ messages.set(ERR_CONFIG_PROVIDER_NOT_SUPPORTED, // NJS-524
515
+ 'Configuration Provider not supported: %s');
516
+ messages.set(ERR_CONFIG_PROVIDER_LOAD_FAILED, // NJS-525
517
+ 'Centralized Config Provider failed to load required libraries. Please install the required libraries.\n %s');
518
+ messages.set(ERR_OCIOBJECT_CONFIG_PROVIDER_AUTH_FAILED, // NJS-526
519
+ 'OCI authentication failed: The authentication parameter value %s may be incorrect');
520
+ messages.set(ERR_AZURE_VAULT_AUTH_FAILED, // NJS-527
521
+ 'Azure Vault: Provide correct azure vault authentication details');
522
+ messages.set(ERR_AZURE_SERVICE_PRINCIPAL_AUTH_FAILED, // NJS-528
523
+ 'Azure service principal authentication requires either a client certificate path or a client secret string');
472
524
  // Oracle SUCCESS_WITH_INFO warning
473
525
 
474
526
  messages.set(WRN_COMPILATION_CREATE, // NJS-700
@@ -695,6 +747,7 @@ function transformErr(err, fnOpt) {
695
747
 
696
748
  // define exports
697
749
  module.exports = {
750
+ ERR_INTEGRITY_ERROR_CODES,
698
751
  ERR_INVALID_POOL,
699
752
  ERR_INVALID_CONNECTION,
700
753
  ERR_INVALID_PROPERTY_VALUE,
@@ -777,6 +830,13 @@ module.exports = {
777
830
  ERR_NO_CONFIG_DIR,
778
831
  ERR_TNS_ENTRY_NOT_FOUND,
779
832
  ERR_CONNECTION_EOF,
833
+ ERR_AZURE_CONFIG_PROVIDER_AUTH_FAILED,
834
+ ERR_OCIOBJECT_CONFIG_PROVIDER_AUTH_FAILED,
835
+ ERR_AZURE_VAULT_AUTH_FAILED,
836
+ ERR_AZURE_SERVICE_PRINCIPAL_AUTH_FAILED,
837
+ ERR_CONFIG_PROVIDER_FAILED_TO_RETRIEVE_CONFIG,
838
+ ERR_CONFIG_PROVIDER_NOT_SUPPORTED,
839
+ ERR_CONFIG_PROVIDER_LOAD_FAILED,
780
840
  ERR_INVALID_BIND_NAME,
781
841
  ERR_WRONG_NUMBER_OF_POSITIONAL_BINDS,
782
842
  ERR_BUFFER_LENGTH_INSUFFICIENT,
@@ -829,7 +889,14 @@ module.exports = {
829
889
  ERR_OBJECT_IS_NOT_A_COLLECTION,
830
890
  ERR_CURSOR_HAS_BEEN_CLOSED,
831
891
  ERR_DML_RETURNING_DUP_BINDS,
892
+ ERR_INVALID_TPC_BEGIN_FLAGS,
893
+ ERR_INVALID_TPC_END_FLAGS,
894
+ ERR_UNKNOWN_TRANSACTION_STATE,
895
+ ERR_INVALID_TRANSACTION_SIZE,
896
+ ERR_INVALID_BRANCH_SIZE,
832
897
  ERR_CONNECTION_CLOSED_CODE: `${ERR_PREFIX}-${ERR_CONNECTION_CLOSED}`,
898
+ ERR_OPERATION_NOT_SUPPORTED_ON_BFILE,
899
+ ERR_OPERATION_ONLY_SUPPORTED_ON_BFILE,
833
900
  WRN_COMPILATION_CREATE,
834
901
  assert,
835
902
  assertArgCount,
@@ -843,8 +843,8 @@ class BaseBuffer {
843
843
  }
844
844
 
845
845
  // throw exception if number cannot be represented as an Oracle Number
846
- if (value.length > constants.NUMBER_MAX_DIGITS || exponent > 126 ||
847
- exponent < -129) {
846
+ if (value.length > constants.NUMBER_MAX_DIGITS || exponent >= 126 ||
847
+ exponent <= -131) {
848
848
  errors.throwErr(errors.ERR_ORACLE_NUMBER_NO_REPR);
849
849
  }
850
850
 
@@ -32,7 +32,8 @@ module.exports = {
32
32
 
33
33
  // vector constants
34
34
  TNS_VECTOR_MAGIC_BYTE: 0xDB,
35
- TNS_VECTOR_VERSION: 0,
35
+ TNS_VECTOR_VERSION_BASE: 0,
36
+ TNS_VECTOR_VERSION_WITH_BINARY: 1,
36
37
 
37
38
  // vector flags
38
39
  TNS_VECTOR_FLAG_NORMSRC: 0x0010,
@@ -99,6 +100,7 @@ module.exports = {
99
100
  VECTOR_FORMAT_FLOAT32: constants.VECTOR_FORMAT_FLOAT32,
100
101
  VECTOR_FORMAT_FLOAT64: constants.VECTOR_FORMAT_FLOAT64,
101
102
  VECTOR_FORMAT_INT8: constants.VECTOR_FORMAT_INT8,
103
+ VECTOR_FORMAT_BINARY: constants.VECTOR_FORMAT_BINARY,
102
104
 
103
105
  TNS_NULL_LENGTH_INDICATOR: 255,
104
106
  TNS_LONG_LENGTH_INDICATOR: 254,
@@ -50,11 +50,11 @@ class VectorDecoder extends BaseBuffer {
50
50
  errors.throwErr(errors.ERR_UNEXPECTED_DATA,
51
51
  Buffer.from([magicByte]).toString('hex'));
52
52
  const version = this.readUInt8();
53
- if (version != constants.TNS_VECTOR_VERSION)
53
+ if (version > constants.TNS_VECTOR_VERSION_WITH_BINARY)
54
54
  errors.throwErr(errors.ERR_VECTOR_VERSION_NOT_SUPPORTED, version);
55
55
  const flags = this.readUInt16BE();
56
56
  const vectorFormat = this.readUInt8();
57
- const numElements = this.readUInt32BE();
57
+ let numElements = this.readUInt32BE();
58
58
  let elementSize, result;
59
59
  if (vectorFormat === constants.VECTOR_FORMAT_FLOAT32) {
60
60
  elementSize = 4;
@@ -65,10 +65,18 @@ class VectorDecoder extends BaseBuffer {
65
65
  } else if (vectorFormat === constants.VECTOR_FORMAT_INT8) {
66
66
  elementSize = 1;
67
67
  result = new Int8Array(numElements);
68
+ } else if (vectorFormat === constants.VECTOR_FORMAT_BINARY) {
69
+ elementSize = 1;
70
+ // The number of dimensions are assumed to be multiple of 8.
71
+ numElements = numElements / 8;
72
+ result = new Uint8Array(numElements);
68
73
  } else {
69
74
  errors.throwErr(errors.ERR_VECTOR_FORMAT_NOT_SUPPORTED, vectorFormat);
70
75
  }
71
- if (flags & constants.TNS_VECTOR_FLAG_NORM)
76
+
77
+ // For binary vector, NORM will never be present but space for NORM is reserved to keep
78
+ // same header lengh across the different vector formats.
79
+ if (vectorFormat === constants.VECTOR_FORMAT_BINARY || flags & constants.TNS_VECTOR_FLAG_NORM)
72
80
  this.skipBytes(8);
73
81
 
74
82
  // parse data
@@ -100,6 +108,10 @@ class VectorEncoder extends GrowableBuffer {
100
108
  // determine some basic information about the vector
101
109
  let vectorFormat = constants.VECTOR_FORMAT_FLOAT32;
102
110
  let writeFn = this.writeBinaryFloat.bind(this);
111
+ let numElements = value.length;
112
+ let vectorVersion = constants.TNS_VECTOR_VERSION_BASE;
113
+ let flags = constants.TNS_VECTOR_FLAG_NORMSRC
114
+ | constants.TNS_VECTOR_FLAG_NORM; // NORM is present and reserve space.
103
115
 
104
116
  if (Array.isArray(value) || value instanceof Float64Array) {
105
117
  vectorFormat = constants.VECTOR_FORMAT_FLOAT64;
@@ -107,18 +119,21 @@ class VectorEncoder extends GrowableBuffer {
107
119
  } else if (value instanceof Int8Array) {
108
120
  vectorFormat = constants.VECTOR_FORMAT_INT8;
109
121
  writeFn = this.writeSB1.bind(this);
122
+ } else if (value.constructor.name === 'Uint8Array') {
123
+ vectorFormat = constants.VECTOR_FORMAT_BINARY;
124
+ // The number of dimensions are assumed to be multiple of 8.
125
+ numElements = numElements * 8;
126
+ vectorVersion = constants.TNS_VECTOR_VERSION_WITH_BINARY;
127
+ flags = constants.TNS_VECTOR_FLAG_NORMSRC; // only space is reserved.
128
+ writeFn = this.writeUInt8.bind(this);
110
129
  }
111
130
 
112
- // Let server generate the norm (TNS_VECTOR_FLAG_NORMSRC)
113
- const flags = constants.TNS_VECTOR_FLAG_NORM
114
- | constants.TNS_VECTOR_FLAG_NORMSRC;
115
-
116
131
  // write header
117
132
  this.writeUInt8(constants.TNS_VECTOR_MAGIC_BYTE);
118
- this.writeUInt8(constants.TNS_VECTOR_VERSION);
133
+ this.writeUInt8(vectorVersion);
119
134
  this.writeUInt16BE(flags);
120
135
  this.writeUInt8(vectorFormat);
121
- this.writeUInt32BE(value.length);
136
+ this.writeUInt32BE(numElements);
122
137
  this.reserveBytes(8);
123
138
 
124
139
  // write data
package/lib/impl/lob.js CHANGED
@@ -53,6 +53,15 @@ class LobImpl {
53
53
  errors.throwNotImplemented("closing a LOB");
54
54
  }
55
55
 
56
+ //---------------------------------------------------------------------------
57
+ // fileExists()
58
+ //
59
+ // Checks if BFILE present or not.
60
+ //---------------------------------------------------------------------------
61
+ fileExists() {
62
+ errors.throwNotImplemented("check if BFILE exists");
63
+ }
64
+
56
65
  //---------------------------------------------------------------------------
57
66
  // getData()
58
67
  //
@@ -62,6 +71,15 @@ class LobImpl {
62
71
  errors.throwNotImplemented("getting all of the data from a LOB");
63
72
  }
64
73
 
74
+ //---------------------------------------------------------------------------
75
+ // getDirFileName()
76
+ //
77
+ // returns directory and filename of LOB (BFILE).
78
+ //----------------------------------------------------------------------------
79
+ getDirFileName() {
80
+ errors.throwNotImplemented("getting directory and filename of LOB(BFILE)");
81
+ }
82
+
65
83
  //---------------------------------------------------------------------------
66
84
  // read()
67
85
  //
@@ -71,6 +89,15 @@ class LobImpl {
71
89
  errors.throwNotImplemented("reading from a LOB");
72
90
  }
73
91
 
92
+ //---------------------------------------------------------------------------
93
+ // setDirFileName()
94
+ //
95
+ // sets directory and filename for LOB (BFILE)
96
+ //---------------------------------------------------------------------------
97
+ setDirFileName() {
98
+ errors.throwNotImplemented("setting directory and filename of LOB(BFILE)");
99
+ }
100
+
74
101
  //---------------------------------------------------------------------------
75
102
  // write()
76
103
  //
@@ -236,7 +236,8 @@ class ResultSetImpl {
236
236
  this.nestedCursorIndices.push(i);
237
237
  } else if (info.fetchType === types.DB_TYPE_CLOB ||
238
238
  info.fetchType === types.DB_TYPE_NCLOB ||
239
- info.fetchType === types.DB_TYPE_BLOB) {
239
+ info.fetchType === types.DB_TYPE_BLOB ||
240
+ info.fetchType === types.DB_TYPE_BFILE) {
240
241
  this.lobIndices.push(i);
241
242
  } else if (info.fetchType === types.DB_TYPE_OBJECT) {
242
243
  this.dbObjectIndices.push(i);
@@ -275,6 +276,30 @@ class ResultSetImpl {
275
276
  errors.throwNotImplemented("getting rows");
276
277
  }
277
278
 
279
+ //---------------------------------------------------------------------------
280
+ // _getAllRows() [INTERNAL]
281
+ //
282
+ // Fetches all the rows from the database to use internally.
283
+ //---------------------------------------------------------------------------
284
+ async _getAllRows() {
285
+ const fetchArraySize = 100;
286
+ // fetch all rows
287
+ let rowsFetched = [];
288
+ while (true) { // eslint-disable-line
289
+ // constant default value for fetchArraySize
290
+ const rows = await this.getRows(fetchArraySize, {});
291
+ if (rows) {
292
+ await this._processRows(rows, false);
293
+ rowsFetched = rowsFetched.concat(rows);
294
+ }
295
+ if (rows.length < fetchArraySize) {
296
+ break;
297
+ }
298
+ }
299
+
300
+ return rowsFetched;
301
+ }
302
+
278
303
  }
279
304
 
280
305
  module.exports = ResultSetImpl;
package/lib/lob.js CHANGED
@@ -46,6 +46,22 @@ class Lob extends Duplex {
46
46
  });
47
47
  }
48
48
 
49
+ // called by BFILE specific functions to throw errors for other
50
+ // datatypes.
51
+ _checkIsBfile() {
52
+ if (this.type !== types.DB_TYPE_BFILE) {
53
+ errors.throwErr(errors.ERR_OPERATION_ONLY_SUPPORTED_ON_BFILE);
54
+ }
55
+ }
56
+
57
+ // called by functions not allowed for BFILE and throw errors if
58
+ // such operations are performed on BFILE.
59
+ _checkNotBfile() {
60
+ if (this.type === types.DB_TYPE_BFILE) {
61
+ errors.throwErr(errors.ERR_OPERATION_NOT_SUPPORTED_ON_BFILE);
62
+ }
63
+ }
64
+
49
65
  // called by stream.destroy() and ensures that the LOB is closed if it has
50
66
  // not already been closed (never called directly)
51
67
  async _destroy(err, cb) {
@@ -101,7 +117,10 @@ class Lob extends Duplex {
101
117
  // called to associate a LOB implementation with this user facing object
102
118
  _setup(lobImpl, autoCloseLob) {
103
119
  this._impl = lobImpl;
104
- this._chunkSize = lobImpl.getChunkSize();
120
+ // chunk size is not defined for BFILE LOBs
121
+ if (this.type !== types.DB_TYPE_BFILE) {
122
+ this._chunkSize = lobImpl.getChunkSize();
123
+ }
105
124
  this._pieceSize = lobImpl.getPieceSize();
106
125
  this._length = lobImpl.getLength();
107
126
  this._type = lobImpl.getType();
@@ -153,6 +172,7 @@ class Lob extends Duplex {
153
172
  // Property for the chunk size of the LOB.
154
173
  //---------------------------------------------------------------------------
155
174
  get chunkSize() {
175
+ this._checkNotBfile();
156
176
  return this._chunkSize;
157
177
  }
158
178
 
@@ -209,6 +229,36 @@ class Lob extends Duplex {
209
229
  return await this._impl.getData(offset, amount);
210
230
  }
211
231
 
232
+ //---------------------------------------------------------------------------
233
+ // getDirFileName()
234
+ // To obtain the BFILE Lob object properties dirName & fileName
235
+ //---------------------------------------------------------------------------
236
+ getDirFileName() {
237
+ this._checkIsBfile();
238
+ return this._impl.getDirFileName();
239
+ }
240
+
241
+ //--------------------------------------------------------------------------
242
+ // setDirFileName()
243
+ // To set the BFILE Lob object properties dirName & fileName
244
+ //--------------------------------------------------------------------------
245
+ setDirFileName(a1) {
246
+ this._checkIsBfile();
247
+ errors.assertArgCount(arguments, 1, 1);
248
+ errors.assertParamValue(nodbUtil.isObject(a1), 1);
249
+ this._impl.setDirFileName(a1);
250
+ }
251
+
252
+ //---------------------------------------------------------------------------
253
+ // fileExists
254
+ //
255
+ // To obtain file existence status of BFILE file
256
+ //---------------------------------------------------------------------------
257
+ async fileExists() {
258
+ this._checkIsBfile();
259
+ return await this._impl.fileExists();
260
+ }
261
+
212
262
  //---------------------------------------------------------------------------
213
263
  // length
214
264
  //
@@ -248,6 +298,7 @@ class Lob extends Duplex {
248
298
 
249
299
  nodbUtil.wrapFns(Lob.prototype, errors.ERR_BUSY_LOB,
250
300
  "close",
301
+ "fileExists",
251
302
  "getData");
252
303
  Lob.prototype._serializedRead = nodbUtil.serialize(Lob.prototype._readData);
253
304
  Lob.prototype._serializedWrite = nodbUtil.serialize(Lob.prototype._writeData);
package/lib/oracledb.js CHANGED
@@ -118,33 +118,6 @@ function _initializeThinDriver() {
118
118
  require('./thin');
119
119
  }
120
120
 
121
- //---------------------------------------------------------------------------
122
- // _isPrivilege()
123
- //
124
- // Returns a boolean indicating if the supplied value is a valid privilege.
125
- //---------------------------------------------------------------------------
126
- function _isPrivilege(value) {
127
- // Privileges are mutually exclusive and cannot be specified together
128
- // except SYSPRELIM, which cannot be specified alone, it is specified in a
129
- // combo with SYSOPER or SYSDBA. SYSPRELIM is used only for
130
- // startup/shutdown
131
-
132
- // If SYSPRELIM specified, clear the bit
133
- if (value & constants.SYSPRELIM) {
134
- value = value ^ constants.SYSPRELIM;
135
- }
136
-
137
- return (
138
- value === constants.SYSASM ||
139
- value === constants.SYSBACKUP ||
140
- value === constants.SYSDBA ||
141
- value === constants.SYSDG ||
142
- value === constants.SYSKM ||
143
- value === constants.SYSOPER ||
144
- value === constants.SYSRAC
145
- );
146
- }
147
-
148
121
  //-----------------------------------------------------------------------------
149
122
  // _verifyOptions()
150
123
  //
@@ -156,6 +129,7 @@ async function _verifyOptions(options, inCreatePool) {
156
129
  // define normalized options (value returned to caller)
157
130
  const outOptions = {};
158
131
 
132
+ options = await _checkConfigProvider(options);
159
133
  // only one of "user" and "username" may be specified (and must be strings)
160
134
  if (options.user !== undefined) {
161
135
  errors.assertParamPropValue(typeof options.user === 'string', 1, "user");
@@ -204,6 +178,13 @@ async function _verifyOptions(options, inCreatePool) {
204
178
  outOptions.walletLocation = options.walletLocation;
205
179
  }
206
180
 
181
+ //wallet content must be a string
182
+ if (options.walletContent !== undefined) {
183
+ errors.assertParamPropValue(typeof options.walletContent === 'string', 1,
184
+ "walletContent");
185
+ outOptions.walletContent = options.walletContent;
186
+ }
187
+
207
188
  // edition must be a string
208
189
  if (options.edition !== undefined) {
209
190
  errors.assertParamPropValue(typeof options.edition === 'string', 1,
@@ -331,6 +312,13 @@ async function _verifyOptions(options, inCreatePool) {
331
312
  outOptions.connectionIdPrefix = options.connectionIdPrefix;
332
313
  }
333
314
 
315
+ // privilege must be one of a set of named constants
316
+ if (options.privilege !== undefined) {
317
+ errors.assertParamPropValue(nodbUtil.isPrivilege(options.privilege), 1,
318
+ "privilege");
319
+ outOptions.privilege = options.privilege;
320
+ }
321
+
334
322
  // check pool specific options
335
323
  if (inCreatePool) {
336
324
 
@@ -444,13 +432,6 @@ async function _verifyOptions(options, inCreatePool) {
444
432
  outOptions.newPassword = options.newPassword;
445
433
  }
446
434
 
447
- // privilege must be one of a set of named constants
448
- if (options.privilege !== undefined) {
449
- errors.assertParamPropValue(_isPrivilege(options.privilege), 1,
450
- "privilege");
451
- outOptions.privilege = options.privilege;
452
- }
453
-
454
435
  // shardingKey must be an array of values
455
436
  if (options.shardingKey !== undefined) {
456
437
  const value = options.shardingKey;
@@ -787,6 +768,51 @@ async function shutdown(a1, a2) {
787
768
  await conn.close();
788
769
  }
789
770
 
771
+ //-----------------------------------------------------------------------------
772
+ // _checkConfigProvider()
773
+ //
774
+ // Look for the config provider in the connection string and retreives
775
+ // object stored in the config Provider.
776
+ // Returns object based on precedence between input object and the one retrieved
777
+ // from Config Provider.
778
+ //-----------------------------------------------------------------------------
779
+ async function _checkConfigProvider(options) {
780
+ const url = options.connectString || options.connectionString;
781
+ if (!url)
782
+ return options;
783
+ let parsedUrl = url;
784
+ let urlExtendedPart;
785
+ const baseRegex = new RegExp("^config-(?<provider>[A-Za-z0-9]+)(://)(?<provider_arg>[^?]+)");
786
+ if (url.indexOf('?') != -1) {
787
+ parsedUrl = url.substring(0, url.indexOf('?'));
788
+ urlExtendedPart = url.substring(url.indexOf('?'), url.length); //extended part
789
+ }
790
+ const match = parsedUrl.match(baseRegex);
791
+ if (match) {
792
+ const provider = match.groups.provider;
793
+ const provider_arg = match.groups.provider_arg;
794
+ let configPckg;
795
+ try {
796
+ configPckg = require('./configProviders/' + provider);
797
+ } catch (err) {
798
+ errors.throwErr(errors.ERR_CONFIG_PROVIDER_NOT_SUPPORTED, provider);
799
+ }
800
+ const configProvider = new configPckg(provider_arg, urlExtendedPart);
801
+ try {
802
+ configProvider.init();
803
+ } catch (err) {
804
+ errors.throwErr(errors.ERR_CONFIG_PROVIDER_LOAD_FAILED, err.message);
805
+ }
806
+ let secondOpts;
807
+ try {
808
+ secondOpts = await configProvider.returnConfig();
809
+ } catch (err) {
810
+ errors.throwErr(errors.ERR_CONFIG_PROVIDER_FAILED_TO_RETRIEVE_CONFIG, err.message);
811
+ }
812
+ options = configProvider.modifyOptionsPrecedence(secondOpts, options);
813
+ }
814
+ return options;
815
+ }
790
816
 
791
817
  //-----------------------------------------------------------------------------
792
818
  // startup()
@@ -1034,6 +1060,7 @@ module.exports = {
1034
1060
  VECTOR_FORMAT_FLOAT32: constants.VECTOR_FORMAT_FLOAT32,
1035
1061
  VECTOR_FORMAT_FLOAT64: constants.VECTOR_FORMAT_FLOAT64,
1036
1062
  VECTOR_FORMAT_INT8: constants.VECTOR_FORMAT_INT8,
1063
+ VECTOR_FORMAT_BINARY: constants.VECTOR_FORMAT_BINARY,
1037
1064
 
1038
1065
  // database type aliases
1039
1066
  BLOB: types.DB_TYPE_BLOB,
package/lib/pool.js CHANGED
@@ -238,6 +238,13 @@ class Pool extends EventEmitter {
238
238
  outOptions.superShardingKey = options.superShardingKey;
239
239
  }
240
240
 
241
+ // privilege must be one of a set of named constants
242
+ if (options.privilege !== undefined) {
243
+ errors.assertParamPropValue(nodbUtil.isPrivilege(options.privilege), 1,
244
+ "privilege");
245
+ outOptions.privilege = options.privilege;
246
+ }
247
+
241
248
  return outOptions;
242
249
  }
243
250