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,370 @@
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 oracledb = require('oracledb');
30
+
31
+ //-----------------------------------------------------------------------------
32
+ // Constants
33
+ //-----------------------------------------------------------------------------
34
+ const DISTANCE_METRICS = new Set([
35
+ 'COSINE',
36
+ 'EUCLIDEAN',
37
+ 'MANHATTAN',
38
+ 'HAMMING',
39
+ 'JACCARD',
40
+ 'DOT',
41
+ 'L2_SQUARED',
42
+ 'EUCLIDEAN_SQUARED'
43
+ ]);
44
+
45
+ //-----------------------------------------------------------------------------
46
+ // Distance metric
47
+ //-----------------------------------------------------------------------------
48
+ function normalizeVectorDistanceType(vectorDistanceType) {
49
+ if (vectorDistanceType == null) {
50
+ return null;
51
+ }
52
+ const metric = String(vectorDistanceType).trim().toUpperCase();
53
+ if (!DISTANCE_METRICS.has(metric)) {
54
+ throw new TypeError(
55
+ `Distance Metric must be one of: ${[...DISTANCE_METRICS].join(', ')}`
56
+ );
57
+ }
58
+ return metric;
59
+ }
60
+
61
+ //-----------------------------------------------------------------------------
62
+ // Assertions
63
+ //-----------------------------------------------------------------------------
64
+ function isPlainObject(value) {
65
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) {
66
+ return false;
67
+ }
68
+
69
+ // Accepts only ordinary objects, reject class instances and built-in objects
70
+ // such as Date, Map, and Set
71
+ const prototype = Object.getPrototypeOf(value);
72
+ return prototype === Object.prototype || prototype === null;
73
+ }
74
+
75
+ function assertCondition(condition, message) {
76
+ if (!condition) {
77
+ throw new TypeError(message);
78
+ }
79
+ }
80
+
81
+ function assertPlainObject(value, name) {
82
+ assertCondition(
83
+ isPlainObject(value),
84
+ `${name} must be an object.`
85
+ );
86
+ }
87
+
88
+ function assertOptionalPlainObject(value, name) {
89
+ if (value != null) {
90
+ assertPlainObject(value, name);
91
+ }
92
+ }
93
+
94
+ function assertBoolean(value, name) {
95
+ assertCondition(
96
+ typeof value === 'boolean',
97
+ `${name} must be a boolean.`
98
+ );
99
+ }
100
+
101
+ function assertOptionalBoolean(value, name) {
102
+ if (value !== undefined) {
103
+ assertBoolean(value, name);
104
+ }
105
+ }
106
+
107
+ function assertNonEmptyString(value, name) {
108
+ assertCondition(
109
+ typeof value === 'string' && value.trim() !== '',
110
+ `${name} must be a non-empty string.`
111
+ );
112
+ }
113
+
114
+ function assertPositiveInteger(value, name) {
115
+ assertCondition(
116
+ Number.isInteger(value) && value > 0,
117
+ `${name} must be a positive integer.`
118
+ );
119
+ }
120
+
121
+ function assertIntegerInRange(value, name, min, max) {
122
+ assertCondition(
123
+ Number.isInteger(value) && value >= min && value <= max,
124
+ `${name} must be an integer between ${min} and ${max}.`
125
+ );
126
+ }
127
+
128
+ function assertArray(value, name) {
129
+ assertCondition(
130
+ Array.isArray(value),
131
+ `${name} must be an array.`
132
+ );
133
+ }
134
+
135
+ function assertNonEmptyArray(value, name) {
136
+ assertCondition(
137
+ Array.isArray(value) && value.length > 0,
138
+ `${name} must be a non-empty array.`
139
+ );
140
+ }
141
+
142
+ function assertOptionalArray(value, name) {
143
+ if (value != null) {
144
+ assertArray(value, name);
145
+ }
146
+ }
147
+
148
+ //-----------------------------------------------------------------------------
149
+ // Database helpers
150
+ //-----------------------------------------------------------------------------
151
+ async function readLobAsString(value) {
152
+ // CLOB output may already be materialized or may expose the Lob getData API.
153
+ if (value == null || typeof value === 'string') return value;
154
+ if (typeof value.getData !== 'function') {
155
+ throw new Error(
156
+ 'Expected a CLOB LOB or string value from Oracle Database.'
157
+ );
158
+ }
159
+ try {
160
+ return await value.getData();
161
+ } finally {
162
+ value.destroy();
163
+ }
164
+ }
165
+
166
+ function assertDatabaseVersion(connection, label) {
167
+ // oracleServerVersion encodes 23.26.2.0.0 as 2326020000.
168
+ if (connection.oracleServerVersion < 2326020000) {
169
+ throw new Error(
170
+ `${label} requires Oracle Database 23.26.2.0.0 or later.`
171
+ );
172
+ }
173
+ }
174
+
175
+ //-----------------------------------------------------------------------------
176
+ // Vector preparation
177
+ //-----------------------------------------------------------------------------
178
+ function isVectorValue(value) {
179
+ return (value instanceof Float32Array ||
180
+ value instanceof Float64Array ||
181
+ value instanceof Int8Array || (Object.getPrototypeOf(value)
182
+ === Uint8Array.prototype) || value instanceof oracledb.SparseVector);
183
+ }
184
+
185
+ function assertDimensions(vector, definition) {
186
+ const dimensions = vector instanceof oracledb.SparseVector
187
+ ? vector.numDimensions
188
+ : vector.length;
189
+
190
+ if (dimensions !== definition.dimensions) {
191
+ throw new TypeError(
192
+ `Vector dimensions must be ${definition.dimensions}; ` +
193
+ `received ${dimensions}`
194
+ );
195
+ }
196
+ }
197
+
198
+ function convertInt8(values) {
199
+ const converted = new Int8Array(values.length);
200
+
201
+ for (let index = 0; index < values.length; index++) {
202
+ const value = values[index];
203
+ if (!Number.isFinite(value)) {
204
+ throw new TypeError(
205
+ `Vector value at index ${index} must be finite.`
206
+ );
207
+ }
208
+
209
+ const rounded = Math.round(value);
210
+ if (rounded < -128 || rounded > 127) {
211
+ throw new TypeError(
212
+ `INT8 vector value at index ${index} must be within [-128, 127].`
213
+ );
214
+ }
215
+ converted[index] = rounded;
216
+ }
217
+
218
+ return converted;
219
+ }
220
+
221
+ function packBinaryVector(values, dimensions) {
222
+ if (values.length !== dimensions) {
223
+ throw new TypeError(
224
+ `Vector dimensions must be ${dimensions}; received ${values.length}`
225
+ );
226
+ }
227
+
228
+ const packed = new Uint8Array(dimensions / 8);
229
+
230
+ for (let index = 0; index < dimensions; index++) {
231
+ const value = values[index];
232
+
233
+ if (!Number.isFinite(value)) {
234
+ throw new TypeError(
235
+ `Vector value at index ${index} must be finite.`
236
+ );
237
+ }
238
+
239
+ // Pack positive dimensions as one, from the most significant bit to the
240
+ // least significant bit within each byte.
241
+ if (value > 0) {
242
+ packed[index >> 3] |= 1 << (7 - (index & 7));
243
+ }
244
+ }
245
+
246
+ return packed;
247
+ }
248
+
249
+ function convertValuesForFormat(values, format) {
250
+ switch (format) {
251
+ case 'FLOAT32':
252
+ return values instanceof Float32Array
253
+ ? values
254
+ : new Float32Array(values);
255
+ // We use a consistent default for wildcard (*) formats. Otherwise, similarity
256
+ // search fails when the stored and query vector formats do not match.
257
+ case '*':
258
+ case 'FLOAT64':
259
+ return values instanceof Float64Array
260
+ ? values
261
+ : new Float64Array(values);
262
+ case 'INT8':
263
+ return values instanceof Int8Array
264
+ ? values
265
+ : convertInt8(values);
266
+ default:
267
+ throw new TypeError(
268
+ `Unsupported vector format: ${format}.`
269
+ );
270
+ }
271
+ }
272
+
273
+ function convertDenseVector(values, definition) {
274
+ if (definition.storageFormat === 'BINARY') {
275
+ if (values instanceof Uint8Array) {
276
+ if (values.length !== definition.dimensions / 8) {
277
+ throw new TypeError(
278
+ `BINARY vector must contain ${definition.dimensions / 8} bytes.`
279
+ );
280
+ }
281
+ return values;
282
+ }
283
+ return packBinaryVector(values, definition.dimensions);
284
+ }
285
+
286
+ assertDimensions(values, definition);
287
+ return convertValuesForFormat(values, definition.storageFormat);
288
+ }
289
+
290
+ function convertDenseToSparseVector(vector, format) {
291
+ // Convert before identifying nonzero values. This matters for INT8 because
292
+ // values may become zero after rounding.
293
+ const converted = convertValuesForFormat(vector, format);
294
+
295
+ const indices = [];
296
+ const values = [];
297
+
298
+ for (let i = 0; i < converted.length; i++) {
299
+ if (converted[i] !== 0) {
300
+ indices.push(i);
301
+ values.push(converted[i]);
302
+ }
303
+ }
304
+
305
+ return new oracledb.SparseVector({
306
+ numDimensions: vector.length,
307
+ indices: new Uint32Array(indices),
308
+ values: new converted.constructor(values),
309
+ });
310
+ }
311
+
312
+ function prepareVector(vector, vectorDefinition) {
313
+
314
+ if (vector == null) {
315
+ throw new TypeError('Vector must not be null or undefined.');
316
+ }
317
+
318
+ if (!Array.isArray(vector) && !isVectorValue(vector)) {
319
+ throw new TypeError('Unsupported vector representation.');
320
+ }
321
+
322
+ const definition = vectorDefinition;
323
+
324
+ if (definition.storageType === 'SPARSE') {
325
+ if (vector instanceof oracledb.SparseVector) {
326
+ assertDimensions(vector, definition);
327
+ return new oracledb.SparseVector({
328
+ numDimensions: vector.numDimensions,
329
+ indices: vector.indices,
330
+ values: convertValuesForFormat(
331
+ vector.values,
332
+ definition.storageFormat
333
+ )
334
+ });
335
+ }
336
+
337
+ assertDimensions(vector, definition);
338
+ // Convert a dense input when the configured column uses sparse storage.
339
+ return convertDenseToSparseVector(vector, definition.storageFormat);
340
+ }
341
+
342
+ if (vector instanceof oracledb.SparseVector) {
343
+ throw new TypeError(
344
+ 'A SparseVector cannot be used with DENSE storage.'
345
+ );
346
+ }
347
+
348
+ return convertDenseVector(vector, definition);
349
+ }
350
+
351
+ //-----------------------------------------------------------------------------
352
+ // Exports
353
+ //-----------------------------------------------------------------------------
354
+
355
+ module.exports = {
356
+ normalizeVectorDistanceType,
357
+ prepareVector,
358
+ assertDatabaseVersion,
359
+ readLobAsString,
360
+ assertBoolean,
361
+ assertIntegerInRange,
362
+ assertNonEmptyArray,
363
+ assertNonEmptyString,
364
+ assertOptionalArray,
365
+ assertOptionalBoolean,
366
+ assertOptionalPlainObject,
367
+ assertPlainObject,
368
+ assertPositiveInteger,
369
+ isPlainObject
370
+ };
@@ -0,0 +1,223 @@
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 oracledb = require('oracledb');
30
+ const { normalizeIdentifier } = require('./vectorSchema.js');
31
+ const {
32
+ assertBoolean,
33
+ assertNonEmptyString,
34
+ assertOptionalPlainObject,
35
+ assertPlainObject,
36
+ readLobAsString,
37
+ assertDatabaseVersion,
38
+ assertNonEmptyArray
39
+ } = require('./utils.js');
40
+
41
+ //-----------------------------------------------------------------------------
42
+ // generateEmbeddings()
43
+
44
+ // Generate a vector embedding for input text using a preloaded model.
45
+ //-----------------------------------------------------------------------------
46
+ async function generateEmbeddings(connection, modelParams, texts) {
47
+ assertNonEmptyArray(texts, 'texts');
48
+ assertPlainObject(modelParams, 'modelParams');
49
+
50
+ const embeddingSql = `
51
+ DECLARE
52
+ generated_embedding VECTOR;
53
+ BEGIN
54
+ generated_embedding := DBMS_VECTOR.UTL_TO_EMBEDDING(
55
+ :query_text,
56
+ :model_params
57
+ );
58
+ :embedding := generated_embedding;
59
+ END;
60
+ `;
61
+
62
+ const result = await connection.executeMany(
63
+ embeddingSql,
64
+ texts.map((text, index) => {
65
+ assertNonEmptyString(text, `texts[${index}]`);
66
+ return {
67
+ query_text: text,
68
+ model_params: modelParams
69
+ };
70
+ }),
71
+ {
72
+ bindDefs: {
73
+ query_text: {
74
+ type: oracledb.DB_TYPE_CLOB
75
+ },
76
+ model_params: {
77
+ type: oracledb.DB_TYPE_JSON
78
+ },
79
+ embedding: {
80
+ dir: oracledb.BIND_OUT,
81
+ type: oracledb.DB_TYPE_VECTOR
82
+ }
83
+ }
84
+ }
85
+ );
86
+
87
+ return result.outBinds.map((binds) => binds.embedding);
88
+ }
89
+
90
+ //-----------------------------------------------------------------------------
91
+ // loadModel()
92
+
93
+ // Load an embedding model into Oracle AI Database.
94
+ //-----------------------------------------------------------------------------
95
+ async function loadModel(connection, options) {
96
+ assertPlainObject(options, 'options');
97
+
98
+ const {
99
+ dirName,
100
+ modelFile,
101
+ modelName,
102
+ modelMetadata = null,
103
+ } = options;
104
+
105
+ assertNonEmptyString(modelFile, 'options.modelFile');
106
+ assertOptionalPlainObject(
107
+ modelMetadata,
108
+ 'options.modelMetadata'
109
+ );
110
+
111
+ const binds = {
112
+ dir_name: normalizeIdentifier(dirName, 'options.dirName'),
113
+ model_file: modelFile,
114
+ model_name: normalizeIdentifier(modelName, 'options.modelName')
115
+ };
116
+
117
+ const plsqlParams = [
118
+ 'directory => :dir_name',
119
+ 'file_name => :model_file',
120
+ 'model_name => :model_name'
121
+ ];
122
+
123
+ if (modelMetadata != null) {
124
+ binds.model_metadata = {
125
+ val: modelMetadata,
126
+ type: oracledb.DB_TYPE_JSON
127
+ };
128
+ plsqlParams.push('metadata => :model_metadata');
129
+ }
130
+
131
+ const plsql = `
132
+ BEGIN
133
+ DBMS_VECTOR.LOAD_ONNX_MODEL(
134
+ ${plsqlParams.join(', ')}
135
+ );
136
+ END;
137
+ `;
138
+
139
+ await connection.execute(plsql, binds);
140
+ }
141
+
142
+ //-----------------------------------------------------------------------------
143
+ // describeModel()
144
+
145
+ // Return metadata for a loaded model, including its algorithm, mining function,
146
+ // creation date, and attributes.
147
+ //-----------------------------------------------------------------------------
148
+ async function describeModel(connection, modelName) {
149
+ // requires Oracle Database 23.26.2.0.0 or later
150
+ assertDatabaseVersion(connection, 'describeModel()');
151
+
152
+ const binds = {
153
+ model_name: normalizeIdentifier(modelName, 'modelName'),
154
+ result: {
155
+ dir: oracledb.BIND_OUT,
156
+ type: oracledb.STRING,
157
+ maxSize: 1024 * 1024
158
+ }
159
+ };
160
+
161
+ const plsql = `
162
+ BEGIN
163
+ :result := DBMS_VECTOR_DATABASE.DESCRIBE_MODEL(MODEL_NAME => :model_name);
164
+ END;`;
165
+
166
+ const res = await connection.execute(plsql, binds);
167
+ return JSON.parse(res.outBinds.result);
168
+ }
169
+
170
+ //-----------------------------------------------------------------------------
171
+ // listModels()
172
+
173
+ // Return the models available in the current schema.
174
+ //-----------------------------------------------------------------------------
175
+ async function listModels(connection) {
176
+ // requires Oracle Database 23.26.2.0.0 or later
177
+ assertDatabaseVersion(connection, 'listModels()');
178
+
179
+ const binds = {
180
+ result: {
181
+ dir: oracledb.BIND_OUT,
182
+ type: oracledb.DB_TYPE_CLOB
183
+ }
184
+ };
185
+
186
+ const plsql = `
187
+ BEGIN
188
+ :result := DBMS_VECTOR_DATABASE.LIST_MODELS();
189
+ END;`;
190
+
191
+ const res = await connection.execute(plsql, binds);
192
+ const output = await readLobAsString(res.outBinds.result);
193
+ return JSON.parse(output);
194
+ }
195
+
196
+ //-----------------------------------------------------------------------------
197
+ // dropModel()
198
+
199
+ // Remove an embedding model from Oracle AI Database.
200
+ //-----------------------------------------------------------------------------
201
+ async function dropModel(connection, modelName, force = false) {
202
+ assertBoolean(force, 'force');
203
+
204
+ const safeModelName = normalizeIdentifier(modelName, 'modelName');
205
+ const dropModelSql = `
206
+ BEGIN
207
+ DBMS_VECTOR.DROP_ONNX_MODEL(
208
+ model_name => :model_name,
209
+ force => ${force ? 'TRUE' : 'FALSE'}
210
+ );
211
+ END;
212
+ `;
213
+
214
+ await connection.execute(dropModelSql, { model_name: safeModelName });
215
+ }
216
+
217
+ module.exports = {
218
+ generateEmbeddings,
219
+ loadModel,
220
+ describeModel,
221
+ listModels,
222
+ dropModel
223
+ };