@sqlrooms/duckdb-core 0.26.1-rc.11
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/LICENSE.md +9 -0
- package/README.md +387 -0
- package/dist/BaseDuckDbConnector.d.ts +20 -0
- package/dist/BaseDuckDbConnector.d.ts.map +1 -0
- package/dist/BaseDuckDbConnector.js +122 -0
- package/dist/BaseDuckDbConnector.js.map +1 -0
- package/dist/DuckDbConnector.d.ts +312 -0
- package/dist/DuckDbConnector.d.ts.map +1 -0
- package/dist/DuckDbConnector.js +2 -0
- package/dist/DuckDbConnector.js.map +1 -0
- package/dist/arrow-utils.d.ts +8 -0
- package/dist/arrow-utils.d.ts.map +1 -0
- package/dist/arrow-utils.js +28 -0
- package/dist/arrow-utils.js.map +1 -0
- package/dist/duckdb-utils.d.ts +140 -0
- package/dist/duckdb-utils.d.ts.map +1 -0
- package/dist/duckdb-utils.js +290 -0
- package/dist/duckdb-utils.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/load/create.d.ts +33 -0
- package/dist/load/create.d.ts.map +1 -0
- package/dist/load/create.js +33 -0
- package/dist/load/create.js.map +1 -0
- package/dist/load/load.d.ts +57 -0
- package/dist/load/load.d.ts.map +1 -0
- package/dist/load/load.js +153 -0
- package/dist/load/load.js.map +1 -0
- package/dist/load/sql-from.d.ts +18 -0
- package/dist/load/sql-from.d.ts.map +1 -0
- package/dist/load/sql-from.js +69 -0
- package/dist/load/sql-from.js.map +1 -0
- package/dist/schema-tree/schemaTree.d.ts +9 -0
- package/dist/schema-tree/schemaTree.d.ts.map +1 -0
- package/dist/schema-tree/schemaTree.js +75 -0
- package/dist/schema-tree/schemaTree.js.map +1 -0
- package/dist/schema-tree/typeCategories.d.ts +16 -0
- package/dist/schema-tree/typeCategories.d.ts.map +1 -0
- package/dist/schema-tree/typeCategories.js +72 -0
- package/dist/schema-tree/typeCategories.js.map +1 -0
- package/dist/schema-tree/types.d.ts +28 -0
- package/dist/schema-tree/types.d.ts.map +1 -0
- package/dist/schema-tree/types.js +2 -0
- package/dist/schema-tree/types.js.map +1 -0
- package/dist/typedRowAccessor.d.ts +19 -0
- package/dist/typedRowAccessor.d.ts.map +1 -0
- package/dist/typedRowAccessor.js +45 -0
- package/dist/typedRowAccessor.js.map +1 -0
- package/dist/types.d.ts +21 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +42 -0
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
export function isQualifiedTableName(tableName) {
|
|
2
|
+
return typeof tableName === 'object' && 'toString' in tableName;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Get a qualified table name from a table name, schema, and database.
|
|
6
|
+
* @param table - The name of the table.
|
|
7
|
+
* @param schema - The schema of the table.
|
|
8
|
+
* @param database - The database of the table.
|
|
9
|
+
* @returns The qualified table name.
|
|
10
|
+
*/
|
|
11
|
+
export function makeQualifiedTableName({ database, schema, table, }) {
|
|
12
|
+
const qualifiedTableName = [database, schema, table]
|
|
13
|
+
.filter((id) => id !== undefined && id !== null)
|
|
14
|
+
.map((id) => escapeId(id))
|
|
15
|
+
.join('.');
|
|
16
|
+
return {
|
|
17
|
+
database,
|
|
18
|
+
schema,
|
|
19
|
+
table,
|
|
20
|
+
toString: () => qualifiedTableName,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Escapes a value for use in DuckDB SQL queries by wrapping it in single quotes
|
|
25
|
+
* and escaping any existing single quotes by doubling them.
|
|
26
|
+
*
|
|
27
|
+
* @param val - The value to escape. Will be converted to string if not already a string.
|
|
28
|
+
* @returns The escaped string value wrapped in single quotes.
|
|
29
|
+
* @example
|
|
30
|
+
* escapeVal("John's data") // Returns "'John''s data'"
|
|
31
|
+
*/
|
|
32
|
+
export const escapeVal = (val) => {
|
|
33
|
+
return `'${String(val).replace(/'/g, "''")}'`;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Escapes an identifier (like table or column names) for use in DuckDB SQL queries
|
|
37
|
+
* by wrapping it in double quotes and escaping any existing double quotes by doubling them.
|
|
38
|
+
* If the identifier is already properly quoted, returns it as is.
|
|
39
|
+
*
|
|
40
|
+
* @param id - The identifier string to escape
|
|
41
|
+
* @returns The escaped identifier wrapped in double quotes
|
|
42
|
+
* @example
|
|
43
|
+
* escapeId("my_table") // Returns '"my_table"'
|
|
44
|
+
* escapeId("my""table") // Returns '"my""""table"'
|
|
45
|
+
*/
|
|
46
|
+
export const escapeId = (id) => {
|
|
47
|
+
const str = String(id);
|
|
48
|
+
if (str.startsWith('"') && str.endsWith('"')) {
|
|
49
|
+
return str;
|
|
50
|
+
}
|
|
51
|
+
return `"${str.replace(/"/g, '""')}"`;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Checks if a DuckDB type string represents a numeric type.
|
|
55
|
+
* Includes INTEGER, DECIMAL, FLOAT, REAL, and DOUBLE types.
|
|
56
|
+
*
|
|
57
|
+
* @param type - The DuckDB type string to check
|
|
58
|
+
* @returns True if the type is numeric, false otherwise
|
|
59
|
+
* @example
|
|
60
|
+
* isNumericDuckType('INTEGER') // Returns true
|
|
61
|
+
* isNumericDuckType('VARCHAR') // Returns false
|
|
62
|
+
*/
|
|
63
|
+
export const isNumericDuckType = (type) => type.indexOf('INT') >= 0 ||
|
|
64
|
+
type.indexOf('DECIMAL') >= 0 ||
|
|
65
|
+
type.indexOf('FLOAT') >= 0 ||
|
|
66
|
+
type.indexOf('REAL') >= 0 ||
|
|
67
|
+
type.indexOf('DOUBLE') >= 0;
|
|
68
|
+
/**
|
|
69
|
+
* Extracts a numeric value from an Arrow Table at the specified column and row index.
|
|
70
|
+
* Handles both column name and index-based access. Converts BigInt values to numbers.
|
|
71
|
+
*
|
|
72
|
+
* @param res - The Arrow Table containing the data
|
|
73
|
+
* @param column - The column name or index (0-based) to read from. Defaults to first column (0)
|
|
74
|
+
* @param index - The row index (0-based) to read from. Defaults to first row (0)
|
|
75
|
+
* @returns The numeric value at the specified position, or NaN if the value is null/undefined
|
|
76
|
+
* @example
|
|
77
|
+
* const value = getColValAsNumber(table, "amount", 0)
|
|
78
|
+
*/
|
|
79
|
+
export function getColValAsNumber(res, column = 0, index = 0) {
|
|
80
|
+
const v = (typeof column === 'number' ? res.getChildAt(column) : res.getChild(column))?.get(index);
|
|
81
|
+
if (v === undefined || v === null) {
|
|
82
|
+
return NaN;
|
|
83
|
+
}
|
|
84
|
+
// if it's an array (can be returned by duckdb as bigint)
|
|
85
|
+
return Number(v[0] ?? v);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Function given a query and position finds the line and column of the console.error();
|
|
89
|
+
*
|
|
90
|
+
* @param query - The query to parse
|
|
91
|
+
* @param position - The position of the error
|
|
92
|
+
* @returns The line and column of the error
|
|
93
|
+
*/
|
|
94
|
+
export const getSqlErrorWithPointer = (query, position) => {
|
|
95
|
+
// Clamp position to be within the string bounds
|
|
96
|
+
const safePos = Math.max(0, Math.min(position, query.length));
|
|
97
|
+
// Get the substring up to the error position
|
|
98
|
+
const upToPos = query.slice(0, safePos);
|
|
99
|
+
// Split by newlines
|
|
100
|
+
const lines = upToPos.split('\n');
|
|
101
|
+
const line = lines.length; // 1-based
|
|
102
|
+
// Defensive: lines[lines.length - 1] is always defined, but add fallback for linter
|
|
103
|
+
const lastLine = lines[lines.length - 1] ?? '';
|
|
104
|
+
const column = lastLine.length + 1; // 1-based
|
|
105
|
+
// Get the full line text from the original query
|
|
106
|
+
const queryLines = query.split('\n');
|
|
107
|
+
const lineText = queryLines[line - 1] ?? '';
|
|
108
|
+
// Pointer line: spaces up to column-1, then ^
|
|
109
|
+
const pointerLine = ' '.repeat(Math.max(0, column - 1)) + '^';
|
|
110
|
+
// Formatted output as requested
|
|
111
|
+
const formatted = `LINE ${line}: ${lineText}\n${' '.repeat(`LINE ${line}: `.length)}${pointerLine}`;
|
|
112
|
+
return { line, column, lineText, pointerLine, formatted };
|
|
113
|
+
};
|
|
114
|
+
//
|
|
115
|
+
// const queries = splitSqlStatements(`
|
|
116
|
+
// SELECT * FROM users WHERE name = 'John;Doe';
|
|
117
|
+
// SELECT * FROM orders -- This comment; won't break;
|
|
118
|
+
// /*
|
|
119
|
+
// Multi-line comment;
|
|
120
|
+
// With semicolons;
|
|
121
|
+
// */
|
|
122
|
+
// SELECT "Quoted;identifier" FROM table;
|
|
123
|
+
//`);
|
|
124
|
+
// Returns:
|
|
125
|
+
// [
|
|
126
|
+
// "SELECT * FROM users WHERE name = 'John;Doe'",
|
|
127
|
+
// "SELECT * FROM orders -- This comment; won't break",
|
|
128
|
+
// "SELECT \"Quoted;identifier\" FROM table"
|
|
129
|
+
// ]
|
|
130
|
+
/**
|
|
131
|
+
* Split a string with potentially multiple SQL queries (separated as usual by ';')
|
|
132
|
+
* into an array of queries.
|
|
133
|
+
* This implementation:
|
|
134
|
+
* - Handles single and double quoted strings with proper escaping
|
|
135
|
+
* - Removes all comments: line comments (--) and block comments (/* ... *\/)
|
|
136
|
+
* - Ignores semicolons in quoted strings and comments
|
|
137
|
+
* - Trims whitespace from queries
|
|
138
|
+
* - Handles SQL-style escaped quotes ('' inside strings)
|
|
139
|
+
* - Returns only non-empty queries
|
|
140
|
+
*
|
|
141
|
+
* @param input - The SQL string containing one or more statements
|
|
142
|
+
* @returns An array of SQL statements with all comments removed
|
|
143
|
+
*/
|
|
144
|
+
export function splitSqlStatements(input) {
|
|
145
|
+
const queries = [];
|
|
146
|
+
let currentQuery = '';
|
|
147
|
+
let inSingleQuote = false;
|
|
148
|
+
let inDoubleQuote = false;
|
|
149
|
+
let inLineComment = false;
|
|
150
|
+
let inBlockComment = false;
|
|
151
|
+
for (let i = 0; i < input.length; i++) {
|
|
152
|
+
const char = input[i];
|
|
153
|
+
if (inLineComment) {
|
|
154
|
+
if (char === '\n') {
|
|
155
|
+
inLineComment = false;
|
|
156
|
+
currentQuery += char; // preserve newlines for line numbers
|
|
157
|
+
}
|
|
158
|
+
// else: skip comment chars
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if (inBlockComment) {
|
|
162
|
+
if (char === '*' && input[i + 1] === '/') {
|
|
163
|
+
inBlockComment = false;
|
|
164
|
+
i++; // skip '/'
|
|
165
|
+
}
|
|
166
|
+
// else: skip comment chars
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
if (inSingleQuote) {
|
|
170
|
+
currentQuery += char;
|
|
171
|
+
if (char === "'") {
|
|
172
|
+
// Handle escaped single quotes in SQL
|
|
173
|
+
if (i + 1 < input.length && input[i + 1] === "'") {
|
|
174
|
+
currentQuery += input[++i];
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
inSingleQuote = false;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
if (inDoubleQuote) {
|
|
183
|
+
currentQuery += char;
|
|
184
|
+
if (char === '"') {
|
|
185
|
+
// Handle escaped double quotes
|
|
186
|
+
if (i + 1 < input.length && input[i + 1] === '"') {
|
|
187
|
+
currentQuery += input[++i];
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
inDoubleQuote = false;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
// Check for comment starts
|
|
196
|
+
if (char === '-' && input[i + 1] === '-') {
|
|
197
|
+
inLineComment = true;
|
|
198
|
+
i++; // skip next '-'
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
if (char === '/' && input[i + 1] === '*') {
|
|
202
|
+
inBlockComment = true;
|
|
203
|
+
i++; // skip next '*'
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
// Check for quote starts
|
|
207
|
+
if (char === "'") {
|
|
208
|
+
inSingleQuote = true;
|
|
209
|
+
currentQuery += char;
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
if (char === '"') {
|
|
213
|
+
inDoubleQuote = true;
|
|
214
|
+
currentQuery += char;
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
// Handle query separator
|
|
218
|
+
if (char === ';') {
|
|
219
|
+
const trimmed = currentQuery.trim();
|
|
220
|
+
if (trimmed.length > 0) {
|
|
221
|
+
queries.push(trimmed);
|
|
222
|
+
}
|
|
223
|
+
currentQuery = '';
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
currentQuery += char;
|
|
227
|
+
}
|
|
228
|
+
// Add the final query
|
|
229
|
+
const trimmed = currentQuery.trim();
|
|
230
|
+
if (trimmed.length > 0) {
|
|
231
|
+
queries.push(trimmed);
|
|
232
|
+
}
|
|
233
|
+
return queries;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Sanitizes a SQL query by removing trailing semicolons, comments, and normalizing whitespace
|
|
237
|
+
*/
|
|
238
|
+
export function sanitizeQuery(query) {
|
|
239
|
+
return query
|
|
240
|
+
.trim() // Remove leading/trailing whitespace
|
|
241
|
+
.replace(/;+$/, '') // Remove all trailing semicolons
|
|
242
|
+
.replace(/--.*$/gm, '') // Remove single-line comments
|
|
243
|
+
.replace(/\/\*[\s\S]*?\*\//g, '') // Remove multi-line comments
|
|
244
|
+
.replace(/\s+/g, ' '); // Normalize whitespace to single spaces
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Make a limit query from a query and a limit.
|
|
248
|
+
* @param query - The SELECT query to make limited.
|
|
249
|
+
* @param options - The options for the limit query.
|
|
250
|
+
* @param options.limit - The number of rows to limit the query to.
|
|
251
|
+
* @param options.offset - The number of rows to offset the query by.
|
|
252
|
+
* @param options.sanitize - Whether to sanitize the query.
|
|
253
|
+
* @returns The limited query.
|
|
254
|
+
*/
|
|
255
|
+
export function makeLimitQuery(query, { limit = 100, offset = 0, sanitize = true, } = {}) {
|
|
256
|
+
return `SELECT * FROM (
|
|
257
|
+
${sanitize ? sanitizeQuery(query) : query}
|
|
258
|
+
) LIMIT ${limit} OFFSET ${offset}`;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Separates a SQL query into preceding statements and the last statement.
|
|
262
|
+
* Useful when you need to execute multiple statements but handle the last one differently
|
|
263
|
+
* (e.g., wrap it in CREATE TABLE, add LIMIT, etc.).
|
|
264
|
+
*
|
|
265
|
+
* @param query - The SQL query string containing one or more statements
|
|
266
|
+
* @returns Object containing preceding statements and the last statement
|
|
267
|
+
* @throws Error if the query contains no statements
|
|
268
|
+
*/
|
|
269
|
+
export function separateLastStatement(query) {
|
|
270
|
+
const statements = splitSqlStatements(query);
|
|
271
|
+
if (statements.length === 0) {
|
|
272
|
+
throw new Error('Query must contain at least one statement');
|
|
273
|
+
}
|
|
274
|
+
return {
|
|
275
|
+
precedingStatements: statements.slice(0, -1),
|
|
276
|
+
lastStatement: statements[statements.length - 1],
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Joins preceding statements with a (potentially modified) last statement into a single query.
|
|
281
|
+
* @param precedingStatements - Statements to execute before the last one
|
|
282
|
+
* @param lastStatement - The final statement (can be modified, e.g., wrapped in CREATE TABLE)
|
|
283
|
+
* @returns A single query string with all statements joined by semicolons
|
|
284
|
+
*/
|
|
285
|
+
export function joinStatements(precedingStatements, lastStatement) {
|
|
286
|
+
return precedingStatements.length > 0
|
|
287
|
+
? [...precedingStatements, lastStatement].join(';\n')
|
|
288
|
+
: lastStatement;
|
|
289
|
+
}
|
|
290
|
+
//# sourceMappingURL=duckdb-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duckdb-utils.js","sourceRoot":"","sources":["../src/duckdb-utils.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,oBAAoB,CAClC,SAAsC;IAEtC,OAAO,OAAO,SAAS,KAAK,QAAQ,IAAI,UAAU,IAAI,SAAS,CAAC;AAClE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,EACrC,QAAQ,EACR,MAAM,EACN,KAAK,GACc;IACnB,MAAM,kBAAkB,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC;SACjD,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,SAAS,IAAI,EAAE,KAAK,IAAI,CAAC;SAC/C,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;SACzB,IAAI,CAAC,GAAG,CAAC,CAAC;IACb,OAAO;QACL,QAAQ;QACR,MAAM;QACN,KAAK;QACL,QAAQ,EAAE,GAAG,EAAE,CAAC,kBAAkB;KACnC,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,GAAY,EAAE,EAAE;IACxC,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;AAChD,CAAC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,EAAU,EAAE,EAAE;IACrC,MAAM,GAAG,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;IACvB,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7C,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;AACxC,CAAC,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAE,EAAE,CAChD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;IACxB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC;IAC5B,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;IAC1B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;IACzB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAE9B;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAC/B,GAAgB,EAChB,SAA0B,CAAC,EAC3B,KAAK,GAAG,CAAC;IAET,MAAM,CAAC,GAAG,CACR,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAC3E,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;IACd,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QAClC,OAAO,GAAG,CAAC;IACb,CAAC;IACD,yDAAyD;IACzD,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC3B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,KAAa,EAAE,QAAgB,EAAE,EAAE;IACxE,gDAAgD;IAChD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9D,6CAA6C;IAC7C,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACxC,oBAAoB;IACpB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,UAAU;IACrC,oFAAoF;IACpF,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/C,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,UAAU;IAE9C,iDAAiD;IACjD,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5C,8CAA8C;IAC9C,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;IAE9D,gCAAgC;IAChC,MAAM,SAAS,GAAG,QAAQ,IAAI,KAAK,QAAQ,KAAK,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,WAAW,EAAE,CAAC;IAEpG,OAAO,EAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAC,CAAC;AAC1D,CAAC,CAAC;AAEF,EAAE;AACF,uCAAuC;AACvC,iDAAiD;AACjD,uDAAuD;AACvD,OAAO;AACP,2BAA2B;AAC3B,wBAAwB;AACxB,OAAO;AACP,2CAA2C;AAC3C,KAAK;AAEL,WAAW;AACX,IAAI;AACJ,mDAAmD;AACnD,yDAAyD;AACzD,8CAA8C;AAC9C,IAAI;AAEJ;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,YAAY,GAAG,EAAE,CAAC;IACtB,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,IAAI,cAAc,GAAG,KAAK,CAAC;IAE3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAEtB,IAAI,aAAa,EAAE,CAAC;YAClB,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBAClB,aAAa,GAAG,KAAK,CAAC;gBACtB,YAAY,IAAI,IAAI,CAAC,CAAC,qCAAqC;YAC7D,CAAC;YACD,2BAA2B;YAC3B,SAAS;QACX,CAAC;QAED,IAAI,cAAc,EAAE,CAAC;YACnB,IAAI,IAAI,KAAK,GAAG,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBACzC,cAAc,GAAG,KAAK,CAAC;gBACvB,CAAC,EAAE,CAAC,CAAC,WAAW;YAClB,CAAC;YACD,2BAA2B;YAC3B,SAAS;QACX,CAAC;QAED,IAAI,aAAa,EAAE,CAAC;YAClB,YAAY,IAAI,IAAI,CAAC;YACrB,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBACjB,sCAAsC;gBACtC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;oBACjD,YAAY,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC7B,CAAC;qBAAM,CAAC;oBACN,aAAa,GAAG,KAAK,CAAC;gBACxB,CAAC;YACH,CAAC;YACD,SAAS;QACX,CAAC;QAED,IAAI,aAAa,EAAE,CAAC;YAClB,YAAY,IAAI,IAAI,CAAC;YACrB,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBACjB,+BAA+B;gBAC/B,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;oBACjD,YAAY,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC7B,CAAC;qBAAM,CAAC;oBACN,aAAa,GAAG,KAAK,CAAC;gBACxB,CAAC;YACH,CAAC;YACD,SAAS;QACX,CAAC;QAED,2BAA2B;QAC3B,IAAI,IAAI,KAAK,GAAG,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YACzC,aAAa,GAAG,IAAI,CAAC;YACrB,CAAC,EAAE,CAAC,CAAC,gBAAgB;YACrB,SAAS;QACX,CAAC;QAED,IAAI,IAAI,KAAK,GAAG,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YACzC,cAAc,GAAG,IAAI,CAAC;YACtB,CAAC,EAAE,CAAC,CAAC,gBAAgB;YACrB,SAAS;QACX,CAAC;QAED,yBAAyB;QACzB,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YACjB,aAAa,GAAG,IAAI,CAAC;YACrB,YAAY,IAAI,IAAI,CAAC;YACrB,SAAS;QACX,CAAC;QAED,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YACjB,aAAa,GAAG,IAAI,CAAC;YACrB,YAAY,IAAI,IAAI,CAAC;YACrB,SAAS;QACX,CAAC;QAED,yBAAyB;QACzB,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YACjB,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC;YACpC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACxB,CAAC;YACD,YAAY,GAAG,EAAE,CAAC;YAClB,SAAS;QACX,CAAC;QAED,YAAY,IAAI,IAAI,CAAC;IACvB,CAAC;IAED,sBAAsB;IACtB,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC;IACpC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,OAAO,KAAK;SACT,IAAI,EAAE,CAAC,qCAAqC;SAC5C,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,iCAAiC;SACpD,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,8BAA8B;SACrD,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC,6BAA6B;SAC9D,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,wCAAwC;AACnE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAC5B,KAAa,EACb,EACE,KAAK,GAAG,GAAG,EACX,MAAM,GAAG,CAAC,EACV,QAAQ,GAAG,IAAI,MAKb,EAAE;IAEN,OAAO;MACH,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK;YACjC,KAAK,WAAW,MAAM,EAAE,CAAC;AACrC,CAAC;AAYD;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAa;IACjD,MAAM,UAAU,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC7C,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO;QACL,mBAAmB,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5C,aAAa,EAAE,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAW;KAC3D,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAC5B,mBAA6B,EAC7B,aAAqB;IAErB,OAAO,mBAAmB,CAAC,MAAM,GAAG,CAAC;QACnC,CAAC,CAAC,CAAC,GAAG,mBAAmB,EAAE,aAAa,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;QACrD,CAAC,CAAC,aAAa,CAAC;AACpB,CAAC","sourcesContent":["import * as arrow from 'apache-arrow';\n\nexport type QualifiedTableName = {\n database?: string;\n schema?: string;\n table: string;\n toString: () => string;\n};\n\nexport function isQualifiedTableName(\n tableName: string | QualifiedTableName,\n): tableName is QualifiedTableName {\n return typeof tableName === 'object' && 'toString' in tableName;\n}\n\n/**\n * Get a qualified table name from a table name, schema, and database.\n * @param table - The name of the table.\n * @param schema - The schema of the table.\n * @param database - The database of the table.\n * @returns The qualified table name.\n */\nexport function makeQualifiedTableName({\n database,\n schema,\n table,\n}: QualifiedTableName) {\n const qualifiedTableName = [database, schema, table]\n .filter((id) => id !== undefined && id !== null)\n .map((id) => escapeId(id))\n .join('.');\n return {\n database,\n schema,\n table,\n toString: () => qualifiedTableName,\n };\n}\n\n/**\n * Escapes a value for use in DuckDB SQL queries by wrapping it in single quotes\n * and escaping any existing single quotes by doubling them.\n *\n * @param val - The value to escape. Will be converted to string if not already a string.\n * @returns The escaped string value wrapped in single quotes.\n * @example\n * escapeVal(\"John's data\") // Returns \"'John''s data'\"\n */\nexport const escapeVal = (val: unknown) => {\n return `'${String(val).replace(/'/g, \"''\")}'`;\n};\n\n/**\n * Escapes an identifier (like table or column names) for use in DuckDB SQL queries\n * by wrapping it in double quotes and escaping any existing double quotes by doubling them.\n * If the identifier is already properly quoted, returns it as is.\n *\n * @param id - The identifier string to escape\n * @returns The escaped identifier wrapped in double quotes\n * @example\n * escapeId(\"my_table\") // Returns '\"my_table\"'\n * escapeId(\"my\"\"table\") // Returns '\"my\"\"\"\"table\"'\n */\nexport const escapeId = (id: string) => {\n const str = String(id);\n if (str.startsWith('\"') && str.endsWith('\"')) {\n return str;\n }\n return `\"${str.replace(/\"/g, '\"\"')}\"`;\n};\n\n/**\n * Checks if a DuckDB type string represents a numeric type.\n * Includes INTEGER, DECIMAL, FLOAT, REAL, and DOUBLE types.\n *\n * @param type - The DuckDB type string to check\n * @returns True if the type is numeric, false otherwise\n * @example\n * isNumericDuckType('INTEGER') // Returns true\n * isNumericDuckType('VARCHAR') // Returns false\n */\nexport const isNumericDuckType = (type: string) =>\n type.indexOf('INT') >= 0 ||\n type.indexOf('DECIMAL') >= 0 ||\n type.indexOf('FLOAT') >= 0 ||\n type.indexOf('REAL') >= 0 ||\n type.indexOf('DOUBLE') >= 0;\n\n/**\n * Extracts a numeric value from an Arrow Table at the specified column and row index.\n * Handles both column name and index-based access. Converts BigInt values to numbers.\n *\n * @param res - The Arrow Table containing the data\n * @param column - The column name or index (0-based) to read from. Defaults to first column (0)\n * @param index - The row index (0-based) to read from. Defaults to first row (0)\n * @returns The numeric value at the specified position, or NaN if the value is null/undefined\n * @example\n * const value = getColValAsNumber(table, \"amount\", 0)\n */\nexport function getColValAsNumber(\n res: arrow.Table,\n column: string | number = 0,\n index = 0,\n): number {\n const v = (\n typeof column === 'number' ? res.getChildAt(column) : res.getChild(column)\n )?.get(index);\n if (v === undefined || v === null) {\n return NaN;\n }\n // if it's an array (can be returned by duckdb as bigint)\n return Number(v[0] ?? v);\n}\n\n/**\n * Function given a query and position finds the line and column of the console.error();\n *\n * @param query - The query to parse\n * @param position - The position of the error\n * @returns The line and column of the error\n */\nexport const getSqlErrorWithPointer = (query: string, position: number) => {\n // Clamp position to be within the string bounds\n const safePos = Math.max(0, Math.min(position, query.length));\n // Get the substring up to the error position\n const upToPos = query.slice(0, safePos);\n // Split by newlines\n const lines = upToPos.split('\\n');\n const line = lines.length; // 1-based\n // Defensive: lines[lines.length - 1] is always defined, but add fallback for linter\n const lastLine = lines[lines.length - 1] ?? '';\n const column = lastLine.length + 1; // 1-based\n\n // Get the full line text from the original query\n const queryLines = query.split('\\n');\n const lineText = queryLines[line - 1] ?? '';\n // Pointer line: spaces up to column-1, then ^\n const pointerLine = ' '.repeat(Math.max(0, column - 1)) + '^';\n\n // Formatted output as requested\n const formatted = `LINE ${line}: ${lineText}\\n${' '.repeat(`LINE ${line}: `.length)}${pointerLine}`;\n\n return {line, column, lineText, pointerLine, formatted};\n};\n\n//\n// const queries = splitSqlStatements(`\n// SELECT * FROM users WHERE name = 'John;Doe';\n// SELECT * FROM orders -- This comment; won't break;\n// /*\n// Multi-line comment;\n// With semicolons;\n// */\n// SELECT \"Quoted;identifier\" FROM table;\n//`);\n\n// Returns:\n// [\n// \"SELECT * FROM users WHERE name = 'John;Doe'\",\n// \"SELECT * FROM orders -- This comment; won't break\",\n// \"SELECT \\\"Quoted;identifier\\\" FROM table\"\n// ]\n\n/**\n * Split a string with potentially multiple SQL queries (separated as usual by ';')\n * into an array of queries.\n * This implementation:\n * - Handles single and double quoted strings with proper escaping\n * - Removes all comments: line comments (--) and block comments (/* ... *\\/)\n * - Ignores semicolons in quoted strings and comments\n * - Trims whitespace from queries\n * - Handles SQL-style escaped quotes ('' inside strings)\n * - Returns only non-empty queries\n *\n * @param input - The SQL string containing one or more statements\n * @returns An array of SQL statements with all comments removed\n */\nexport function splitSqlStatements(input: string): string[] {\n const queries: string[] = [];\n let currentQuery = '';\n let inSingleQuote = false;\n let inDoubleQuote = false;\n let inLineComment = false;\n let inBlockComment = false;\n\n for (let i = 0; i < input.length; i++) {\n const char = input[i];\n\n if (inLineComment) {\n if (char === '\\n') {\n inLineComment = false;\n currentQuery += char; // preserve newlines for line numbers\n }\n // else: skip comment chars\n continue;\n }\n\n if (inBlockComment) {\n if (char === '*' && input[i + 1] === '/') {\n inBlockComment = false;\n i++; // skip '/'\n }\n // else: skip comment chars\n continue;\n }\n\n if (inSingleQuote) {\n currentQuery += char;\n if (char === \"'\") {\n // Handle escaped single quotes in SQL\n if (i + 1 < input.length && input[i + 1] === \"'\") {\n currentQuery += input[++i];\n } else {\n inSingleQuote = false;\n }\n }\n continue;\n }\n\n if (inDoubleQuote) {\n currentQuery += char;\n if (char === '\"') {\n // Handle escaped double quotes\n if (i + 1 < input.length && input[i + 1] === '\"') {\n currentQuery += input[++i];\n } else {\n inDoubleQuote = false;\n }\n }\n continue;\n }\n\n // Check for comment starts\n if (char === '-' && input[i + 1] === '-') {\n inLineComment = true;\n i++; // skip next '-'\n continue;\n }\n\n if (char === '/' && input[i + 1] === '*') {\n inBlockComment = true;\n i++; // skip next '*'\n continue;\n }\n\n // Check for quote starts\n if (char === \"'\") {\n inSingleQuote = true;\n currentQuery += char;\n continue;\n }\n\n if (char === '\"') {\n inDoubleQuote = true;\n currentQuery += char;\n continue;\n }\n\n // Handle query separator\n if (char === ';') {\n const trimmed = currentQuery.trim();\n if (trimmed.length > 0) {\n queries.push(trimmed);\n }\n currentQuery = '';\n continue;\n }\n\n currentQuery += char;\n }\n\n // Add the final query\n const trimmed = currentQuery.trim();\n if (trimmed.length > 0) {\n queries.push(trimmed);\n }\n\n return queries;\n}\n\n/**\n * Sanitizes a SQL query by removing trailing semicolons, comments, and normalizing whitespace\n */\nexport function sanitizeQuery(query: string): string {\n return query\n .trim() // Remove leading/trailing whitespace\n .replace(/;+$/, '') // Remove all trailing semicolons\n .replace(/--.*$/gm, '') // Remove single-line comments\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '') // Remove multi-line comments\n .replace(/\\s+/g, ' '); // Normalize whitespace to single spaces\n}\n\n/**\n * Make a limit query from a query and a limit.\n * @param query - The SELECT query to make limited.\n * @param options - The options for the limit query.\n * @param options.limit - The number of rows to limit the query to.\n * @param options.offset - The number of rows to offset the query by.\n * @param options.sanitize - Whether to sanitize the query.\n * @returns The limited query.\n */\nexport function makeLimitQuery(\n query: string,\n {\n limit = 100,\n offset = 0,\n sanitize = true,\n }: {\n limit?: number;\n offset?: number;\n sanitize?: boolean;\n } = {},\n) {\n return `SELECT * FROM (\n ${sanitize ? sanitizeQuery(query) : query}\n ) LIMIT ${limit} OFFSET ${offset}`;\n}\n\n/**\n * Result of separating the last SQL statement from preceding ones.\n */\nexport type SeparatedStatements = {\n /** All statements except the last one */\n precedingStatements: string[];\n /** The last statement */\n lastStatement: string;\n};\n\n/**\n * Separates a SQL query into preceding statements and the last statement.\n * Useful when you need to execute multiple statements but handle the last one differently\n * (e.g., wrap it in CREATE TABLE, add LIMIT, etc.).\n *\n * @param query - The SQL query string containing one or more statements\n * @returns Object containing preceding statements and the last statement\n * @throws Error if the query contains no statements\n */\nexport function separateLastStatement(query: string): SeparatedStatements {\n const statements = splitSqlStatements(query);\n if (statements.length === 0) {\n throw new Error('Query must contain at least one statement');\n }\n return {\n precedingStatements: statements.slice(0, -1),\n lastStatement: statements[statements.length - 1] as string,\n };\n}\n\n/**\n * Joins preceding statements with a (potentially modified) last statement into a single query.\n * @param precedingStatements - Statements to execute before the last one\n * @param lastStatement - The final statement (can be modified, e.g., wrapped in CREATE TABLE)\n * @returns A single query string with all statements joined by semicolons\n */\nexport function joinStatements(\n precedingStatements: string[],\n lastStatement: string,\n): string {\n return precedingStatements.length > 0\n ? [...precedingStatements, lastStatement].join(';\\n')\n : lastStatement;\n}\n"]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { createTypedRowAccessor } from './typedRowAccessor';
|
|
2
|
+
export type { TypedRowAccessor } from './typedRowAccessor';
|
|
3
|
+
export { createBaseDuckDbConnector, type BaseDuckDbConnectorOptions, type BaseDuckDbConnectorImpl, } from './BaseDuckDbConnector';
|
|
4
|
+
export { literalToSQL, sqlFrom, load, loadCSV, loadJSON, loadParquet, loadSpatial, loadObjects, } from './load/load';
|
|
5
|
+
export { type QueryOptions, type QueryHandle, type DuckDbConnector, } from './DuckDbConnector';
|
|
6
|
+
export { arrowTableToJson } from './arrow-utils';
|
|
7
|
+
export { isQualifiedTableName, makeQualifiedTableName, escapeVal, escapeId, isNumericDuckType, getColValAsNumber, getSqlErrorWithPointer, splitSqlStatements, sanitizeQuery, makeLimitQuery, separateLastStatement, joinStatements, type QualifiedTableName, type SeparatedStatements, } from './duckdb-utils';
|
|
8
|
+
export { getDuckDbTypeCategory, getArrowColumnTypeCategory, type ColumnTypeCategory, } from './schema-tree/typeCategories';
|
|
9
|
+
export { createDbSchemaTrees } from './schema-tree/schemaTree';
|
|
10
|
+
export { type DbSchemaNode, type NodeObject, type ColumnNodeObject, type TableNodeObject, type SchemaNodeObject, type DatabaseNodeObject, } from './schema-tree/types';
|
|
11
|
+
export { type TableColumn, type DataTable } from './types';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,sBAAsB,EAAC,MAAM,oBAAoB,CAAC;AAC1D,YAAY,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AAEzD,OAAO,EACL,yBAAyB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,uBAAuB,GAC7B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,YAAY,EACZ,OAAO,EACP,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,WAAW,EACX,WAAW,EACX,WAAW,GACZ,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,eAAe,GACrB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAC,gBAAgB,EAAC,MAAM,eAAe,CAAC;AAE/C,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,SAAS,EACT,QAAQ,EACR,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,qBAAqB,EACrB,cAAc,EACd,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,GACzB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,qBAAqB,EACrB,0BAA0B,EAC1B,KAAK,kBAAkB,GACxB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAC,mBAAmB,EAAC,MAAM,0BAA0B,CAAC;AAE7D,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,GACxB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAC,KAAK,WAAW,EAAE,KAAK,SAAS,EAAC,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { createTypedRowAccessor } from './typedRowAccessor';
|
|
2
|
+
export { createBaseDuckDbConnector, } from './BaseDuckDbConnector';
|
|
3
|
+
export { literalToSQL, sqlFrom, load, loadCSV, loadJSON, loadParquet, loadSpatial, loadObjects, } from './load/load';
|
|
4
|
+
export { arrowTableToJson } from './arrow-utils';
|
|
5
|
+
export { isQualifiedTableName, makeQualifiedTableName, escapeVal, escapeId, isNumericDuckType, getColValAsNumber, getSqlErrorWithPointer, splitSqlStatements, sanitizeQuery, makeLimitQuery, separateLastStatement, joinStatements, } from './duckdb-utils';
|
|
6
|
+
export { getDuckDbTypeCategory, getArrowColumnTypeCategory, } from './schema-tree/typeCategories';
|
|
7
|
+
export { createDbSchemaTrees } from './schema-tree/schemaTree';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,sBAAsB,EAAC,MAAM,oBAAoB,CAAC;AAG1D,OAAO,EACL,yBAAyB,GAG1B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,YAAY,EACZ,OAAO,EACP,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,WAAW,EACX,WAAW,EACX,WAAW,GACZ,MAAM,aAAa,CAAC;AAQrB,OAAO,EAAC,gBAAgB,EAAC,MAAM,eAAe,CAAC;AAE/C,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,SAAS,EACT,QAAQ,EACR,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,qBAAqB,EACrB,cAAc,GAGf,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,qBAAqB,EACrB,0BAA0B,GAE3B,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAC,mBAAmB,EAAC,MAAM,0BAA0B,CAAC","sourcesContent":["export {createTypedRowAccessor} from './typedRowAccessor';\nexport type {TypedRowAccessor} from './typedRowAccessor';\n\nexport {\n createBaseDuckDbConnector,\n type BaseDuckDbConnectorOptions,\n type BaseDuckDbConnectorImpl,\n} from './BaseDuckDbConnector';\n\nexport {\n literalToSQL,\n sqlFrom,\n load,\n loadCSV,\n loadJSON,\n loadParquet,\n loadSpatial,\n loadObjects,\n} from './load/load';\n\nexport {\n type QueryOptions,\n type QueryHandle,\n type DuckDbConnector,\n} from './DuckDbConnector';\n\nexport {arrowTableToJson} from './arrow-utils';\n\nexport {\n isQualifiedTableName,\n makeQualifiedTableName,\n escapeVal,\n escapeId,\n isNumericDuckType,\n getColValAsNumber,\n getSqlErrorWithPointer,\n splitSqlStatements,\n sanitizeQuery,\n makeLimitQuery,\n separateLastStatement,\n joinStatements,\n type QualifiedTableName,\n type SeparatedStatements,\n} from './duckdb-utils';\n\nexport {\n getDuckDbTypeCategory,\n getArrowColumnTypeCategory,\n type ColumnTypeCategory,\n} from './schema-tree/typeCategories';\n\nexport {createDbSchemaTrees} from './schema-tree/schemaTree';\n\nexport {\n type DbSchemaNode,\n type NodeObject,\n type ColumnNodeObject,\n type TableNodeObject,\n type SchemaNodeObject,\n type DatabaseNodeObject,\n} from './schema-tree/types';\n\nexport {type TableColumn, type DataTable} from './types';\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
interface TableOptions {
|
|
2
|
+
/** Whether to replace existing table/view if it exists */
|
|
3
|
+
replace?: boolean;
|
|
4
|
+
/** Whether to create a temporary table/view */
|
|
5
|
+
temp?: boolean;
|
|
6
|
+
/** Whether to create a view instead of a table */
|
|
7
|
+
view?: boolean;
|
|
8
|
+
}
|
|
9
|
+
interface SchemaOptions {
|
|
10
|
+
/** Whether to enforce strict schema creation (no IF NOT EXISTS) */
|
|
11
|
+
strict?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Creates a SQL query string to create a new table or view in DuckDB
|
|
15
|
+
* @param name - Name of the table or view to create
|
|
16
|
+
* @param query - SQL query whose results will populate the table/view
|
|
17
|
+
* @param options - Options for table/view creation
|
|
18
|
+
* @param options.replace - Whether to replace existing table/view if it exists (default: false)
|
|
19
|
+
* @param options.temp - Whether to create a temporary table/view (default: false)
|
|
20
|
+
* @param options.view - Whether to create a view instead of a table (default: false)
|
|
21
|
+
* @returns SQL query string to create the table/view
|
|
22
|
+
*/
|
|
23
|
+
export declare function createTable(name: string, query: string, { replace, temp, view }?: TableOptions): string;
|
|
24
|
+
/**
|
|
25
|
+
* Creates a SQL query string to create a new schema in DuckDB
|
|
26
|
+
* @param name - Name of the schema to create
|
|
27
|
+
* @param options - Options for schema creation
|
|
28
|
+
* @param options.strict - Whether to enforce strict schema creation (no IF NOT EXISTS) (default: false)
|
|
29
|
+
* @returns SQL query string to create the schema
|
|
30
|
+
*/
|
|
31
|
+
export declare function createSchema(name: string, { strict }?: SchemaOptions): string;
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=create.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/load/create.ts"],"names":[],"mappings":"AAGA,UAAU,YAAY;IACpB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,+CAA+C;IAC/C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,kDAAkD;IAClD,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,UAAU,aAAa;IACrB,mEAAmE;IACnE,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,EAAC,OAAe,EAAE,IAAY,EAAE,IAAY,EAAC,GAAE,YAAiB,GAC/D,MAAM,CAWR;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,EAAC,MAAc,EAAC,GAAE,aAAkB,GACnC,MAAM,CAER"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Adapted from https://github.com/uwdata/mosaic/blob/main/packages/sql/src/load/
|
|
2
|
+
// BSD 3-Clause License Copyright (c) 2023, UW Interactive Data Lab
|
|
3
|
+
/**
|
|
4
|
+
* Creates a SQL query string to create a new table or view in DuckDB
|
|
5
|
+
* @param name - Name of the table or view to create
|
|
6
|
+
* @param query - SQL query whose results will populate the table/view
|
|
7
|
+
* @param options - Options for table/view creation
|
|
8
|
+
* @param options.replace - Whether to replace existing table/view if it exists (default: false)
|
|
9
|
+
* @param options.temp - Whether to create a temporary table/view (default: false)
|
|
10
|
+
* @param options.view - Whether to create a view instead of a table (default: false)
|
|
11
|
+
* @returns SQL query string to create the table/view
|
|
12
|
+
*/
|
|
13
|
+
export function createTable(name, query, { replace = false, temp = false, view = false } = {}) {
|
|
14
|
+
return ('CREATE' +
|
|
15
|
+
(replace ? ' OR REPLACE ' : ' ') +
|
|
16
|
+
(temp ? 'TEMP ' : '') +
|
|
17
|
+
(view ? 'VIEW' : 'TABLE') +
|
|
18
|
+
(replace ? ' ' : ' IF NOT EXISTS ') +
|
|
19
|
+
name +
|
|
20
|
+
' AS ' +
|
|
21
|
+
query);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Creates a SQL query string to create a new schema in DuckDB
|
|
25
|
+
* @param name - Name of the schema to create
|
|
26
|
+
* @param options - Options for schema creation
|
|
27
|
+
* @param options.strict - Whether to enforce strict schema creation (no IF NOT EXISTS) (default: false)
|
|
28
|
+
* @returns SQL query string to create the schema
|
|
29
|
+
*/
|
|
30
|
+
export function createSchema(name, { strict = false } = {}) {
|
|
31
|
+
return 'CREATE SCHEMA ' + (strict ? '' : 'IF NOT EXISTS ') + name;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=create.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/load/create.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,mEAAmE;AAgBnE;;;;;;;;;GASG;AACH,MAAM,UAAU,WAAW,CACzB,IAAY,EACZ,KAAa,EACb,EAAC,OAAO,GAAG,KAAK,EAAE,IAAI,GAAG,KAAK,EAAE,IAAI,GAAG,KAAK,KAAkB,EAAE;IAEhE,OAAO,CACL,QAAQ;QACR,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC;QAChC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACrB,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;QACzB,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,iBAAiB,CAAC;QACnC,IAAI;QACJ,MAAM;QACN,KAAK,CACN,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAC1B,IAAY,EACZ,EAAC,MAAM,GAAG,KAAK,KAAmB,EAAE;IAEpC,OAAO,gBAAgB,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC;AACpE,CAAC","sourcesContent":["// Adapted from https://github.com/uwdata/mosaic/blob/main/packages/sql/src/load/\n// BSD 3-Clause License Copyright (c) 2023, UW Interactive Data Lab\n\ninterface TableOptions {\n /** Whether to replace existing table/view if it exists */\n replace?: boolean;\n /** Whether to create a temporary table/view */\n temp?: boolean;\n /** Whether to create a view instead of a table */\n view?: boolean;\n}\n\ninterface SchemaOptions {\n /** Whether to enforce strict schema creation (no IF NOT EXISTS) */\n strict?: boolean;\n}\n\n/**\n * Creates a SQL query string to create a new table or view in DuckDB\n * @param name - Name of the table or view to create\n * @param query - SQL query whose results will populate the table/view\n * @param options - Options for table/view creation\n * @param options.replace - Whether to replace existing table/view if it exists (default: false)\n * @param options.temp - Whether to create a temporary table/view (default: false)\n * @param options.view - Whether to create a view instead of a table (default: false)\n * @returns SQL query string to create the table/view\n */\nexport function createTable(\n name: string,\n query: string,\n {replace = false, temp = false, view = false}: TableOptions = {},\n): string {\n return (\n 'CREATE' +\n (replace ? ' OR REPLACE ' : ' ') +\n (temp ? 'TEMP ' : '') +\n (view ? 'VIEW' : 'TABLE') +\n (replace ? ' ' : ' IF NOT EXISTS ') +\n name +\n ' AS ' +\n query\n );\n}\n\n/**\n * Creates a SQL query string to create a new schema in DuckDB\n * @param name - Name of the schema to create\n * @param options - Options for schema creation\n * @param options.strict - Whether to enforce strict schema creation (no IF NOT EXISTS) (default: false)\n * @returns SQL query string to create the schema\n */\nexport function createSchema(\n name: string,\n {strict = false}: SchemaOptions = {},\n): string {\n return 'CREATE SCHEMA ' + (strict ? '' : 'IF NOT EXISTS ') + name;\n}\n"]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { LoadFile, SpatialLoadOptions, StandardLoadOptions } from '@sqlrooms/room-config';
|
|
2
|
+
import { literalToSQL, sqlFrom } from './sql-from';
|
|
3
|
+
export { literalToSQL, sqlFrom };
|
|
4
|
+
/**
|
|
5
|
+
* Generic function to load data from a file into a DuckDB table
|
|
6
|
+
* @param method - The DuckDB read method to use (e.g., 'read_csv', 'read_json')
|
|
7
|
+
* @param tableName - Name of the table to create
|
|
8
|
+
* @param fileName - Path to the input file
|
|
9
|
+
* @param options - Load options including select, where, view, temp, replace and file-specific options
|
|
10
|
+
* @param defaults - Default options to merge with provided options
|
|
11
|
+
* @returns SQL query string to create the table
|
|
12
|
+
*/
|
|
13
|
+
export declare function load(method: LoadFile, tableName: string, fileName: string, options?: StandardLoadOptions, defaults?: Record<string, unknown>): string;
|
|
14
|
+
/**
|
|
15
|
+
* Load data from a CSV file into a DuckDB table
|
|
16
|
+
* @param tableName - Name of the table to create
|
|
17
|
+
* @param fileName - Path to the CSV file
|
|
18
|
+
* @param options - Load options
|
|
19
|
+
* @returns SQL query string to create the table
|
|
20
|
+
*/
|
|
21
|
+
export declare function loadCSV(tableName: string, fileName: string, options?: StandardLoadOptions): string;
|
|
22
|
+
/**
|
|
23
|
+
* Load data from a JSON file into a DuckDB table
|
|
24
|
+
* @param tableName - Name of the table to create
|
|
25
|
+
* @param fileName - Path to the JSON file
|
|
26
|
+
* @param options - Load options
|
|
27
|
+
* @returns SQL query string to create the table
|
|
28
|
+
*/
|
|
29
|
+
export declare function loadJSON(tableName: string, fileName: string, options?: StandardLoadOptions): string;
|
|
30
|
+
/**
|
|
31
|
+
* Load data from a Parquet file into a DuckDB table
|
|
32
|
+
* @param tableName - Name of the table to create
|
|
33
|
+
* @param fileName - Path to the Parquet file
|
|
34
|
+
* @param options - Load options
|
|
35
|
+
* @returns SQL query string to create the table
|
|
36
|
+
*/
|
|
37
|
+
export declare function loadParquet(tableName: string, fileName: string, options?: StandardLoadOptions): string;
|
|
38
|
+
/**
|
|
39
|
+
* Load geometry data within a spatial file format.
|
|
40
|
+
* This method requires that the DuckDB spatial extension is loaded.
|
|
41
|
+
* Supports GeoJSON, TopoJSON, and other common spatial formats.
|
|
42
|
+
* For TopoJSON, set the layer option to indicate the feature to extract.
|
|
43
|
+
* @param tableName - Name of the table to create
|
|
44
|
+
* @param fileName - Path to the spatial data file
|
|
45
|
+
* @param options - Load options including spatial-specific options
|
|
46
|
+
* @returns SQL query string to create the table
|
|
47
|
+
*/
|
|
48
|
+
export declare function loadSpatial(tableName: string, fileName: string, options?: SpatialLoadOptions): string;
|
|
49
|
+
/**
|
|
50
|
+
* Load JavaScript objects directly into a DuckDB table
|
|
51
|
+
* @param tableName - Name of the table to create
|
|
52
|
+
* @param data - Array of objects to load
|
|
53
|
+
* @param options - Load options
|
|
54
|
+
* @returns SQL query string to create the table
|
|
55
|
+
*/
|
|
56
|
+
export declare function loadObjects(tableName: string, data: Record<string, unknown>[], options?: StandardLoadOptions): string;
|
|
57
|
+
//# sourceMappingURL=load.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../src/load/load.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,QAAQ,EACR,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAC,YAAY,EAAE,OAAO,EAAC,MAAM,YAAY,CAAC;AAGjD,OAAO,EAAC,YAAY,EAAE,OAAO,EAAC,CAAC;AAE/B;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAClB,MAAM,EAAE,QAAQ,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,mBAAwB,EACjC,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACrC,MAAM,CA2BR;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CACrB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,MAAM,CAKR;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CACtB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,MAAM,CAKR;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,MAAM,CAER;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,kBAAuB,GAC/B,MAAM,CAsBR;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC/B,OAAO,GAAE,mBAAwB,GAChC,MAAM,CAQR"}
|