oracledb 7.0.0 → 26.0.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 (84) hide show
  1. package/README.md +16 -6
  2. package/build/Release/oracledb-26.0.0-darwin-arm64.node +0 -0
  3. package/build/Release/oracledb-26.0.0-darwin-arm64.node-buildinfo.txt +1 -0
  4. package/build/Release/oracledb-26.0.0-js-buildinfo.txt +1 -0
  5. package/build/Release/oracledb-26.0.0-linux-arm64.node +0 -0
  6. package/build/Release/oracledb-26.0.0-linux-arm64.node-buildinfo.txt +1 -0
  7. package/build/Release/oracledb-26.0.0-linux-x64.node +0 -0
  8. package/build/Release/oracledb-26.0.0-linux-x64.node-buildinfo.txt +1 -0
  9. package/build/Release/oracledb-26.0.0-win32-x64.node +0 -0
  10. package/build/Release/oracledb-26.0.0-win32-x64.node-buildinfo.txt +1 -0
  11. package/lib/aqDeqOptions.js +4 -4
  12. package/lib/aqEnqOptions.js +2 -2
  13. package/lib/aqQueue.js +11 -6
  14. package/lib/connection.js +73 -18
  15. package/lib/constants.js +4 -0
  16. package/lib/endUserSecurityContext.js +30 -25
  17. package/lib/errors.js +92 -5
  18. package/lib/impl/connection.js +36 -0
  19. package/lib/impl/datahandlers/buffer.js +91 -18
  20. package/lib/impl/datahandlers/oson.js +3 -2
  21. package/lib/impl/parserHelpers.js +6 -2
  22. package/lib/impl/resultset.js +32 -11
  23. package/lib/oracledb.js +34 -0
  24. package/lib/pool.js +6 -2
  25. package/lib/queryStream.js +13 -5
  26. package/lib/resultset.js +10 -3
  27. package/lib/securityContextProvider.js +206 -0
  28. package/lib/thin/aq.js +2 -3
  29. package/lib/thin/connection.js +380 -24
  30. package/lib/thin/dbObject.js +20 -11
  31. package/lib/thin/pool.js +4 -3
  32. package/lib/thin/protocol/capabilities.js +37 -4
  33. package/lib/thin/protocol/constants.js +49 -1
  34. package/lib/thin/protocol/messages/aqArray.js +2 -2
  35. package/lib/thin/protocol/messages/aqBase.js +2 -2
  36. package/lib/thin/protocol/messages/auth.js +17 -6
  37. package/lib/thin/protocol/messages/base.js +75 -17
  38. package/lib/thin/protocol/messages/dataType.js +46 -0
  39. package/lib/thin/protocol/messages/directPathLoadStream.js +3 -2
  40. package/lib/thin/protocol/messages/execute.js +10 -4
  41. package/lib/thin/protocol/messages/index.js +4 -0
  42. package/lib/thin/protocol/messages/notification.js +281 -0
  43. package/lib/thin/protocol/messages/subscribe.js +181 -0
  44. package/lib/thin/protocol/messages/withData.js +23 -10
  45. package/lib/thin/protocol/packet.js +2 -4
  46. package/lib/thin/protocol/protocol.js +7 -4
  47. package/lib/thin/resultSet.js +40 -20
  48. package/lib/thin/sqlnet/ezConnectResolver.js +9 -2
  49. package/lib/thin/sqlnet/navNodes.js +7 -5
  50. package/lib/thin/sqlnet/networkSession.js +17 -11
  51. package/lib/thin/sqlnet/ntTcp.js +24 -8
  52. package/lib/thin/sqlnet/packet.js +24 -4
  53. package/lib/thin/sqlnet/sessionAtts.js +2 -2
  54. package/lib/thin/statement.js +6 -1
  55. package/lib/thin/statementCache.js +34 -6
  56. package/lib/thin/subscr.js +363 -0
  57. package/lib/transformer.js +60 -17
  58. package/lib/util.js +46 -8
  59. package/lib/version.js +1 -1
  60. package/package.json +1 -1
  61. package/plugins/configProviders/gcpstorage/index.js +121 -0
  62. package/plugins/configProviders/ociobject/index.js +1 -1
  63. package/plugins/token/cache.js +154 -0
  64. package/plugins/token/endUserSecurityProvider/index.js +377 -0
  65. package/plugins/token/extensionAzure/index.js +160 -28
  66. package/plugins/token/extensionOci/index.js +221 -16
  67. package/plugins/vectorsdk/OracleVecDB.js +346 -0
  68. package/plugins/vectorsdk/index.js +49 -0
  69. package/plugins/vectorsdk/utils.js +370 -0
  70. package/plugins/vectorsdk/vectorEmbedding.js +223 -0
  71. package/plugins/vectorsdk/vectorIndex.js +177 -0
  72. package/plugins/vectorsdk/vectorRecords.js +406 -0
  73. package/plugins/vectorsdk/vectorSchema.js +408 -0
  74. package/plugins/vectorsdk/vectorSearch.js +538 -0
  75. package/build/Release/oracledb-7.0.0-darwin-arm64.node +0 -0
  76. package/build/Release/oracledb-7.0.0-darwin-arm64.node-buildinfo.txt +0 -1
  77. package/build/Release/oracledb-7.0.0-js-buildinfo.txt +0 -1
  78. package/build/Release/oracledb-7.0.0-linux-arm64.node +0 -0
  79. package/build/Release/oracledb-7.0.0-linux-arm64.node-buildinfo.txt +0 -1
  80. package/build/Release/oracledb-7.0.0-linux-x64.node +0 -0
  81. package/build/Release/oracledb-7.0.0-linux-x64.node-buildinfo.txt +0 -1
  82. package/build/Release/oracledb-7.0.0-win32-x64.node +0 -0
  83. package/build/Release/oracledb-7.0.0-win32-x64.node-buildinfo.txt +0 -1
  84. package/eslint.config.js +0 -39
@@ -0,0 +1,408 @@
1
+ // Copyright (c) 2026, 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 {
30
+ isSimpleSqlName,
31
+ enquoteName
32
+ } = require('oracledb');
33
+
34
+ const {
35
+ assertNonEmptyString,
36
+ assertPlainObject,
37
+ assertOptionalBoolean,
38
+ assertBoolean
39
+ } = require('./utils');
40
+
41
+ //-----------------------------------------------------------------------------
42
+ // Constants and defaults
43
+ //-----------------------------------------------------------------------------
44
+ const VECTOR_STORAGE_FORMATS = new Set([
45
+ '*',
46
+ 'BINARY',
47
+ 'FLOAT32',
48
+ 'FLOAT64',
49
+ 'INT8'
50
+ ]);
51
+
52
+ const VECTOR_STORAGE_TYPES = new Set([
53
+ 'DENSE',
54
+ 'SPARSE'
55
+ ]);
56
+
57
+ const DEFAULT_COLUMNS = {
58
+ rowid: 'id',
59
+ id: 'external_id',
60
+ content: 'text',
61
+ metadata: 'metadata'
62
+ };
63
+
64
+ //-----------------------------------------------------------------------------
65
+ // Identifier normalization and rendering
66
+ //-----------------------------------------------------------------------------
67
+ function normalizeIdentifier(
68
+ value,
69
+ label,
70
+ quoteIdentifiers = false
71
+ ) {
72
+ if (typeof value !== 'string') {
73
+ throw new TypeError(`${label} must be a string`);
74
+ }
75
+
76
+ if (value.includes('"')) {
77
+ throw new TypeError(`${label} must not include double quotes`);
78
+ }
79
+
80
+ if (quoteIdentifiers) {
81
+ if (value.length === 0) {
82
+ throw new TypeError(`${label} must not be empty`);
83
+ }
84
+
85
+ if (value.includes('\0')) {
86
+ throw new TypeError(`${label} must not include the null character`);
87
+ }
88
+
89
+ return value;
90
+ }
91
+
92
+ const normalized = value.trim();
93
+
94
+ if (normalized.length === 0) {
95
+ throw new TypeError(`${label} must not be empty`);
96
+ }
97
+
98
+ if (!isSimpleSqlName(normalized)) {
99
+ throw new TypeError(`${label} contains invalid characters`);
100
+ }
101
+
102
+ return normalized;
103
+ }
104
+
105
+ function normalizeTableName(value, label, quoteIdentifiers = false) {
106
+ if (typeof value === 'string') {
107
+ return normalizeIdentifier(value, label, quoteIdentifiers);
108
+ }
109
+
110
+ assertPlainObject(value, label);
111
+ return {
112
+ schema: normalizeIdentifier(
113
+ value.schema,
114
+ `${label}.schema`,
115
+ quoteIdentifiers
116
+ ),
117
+ name: normalizeIdentifier(
118
+ value.name,
119
+ `${label}.name`,
120
+ quoteIdentifiers
121
+ )
122
+ };
123
+ }
124
+
125
+ function renderIdentifier(value, label, quoteIdentifiers = false) {
126
+ const name = normalizeIdentifier(
127
+ value,
128
+ label,
129
+ quoteIdentifiers
130
+ );
131
+
132
+ return quoteIdentifiers ? enquoteName(name, false) : name;
133
+ }
134
+
135
+ function renderQualifiedName(tableName, label, quoteIdentifiers = false) {
136
+ if (typeof tableName === 'string') {
137
+ return renderIdentifier(tableName, label, quoteIdentifiers);
138
+ }
139
+
140
+ assertPlainObject(tableName, label);
141
+ const schema = renderIdentifier(
142
+ tableName.schema,
143
+ `${label}.schema`,
144
+ quoteIdentifiers
145
+ );
146
+
147
+ const name = renderIdentifier(
148
+ tableName.name,
149
+ `${label}.name`,
150
+ quoteIdentifiers
151
+ );
152
+
153
+ return `${schema}.${name}`;
154
+ }
155
+
156
+ function escapeSingleQuotes(value) {
157
+ return value.replace(/'/g, "''");
158
+ }
159
+
160
+ //-----------------------------------------------------------------------------
161
+ // Definition normalization
162
+ //-----------------------------------------------------------------------------
163
+ function normalizeVectorStorageFormat(storageFormat, dimensions) {
164
+ if (storageFormat == null) {
165
+ return 'FLOAT32';
166
+ }
167
+ const value = String(storageFormat).trim().toUpperCase();
168
+ if (!VECTOR_STORAGE_FORMATS.has(value)) {
169
+ throw new TypeError(
170
+ `Vector storage format must be one of: ${[...VECTOR_STORAGE_FORMATS].join(', ')}`
171
+ );
172
+ }
173
+ if (value === 'BINARY' && dimensions % 8 !== 0) {
174
+ throw new TypeError(
175
+ 'BINARY vector format requires dimensions to be a multiple of 8'
176
+ );
177
+ }
178
+ return value;
179
+ }
180
+
181
+ function normalizeVectorStorageType(storageType) {
182
+ if (storageType == null) {
183
+ return 'DENSE';
184
+ }
185
+ const value = String(storageType).trim().toUpperCase();
186
+ if (!VECTOR_STORAGE_TYPES.has(value)) {
187
+ throw new TypeError(
188
+ `Vector storage type must be one of: ${[...VECTOR_STORAGE_TYPES].join(', ')}`
189
+ );
190
+ }
191
+ return value;
192
+ }
193
+
194
+ function normalizeVectorDef(vector) {
195
+ if (vector === null || typeof vector !== 'object' || Array.isArray(vector)) {
196
+ throw new TypeError('vector must be an object.');
197
+ }
198
+
199
+ const { dimensions } = vector;
200
+ if (!Number.isInteger(dimensions) || dimensions <= 0) {
201
+ throw new TypeError(
202
+ 'vector.dimensions must be a positive integer.'
203
+ );
204
+ }
205
+
206
+ const storageFormat = normalizeVectorStorageFormat(
207
+ vector.storageFormat,
208
+ dimensions
209
+ );
210
+ const storageType = normalizeVectorStorageType(vector.storageType);
211
+
212
+ // node-oracledb does not currently support BINARY values with SPARSE storage.
213
+ if (storageType === 'SPARSE' && storageFormat === 'BINARY') {
214
+ throw new TypeError(
215
+ 'BINARY format is not supported for SPARSE vectors.'
216
+ );
217
+ }
218
+
219
+ return { dimensions, storageFormat, storageType };
220
+ }
221
+
222
+ function normalizeColumn(column, defaultName, label, quoteIdentifiers) {
223
+ if (column == null || typeof column === 'string') {
224
+ return {
225
+ name: normalizeIdentifier(
226
+ column ?? defaultName,
227
+ label,
228
+ quoteIdentifiers
229
+ ),
230
+ annotation: null
231
+ };
232
+ }
233
+
234
+ assertPlainObject(column, label);
235
+ const name = normalizeIdentifier(column.name ?? defaultName, `${label}.name`, quoteIdentifiers);
236
+ let annotation = null;
237
+ if (column.annotation != null) {
238
+ assertNonEmptyString(column.annotation, `${label}.annotation`);
239
+ annotation = column.annotation.trim();
240
+ }
241
+ return {name, annotation};
242
+ }
243
+
244
+ // Validate table options and normalize the configured column identifiers.
245
+ function normalizeTableDef(options) {
246
+ assertPlainObject(options, 'options');
247
+ assertOptionalBoolean(options.quoteIdentifiers, 'options.quoteIdentifiers');
248
+
249
+ const quoteIdentifiers = options.quoteIdentifiers ?? false;
250
+ const tableName = normalizeTableName(
251
+ options.tableName,
252
+ 'tableName',
253
+ quoteIdentifiers
254
+ );
255
+ const rawColumns = options.columns ?? {};
256
+ assertPlainObject(rawColumns, 'options.columns');
257
+
258
+ const rawVector = options.vector;
259
+ const vectorDefinition = normalizeVectorDef(rawVector);
260
+ const vector = {...vectorDefinition};
261
+ const columns = {};
262
+ const annotations = {};
263
+ // The name "distance" is reserved for vector search results.
264
+ const usedNames = new Set(['DISTANCE', 'distance']);
265
+ const columnConfigs = [
266
+ ['rowid', rawColumns.rowid, DEFAULT_COLUMNS.rowid, 'columns.rowid'],
267
+ ['id', rawColumns.id, DEFAULT_COLUMNS.id, 'columns.id'],
268
+ ['content', rawColumns.content, DEFAULT_COLUMNS.content, 'columns.content'],
269
+ ['metadata', rawColumns.metadata, DEFAULT_COLUMNS.metadata, 'columns.metadata'],
270
+ ['vector', rawVector.column, 'embedding', 'vector.column']
271
+ ];
272
+
273
+ for (const [key, rawColumn, defaultName, label] of columnConfigs) {
274
+ const column = normalizeColumn(rawColumn, defaultName, label, quoteIdentifiers);
275
+ const lookupName = quoteIdentifiers ? column.name : column.name.toUpperCase();
276
+ if (usedNames.has(lookupName)) {
277
+ throw new TypeError(`${label} duplicates another generated column name.`);
278
+ }
279
+ usedNames.add(lookupName);
280
+ if (key === 'vector') {
281
+ vector.column = column.name;
282
+ } else {
283
+ columns[key] = column.name;
284
+ }
285
+ if (column.annotation != null) {
286
+ annotations[column.name] = column.annotation;
287
+ }
288
+ }
289
+
290
+ if (options.description != null) {
291
+ assertNonEmptyString(options.description, 'options.description');
292
+ }
293
+ const description = options.description?.trim() ?? null;
294
+ return {
295
+ tableName,
296
+ columns,
297
+ vector,
298
+ description,
299
+ annotations,
300
+ quoteIdentifiers
301
+ };
302
+ }
303
+
304
+ //-----------------------------------------------------------------------------
305
+ // SQL generation
306
+ //-----------------------------------------------------------------------------
307
+ function buildVectorType(vector) {
308
+ const sparse = vector.storageType === 'SPARSE' ? ', SPARSE' : '';
309
+ return `VECTOR(${vector.dimensions}, ${vector.storageFormat}${sparse})`;
310
+ }
311
+
312
+ function buildColumnDefinitions(definition) {
313
+ const { columns, quoteIdentifiers, vector } = definition;
314
+ return [
315
+ [columns.rowid, 'RAW(16) DEFAULT SYS_GUID() PRIMARY KEY'],
316
+ [columns.id, 'VARCHAR2(255) UNIQUE'],
317
+ [vector.column, buildVectorType(vector)],
318
+ [columns.content, 'CLOB'],
319
+ [columns.metadata, 'JSON']
320
+ ].map(([name, type]) =>
321
+ `${renderIdentifier(name, 'columnName', quoteIdentifiers)} ${type}`);
322
+ }
323
+
324
+ function buildCommentStatements(definition, sqlTableName) {
325
+ const { annotations, description, quoteIdentifiers } = definition;
326
+ const statements = [];
327
+
328
+ if (description != null) {
329
+ statements.push(
330
+ `COMMENT ON TABLE ${sqlTableName} IS ` +
331
+ `'${escapeSingleQuotes(description)}'`
332
+ );
333
+ }
334
+
335
+ for (const [columnName, comment] of Object.entries(annotations ?? {})) {
336
+ const sqlColumnName = renderIdentifier(
337
+ columnName,
338
+ 'annotation column',
339
+ quoteIdentifiers
340
+ );
341
+ statements.push(
342
+ `COMMENT ON COLUMN ${sqlTableName}.${sqlColumnName} IS ` +
343
+ `'${escapeSingleQuotes(comment)}'`
344
+ );
345
+ }
346
+
347
+ return statements;
348
+ }
349
+
350
+ //-----------------------------------------------------------------------------
351
+ // dropTable()
352
+
353
+ // Drop vector table.
354
+ //-----------------------------------------------------------------------------
355
+ async function dropTable(
356
+ connection,
357
+ definition,
358
+ purge = false
359
+ ) {
360
+ assertBoolean(purge, 'purge');
361
+ const sqlTableName = renderQualifiedName(
362
+ definition.tableName,
363
+ 'tableName',
364
+ definition.quoteIdentifiers
365
+ );
366
+
367
+ const ddl = `DROP TABLE IF EXISTS ${sqlTableName}${purge ? ' PURGE' : ''}`;
368
+ await connection.execute(ddl);
369
+ }
370
+
371
+ //-----------------------------------------------------------------------------
372
+ // createVectorTable()
373
+
374
+ // Create the vector-ready table if it does not exist.
375
+ //-----------------------------------------------------------------------------
376
+ async function createVectorTable(connection, definition) {
377
+ const sqlTableName = renderQualifiedName(
378
+ definition.tableName,
379
+ 'tableName',
380
+ definition.quoteIdentifiers
381
+ );
382
+
383
+ const columnDefinitions = buildColumnDefinitions(definition);
384
+ const sqlStatement =
385
+ `CREATE TABLE IF NOT EXISTS ${sqlTableName} (${columnDefinitions.join(', ')})`;
386
+ const statements = [
387
+ sqlStatement,
388
+ ...buildCommentStatements(definition, sqlTableName)
389
+ ].map((statement) =>
390
+ `EXECUTE IMMEDIATE '${escapeSingleQuotes(statement)}';`);
391
+
392
+ await connection.execute(`
393
+ BEGIN
394
+ ${statements.join('\n ')}
395
+ END;
396
+ `);
397
+
398
+ return sqlTableName;
399
+ }
400
+
401
+ module.exports = {
402
+ createVectorTable,
403
+ dropTable,
404
+ normalizeIdentifier,
405
+ normalizeTableDef,
406
+ renderIdentifier,
407
+ renderQualifiedName
408
+ };