oracledb 6.2.0 → 6.4.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 (70) hide show
  1. package/LICENSE.txt +1 -1
  2. package/NOTICE.txt +1 -1
  3. package/README.md +3 -3
  4. package/build/Release/oracledb-6.4.0-darwin-x64.node +0 -0
  5. package/build/Release/oracledb-6.4.0-darwin-x64.node-buildinfo.txt +1 -0
  6. package/build/Release/oracledb-6.4.0-js-buildinfo.txt +1 -0
  7. package/build/Release/oracledb-6.4.0-linux-arm64.node +0 -0
  8. package/build/Release/oracledb-6.4.0-linux-arm64.node-buildinfo.txt +1 -0
  9. package/build/Release/oracledb-6.4.0-linux-x64.node +0 -0
  10. package/build/Release/oracledb-6.4.0-linux-x64.node-buildinfo.txt +1 -0
  11. package/build/Release/oracledb-6.4.0-win32-x64.node +0 -0
  12. package/build/Release/oracledb-6.4.0-win32-x64.node-buildinfo.txt +1 -0
  13. package/examples/README.md +29 -8
  14. package/examples/dbconfig.js +50 -26
  15. package/examples/example.js +6 -4
  16. package/lib/aqQueue.js +8 -8
  17. package/lib/connection.js +121 -9
  18. package/lib/constants.js +7 -1
  19. package/lib/dbObject.js +72 -1
  20. package/lib/errors.js +45 -8
  21. package/lib/future.js +53 -0
  22. package/lib/impl/connection.js +56 -0
  23. package/lib/{thin/protocol → impl/datahandlers}/buffer.js +51 -39
  24. package/lib/impl/datahandlers/constants.js +105 -0
  25. package/lib/{thin/protocol → impl/datahandlers}/oson.js +19 -1
  26. package/lib/impl/datahandlers/vector.js +156 -0
  27. package/lib/impl/pool.js +14 -3
  28. package/lib/impl/resultset.js +65 -11
  29. package/lib/lob.js +22 -6
  30. package/lib/oracledb.js +47 -8
  31. package/lib/pool.js +20 -1
  32. package/lib/poolStatistics.js +3 -1
  33. package/lib/settings.js +30 -6
  34. package/lib/sodaDocCursor.js +14 -1
  35. package/lib/thin/connection.js +146 -146
  36. package/lib/thin/dbObject.js +49 -3
  37. package/lib/thin/index.js +1 -1
  38. package/lib/thin/lob.js +6 -6
  39. package/lib/thin/pool.js +25 -6
  40. package/lib/thin/protocol/capabilities.js +6 -2
  41. package/lib/thin/protocol/constants.js +50 -65
  42. package/lib/thin/protocol/messages/auth.js +6 -2
  43. package/lib/thin/protocol/messages/base.js +50 -32
  44. package/lib/thin/protocol/messages/dataType.js +10 -6
  45. package/lib/thin/protocol/messages/lobOp.js +7 -8
  46. package/lib/thin/protocol/messages/withData.js +91 -24
  47. package/lib/thin/protocol/packet.js +58 -4
  48. package/lib/thin/protocol/utils.js +1 -1
  49. package/lib/thin/sqlnet/connStrategy.js +8 -4
  50. package/lib/thin/sqlnet/constants.js +138 -138
  51. package/lib/thin/sqlnet/navNodes.js +5 -5
  52. package/lib/thin/sqlnet/networkSession.js +22 -3
  53. package/lib/thin/sqlnet/ntTcp.js +7 -7
  54. package/lib/thin/statement.js +8 -8
  55. package/lib/thin/statementCache.js +167 -0
  56. package/lib/thin/util.js +15 -4
  57. package/lib/transformer.js +13 -4
  58. package/lib/types.js +17 -2
  59. package/lib/util.js +37 -0
  60. package/lib/version.js +2 -2
  61. package/package.json +1 -1
  62. package/build/Release/oracledb-6.2.0-darwin-x64.node +0 -0
  63. package/build/Release/oracledb-6.2.0-darwin-x64.node-buildinfo.txt +0 -1
  64. package/build/Release/oracledb-6.2.0-js-buildinfo.txt +0 -1
  65. package/build/Release/oracledb-6.2.0-linux-arm64.node +0 -0
  66. package/build/Release/oracledb-6.2.0-linux-arm64.node-buildinfo.txt +0 -1
  67. package/build/Release/oracledb-6.2.0-linux-x64.node +0 -0
  68. package/build/Release/oracledb-6.2.0-linux-x64.node-buildinfo.txt +0 -1
  69. package/build/Release/oracledb-6.2.0-win32-x64.node +0 -0
  70. package/build/Release/oracledb-6.2.0-win32-x64.node-buildinfo.txt +0 -1
package/lib/errors.js CHANGED
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
1
+ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -107,7 +107,6 @@ const ERR_POOL_HAS_BUSY_CONNECTIONS = 104;
107
107
  const ERR_NAN_VALUE = 105;
108
108
  const ERR_INTERNAL = 106;
109
109
  const ERR_INVALID_REF_CURSOR = 107;
110
- const ERR_LOB_CLOSED = 108;
111
110
  const ERR_INVALID_TYPE_NUM = 109;
112
111
  const ERR_INVALID_ORACLE_TYPE_NUM = 110;
113
112
  const ERR_UNEXPECTED_NEGATIVE_INTEGER = 111;
@@ -136,6 +135,14 @@ const ERR_WRONG_VALUE_FOR_DBOBJECT_ELEM = 135;
136
135
  const ERR_WRONG_CRED_FOR_EXTAUTH = 136;
137
136
  const ERR_MISSING_BIND_VALUE = 137;
138
137
  const ERR_SERVER_VERSION_NOT_SUPPORTED = 138;
138
+ const ERR_UNEXPECTED_XML_TYPE = 139;
139
+ const ERR_WRONG_USER_FORMAT_EXTAUTH_PROXY = 140;
140
+ const ERR_TOO_MANY_BATCH_ERRORS = 141;
141
+ const ERR_WRONG_LENGTH_FOR_DBOBJECT_ATTR = 142;
142
+ const ERR_WRONG_LENGTH_FOR_DBOBJECT_ELEM = 143;
143
+ const ERR_VECTOR_FORMAT_NOT_SUPPORTED = 144;
144
+ const ERR_VECTOR_VERSION_NOT_SUPPORTED = 145;
145
+ const ERR_OBJECT_IS_NOT_A_COLLECTION = 146;
139
146
 
140
147
  // Oracle Net layer errors start from 500
141
148
  const ERR_CONNECTION_CLOSED = 500;
@@ -160,12 +167,14 @@ const ERR_INVALID_SID = 519;
160
167
  const ERR_TNS_NAMES_FILE_MISSING = 520;
161
168
  const ERR_CONNECTION_EOF = 521;
162
169
 
170
+ // Oracle SUCCESS_WITH_INFO warning start from 700
171
+ const WRN_COMPILATION_CREATE = 700;
172
+
163
173
  // define mapping for ODPI-C, OCI & ORA errors that need to be wrapped
164
174
  // with NJS errors
165
175
  const adjustErrorXref = new Map();
166
- adjustErrorXref.set("DPI-1010", ERR_CONNECTION_CLOSED);
176
+ adjustErrorXref.set("DPI-1010", ERR_INVALID_CONNECTION);
167
177
  adjustErrorXref.set("DPI-1024", [ERR_INVALID_COLL_INDEX_GET, 'at index ([0-9]+) does']);
168
- adjustErrorXref.set("DPI-1040", ERR_LOB_CLOSED);
169
178
  adjustErrorXref.set("DPI-1044", ERR_ORACLE_NUMBER_NO_REPR);
170
179
  adjustErrorXref.set("DPI-1055", ERR_NAN_VALUE);
171
180
  adjustErrorXref.set("DPI-1063", ERR_EXEC_MODE_ONLY_FOR_DML);
@@ -178,13 +187,14 @@ adjustErrorXref.set("ORA-00028", ERR_CONNECTION_CLOSED);
178
187
  adjustErrorXref.set("ORA-00600", ERR_CONNECTION_CLOSED);
179
188
  adjustErrorXref.set("ORA-24338", ERR_INVALID_REF_CURSOR);
180
189
  adjustErrorXref.set("ORA-25708", ERR_TOKEN_HAS_EXPIRED);
190
+ adjustErrorXref.set("ORA-24344", WRN_COMPILATION_CREATE);
181
191
 
182
192
  // define mapping for error messages
183
193
  const messages = new Map();
184
194
  messages.set(ERR_INVALID_POOL, // NJS-002
185
195
  'invalid pool');
186
196
  messages.set(ERR_INVALID_CONNECTION, // NJS-003
187
- 'invalid connection');
197
+ 'invalid or closed connection');
188
198
  messages.set(ERR_INVALID_PROPERTY_VALUE, // NJS-004
189
199
  'invalid value for property "%s"');
190
200
  messages.set(ERR_INVALID_PARAMETER_VALUE, // NJS-005
@@ -335,8 +345,6 @@ messages.set(ERR_INTERNAL, // NJS-106
335
345
  'internal error: %s');
336
346
  messages.set(ERR_INVALID_REF_CURSOR, // NJS-107
337
347
  'invalid cursor');
338
- messages.set(ERR_LOB_CLOSED, // NJS-108
339
- 'LOB was already closed');
340
348
  messages.set(ERR_INVALID_TYPE_NUM, // NJS-109
341
349
  'invalid type number %d');
342
350
  messages.set(ERR_INVALID_ORACLE_TYPE_NUM, // NJS-110
@@ -393,6 +401,22 @@ messages.set(ERR_MISSING_BIND_VALUE, // NJS-137
393
401
  'a bind variable replacement value for placeholder ":%s" was not provided');
394
402
  messages.set(ERR_SERVER_VERSION_NOT_SUPPORTED, // NJS-138
395
403
  'connections to this database server version are not supported by node-oracledb in Thin mode');
404
+ messages.set(ERR_UNEXPECTED_XML_TYPE, // NJS-139
405
+ 'unexpected XML type with flag %d');
406
+ messages.set(ERR_WRONG_USER_FORMAT_EXTAUTH_PROXY, // NJS-140
407
+ 'user name must be enclosed in [] when using external authentication with a proxy user');
408
+ messages.set(ERR_TOO_MANY_BATCH_ERRORS, // NJS-141
409
+ 'the number of batch errors from executemany() exceeds 65535');
410
+ messages.set(ERR_WRONG_LENGTH_FOR_DBOBJECT_ATTR, // NJS-142
411
+ 'value too large for attribute %s of object %s (actual: %d, maximum: %d)');
412
+ messages.set(ERR_WRONG_LENGTH_FOR_DBOBJECT_ELEM, // NJS-143
413
+ 'value too large for element %d of object %s (actual: %d, maximum: %d)');
414
+ messages.set(ERR_VECTOR_FORMAT_NOT_SUPPORTED, // NJS-144
415
+ 'VECTOR format %d is not supported');
416
+ messages.set(ERR_VECTOR_VERSION_NOT_SUPPORTED, // NJS-145
417
+ 'VECTOR version %d is not supported');
418
+ messages.set(ERR_OBJECT_IS_NOT_A_COLLECTION, // NJS-146
419
+ 'object %s is not a collection');
396
420
 
397
421
  // Oracle Net layer errors
398
422
 
@@ -439,6 +463,11 @@ messages.set(ERR_TNS_NAMES_FILE_MISSING, // NJS-520
439
463
  messages.set(ERR_CONNECTION_EOF, // NJS-521
440
464
  'connection to host %s port %d received end-of-file on communication channel. (CONNECTION_ID=%s)');
441
465
 
466
+ // Oracle SUCCESS_WITH_INFO warning
467
+
468
+ messages.set(WRN_COMPILATION_CREATE, // NJS-700
469
+ 'creation succeeded with compilation errors');
470
+
442
471
  //-----------------------------------------------------------------------------
443
472
  // assert()
444
473
  //
@@ -741,7 +770,6 @@ module.exports = {
741
770
  ERR_INVALID_REF_CURSOR,
742
771
  ERR_UNSUPPORTED_VERIFIER_TYPE,
743
772
  ERR_NAN_VALUE,
744
- ERR_LOB_CLOSED,
745
773
  ERR_ORACLE_NUMBER_NO_REPR,
746
774
  ERR_INVALID_SERVICE_NAME,
747
775
  ERR_INVALID_SID,
@@ -772,7 +800,16 @@ module.exports = {
772
800
  ERR_WRONG_CRED_FOR_EXTAUTH,
773
801
  ERR_MISSING_BIND_VALUE,
774
802
  ERR_SERVER_VERSION_NOT_SUPPORTED,
803
+ ERR_UNEXPECTED_XML_TYPE,
804
+ ERR_WRONG_USER_FORMAT_EXTAUTH_PROXY,
805
+ ERR_TOO_MANY_BATCH_ERRORS,
806
+ ERR_WRONG_LENGTH_FOR_DBOBJECT_ATTR,
807
+ ERR_WRONG_LENGTH_FOR_DBOBJECT_ELEM,
808
+ ERR_VECTOR_FORMAT_NOT_SUPPORTED,
809
+ ERR_VECTOR_VERSION_NOT_SUPPORTED,
810
+ ERR_OBJECT_IS_NOT_A_COLLECTION,
775
811
  ERR_CONNECTION_CLOSED_CODE: `${ERR_PREFIX}-${ERR_CONNECTION_CLOSED}`,
812
+ WRN_COMPILATION_CREATE,
776
813
  assert,
777
814
  assertArgCount,
778
815
  assertParamPropBool,
package/lib/future.js ADDED
@@ -0,0 +1,53 @@
1
+ // Copyright (c) 2023, Oracle and/or its affiliates.
2
+
3
+ //-----------------------------------------------------------------------------
4
+ //
5
+ // This software is dual-licensed to you under the Universal Permissive License
6
+ // (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
7
+ // 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
8
+ // either license.
9
+ //
10
+ // If you elect to accept the software under the Apache License, Version 2.0,
11
+ // the following applies:
12
+ //
13
+ // Licensed under the Apache License, Version 2.0 (the "License");
14
+ // you may not use this file except in compliance with the License.
15
+ // You may obtain a copy of the License at
16
+ //
17
+ // https://www.apache.org/licenses/LICENSE-2.0
18
+ //
19
+ // Unless required by applicable law or agreed to in writing, software
20
+ // distributed under the License is distributed on an "AS IS" BASIS,
21
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22
+ // See the License for the specific language governing permissions and
23
+ // limitations under the License.
24
+ //
25
+ //-----------------------------------------------------------------------------
26
+
27
+ 'use strict';
28
+
29
+ const errors = require('./errors.js');
30
+
31
+ // future object used for managing backwards incompatible changes.
32
+ class Future {
33
+
34
+ constructor() {
35
+ this._featureFlags = {};
36
+ this._featureFlags.oldJsonColumnAsObj = false;
37
+ }
38
+
39
+ get oldJsonColumnAsObj() {
40
+ return this._featureFlags.oldJsonColumnAsObj;
41
+ }
42
+
43
+ // fetch VARCHAR2 and LOB columns that contain JSON data (and have
44
+ // the "IS JSON" constraint enabled) in the same way that columns
45
+ // of type JSON (which requires Oracle Database 21 and higher) are fetched.
46
+ set oldJsonColumnAsObj(value) {
47
+ errors.assertPropValue(typeof value === 'boolean', "oldJsonColumnAsObj");
48
+ this._featureFlags.oldJsonColumnAsObj = value;
49
+ }
50
+
51
+ }
52
+
53
+ module.exports = new Future;
@@ -208,6 +208,24 @@ class ConnectionImpl {
208
208
  errors.throwNotImplemented("getting current schema");
209
209
  }
210
210
 
211
+ //---------------------------------------------------------------------------
212
+ // getDbDomain()
213
+ //
214
+ // Returns the Oracle Database domain name associated with the connection.
215
+ //---------------------------------------------------------------------------
216
+ getDbDomain() {
217
+ errors.throwNotImplemented("getting db domain");
218
+ }
219
+
220
+ //---------------------------------------------------------------------------
221
+ // getDbName()
222
+ //
223
+ // Returns the Oracle Database name associated with the connection.
224
+ //---------------------------------------------------------------------------
225
+ getDbName() {
226
+ errors.throwNotImplemented("getting db name");
227
+ }
228
+
211
229
  //---------------------------------------------------------------------------
212
230
  // getDbObjectClass()
213
231
  //
@@ -244,6 +262,15 @@ class ConnectionImpl {
244
262
  errors.throwNotImplemented("getting the internal name");
245
263
  }
246
264
 
265
+ //---------------------------------------------------------------------------
266
+ // getMaxOpenCursors()
267
+ //
268
+ // Returns maximum number of cursors that can be opened in one session.
269
+ //---------------------------------------------------------------------------
270
+ getMaxOpenCursors() {
271
+ errors.throwNotImplemented("getting max open cursors");
272
+ }
273
+
247
274
  //---------------------------------------------------------------------------
248
275
  // getOracleServerVersion()
249
276
  //
@@ -271,6 +298,15 @@ class ConnectionImpl {
271
298
  errors.throwNotImplemented("getting a queue");
272
299
  }
273
300
 
301
+ //---------------------------------------------------------------------------
302
+ // getServiceName()
303
+ //
304
+ // Returns the Oracle Database service name associated with the connection.
305
+ //---------------------------------------------------------------------------
306
+ getServiceName() {
307
+ errors.throwNotImplemented("getting service name");
308
+ }
309
+
274
310
  //---------------------------------------------------------------------------
275
311
  // getSodaDatabase()
276
312
  //
@@ -307,6 +343,26 @@ class ConnectionImpl {
307
343
  errors.throwNotImplemented("getting the tag for the connection");
308
344
  }
309
345
 
346
+ //---------------------------------------------------------------------------
347
+ // getTransactionInProgress()
348
+ //
349
+ // Returns boolean based on the presence of an active transaction on the
350
+ // connection
351
+ //---------------------------------------------------------------------------
352
+ getTransactionInProgress() {
353
+ errors.throwNotImplemented("getting the status of an active transaction" +
354
+ " on the connection");
355
+ }
356
+
357
+ //---------------------------------------------------------------------------
358
+ // getWarning()
359
+ //
360
+ // Returns a warning on a connection
361
+ //---------------------------------------------------------------------------
362
+ getWarning() {
363
+ errors.throwNotImplemented("getting information about warning");
364
+ }
365
+
310
366
  //---------------------------------------------------------------------------
311
367
  // isHealthy()
312
368
  //
@@ -1,4 +1,4 @@
1
- // Copyright (c) 2022, 2023, Oracle and/or its affiliates.
1
+ // Copyright (c) 2022, 2024, Oracle and/or its affiliates.
2
2
 
3
3
  //-----------------------------------------------------------------------------
4
4
  //
@@ -29,8 +29,8 @@
29
29
  const { Buffer } = require('buffer');
30
30
  const constants = require("./constants.js");
31
31
  const errors = require("../../errors.js");
32
- const settings = require("../../settings.js");
33
32
  const types = require("../../types.js");
33
+ const nodbUtil = require("../../util.js");
34
34
 
35
35
  /**
36
36
  * Base buffer class used for managing buffered data without unnecessary
@@ -184,7 +184,7 @@ class BaseBuffer {
184
184
  fseconds = Math.floor(buf.readUInt32BE(7) / (1000 * 1000));
185
185
  }
186
186
  const year = (buf[0] - 100) * 100 + buf[1] - 100;
187
- return settings._makeDate(useLocalTime, year, buf[2], buf[3], buf[4] - 1,
187
+ return nodbUtil.makeDate(useLocalTime, year, buf[2], buf[3], buf[4] - 1,
188
188
  buf[5] - 1, buf[6] - 1, fseconds, 0);
189
189
  }
190
190
 
@@ -321,6 +321,22 @@ class BaseBuffer {
321
321
  return this.parseBinaryFloat(buf);
322
322
  }
323
323
 
324
+ //---------------------------------------------------------------------------
325
+ // readBinaryInteger()
326
+ //
327
+ // Reads a binary integer value from the buffer and returns a Number
328
+ //---------------------------------------------------------------------------
329
+ readBinaryInteger() {
330
+ const buf = this.readBytesWithLength();
331
+ if (!buf) {
332
+ return 0;
333
+ }
334
+ if (buf.length > 4) {
335
+ errors.throwErr(errors.ERR_INTEGER_TOO_LARGE, buf.length, 4, this.pos, this.packetNum);
336
+ }
337
+ return (buf.readIntBE(0, buf.length));
338
+ }
339
+
324
340
  //---------------------------------------------------------------------------
325
341
  // readBool()
326
342
  //
@@ -617,9 +633,10 @@ class BaseBuffer {
617
633
  //
618
634
  // Writes the number in binary double format to the buffer.
619
635
  //---------------------------------------------------------------------------
620
- writeBinaryDouble(n) {
621
- this.writeUInt8(8);
622
- const pos = this.reserveBytes(8);
636
+ writeBinaryDouble(n, pos) {
637
+ if (!pos) {
638
+ pos = this.reserveBytes(8);
639
+ }
623
640
  this.buf.writeDoubleBE(n, pos);
624
641
  if ((this.buf[pos] & 0x80) === 0) {
625
642
  this.buf[pos] |= 0x80;
@@ -641,9 +658,10 @@ class BaseBuffer {
641
658
  //
642
659
  // Writes the number in binary float format to the buffer.
643
660
  //---------------------------------------------------------------------------
644
- writeBinaryFloat(n) {
645
- this.writeUInt8(4);
646
- const pos = this.reserveBytes(4);
661
+ writeBinaryFloat(n, pos) {
662
+ if (!pos) {
663
+ pos = this.reserveBytes(4);
664
+ }
647
665
  this.buf.writeFloatBE(n, pos);
648
666
  if ((this.buf[pos] & 0x80) === 0) {
649
667
  this.buf[pos] |= 0x80;
@@ -677,15 +695,12 @@ class BaseBuffer {
677
695
  }
678
696
  }
679
697
 
680
- //---------------------------------------------------------------------------
681
- // writeBytesWithLength()
698
+ // _writeRawBytesAndLength()
682
699
  //
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.
700
+ // Writes the length in the format required before
701
+ // writing the bytes.
686
702
  //---------------------------------------------------------------------------
687
- writeBytesWithLength(value) {
688
- let numBytes = value.length;
703
+ _writeRawBytesAndLength(value, numBytes) {
689
704
  if (numBytes <= constants.TNS_MAX_SHORT_LENGTH) {
690
705
  this.writeUInt8(numBytes);
691
706
  if (numBytes > 0) {
@@ -704,6 +719,17 @@ class BaseBuffer {
704
719
  this.writeUB4(0);
705
720
  }
706
721
  }
722
+ //---------------------------------------------------------------------------
723
+ // writeBytesWithLength()
724
+ //
725
+ // Writes the bytes in the supplied buffer to the buffer, but first writes
726
+ // the length. If the length exceeds a fixed value, the value is written in
727
+ // chunks instead.
728
+ //---------------------------------------------------------------------------
729
+ writeBytesWithLength(value) {
730
+ const numBytes = value.length;
731
+ this._writeRawBytesAndLength(value, numBytes);
732
+ }
707
733
 
708
734
  //---------------------------------------------------------------------------
709
735
  // writeDbObject()
@@ -861,29 +887,6 @@ class BaseBuffer {
861
887
 
862
888
  }
863
889
 
864
- //---------------------------------------------------------------------------
865
- // writeQLocator()
866
- //
867
- // Writes a QLocator. QLocators are always 40 bytes in length.
868
- //---------------------------------------------------------------------------
869
- writeQLocator(numBytes) {
870
- this.writeUB4(40); // QLocator length
871
- this.writeUInt8(40); // repeated length
872
- this.writeUInt16BE(38); // internal length
873
- this.writeUInt16BE(constants.TNS_LOB_QLOCATOR_VERSION);
874
- this.writeUInt8(constants.TNS_LOB_LOC_FLAGS_VALUE_BASED |
875
- constants.TNS_LOB_LOC_FLAGS_BLOB | constants.TNS_LOB_LOC_FLAGS_ABSTRACT);
876
- this.writeUInt8(constants.TNS_LOB_LOC_FLAGS_INIT);
877
- this.writeUInt16BE(0); // additional flags
878
- this.writeUInt16BE(1); // byt1
879
- this.writeUInt64BE(numBytes);
880
- this.writeUInt16BE(0); // unused
881
- this.writeUInt16BE(0); // csid
882
- this.writeUInt16BE(0); // unused
883
- this.writeUInt64BE(0); // unused
884
- this.writeUInt64BE(0); // unused
885
- }
886
-
887
890
  //---------------------------------------------------------------------------
888
891
  // writeStr()
889
892
  //
@@ -976,6 +979,15 @@ class BaseBuffer {
976
979
  this.buf[pos] = n;
977
980
  }
978
981
 
982
+ // writeSB1()
983
+ //
984
+ // Writes an signed 8-bit integer to the buffer.
985
+ //---------------------------------------------------------------------------
986
+ writeSB1(n) {
987
+ const pos = this.reserveBytes(1);
988
+ this.buf[pos] = n;
989
+ }
990
+
979
991
  //---------------------------------------------------------------------------
980
992
  // writeUInt16BE()
981
993
  //
@@ -0,0 +1,105 @@
1
+ // Copyright (c) 2024, Oracle and/or its affiliates.
2
+
3
+ //-----------------------------------------------------------------------------
4
+ //
5
+ // This software is dual-licensed to you under the Universal Permissive License
6
+ // (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
7
+ // 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
8
+ // either license.
9
+ //
10
+ // If you elect to accept the software under the Apache License, Version 2.0,
11
+ // the following applies:
12
+ //
13
+ // Licensed under the Apache License, Version 2.0 (the "License");
14
+ // you may not use this file except in compliance with the License.
15
+ // You may obtain a copy of the License at
16
+ //
17
+ // https://www.apache.org/licenses/LICENSE-2.0
18
+ //
19
+ // Unless required by applicable law or agreed to in writing, software
20
+ // distributed under the License is distributed on an "AS IS" BASIS,
21
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22
+ // See the License for the specific language governing permissions and
23
+ // limitations under the License.
24
+ //
25
+ //-----------------------------------------------------------------------------
26
+
27
+ 'use strict';
28
+
29
+ const constants = require('../../constants.js');
30
+
31
+ module.exports = {
32
+
33
+ // vector constants
34
+ TNS_VECTOR_MAGIC_BYTE: 0xDB,
35
+ TNS_VECTOR_VERSION: 0,
36
+
37
+ // vector flags
38
+ TNS_VECTOR_FLAG_DIM_UINT8: 0x0001,
39
+ TNS_VECTOR_FLAG_DIM_UINT32: 0x0002,
40
+ TNS_VECTOR_FLAG_NORMSRC: 0x0040,
41
+ TNS_VECTOR_FLAG_NORM: 0x0008,
42
+
43
+ // base JSON constants
44
+ TNS_JSON_MAGIC_BYTE_1: 0xff,
45
+ TNS_JSON_MAGIC_BYTE_2: 0x4a, // 'J'
46
+ TNS_JSON_MAGIC_BYTE_3: 0x5a, // 'Z'
47
+ TNS_JSON_VERSION: 1,
48
+ TNS_JSON_FLAG_HASH_ID_UINT8: 0x0100,
49
+ TNS_JSON_FLAG_HASH_ID_UINT16: 0x0200,
50
+ TNS_JSON_FLAG_NUM_FNAMES_UINT16: 0x0400,
51
+ TNS_JSON_FLAG_FNAMES_SEG_UINT32: 0x0800,
52
+ TNS_JSON_FLAG_TINY_NODES_STAT: 0x2000,
53
+ TNS_JSON_FLAG_TREE_SEG_UINT32: 0x1000,
54
+ TNS_JSON_FLAG_REL_OFFSET_MODE: 0x01,
55
+ TNS_JSON_FLAG_INLINE_LEAF: 0x02,
56
+ TNS_JSON_FLAG_LEN_IN_PCODE: 0x04,
57
+ TNS_JSON_FLAG_NUM_FNAMES_UINT32: 0x08,
58
+ TNS_JSON_FLAG_IS_SCALAR: 0x10,
59
+
60
+ // JSON data types
61
+ TNS_JSON_TYPE_NULL: 0x30,
62
+ TNS_JSON_TYPE_TRUE: 0x31,
63
+ TNS_JSON_TYPE_FALSE: 0x32,
64
+ TNS_JSON_TYPE_STRING_LENGTH_UINT8: 0x33,
65
+ TNS_JSON_TYPE_NUMBER_LENGTH_UINT8: 0x34,
66
+ TNS_JSON_TYPE_BINARY_DOUBLE: 0x36,
67
+ TNS_JSON_TYPE_STRING_LENGTH_UINT16: 0x37,
68
+ TNS_JSON_TYPE_STRING_LENGTH_UINT32: 0x38,
69
+ TNS_JSON_TYPE_TIMESTAMP: 0x39,
70
+ TNS_JSON_TYPE_BINARY_LENGTH_UINT16: 0x3a,
71
+ TNS_JSON_TYPE_BINARY_LENGTH_UINT32: 0x3b,
72
+ TNS_JSON_TYPE_DATE: 0x3c,
73
+ TNS_JSON_TYPE_INTERVAL_YM: 0x3d,
74
+ TNS_JSON_TYPE_INTERVAL_DS: 0x3e,
75
+ TNS_JSON_TYPE_TIMESTAMP_TZ: 0x7c,
76
+ TNS_JSON_TYPE_TIMESTAMP7: 0x7d,
77
+ TNS_JSON_TYPE_BINARY_FLOAT: 0x7f,
78
+ TNS_JSON_TYPE_OBJECT: 0x84,
79
+ TNS_JSON_TYPE_ARRAY: 0xc0,
80
+ TNS_JSON_TYPE_EXTENDED: 0x7b,
81
+ TNS_JSON_TYPE_VECTOR: 0x01,
82
+
83
+ // timezone offsets
84
+ TZ_HOUR_OFFSET: 20,
85
+ TZ_MINUTE_OFFSET: 60,
86
+
87
+ // general constants
88
+ TNS_MAX_SHORT_LENGTH: 252,
89
+ TNS_DURATION_MID: 0x80000000,
90
+ TNS_DURATION_OFFSET: 60,
91
+ TNS_CHUNK_SIZE: 32767,
92
+ TNS_HAS_REGION_ID: 0x80,
93
+ NUMBER_MAX_DIGITS: 40,
94
+ BUFFER_CHUNK_SIZE: 65536,
95
+ CSFRM_IMPLICIT: constants.CSFRM_IMPLICIT,
96
+
97
+ // vector generic constants
98
+ VECTOR_FORMAT_FLOAT32: constants.VECTOR_FORMAT_FLOAT32,
99
+ VECTOR_FORMAT_FLOAT64: constants.VECTOR_FORMAT_FLOAT64,
100
+ VECTOR_FORMAT_INT8: constants.VECTOR_FORMAT_INT8,
101
+
102
+ TNS_NULL_LENGTH_INDICATOR: 255,
103
+ TNS_LONG_LENGTH_INDICATOR: 254,
104
+
105
+ };
@@ -32,6 +32,8 @@ const constants = require("./constants.js");
32
32
  const errors = require("../../errors.js");
33
33
  const types = require("../../types.js");
34
34
  const util = require("util");
35
+ const vector = require("./vector.js");
36
+ const nodbUtil = require("../../util.js");
35
37
 
36
38
  /**
37
39
  * Class used for decodeing
@@ -106,7 +108,7 @@ class OsonDecoder extends BaseBuffer {
106
108
  _decodeNode() {
107
109
 
108
110
  // if the most significant bit is set the node refers to a container
109
- const nodeType = this.readUInt8();
111
+ let nodeType = this.readUInt8();
110
112
  if (nodeType & 0x80) {
111
113
  return this._decodeContainerNode(nodeType);
112
114
  }
@@ -145,6 +147,13 @@ class OsonDecoder extends BaseBuffer {
145
147
  return Buffer.from(this.readBytes(this.readUInt16BE()));
146
148
  } else if (nodeType === constants.TNS_JSON_TYPE_BINARY_LENGTH_UINT32) {
147
149
  return Buffer.from(this.readBytes(this.readUInt32BE()));
150
+ } else if (nodeType === constants.TNS_JSON_TYPE_EXTENDED) {
151
+ nodeType = this.readUInt8();
152
+ if (nodeType === constants.TNS_JSON_TYPE_VECTOR) {
153
+ const vecImage = this.readBytes(this.readUInt32BE());
154
+ const decoder = new vector.VectorDecoder(vecImage);
155
+ return decoder.decode();
156
+ }
148
157
  }
149
158
 
150
159
  // handle number/decimal with length stored inside the node itself
@@ -544,6 +553,15 @@ class OsonTreeSegment extends GrowableBuffer {
544
553
  } else if (Array.isArray(value)) {
545
554
  this._encodeArray(value, fnamesSeg);
546
555
 
556
+ // handle vectors
557
+ } else if (nodbUtil.isVectorValue(value)) {
558
+ this.writeUInt8(constants.TNS_JSON_TYPE_EXTENDED);
559
+ this.writeUInt8(constants.TNS_JSON_TYPE_VECTOR);
560
+ const encoder = new vector.VectorEncoder();
561
+ const buf = encoder.encode(value);
562
+ this.writeUInt32BE(buf.length);
563
+ this.writeBytes(buf);
564
+
547
565
  // handle objects
548
566
  } else {
549
567
  this._encodeObject(value, fnamesSeg);