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.
- package/README.md +16 -6
- package/build/Release/oracledb-26.0.0-darwin-arm64.node +0 -0
- package/build/Release/oracledb-26.0.0-darwin-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-26.0.0-js-buildinfo.txt +1 -0
- package/build/Release/oracledb-26.0.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-26.0.0-linux-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-26.0.0-linux-x64.node +0 -0
- package/build/Release/oracledb-26.0.0-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-26.0.0-win32-x64.node +0 -0
- package/build/Release/oracledb-26.0.0-win32-x64.node-buildinfo.txt +1 -0
- package/lib/aqDeqOptions.js +4 -4
- package/lib/aqEnqOptions.js +2 -2
- package/lib/aqQueue.js +11 -6
- package/lib/connection.js +73 -18
- package/lib/constants.js +4 -0
- package/lib/endUserSecurityContext.js +30 -25
- package/lib/errors.js +92 -5
- package/lib/impl/connection.js +36 -0
- package/lib/impl/datahandlers/buffer.js +91 -18
- package/lib/impl/datahandlers/oson.js +3 -2
- package/lib/impl/parserHelpers.js +6 -2
- package/lib/impl/resultset.js +32 -11
- package/lib/oracledb.js +34 -0
- package/lib/pool.js +6 -2
- package/lib/queryStream.js +13 -5
- package/lib/resultset.js +10 -3
- package/lib/securityContextProvider.js +206 -0
- package/lib/thin/aq.js +2 -3
- package/lib/thin/connection.js +380 -24
- package/lib/thin/dbObject.js +20 -11
- package/lib/thin/pool.js +4 -3
- package/lib/thin/protocol/capabilities.js +37 -4
- package/lib/thin/protocol/constants.js +49 -1
- package/lib/thin/protocol/messages/aqArray.js +2 -2
- package/lib/thin/protocol/messages/aqBase.js +2 -2
- package/lib/thin/protocol/messages/auth.js +17 -6
- package/lib/thin/protocol/messages/base.js +75 -17
- package/lib/thin/protocol/messages/dataType.js +46 -0
- package/lib/thin/protocol/messages/directPathLoadStream.js +3 -2
- package/lib/thin/protocol/messages/execute.js +10 -4
- package/lib/thin/protocol/messages/index.js +4 -0
- package/lib/thin/protocol/messages/notification.js +281 -0
- package/lib/thin/protocol/messages/subscribe.js +181 -0
- package/lib/thin/protocol/messages/withData.js +23 -10
- package/lib/thin/protocol/packet.js +2 -4
- package/lib/thin/protocol/protocol.js +7 -4
- package/lib/thin/resultSet.js +40 -20
- package/lib/thin/sqlnet/ezConnectResolver.js +9 -2
- package/lib/thin/sqlnet/navNodes.js +7 -5
- package/lib/thin/sqlnet/networkSession.js +17 -11
- package/lib/thin/sqlnet/ntTcp.js +24 -8
- package/lib/thin/sqlnet/packet.js +24 -4
- package/lib/thin/sqlnet/sessionAtts.js +2 -2
- package/lib/thin/statement.js +6 -1
- package/lib/thin/statementCache.js +34 -6
- package/lib/thin/subscr.js +363 -0
- package/lib/transformer.js +60 -17
- package/lib/util.js +46 -8
- package/lib/version.js +1 -1
- package/package.json +1 -1
- package/plugins/configProviders/gcpstorage/index.js +121 -0
- package/plugins/configProviders/ociobject/index.js +1 -1
- package/plugins/token/cache.js +154 -0
- package/plugins/token/endUserSecurityProvider/index.js +377 -0
- package/plugins/token/extensionAzure/index.js +160 -28
- package/plugins/token/extensionOci/index.js +221 -16
- package/plugins/vectorsdk/OracleVecDB.js +346 -0
- package/plugins/vectorsdk/index.js +49 -0
- package/plugins/vectorsdk/utils.js +370 -0
- package/plugins/vectorsdk/vectorEmbedding.js +223 -0
- package/plugins/vectorsdk/vectorIndex.js +177 -0
- package/plugins/vectorsdk/vectorRecords.js +406 -0
- package/plugins/vectorsdk/vectorSchema.js +408 -0
- package/plugins/vectorsdk/vectorSearch.js +538 -0
- package/build/Release/oracledb-7.0.0-darwin-arm64.node +0 -0
- package/build/Release/oracledb-7.0.0-darwin-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-7.0.0-js-buildinfo.txt +0 -1
- package/build/Release/oracledb-7.0.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-7.0.0-linux-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-7.0.0-linux-x64.node +0 -0
- package/build/Release/oracledb-7.0.0-linux-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-7.0.0-win32-x64.node +0 -0
- package/build/Release/oracledb-7.0.0-win32-x64.node-buildinfo.txt +0 -1
- 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
|
+
};
|