@sqlrooms/duckdb 0.29.0-rc.7 → 0.29.0-rc.8
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 +2 -1
- package/README.md +32 -2
- package/dist/DuckDbSlice.d.ts +11 -5
- package/dist/DuckDbSlice.d.ts.map +1 -1
- package/dist/DuckDbSlice.js +18 -11
- package/dist/DuckDbSlice.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/useDataTable.d.ts +14 -0
- package/dist/useDataTable.d.ts.map +1 -0
- package/dist/useDataTable.js +21 -0
- package/dist/useDataTable.js.map +1 -0
- package/package.json +7 -7
package/LICENSE.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright
|
|
3
|
+
Copyright 2024-2026 SQLRooms Contributors
|
|
4
|
+
Copyright Vis.gl contributors
|
|
4
5
|
|
|
5
6
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
7
|
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ A powerful wrapper around DuckDB-WASM that provides React hooks and utilities fo
|
|
|
4
4
|
|
|
5
5
|
### React Integration & Type Safety
|
|
6
6
|
|
|
7
|
-
- **React Hooks**: Seamless integration with React applications via `useSql`
|
|
7
|
+
- **React Hooks**: Seamless integration with React applications via `useSql` and `useDataTable`
|
|
8
8
|
- **Runtime Validation**: Optional Zod schema validation for query results with type transformations
|
|
9
9
|
- **Typed Row Accessors**: Type-safe row access with validation and multiple iteration methods
|
|
10
10
|
|
|
@@ -57,6 +57,28 @@ function UserList() {
|
|
|
57
57
|
|
|
58
58
|
For more information and examples on using the `useSql` hook, see the [useSql API documentation](/api/duckdb/functions/useSql).
|
|
59
59
|
|
|
60
|
+
### Looking up Table Metadata
|
|
61
|
+
|
|
62
|
+
Use `useDataTable()` in React components or `db.findTable()` from the room
|
|
63
|
+
store. String references are parsed like SQL identifiers, so use quotes for
|
|
64
|
+
literal dots in table names.
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
import {useDataTable} from '@sqlrooms/duckdb';
|
|
68
|
+
|
|
69
|
+
function TableColumns() {
|
|
70
|
+
const table = useDataTable('"memory"."main"."earthquakes"');
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<ul>
|
|
74
|
+
{table?.columns.map((column) => (
|
|
75
|
+
<li key={column.name}>{column.name}</li>
|
|
76
|
+
))}
|
|
77
|
+
</ul>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
60
82
|
### Using Zod for Runtime Validation
|
|
61
83
|
|
|
62
84
|
```tsx
|
|
@@ -207,7 +229,11 @@ function DatabaseManager() {
|
|
|
207
229
|
### Working with Qualified Table Names
|
|
208
230
|
|
|
209
231
|
```tsx
|
|
210
|
-
import {
|
|
232
|
+
import {
|
|
233
|
+
makeQualifiedTableName,
|
|
234
|
+
quoteTableReference,
|
|
235
|
+
resolveTableReference,
|
|
236
|
+
} from '@sqlrooms/duckdb';
|
|
211
237
|
import {useRoomStore} from './store';
|
|
212
238
|
import {Button} from '@sqlrooms/ui';
|
|
213
239
|
|
|
@@ -225,8 +251,12 @@ function QualifiedTableOps() {
|
|
|
225
251
|
schema: 'public',
|
|
226
252
|
table: 'users',
|
|
227
253
|
});
|
|
254
|
+
const tableSql = quoteTableReference(qualifiedTable.toString());
|
|
255
|
+
const resolved = resolveTableReference([{table: qualifiedTable}], 'users');
|
|
228
256
|
|
|
229
257
|
await createTableFromQuery(qualifiedTable, 'SELECT * FROM source_table');
|
|
258
|
+
console.log('Quoted table reference:', tableSql);
|
|
259
|
+
console.log('Resolved table:', resolved.table?.table.toString());
|
|
230
260
|
const tableExists = await checkTableExists(qualifiedTable);
|
|
231
261
|
console.log('Table exists after create:', tableExists);
|
|
232
262
|
await dropTable(qualifiedTable);
|
package/dist/DuckDbSlice.d.ts
CHANGED
|
@@ -84,7 +84,7 @@ export type DuckDbSliceState = {
|
|
|
84
84
|
*/
|
|
85
85
|
loadTableSchemas(filter?: LoadTableSchemasFilter): Promise<DataTable[]>;
|
|
86
86
|
/**
|
|
87
|
-
* @deprecated Use
|
|
87
|
+
* @deprecated Use findTable instead
|
|
88
88
|
*/
|
|
89
89
|
getTable(tableName: string): DataTable | undefined;
|
|
90
90
|
/**
|
|
@@ -92,12 +92,18 @@ export type DuckDbSliceState = {
|
|
|
92
92
|
*/
|
|
93
93
|
setTableRowCount(tableName: string | QualifiedTableName, rowCount: number): void;
|
|
94
94
|
/**
|
|
95
|
-
* Find a table by
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
95
|
+
* Find a table by reference in the last refreshed table schemas.
|
|
96
|
+
* String references are parsed as SQL identifiers, so dots separate
|
|
97
|
+
* database/schema/table segments unless quoted. If no schema or database is
|
|
98
|
+
* provided, the table is resolved in the current schema and database from
|
|
99
|
+
* the last schema refresh.
|
|
100
|
+
* @param tableName - The table reference to find.
|
|
99
101
|
* @returns The table or undefined if not found.
|
|
100
102
|
*/
|
|
103
|
+
findTable(tableName: string | QualifiedTableName): DataTable | undefined;
|
|
104
|
+
/**
|
|
105
|
+
* @deprecated Use findTable instead
|
|
106
|
+
*/
|
|
101
107
|
findTableByName(tableName: string | QualifiedTableName): DataTable | undefined;
|
|
102
108
|
/**
|
|
103
109
|
* Refresh table schemas from the database.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DuckDbSlice.d.ts","sourceRoot":"","sources":["../src/DuckDbSlice.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,SAAS,EACT,YAAY,EACZ,eAAe,
|
|
1
|
+
{"version":3,"file":"DuckDbSlice.d.ts","sourceRoot":"","sources":["../src/DuckDbSlice.ts"],"names":[],"mappings":"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"}
|
package/dist/DuckDbSlice.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createDbSchemaTrees, escapeVal, getColValAsNumber, isQualifiedTableName, joinStatements, makeQualifiedTableName, separateLastStatement, } from '@sqlrooms/duckdb-core';
|
|
1
|
+
import { createDbSchemaTrees, escapeVal, getColValAsNumber, isQualifiedTableName, joinStatements, makeQualifiedTableName, parseQualifiedSqlIdentifier, separateLastStatement, } from '@sqlrooms/duckdb-core';
|
|
2
2
|
import { createSlice, registerCommandsForOwner, unregisterCommandsForOwner, useBaseRoomStore, } from '@sqlrooms/room-store';
|
|
3
3
|
import * as arrow from 'apache-arrow';
|
|
4
4
|
import deepEquals from 'fast-deep-equal';
|
|
@@ -269,7 +269,7 @@ export function createDuckDbSlice({ connector = createWasmDuckDbConnector(), loa
|
|
|
269
269
|
const qualifiedTable = isQualifiedTableName(tableName)
|
|
270
270
|
? tableName
|
|
271
271
|
: makeQualifiedTableName({ table: tableName });
|
|
272
|
-
const table = get().db.
|
|
272
|
+
const table = get().db.findTable(qualifiedTable) ??
|
|
273
273
|
(await loadTableSchemaByName(qualifiedTable));
|
|
274
274
|
const isView = table?.isView;
|
|
275
275
|
if (isView) {
|
|
@@ -285,7 +285,7 @@ export function createDuckDbSlice({ connector = createWasmDuckDbConnector(), loa
|
|
|
285
285
|
const qualifiedTable = isQualifiedTableName(tableName)
|
|
286
286
|
? tableName
|
|
287
287
|
: makeQualifiedTableName({ table: tableName });
|
|
288
|
-
const table = get().db.
|
|
288
|
+
const table = get().db.findTable(qualifiedTable) ??
|
|
289
289
|
(await loadTableSchemaByName(qualifiedTable));
|
|
290
290
|
if (table?.isView) {
|
|
291
291
|
throw new Error(`"${qualifiedTable}" is a view. Use dropRelation() to remove views.`);
|
|
@@ -326,19 +326,26 @@ export function createDuckDbSlice({ connector = createWasmDuckDbConnector(), loa
|
|
|
326
326
|
}));
|
|
327
327
|
},
|
|
328
328
|
getTable(tableName) {
|
|
329
|
-
return get().db.
|
|
329
|
+
return get().db.findTable(tableName);
|
|
330
330
|
},
|
|
331
|
-
|
|
331
|
+
findTable(tableName) {
|
|
332
|
+
const { currentSchema, currentDatabase, tables } = get().db;
|
|
333
|
+
const findMatchingTable = ({ table, schema, database, }) => table
|
|
334
|
+
? tables.find((t) => t.table.table === table &&
|
|
335
|
+
(!schema || t.table.schema === schema) &&
|
|
336
|
+
(!database || t.table.database === database))
|
|
337
|
+
: undefined;
|
|
332
338
|
const { table, schema, database } = {
|
|
333
|
-
schema:
|
|
334
|
-
database:
|
|
339
|
+
schema: currentSchema,
|
|
340
|
+
database: currentDatabase,
|
|
335
341
|
...(typeof tableName === 'string'
|
|
336
|
-
?
|
|
342
|
+
? (parseQualifiedSqlIdentifier(tableName) ?? {})
|
|
337
343
|
: tableName),
|
|
338
344
|
};
|
|
339
|
-
return
|
|
340
|
-
|
|
341
|
-
|
|
345
|
+
return findMatchingTable({ table, schema, database });
|
|
346
|
+
},
|
|
347
|
+
findTableByName(tableName) {
|
|
348
|
+
return get().db.findTable(tableName);
|
|
342
349
|
},
|
|
343
350
|
async refreshTableSchemas() {
|
|
344
351
|
if (refreshPromise) {
|
package/dist/DuckDbSlice.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DuckDbSlice.js","sourceRoot":"","sources":["../src/DuckDbSlice.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createDbSchemaTrees,\n DataTable,\n DbSchemaNode,\n DuckDbConnector,\n escapeVal,\n getColValAsNumber,\n isQualifiedTableName,\n joinStatements,\n makeQualifiedTableName,\n QualifiedTableName,\n QueryHandle,\n SchemaWithTables,\n separateLastStatement,\n} from '@sqlrooms/duckdb-core';\nimport {\n BaseRoomStoreState,\n createSlice,\n registerCommandsForOwner,\n RoomCommand,\n unregisterCommandsForOwner,\n useBaseRoomStore,\n} from '@sqlrooms/room-store';\nimport * as arrow from 'apache-arrow';\nimport deepEquals from 'fast-deep-equal';\nimport {produce} from 'immer';\nimport {z} from 'zod';\nimport {StateCreator} from 'zustand';\nimport {createWasmDuckDbConnector} from './connectors/createDuckDbConnector';\nimport {\n loadSchemaCatalog,\n LoadSchemaCatalogFilterFunction,\n loadTableSchemas,\n LoadTableSchemasFilter,\n LoadTableSchemasFilterFunction,\n} from './loadTableSchemas';\n\nconst DUCKDB_COMMAND_OWNER = '@sqlrooms/duckdb';\nconst INTERNAL_SQLROOMS_PREFIX = '__sqlrooms';\n\n/** DuckDB's temporary database catalog; never show in the default data source tree. */\nconst DUCKDB_TEMP_DATABASE = 'temp';\n\n/**\n * Default predicate: which tables/schemas/databases appear in the data source panel.\n * Hides `__sqlrooms_*` names and DuckDB's `temp` database.\n */\nexport const defaultLoadTableSchemasFilter: LoadTableSchemasFilterFunction = (\n table: QualifiedTableName,\n): boolean => {\n if (\n table.table?.startsWith(INTERNAL_SQLROOMS_PREFIX) ||\n table.database?.startsWith(INTERNAL_SQLROOMS_PREFIX) ||\n table.schema?.startsWith(INTERNAL_SQLROOMS_PREFIX)\n ) {\n return false;\n }\n if (table.database === DUCKDB_TEMP_DATABASE) {\n return false;\n }\n return true;\n};\n\n/**\n * Factory returning {@link defaultLoadTableSchemasFilter}.\n * Hides `__sqlrooms_*` names and DuckDB's `temp` database.\n * Apps can pass {@link CreateDuckDbSliceProps.loadTableSchemasFilter} to add more rules.\n */\nexport function createDefaultLoadTableSchemasFilter(): LoadTableSchemasFilterFunction {\n return defaultLoadTableSchemasFilter;\n}\n\n/**\n * Default catalog visibility predicate for the data source panel.\n * Hides SQLRooms internal objects and DuckDB's temporary database catalog.\n */\nexport const defaultLoadSchemaCatalogFilter: LoadSchemaCatalogFilterFunction = (\n entry,\n): boolean => {\n switch (entry.type) {\n case 'database':\n return (\n !entry.database.startsWith(INTERNAL_SQLROOMS_PREFIX) &&\n entry.database !== DUCKDB_TEMP_DATABASE\n );\n case 'schema':\n return (\n !entry.database.startsWith(INTERNAL_SQLROOMS_PREFIX) &&\n entry.database !== DUCKDB_TEMP_DATABASE &&\n !entry.schema.startsWith(INTERNAL_SQLROOMS_PREFIX)\n );\n case 'table':\n return defaultLoadTableSchemasFilter(entry.table);\n }\n};\n\nconst DropTableCommandInput = z.object({\n tableName: z.string().describe('Name of the table to drop.'),\n});\ntype DropTableCommandInput = z.infer<typeof DropTableCommandInput>;\n\nconst CreateTableFromQueryCommandInput = z.object({\n tableName: z.string().describe('Name of the table or view to create.'),\n query: z.string().describe('SQL query used to populate the table/view.'),\n replace: z\n .boolean()\n .optional()\n .default(true)\n .describe('Whether to replace existing table/view with the same name.'),\n view: z\n .boolean()\n .optional()\n .default(false)\n .describe('Whether to create a view instead of a table.'),\n temp: z\n .boolean()\n .optional()\n .default(false)\n .describe('Whether to create a temporary object.'),\n allowMultipleStatements: z\n .boolean()\n .optional()\n .default(false)\n .describe('Allow multiple SQL statements where the final one is SELECT.'),\n});\n\ntype CreateTableFromQueryCommandInput = z.infer<\n typeof CreateTableFromQueryCommandInput\n>;\n\n/**\n * State and actions for the DuckDB slice\n */\nexport type DuckDbSliceState = {\n db: {\n /**\n * The DuckDB connector instance\n */\n connector: DuckDbConnector;\n /**\n * @deprecated We shouldn't limit the schema to a single one.\n */\n schema: string;\n\n currentSchema: string | undefined;\n currentDatabase: string | undefined;\n\n /**\n * Cache of refreshed table schemas\n */\n tables: DataTable[];\n /**\n * Cache of row counts for tables\n */\n tableRowCounts: {[tableName: string]: number};\n /**\n * Cache of schema trees for tables\n */\n schemaTrees?: DbSchemaNode[];\n /**\n * Cache of currently running query handles.\n * This is only used for running queries to deduplicate them (especially for useSql),\n * the cache is cleared when the query is completed.\n */\n queryCache: {[key: string]: QueryHandle};\n /**\n * Whether the table schemas are being refreshed\n */\n isRefreshingTableSchemas: boolean;\n\n /**\n * Set a new DuckDB connector\n */\n setConnector: (connector: DuckDbConnector) => void;\n\n /**\n * Initialize the connector (creates a WasmDuckDbConnector if none exists)\n */\n initialize: () => Promise<void>;\n\n /**\n * Close and clean up the connector\n */\n destroy: () => Promise<void>;\n\n /**\n * Add a table to the room.\n * @param tableName - The name of the table to add.\n * @param data - The data to add to the table: an arrow table or an array of records.\n * @returns A promise that resolves to the table that was added.\n */\n addTable(\n tableName: string | QualifiedTableName,\n data: arrow.Table | Record<string, unknown>[],\n ): Promise<DataTable>;\n\n /**\n * Load the schemas of the tables in the database.\n */\n loadTableSchemas(filter?: LoadTableSchemasFilter): Promise<DataTable[]>;\n\n /**\n * @deprecated Use findTableByName instead\n */\n getTable(tableName: string): DataTable | undefined;\n\n /**\n * @internal Avoid using this directly, it's for internal use.\n */\n setTableRowCount(\n tableName: string | QualifiedTableName,\n rowCount: number,\n ): void;\n\n /**\n * Find a table by name in the last refreshed table schemas.\n * If no schema or database is provided, the table will be found in the current schema\n * and database (from last table schemas refresh).\n * @param tableName - The name of the table to find or a qualified table name.\n * @returns The table or undefined if not found.\n */\n findTableByName(\n tableName: string | QualifiedTableName,\n ): DataTable | undefined;\n\n /**\n * Refresh table schemas from the database.\n * @returns A promise that resolves to the updated tables.\n */\n refreshTableSchemas(): Promise<DataTable[]>;\n /**\n * Get the connector. If it's not initialized, it will be initialized.\n */\n getConnector: () => Promise<DuckDbConnector>;\n\n /**\n * @deprecated Use .loadTableRowCount() instead\n */\n getTableRowCount: (table: string, schema?: string) => Promise<number>;\n\n /**\n * Load the row count of a table\n */\n loadTableRowCount: (\n tableName: string | QualifiedTableName,\n ) => Promise<number>;\n\n /**\n * Execute a query with query handle (not result) caching and deduplication\n * @param query - The SQL query to execute\n * @returns The QueryHandle for the query or null if disabled\n */\n executeSql: (\n query: string,\n version?: number,\n ) => Promise<QueryHandle | null>;\n\n /**\n * @deprecated Use .tables or .loadTableSchemas() instead\n */\n getTables: (schema?: string) => Promise<string[]>;\n\n /**\n * @deprecated Use .loadTableSchemas() instead\n */\n getTableSchema: (\n tableName: string,\n schema?: string,\n ) => Promise<DataTable | undefined>;\n\n /**\n * @deprecated Use .tables or .loadTableSchemas() instead\n */\n getTableSchemas: (schema?: string) => Promise<DataTable[]>;\n\n /**\n * Check if a table exists\n */\n checkTableExists: (\n tableName: string | QualifiedTableName,\n ) => Promise<boolean>;\n\n /**\n * Delete a table or view with optional schema and database.\n * @param tableName - The name of the relation to delete (qualified or plain)\n */\n dropRelation: (tableName: string | QualifiedTableName) => Promise<void>;\n\n /**\n * Delete a table with optional schema and database.\n * @param tableName - The name of the table to delete (qualified or plain)\n */\n dropTable: (tableName: string | QualifiedTableName) => Promise<void>;\n\n /**\n * Create a table or view from a query.\n * @param tableName - The name of the table/view to create.\n * @param query - The query to create the table/view from.\n * @param options - Creation options.\n * @returns The table/view name and rowCount (undefined for views).\n */\n createTableFromQuery: (\n tableName: string | QualifiedTableName,\n query: string,\n options?: {\n replace?: boolean;\n temp?: boolean;\n view?: boolean;\n allowMultipleStatements?: boolean;\n abortSignal?: AbortSignal;\n },\n ) => Promise<{\n tableName: string | QualifiedTableName;\n rowCount: number | undefined;\n }>;\n\n /**\n * Parse a SQL SELECT statement to JSON\n * @param sql - The SQL SELECT statement to parse.\n * @returns A promise that resolves to the parsed JSON.\n */\n sqlSelectToJson: (sql: string) => Promise<\n | {\n error: true;\n error_type: string;\n error_message: string;\n error_subtype: string;\n position: string;\n }\n | {\n error: false;\n statements: {\n node: {\n from_table: {\n alias: string;\n show_type: string;\n table_name: string;\n };\n select_list: Record<string, unknown>[];\n type: string;\n };\n }[];\n }\n >;\n };\n};\n\nexport type CreateDuckDbSliceProps = {\n connector?: DuckDbConnector;\n /**\n * Optional table visibility filter.\n * Defaults to {@link createDefaultLoadTableSchemasFilter}.\n */\n loadTableSchemasFilter?: LoadTableSchemasFilterFunction | null;\n /**\n * Optional catalog visibility filter for the data source panel.\n * Defaults to {@link defaultLoadSchemaCatalogFilter}. When omitted, custom\n * table filters still apply to table entries while schemas/databases use the default.\n */\n loadSchemaCatalogFilter?: LoadSchemaCatalogFilterFunction | null;\n};\n\n/**\n * Create a DuckDB slice for managing the connector\n */\nexport function createDuckDbSlice({\n connector = createWasmDuckDbConnector(),\n loadTableSchemasFilter = defaultLoadTableSchemasFilter,\n loadSchemaCatalogFilter,\n}: CreateDuckDbSliceProps = {}): StateCreator<DuckDbSliceState> {\n let refreshPromise: Promise<DataTable[]> | null = null;\n let pendingSchemaRefresh = false;\n const effectiveSchemaCatalogFilter =\n loadSchemaCatalogFilter ??\n (loadTableSchemasFilter === null\n ? null\n : (((entry) => {\n if (entry.type === 'table') {\n return loadTableSchemasFilter\n ? loadTableSchemasFilter(entry.table)\n : true;\n }\n return defaultLoadSchemaCatalogFilter(entry);\n }) satisfies LoadSchemaCatalogFilterFunction));\n return createSlice<DuckDbSliceState, BaseRoomStoreState & DuckDbSliceState>(\n (set, get, store) => {\n /**\n * Internal helper to load a table schema by exact name, bypassing the visibility filter.\n * Used when performing exact lookups (e.g., checking if a specific table exists).\n */\n const loadTableSchemaByName = async (\n tableName: string | QualifiedTableName,\n ): Promise<DataTable | undefined> => {\n const qualifiedName = isQualifiedTableName(tableName)\n ? tableName\n : makeQualifiedTableName({table: tableName});\n const connector = await get().db.getConnector();\n const [table] = await loadTableSchemas(connector, qualifiedName);\n return table;\n };\n\n return {\n db: {\n connector, // Will be initialized during init\n schema: 'main', // TODO: remove schema, we should not limit the schema to a single one.\n currentSchema: undefined,\n currentDatabase: undefined,\n isRefreshingTableSchemas: false,\n tables: [],\n tableRowCounts: {},\n schemaTrees: undefined,\n queryCache: {},\n\n setConnector: (connector: DuckDbConnector) => {\n set(\n produce((state) => {\n state.config.dataSources = [];\n state.db.connector = connector;\n }),\n );\n },\n\n initialize: async () => {\n await get().db.connector.initialize();\n // No await here, we want to continue initializing the room even\n // if the table schemas are not refreshed yet\n get().db.refreshTableSchemas();\n registerCommandsForOwner(\n store,\n DUCKDB_COMMAND_OWNER,\n createDuckDbCommands(),\n );\n },\n\n getConnector: async () => {\n await get().db.connector.initialize();\n return get().db.connector;\n },\n\n destroy: async () => {\n unregisterCommandsForOwner(store, DUCKDB_COMMAND_OWNER);\n // Wait for any in-flight refreshTableSchemas() to finish before\n // destroying the connector. initialize() fires it without await,\n // so it may still be querying the native DuckDB instance; tearing\n // that down mid-flight causes a use-after-free segfault.\n if (refreshPromise) {\n try {\n await refreshPromise;\n } catch {\n // ignore – we're shutting down\n }\n }\n try {\n if (get().db.connector) {\n await get().db.connector.destroy();\n }\n } catch (err) {\n console.error('Error during DuckDB shutdown:', err);\n }\n },\n\n /**\n * Creates a table or view from a SQL query.\n * @param tableName - Name of the table/view to create\n * @param query - SQL query (must be a SELECT statement, or multiple statements ending with a SELECT when allowMultipleStatements is true)\n * @param options - Creation options\n * @param options.replace - If true, uses CREATE OR REPLACE (default: true)\n * @param options.temp - If true, creates a temporary table/view (default: false)\n * @param options.view - If true, creates a view instead of a table (default: false)\n * @param options.allowMultipleStatements - If true, allows multiple statements where preceding statements are executed first and the final SELECT is wrapped in CREATE TABLE/VIEW (default: false)\n * @returns Object with tableName and rowCount (rowCount is undefined for views)\n */\n async createTableFromQuery(\n tableName: string | QualifiedTableName,\n query: string,\n options?: {\n replace?: boolean;\n temp?: boolean;\n view?: boolean;\n allowMultipleStatements?: boolean;\n abortSignal?: AbortSignal;\n },\n ) {\n const {\n replace = true,\n temp = false,\n view = false,\n allowMultipleStatements = false,\n abortSignal,\n } = options || {};\n\n // For temp tables/views, DuckDB requires the \"temp\" database\n const baseQualifiedName = isQualifiedTableName(tableName)\n ? tableName\n : makeQualifiedTableName({table: tableName});\n\n const qualifiedName = temp\n ? makeQualifiedTableName({\n table: baseQualifiedName.table,\n schema: baseQualifiedName.schema,\n database: 'temp',\n })\n : baseQualifiedName;\n\n const connector = await get().db.getConnector();\n\n const {precedingStatements, lastStatement} =\n separateLastStatement(query);\n\n if (!allowMultipleStatements && precedingStatements.length > 0) {\n throw new Error(\n 'Query must contain exactly one statement (set allowMultipleStatements: true to execute multiple statements)',\n );\n }\n\n // The last statement must be a SELECT\n const parsedQuery = await get().db.sqlSelectToJson(lastStatement);\n if (parsedQuery.error) {\n throw new Error(\n 'Final statement must be a valid SELECT statement',\n );\n }\n\n // Build CREATE statement with options\n const createKeyword = [\n 'CREATE',\n replace ? 'OR REPLACE' : '',\n temp ? 'TEMP' : '',\n view ? 'VIEW' : 'TABLE',\n ]\n .filter(Boolean)\n .join(' ');\n\n const createStatement = `${createKeyword} ${qualifiedName} AS (\n ${lastStatement}\n )`;\n\n const fullQuery = joinStatements(\n precedingStatements,\n createStatement,\n );\n const result = await connector.query(fullQuery, {\n signal: abortSignal,\n });\n // Views don't have a row count, only tables do\n const rowCount = view ? undefined : getColValAsNumber(result);\n return {tableName, rowCount};\n },\n\n /**\n * @deprecated Use .tables or .loadTableSchemas() instead\n */\n async getTables(schema) {\n const tableSchemas = await get().db.loadTableSchemas({schema});\n return tableSchemas.map((t) => t.table.table);\n },\n\n /**\n * @deprecated Use .loadTableSchemas() instead\n */\n async getTableSchema(tableName: string, schema = 'main') {\n const newLocal = await get().db.loadTableSchemas({\n schema,\n table: tableName,\n });\n return newLocal[0];\n },\n\n /**\n * @deprecated Use .loadTableRowCount() instead\n */\n async getTableRowCount(table, schema = 'main') {\n return get().db.loadTableRowCount({table, schema});\n },\n\n async loadTableRowCount(tableName: string | QualifiedTableName) {\n const {schema, database, table} =\n typeof tableName === 'string'\n ? {table: tableName}\n : tableName || {};\n const connector = await get().db.getConnector();\n const result = await connector.query(\n `SELECT COUNT(*) FROM ${makeQualifiedTableName({\n schema,\n database,\n table,\n })}`,\n );\n return getColValAsNumber(result);\n },\n\n /**\n * @deprecated Use .loadTableSchemas() instead\n */\n async getTableSchemas(schema) {\n return await get().db.loadTableSchemas({schema});\n },\n\n async loadTableSchemas(\n filter?: LoadTableSchemasFilter,\n ): Promise<DataTable[]> {\n const connector = await get().db.getConnector();\n return loadTableSchemas(connector, {\n ...filter,\n filterFunction: loadTableSchemasFilter,\n });\n },\n\n async checkTableExists(tableName: string | QualifiedTableName) {\n const table = await loadTableSchemaByName(tableName);\n return Boolean(table);\n },\n\n async dropRelation(tableName): Promise<void> {\n const connector = await get().db.getConnector();\n const qualifiedTable = isQualifiedTableName(tableName)\n ? tableName\n : makeQualifiedTableName({table: tableName});\n const table =\n get().db.findTableByName(qualifiedTable) ??\n (await loadTableSchemaByName(qualifiedTable));\n const isView = table?.isView;\n if (isView) {\n await connector.query(`DROP VIEW IF EXISTS ${qualifiedTable};`);\n } else {\n await connector.query(`DROP TABLE IF EXISTS ${qualifiedTable};`);\n }\n get().db.refreshTableSchemas();\n },\n\n async dropTable(tableName): Promise<void> {\n const connector = await get().db.getConnector();\n const qualifiedTable = isQualifiedTableName(tableName)\n ? tableName\n : makeQualifiedTableName({table: tableName});\n const table =\n get().db.findTableByName(qualifiedTable) ??\n (await loadTableSchemaByName(qualifiedTable));\n\n if (table?.isView) {\n throw new Error(\n `\"${qualifiedTable}\" is a view. Use dropRelation() to remove views.`,\n );\n }\n\n await connector.query(`DROP TABLE IF EXISTS ${qualifiedTable};`);\n get().db.refreshTableSchemas();\n },\n\n async addTable(tableName, data) {\n const qualifiedName = isQualifiedTableName(tableName)\n ? tableName\n : makeQualifiedTableName({table: tableName});\n\n const {db} = get();\n if (data instanceof arrow.Table) {\n // TODO: make sure the table is replaced\n await db.connector.loadArrow(data, qualifiedName.toString());\n } else {\n await db.connector.loadObjects(data, qualifiedName.toString(), {\n replace: true,\n });\n }\n const newTable = await loadTableSchemaByName(qualifiedName);\n if (!newTable) {\n throw new Error('Failed to add table');\n }\n set((state) =>\n produce(state, (draft) => {\n draft.db.tables.push(newTable);\n }),\n );\n get().db.refreshTableSchemas();\n return newTable;\n },\n\n async setTableRowCount(tableName, rowCount) {\n const qualifiedName = isQualifiedTableName(tableName)\n ? tableName\n : makeQualifiedTableName({table: tableName});\n set((state) =>\n produce(state, (draft) => {\n draft.db.tableRowCounts[qualifiedName.toString()] = rowCount;\n }),\n );\n },\n\n getTable(tableName) {\n return get().db.findTableByName(tableName);\n },\n\n findTableByName(tableName: string | QualifiedTableName) {\n const {table, schema, database} = {\n schema: get().db.currentSchema,\n database: get().db.currentDatabase,\n ...(typeof tableName === 'string'\n ? {table: tableName}\n : tableName),\n };\n return get().db.tables.find(\n (t) =>\n t.table.table === table &&\n (!schema || t.table.schema === schema) &&\n (!database || t.table.database === database),\n );\n },\n\n async refreshTableSchemas(): Promise<DataTable[]> {\n if (refreshPromise) {\n pendingSchemaRefresh = true;\n return refreshPromise;\n }\n set((state) =>\n produce(state, (draft) => {\n draft.db.isRefreshingTableSchemas = true;\n }),\n );\n refreshPromise = (async () => {\n try {\n let schemasWithTables: SchemaWithTables[] = [];\n do {\n pendingSchemaRefresh = false;\n const connector = await get().db.getConnector();\n const result = await connector.query(\n `SELECT current_schema() AS schema, current_database() AS database`,\n );\n set((state) =>\n produce(state, (draft) => {\n draft.db.currentSchema = result\n .getChild('schema')\n ?.get(0);\n draft.db.currentDatabase = result\n .getChild('database')\n ?.get(0);\n }),\n );\n schemasWithTables = await loadSchemaCatalog(connector, {\n filterFunction: effectiveSchemaCatalogFilter,\n });\n } while (pendingSchemaRefresh);\n\n const newTables = schemasWithTables.flatMap((s) => s.tables);\n const currentTables = get().db.tables;\n const currentSchemaTrees = get().db.schemaTrees;\n const newSchemaTrees = createDbSchemaTrees(schemasWithTables);\n\n if (\n !deepEquals(newTables, currentTables) ||\n !deepEquals(newSchemaTrees, currentSchemaTrees)\n ) {\n set((state) =>\n produce(state, (draft) => {\n draft.db.tables = newTables;\n draft.db.schemaTrees = newSchemaTrees;\n }),\n );\n }\n return newTables;\n } catch (err) {\n get().room.captureException(err);\n return [];\n } finally {\n refreshPromise = null;\n set((state) =>\n produce(state, (draft) => {\n draft.db.isRefreshingTableSchemas = false;\n }),\n );\n }\n })();\n return refreshPromise;\n },\n\n async sqlSelectToJson(sql: string) {\n const connector = await get().db.getConnector();\n const parsedQuery = (\n await connector.query(\n `SELECT json_serialize_sql(${escapeVal(sql)})`,\n )\n )\n .getChildAt(0)\n ?.get(0);\n return JSON.parse(parsedQuery);\n },\n\n async executeSql(query: string): Promise<QueryHandle | null> {\n // Create a unique key for this query\n const queryKey = `${query}`;\n const connector = await get().db.getConnector();\n\n // Check if we already have a cached query for this key\n const existingQuery = get().db.queryCache[queryKey];\n if (existingQuery) {\n return existingQuery;\n }\n\n const queryHandle = connector.query(query);\n // Cache the query handle immediately\n set((state) =>\n produce(state, (draft) => {\n draft.db.queryCache[queryKey] = queryHandle;\n }),\n );\n\n queryHandle.result.finally(() => {\n // remove from cache after completion\n set((state) =>\n produce(state, (draft) => {\n delete draft.db.queryCache[queryKey];\n }),\n );\n });\n\n return queryHandle;\n },\n },\n };\n },\n );\n}\n\ntype DuckDbCommandStoreState = BaseRoomStoreState & DuckDbSliceState;\n\nfunction createDuckDbCommands(): RoomCommand<DuckDbCommandStoreState>[] {\n return [\n {\n id: 'db.refresh-table-schemas',\n name: 'Refresh table schemas',\n description: 'Reload table and schema metadata from DuckDB',\n group: 'Database',\n keywords: ['duckdb', 'database', 'refresh', 'tables', 'schemas'],\n metadata: {\n readOnly: true,\n idempotent: true,\n riskLevel: 'low',\n },\n isEnabled: ({getState}) => !getState().db.isRefreshingTableSchemas,\n execute: async ({getState}) => {\n await getState().db.refreshTableSchemas();\n return {\n success: true,\n commandId: 'db.refresh-table-schemas',\n message: 'Table schemas refreshed.',\n };\n },\n },\n {\n id: 'db.drop-table',\n name: 'Drop relation',\n description: 'Drop a table or view from DuckDB by name',\n group: 'Database',\n keywords: [\n 'duckdb',\n 'database',\n 'drop',\n 'table',\n 'view',\n 'relation',\n 'delete',\n ],\n inputSchema: DropTableCommandInput,\n inputDescription: 'Provide a tableName to remove from DuckDB.',\n metadata: {\n readOnly: false,\n idempotent: true,\n riskLevel: 'high',\n requiresConfirmation: true,\n },\n validateInput: async (input, {getState}) => {\n const {tableName} = input as DropTableCommandInput;\n const exists = await getState().db.checkTableExists(tableName);\n if (!exists) {\n throw new Error(`Table \"${tableName}\" does not exist.`);\n }\n },\n execute: async ({getState}, input) => {\n const {tableName} = input as DropTableCommandInput;\n await getState().db.dropRelation(tableName);\n return {\n success: true,\n commandId: 'db.drop-table',\n message: `Dropped relation \"${tableName}\".`,\n };\n },\n },\n {\n id: 'db.create-table-from-query',\n name: 'Create table from query',\n description: 'Create a table or view from a SQL query',\n group: 'Database',\n keywords: ['duckdb', 'database', 'create', 'table', 'view', 'query'],\n inputSchema: CreateTableFromQueryCommandInput,\n inputDescription:\n 'Provide tableName and query, with optional replace/view/temp flags.',\n metadata: {\n readOnly: false,\n idempotent: false,\n riskLevel: 'medium',\n },\n validateInput: (input) => {\n const {query} = input as CreateTableFromQueryCommandInput;\n if (!query.trim()) {\n throw new Error('Query cannot be empty.');\n }\n },\n execute: async ({getState}, input) => {\n const {tableName, query, replace, view, temp, allowMultipleStatements} =\n input as CreateTableFromQueryCommandInput;\n const result = await getState().db.createTableFromQuery(\n tableName,\n query,\n {\n replace,\n view,\n temp,\n allowMultipleStatements,\n },\n );\n await getState().db.refreshTableSchemas();\n return {\n success: true,\n commandId: 'db.create-table-from-query',\n message: `Created ${view ? 'view' : 'table'} \"${tableName}\".`,\n data: result,\n };\n },\n },\n ];\n}\n\n/**\n * @internal\n * Select values from the room store that includes the DuckDB slice.\n *\n * This is a typed wrapper around `useBaseRoomStore` that narrows the\n * state to `RoomStateWithDuckDb` so selectors can access `db` safely.\n *\n * @typeParam T - The selected slice of state returned by the selector\n * @param selector - Function that selects a value from the store state\n * @returns The selected value of type `T`\n */\nexport function useStoreWithDuckDb<T>(\n selector: (state: BaseRoomStoreState & DuckDbSliceState) => T,\n): T {\n return useBaseRoomStore<DuckDbSliceState, T>((state) => selector(state));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"DuckDbSlice.js","sourceRoot":"","sources":["../src/DuckDbSlice.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createDbSchemaTrees,\n DataTable,\n DbSchemaNode,\n DuckDbConnector,\n escapeVal,\n getColValAsNumber,\n isQualifiedTableName,\n joinStatements,\n makeQualifiedTableName,\n parseQualifiedSqlIdentifier,\n QualifiedTableName,\n QueryHandle,\n SchemaWithTables,\n separateLastStatement,\n} from '@sqlrooms/duckdb-core';\nimport {\n BaseRoomStoreState,\n createSlice,\n registerCommandsForOwner,\n RoomCommand,\n unregisterCommandsForOwner,\n useBaseRoomStore,\n} from '@sqlrooms/room-store';\nimport * as arrow from 'apache-arrow';\nimport deepEquals from 'fast-deep-equal';\nimport {produce} from 'immer';\nimport {z} from 'zod';\nimport {StateCreator} from 'zustand';\nimport {createWasmDuckDbConnector} from './connectors/createDuckDbConnector';\nimport {\n loadSchemaCatalog,\n LoadSchemaCatalogFilterFunction,\n loadTableSchemas,\n LoadTableSchemasFilter,\n LoadTableSchemasFilterFunction,\n} from './loadTableSchemas';\n\nconst DUCKDB_COMMAND_OWNER = '@sqlrooms/duckdb';\nconst INTERNAL_SQLROOMS_PREFIX = '__sqlrooms';\n\n/** DuckDB's temporary database catalog; never show in the default data source tree. */\nconst DUCKDB_TEMP_DATABASE = 'temp';\n\n/**\n * Default predicate: which tables/schemas/databases appear in the data source panel.\n * Hides `__sqlrooms_*` names and DuckDB's `temp` database.\n */\nexport const defaultLoadTableSchemasFilter: LoadTableSchemasFilterFunction = (\n table: QualifiedTableName,\n): boolean => {\n if (\n table.table?.startsWith(INTERNAL_SQLROOMS_PREFIX) ||\n table.database?.startsWith(INTERNAL_SQLROOMS_PREFIX) ||\n table.schema?.startsWith(INTERNAL_SQLROOMS_PREFIX)\n ) {\n return false;\n }\n if (table.database === DUCKDB_TEMP_DATABASE) {\n return false;\n }\n return true;\n};\n\n/**\n * Factory returning {@link defaultLoadTableSchemasFilter}.\n * Hides `__sqlrooms_*` names and DuckDB's `temp` database.\n * Apps can pass {@link CreateDuckDbSliceProps.loadTableSchemasFilter} to add more rules.\n */\nexport function createDefaultLoadTableSchemasFilter(): LoadTableSchemasFilterFunction {\n return defaultLoadTableSchemasFilter;\n}\n\n/**\n * Default catalog visibility predicate for the data source panel.\n * Hides SQLRooms internal objects and DuckDB's temporary database catalog.\n */\nexport const defaultLoadSchemaCatalogFilter: LoadSchemaCatalogFilterFunction = (\n entry,\n): boolean => {\n switch (entry.type) {\n case 'database':\n return (\n !entry.database.startsWith(INTERNAL_SQLROOMS_PREFIX) &&\n entry.database !== DUCKDB_TEMP_DATABASE\n );\n case 'schema':\n return (\n !entry.database.startsWith(INTERNAL_SQLROOMS_PREFIX) &&\n entry.database !== DUCKDB_TEMP_DATABASE &&\n !entry.schema.startsWith(INTERNAL_SQLROOMS_PREFIX)\n );\n case 'table':\n return defaultLoadTableSchemasFilter(entry.table);\n }\n};\n\nconst DropTableCommandInput = z.object({\n tableName: z.string().describe('Name of the table to drop.'),\n});\ntype DropTableCommandInput = z.infer<typeof DropTableCommandInput>;\n\nconst CreateTableFromQueryCommandInput = z.object({\n tableName: z.string().describe('Name of the table or view to create.'),\n query: z.string().describe('SQL query used to populate the table/view.'),\n replace: z\n .boolean()\n .optional()\n .default(true)\n .describe('Whether to replace existing table/view with the same name.'),\n view: z\n .boolean()\n .optional()\n .default(false)\n .describe('Whether to create a view instead of a table.'),\n temp: z\n .boolean()\n .optional()\n .default(false)\n .describe('Whether to create a temporary object.'),\n allowMultipleStatements: z\n .boolean()\n .optional()\n .default(false)\n .describe('Allow multiple SQL statements where the final one is SELECT.'),\n});\n\ntype CreateTableFromQueryCommandInput = z.infer<\n typeof CreateTableFromQueryCommandInput\n>;\n\n/**\n * State and actions for the DuckDB slice\n */\nexport type DuckDbSliceState = {\n db: {\n /**\n * The DuckDB connector instance\n */\n connector: DuckDbConnector;\n /**\n * @deprecated We shouldn't limit the schema to a single one.\n */\n schema: string;\n\n currentSchema: string | undefined;\n currentDatabase: string | undefined;\n\n /**\n * Cache of refreshed table schemas\n */\n tables: DataTable[];\n /**\n * Cache of row counts for tables\n */\n tableRowCounts: {[tableName: string]: number};\n /**\n * Cache of schema trees for tables\n */\n schemaTrees?: DbSchemaNode[];\n /**\n * Cache of currently running query handles.\n * This is only used for running queries to deduplicate them (especially for useSql),\n * the cache is cleared when the query is completed.\n */\n queryCache: {[key: string]: QueryHandle};\n /**\n * Whether the table schemas are being refreshed\n */\n isRefreshingTableSchemas: boolean;\n\n /**\n * Set a new DuckDB connector\n */\n setConnector: (connector: DuckDbConnector) => void;\n\n /**\n * Initialize the connector (creates a WasmDuckDbConnector if none exists)\n */\n initialize: () => Promise<void>;\n\n /**\n * Close and clean up the connector\n */\n destroy: () => Promise<void>;\n\n /**\n * Add a table to the room.\n * @param tableName - The name of the table to add.\n * @param data - The data to add to the table: an arrow table or an array of records.\n * @returns A promise that resolves to the table that was added.\n */\n addTable(\n tableName: string | QualifiedTableName,\n data: arrow.Table | Record<string, unknown>[],\n ): Promise<DataTable>;\n\n /**\n * Load the schemas of the tables in the database.\n */\n loadTableSchemas(filter?: LoadTableSchemasFilter): Promise<DataTable[]>;\n\n /**\n * @deprecated Use findTable instead\n */\n getTable(tableName: string): DataTable | undefined;\n\n /**\n * @internal Avoid using this directly, it's for internal use.\n */\n setTableRowCount(\n tableName: string | QualifiedTableName,\n rowCount: number,\n ): void;\n\n /**\n * Find a table by reference in the last refreshed table schemas.\n * String references are parsed as SQL identifiers, so dots separate\n * database/schema/table segments unless quoted. If no schema or database is\n * provided, the table is resolved in the current schema and database from\n * the last schema refresh.\n * @param tableName - The table reference to find.\n * @returns The table or undefined if not found.\n */\n findTable(tableName: string | QualifiedTableName): DataTable | undefined;\n\n /**\n * @deprecated Use findTable instead\n */\n findTableByName(\n tableName: string | QualifiedTableName,\n ): DataTable | undefined;\n\n /**\n * Refresh table schemas from the database.\n * @returns A promise that resolves to the updated tables.\n */\n refreshTableSchemas(): Promise<DataTable[]>;\n /**\n * Get the connector. If it's not initialized, it will be initialized.\n */\n getConnector: () => Promise<DuckDbConnector>;\n\n /**\n * @deprecated Use .loadTableRowCount() instead\n */\n getTableRowCount: (table: string, schema?: string) => Promise<number>;\n\n /**\n * Load the row count of a table\n */\n loadTableRowCount: (\n tableName: string | QualifiedTableName,\n ) => Promise<number>;\n\n /**\n * Execute a query with query handle (not result) caching and deduplication\n * @param query - The SQL query to execute\n * @returns The QueryHandle for the query or null if disabled\n */\n executeSql: (\n query: string,\n version?: number,\n ) => Promise<QueryHandle | null>;\n\n /**\n * @deprecated Use .tables or .loadTableSchemas() instead\n */\n getTables: (schema?: string) => Promise<string[]>;\n\n /**\n * @deprecated Use .loadTableSchemas() instead\n */\n getTableSchema: (\n tableName: string,\n schema?: string,\n ) => Promise<DataTable | undefined>;\n\n /**\n * @deprecated Use .tables or .loadTableSchemas() instead\n */\n getTableSchemas: (schema?: string) => Promise<DataTable[]>;\n\n /**\n * Check if a table exists\n */\n checkTableExists: (\n tableName: string | QualifiedTableName,\n ) => Promise<boolean>;\n\n /**\n * Delete a table or view with optional schema and database.\n * @param tableName - The name of the relation to delete (qualified or plain)\n */\n dropRelation: (tableName: string | QualifiedTableName) => Promise<void>;\n\n /**\n * Delete a table with optional schema and database.\n * @param tableName - The name of the table to delete (qualified or plain)\n */\n dropTable: (tableName: string | QualifiedTableName) => Promise<void>;\n\n /**\n * Create a table or view from a query.\n * @param tableName - The name of the table/view to create.\n * @param query - The query to create the table/view from.\n * @param options - Creation options.\n * @returns The table/view name and rowCount (undefined for views).\n */\n createTableFromQuery: (\n tableName: string | QualifiedTableName,\n query: string,\n options?: {\n replace?: boolean;\n temp?: boolean;\n view?: boolean;\n allowMultipleStatements?: boolean;\n abortSignal?: AbortSignal;\n },\n ) => Promise<{\n tableName: string | QualifiedTableName;\n rowCount: number | undefined;\n }>;\n\n /**\n * Parse a SQL SELECT statement to JSON\n * @param sql - The SQL SELECT statement to parse.\n * @returns A promise that resolves to the parsed JSON.\n */\n sqlSelectToJson: (sql: string) => Promise<\n | {\n error: true;\n error_type: string;\n error_message: string;\n error_subtype: string;\n position: string;\n }\n | {\n error: false;\n statements: {\n node: {\n from_table: {\n alias: string;\n show_type: string;\n table_name: string;\n };\n select_list: Record<string, unknown>[];\n type: string;\n };\n }[];\n }\n >;\n };\n};\n\nexport type CreateDuckDbSliceProps = {\n connector?: DuckDbConnector;\n /**\n * Optional table visibility filter.\n * Defaults to {@link createDefaultLoadTableSchemasFilter}.\n */\n loadTableSchemasFilter?: LoadTableSchemasFilterFunction | null;\n /**\n * Optional catalog visibility filter for the data source panel.\n * Defaults to {@link defaultLoadSchemaCatalogFilter}. When omitted, custom\n * table filters still apply to table entries while schemas/databases use the default.\n */\n loadSchemaCatalogFilter?: LoadSchemaCatalogFilterFunction | null;\n};\n\n/**\n * Create a DuckDB slice for managing the connector\n */\nexport function createDuckDbSlice({\n connector = createWasmDuckDbConnector(),\n loadTableSchemasFilter = defaultLoadTableSchemasFilter,\n loadSchemaCatalogFilter,\n}: CreateDuckDbSliceProps = {}): StateCreator<DuckDbSliceState> {\n let refreshPromise: Promise<DataTable[]> | null = null;\n let pendingSchemaRefresh = false;\n const effectiveSchemaCatalogFilter =\n loadSchemaCatalogFilter ??\n (loadTableSchemasFilter === null\n ? null\n : (((entry) => {\n if (entry.type === 'table') {\n return loadTableSchemasFilter\n ? loadTableSchemasFilter(entry.table)\n : true;\n }\n return defaultLoadSchemaCatalogFilter(entry);\n }) satisfies LoadSchemaCatalogFilterFunction));\n return createSlice<DuckDbSliceState, BaseRoomStoreState & DuckDbSliceState>(\n (set, get, store) => {\n /**\n * Internal helper to load a table schema by exact name, bypassing the visibility filter.\n * Used when performing exact lookups (e.g., checking if a specific table exists).\n */\n const loadTableSchemaByName = async (\n tableName: string | QualifiedTableName,\n ): Promise<DataTable | undefined> => {\n const qualifiedName = isQualifiedTableName(tableName)\n ? tableName\n : makeQualifiedTableName({table: tableName});\n const connector = await get().db.getConnector();\n const [table] = await loadTableSchemas(connector, qualifiedName);\n return table;\n };\n\n return {\n db: {\n connector, // Will be initialized during init\n schema: 'main', // TODO: remove schema, we should not limit the schema to a single one.\n currentSchema: undefined,\n currentDatabase: undefined,\n isRefreshingTableSchemas: false,\n tables: [],\n tableRowCounts: {},\n schemaTrees: undefined,\n queryCache: {},\n\n setConnector: (connector: DuckDbConnector) => {\n set(\n produce((state) => {\n state.config.dataSources = [];\n state.db.connector = connector;\n }),\n );\n },\n\n initialize: async () => {\n await get().db.connector.initialize();\n // No await here, we want to continue initializing the room even\n // if the table schemas are not refreshed yet\n get().db.refreshTableSchemas();\n registerCommandsForOwner(\n store,\n DUCKDB_COMMAND_OWNER,\n createDuckDbCommands(),\n );\n },\n\n getConnector: async () => {\n await get().db.connector.initialize();\n return get().db.connector;\n },\n\n destroy: async () => {\n unregisterCommandsForOwner(store, DUCKDB_COMMAND_OWNER);\n // Wait for any in-flight refreshTableSchemas() to finish before\n // destroying the connector. initialize() fires it without await,\n // so it may still be querying the native DuckDB instance; tearing\n // that down mid-flight causes a use-after-free segfault.\n if (refreshPromise) {\n try {\n await refreshPromise;\n } catch {\n // ignore – we're shutting down\n }\n }\n try {\n if (get().db.connector) {\n await get().db.connector.destroy();\n }\n } catch (err) {\n console.error('Error during DuckDB shutdown:', err);\n }\n },\n\n /**\n * Creates a table or view from a SQL query.\n * @param tableName - Name of the table/view to create\n * @param query - SQL query (must be a SELECT statement, or multiple statements ending with a SELECT when allowMultipleStatements is true)\n * @param options - Creation options\n * @param options.replace - If true, uses CREATE OR REPLACE (default: true)\n * @param options.temp - If true, creates a temporary table/view (default: false)\n * @param options.view - If true, creates a view instead of a table (default: false)\n * @param options.allowMultipleStatements - If true, allows multiple statements where preceding statements are executed first and the final SELECT is wrapped in CREATE TABLE/VIEW (default: false)\n * @returns Object with tableName and rowCount (rowCount is undefined for views)\n */\n async createTableFromQuery(\n tableName: string | QualifiedTableName,\n query: string,\n options?: {\n replace?: boolean;\n temp?: boolean;\n view?: boolean;\n allowMultipleStatements?: boolean;\n abortSignal?: AbortSignal;\n },\n ) {\n const {\n replace = true,\n temp = false,\n view = false,\n allowMultipleStatements = false,\n abortSignal,\n } = options || {};\n\n // For temp tables/views, DuckDB requires the \"temp\" database\n const baseQualifiedName = isQualifiedTableName(tableName)\n ? tableName\n : makeQualifiedTableName({table: tableName});\n\n const qualifiedName = temp\n ? makeQualifiedTableName({\n table: baseQualifiedName.table,\n schema: baseQualifiedName.schema,\n database: 'temp',\n })\n : baseQualifiedName;\n\n const connector = await get().db.getConnector();\n\n const {precedingStatements, lastStatement} =\n separateLastStatement(query);\n\n if (!allowMultipleStatements && precedingStatements.length > 0) {\n throw new Error(\n 'Query must contain exactly one statement (set allowMultipleStatements: true to execute multiple statements)',\n );\n }\n\n // The last statement must be a SELECT\n const parsedQuery = await get().db.sqlSelectToJson(lastStatement);\n if (parsedQuery.error) {\n throw new Error(\n 'Final statement must be a valid SELECT statement',\n );\n }\n\n // Build CREATE statement with options\n const createKeyword = [\n 'CREATE',\n replace ? 'OR REPLACE' : '',\n temp ? 'TEMP' : '',\n view ? 'VIEW' : 'TABLE',\n ]\n .filter(Boolean)\n .join(' ');\n\n const createStatement = `${createKeyword} ${qualifiedName} AS (\n ${lastStatement}\n )`;\n\n const fullQuery = joinStatements(\n precedingStatements,\n createStatement,\n );\n const result = await connector.query(fullQuery, {\n signal: abortSignal,\n });\n // Views don't have a row count, only tables do\n const rowCount = view ? undefined : getColValAsNumber(result);\n return {tableName, rowCount};\n },\n\n /**\n * @deprecated Use .tables or .loadTableSchemas() instead\n */\n async getTables(schema) {\n const tableSchemas = await get().db.loadTableSchemas({schema});\n return tableSchemas.map((t) => t.table.table);\n },\n\n /**\n * @deprecated Use .loadTableSchemas() instead\n */\n async getTableSchema(tableName: string, schema = 'main') {\n const newLocal = await get().db.loadTableSchemas({\n schema,\n table: tableName,\n });\n return newLocal[0];\n },\n\n /**\n * @deprecated Use .loadTableRowCount() instead\n */\n async getTableRowCount(table, schema = 'main') {\n return get().db.loadTableRowCount({table, schema});\n },\n\n async loadTableRowCount(tableName: string | QualifiedTableName) {\n const {schema, database, table} =\n typeof tableName === 'string'\n ? {table: tableName}\n : tableName || {};\n const connector = await get().db.getConnector();\n const result = await connector.query(\n `SELECT COUNT(*) FROM ${makeQualifiedTableName({\n schema,\n database,\n table,\n })}`,\n );\n return getColValAsNumber(result);\n },\n\n /**\n * @deprecated Use .loadTableSchemas() instead\n */\n async getTableSchemas(schema) {\n return await get().db.loadTableSchemas({schema});\n },\n\n async loadTableSchemas(\n filter?: LoadTableSchemasFilter,\n ): Promise<DataTable[]> {\n const connector = await get().db.getConnector();\n return loadTableSchemas(connector, {\n ...filter,\n filterFunction: loadTableSchemasFilter,\n });\n },\n\n async checkTableExists(tableName: string | QualifiedTableName) {\n const table = await loadTableSchemaByName(tableName);\n return Boolean(table);\n },\n\n async dropRelation(tableName): Promise<void> {\n const connector = await get().db.getConnector();\n const qualifiedTable = isQualifiedTableName(tableName)\n ? tableName\n : makeQualifiedTableName({table: tableName});\n const table =\n get().db.findTable(qualifiedTable) ??\n (await loadTableSchemaByName(qualifiedTable));\n const isView = table?.isView;\n if (isView) {\n await connector.query(`DROP VIEW IF EXISTS ${qualifiedTable};`);\n } else {\n await connector.query(`DROP TABLE IF EXISTS ${qualifiedTable};`);\n }\n get().db.refreshTableSchemas();\n },\n\n async dropTable(tableName): Promise<void> {\n const connector = await get().db.getConnector();\n const qualifiedTable = isQualifiedTableName(tableName)\n ? tableName\n : makeQualifiedTableName({table: tableName});\n const table =\n get().db.findTable(qualifiedTable) ??\n (await loadTableSchemaByName(qualifiedTable));\n\n if (table?.isView) {\n throw new Error(\n `\"${qualifiedTable}\" is a view. Use dropRelation() to remove views.`,\n );\n }\n\n await connector.query(`DROP TABLE IF EXISTS ${qualifiedTable};`);\n get().db.refreshTableSchemas();\n },\n\n async addTable(tableName, data) {\n const qualifiedName = isQualifiedTableName(tableName)\n ? tableName\n : makeQualifiedTableName({table: tableName});\n\n const {db} = get();\n if (data instanceof arrow.Table) {\n // TODO: make sure the table is replaced\n await db.connector.loadArrow(data, qualifiedName.toString());\n } else {\n await db.connector.loadObjects(data, qualifiedName.toString(), {\n replace: true,\n });\n }\n const newTable = await loadTableSchemaByName(qualifiedName);\n if (!newTable) {\n throw new Error('Failed to add table');\n }\n set((state) =>\n produce(state, (draft) => {\n draft.db.tables.push(newTable);\n }),\n );\n get().db.refreshTableSchemas();\n return newTable;\n },\n\n async setTableRowCount(tableName, rowCount) {\n const qualifiedName = isQualifiedTableName(tableName)\n ? tableName\n : makeQualifiedTableName({table: tableName});\n set((state) =>\n produce(state, (draft) => {\n draft.db.tableRowCounts[qualifiedName.toString()] = rowCount;\n }),\n );\n },\n\n getTable(tableName) {\n return get().db.findTable(tableName);\n },\n\n findTable(tableName: string | QualifiedTableName) {\n const {currentSchema, currentDatabase, tables} = get().db;\n const findMatchingTable = ({\n table,\n schema,\n database,\n }: Partial<QualifiedTableName>) =>\n table\n ? tables.find(\n (t) =>\n t.table.table === table &&\n (!schema || t.table.schema === schema) &&\n (!database || t.table.database === database),\n )\n : undefined;\n\n const {table, schema, database} = {\n schema: currentSchema,\n database: currentDatabase,\n ...(typeof tableName === 'string'\n ? (parseQualifiedSqlIdentifier(tableName) ?? {})\n : tableName),\n };\n return findMatchingTable({table, schema, database});\n },\n\n findTableByName(tableName: string | QualifiedTableName) {\n return get().db.findTable(tableName);\n },\n\n async refreshTableSchemas(): Promise<DataTable[]> {\n if (refreshPromise) {\n pendingSchemaRefresh = true;\n return refreshPromise;\n }\n set((state) =>\n produce(state, (draft) => {\n draft.db.isRefreshingTableSchemas = true;\n }),\n );\n refreshPromise = (async () => {\n try {\n let schemasWithTables: SchemaWithTables[] = [];\n do {\n pendingSchemaRefresh = false;\n const connector = await get().db.getConnector();\n const result = await connector.query(\n `SELECT current_schema() AS schema, current_database() AS database`,\n );\n set((state) =>\n produce(state, (draft) => {\n draft.db.currentSchema = result\n .getChild('schema')\n ?.get(0);\n draft.db.currentDatabase = result\n .getChild('database')\n ?.get(0);\n }),\n );\n schemasWithTables = await loadSchemaCatalog(connector, {\n filterFunction: effectiveSchemaCatalogFilter,\n });\n } while (pendingSchemaRefresh);\n\n const newTables = schemasWithTables.flatMap((s) => s.tables);\n const currentTables = get().db.tables;\n const currentSchemaTrees = get().db.schemaTrees;\n const newSchemaTrees = createDbSchemaTrees(schemasWithTables);\n\n if (\n !deepEquals(newTables, currentTables) ||\n !deepEquals(newSchemaTrees, currentSchemaTrees)\n ) {\n set((state) =>\n produce(state, (draft) => {\n draft.db.tables = newTables;\n draft.db.schemaTrees = newSchemaTrees;\n }),\n );\n }\n return newTables;\n } catch (err) {\n get().room.captureException(err);\n return [];\n } finally {\n refreshPromise = null;\n set((state) =>\n produce(state, (draft) => {\n draft.db.isRefreshingTableSchemas = false;\n }),\n );\n }\n })();\n return refreshPromise;\n },\n\n async sqlSelectToJson(sql: string) {\n const connector = await get().db.getConnector();\n const parsedQuery = (\n await connector.query(\n `SELECT json_serialize_sql(${escapeVal(sql)})`,\n )\n )\n .getChildAt(0)\n ?.get(0);\n return JSON.parse(parsedQuery);\n },\n\n async executeSql(query: string): Promise<QueryHandle | null> {\n // Create a unique key for this query\n const queryKey = `${query}`;\n const connector = await get().db.getConnector();\n\n // Check if we already have a cached query for this key\n const existingQuery = get().db.queryCache[queryKey];\n if (existingQuery) {\n return existingQuery;\n }\n\n const queryHandle = connector.query(query);\n // Cache the query handle immediately\n set((state) =>\n produce(state, (draft) => {\n draft.db.queryCache[queryKey] = queryHandle;\n }),\n );\n\n queryHandle.result.finally(() => {\n // remove from cache after completion\n set((state) =>\n produce(state, (draft) => {\n delete draft.db.queryCache[queryKey];\n }),\n );\n });\n\n return queryHandle;\n },\n },\n };\n },\n );\n}\n\ntype DuckDbCommandStoreState = BaseRoomStoreState & DuckDbSliceState;\n\nfunction createDuckDbCommands(): RoomCommand<DuckDbCommandStoreState>[] {\n return [\n {\n id: 'db.refresh-table-schemas',\n name: 'Refresh table schemas',\n description: 'Reload table and schema metadata from DuckDB',\n group: 'Database',\n keywords: ['duckdb', 'database', 'refresh', 'tables', 'schemas'],\n metadata: {\n readOnly: true,\n idempotent: true,\n riskLevel: 'low',\n },\n isEnabled: ({getState}) => !getState().db.isRefreshingTableSchemas,\n execute: async ({getState}) => {\n await getState().db.refreshTableSchemas();\n return {\n success: true,\n commandId: 'db.refresh-table-schemas',\n message: 'Table schemas refreshed.',\n };\n },\n },\n {\n id: 'db.drop-table',\n name: 'Drop relation',\n description: 'Drop a table or view from DuckDB by name',\n group: 'Database',\n keywords: [\n 'duckdb',\n 'database',\n 'drop',\n 'table',\n 'view',\n 'relation',\n 'delete',\n ],\n inputSchema: DropTableCommandInput,\n inputDescription: 'Provide a tableName to remove from DuckDB.',\n metadata: {\n readOnly: false,\n idempotent: true,\n riskLevel: 'high',\n requiresConfirmation: true,\n },\n validateInput: async (input, {getState}) => {\n const {tableName} = input as DropTableCommandInput;\n const exists = await getState().db.checkTableExists(tableName);\n if (!exists) {\n throw new Error(`Table \"${tableName}\" does not exist.`);\n }\n },\n execute: async ({getState}, input) => {\n const {tableName} = input as DropTableCommandInput;\n await getState().db.dropRelation(tableName);\n return {\n success: true,\n commandId: 'db.drop-table',\n message: `Dropped relation \"${tableName}\".`,\n };\n },\n },\n {\n id: 'db.create-table-from-query',\n name: 'Create table from query',\n description: 'Create a table or view from a SQL query',\n group: 'Database',\n keywords: ['duckdb', 'database', 'create', 'table', 'view', 'query'],\n inputSchema: CreateTableFromQueryCommandInput,\n inputDescription:\n 'Provide tableName and query, with optional replace/view/temp flags.',\n metadata: {\n readOnly: false,\n idempotent: false,\n riskLevel: 'medium',\n },\n validateInput: (input) => {\n const {query} = input as CreateTableFromQueryCommandInput;\n if (!query.trim()) {\n throw new Error('Query cannot be empty.');\n }\n },\n execute: async ({getState}, input) => {\n const {tableName, query, replace, view, temp, allowMultipleStatements} =\n input as CreateTableFromQueryCommandInput;\n const result = await getState().db.createTableFromQuery(\n tableName,\n query,\n {\n replace,\n view,\n temp,\n allowMultipleStatements,\n },\n );\n await getState().db.refreshTableSchemas();\n return {\n success: true,\n commandId: 'db.create-table-from-query',\n message: `Created ${view ? 'view' : 'table'} \"${tableName}\".`,\n data: result,\n };\n },\n },\n ];\n}\n\n/**\n * @internal\n * Select values from the room store that includes the DuckDB slice.\n *\n * This is a typed wrapper around `useBaseRoomStore` that narrows the\n * state to `RoomStateWithDuckDb` so selectors can access `db` safely.\n *\n * @typeParam T - The selected slice of state returned by the selector\n * @param selector - Function that selects a value from the store state\n * @returns The selected value of type `T`\n */\nexport function useStoreWithDuckDb<T>(\n selector: (state: BaseRoomStoreState & DuckDbSliceState) => T,\n): T {\n return useBaseRoomStore<DuckDbSliceState, T>((state) => selector(state));\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export { loadSchemaCatalog, type LoadSchemaCatalogFilterFunction, type LoadSchem
|
|
|
12
12
|
export { useExportToCsv, type UseExportToCsvReturn } from './use-export-to-csv';
|
|
13
13
|
export { useCopyAsTsv, type CopyAsTsvOptions, type CopyAsTsvResult, type UseCopyAsTsvReturn, } from './use-copy-as-tsv';
|
|
14
14
|
export { useDuckDb } from './useDuckDb';
|
|
15
|
+
export { useDataTable } from './useDataTable';
|
|
15
16
|
export { useDuckDbQuery, useSql, type DuckDbQueryResult, type UseSqlQueryResult, } from './useSql';
|
|
16
|
-
export { arrowTableToJson, createBaseDuckDbConnector, createDbSchemaTrees, createTypedRowAccessor, escapeId, escapeVal, findTableInSchemaTrees, getAllTablesFromSchemaTrees, getArrowColumnTypeCategory, getColValAsNumber, getDuckDbTypeCategory, getSqlErrorWithPointer, isNumericDuckType, isQualifiedTableName, joinStatements, literalToSQL, load, loadCSV, loadJSON, loadObjects, loadParquet, loadSpatial, makeLimitQuery, makeQualifiedTableName, sanitizeQuery, separateLastStatement, splitSqlStatements, sqlFrom, getFunctionSuggestions, getFunctionDocumentation, type BaseDuckDbConnectorImpl, type BaseDuckDbConnectorOptions, type ColumnNodeObject, type ColumnTypeCategory, type DatabaseNodeObject, type DataTable, type DbSchemaNode, type DuckDbConnector, type FunctionSuggestion, type GroupedFunctionSuggestion, type NodeObject, type QualifiedTableName, type QueryHandle, type QueryOptions, type SchemaNodeObject, type SchemaWithTables, type SeparatedStatements, type TableColumn, type TableNodeObject, type TypedRowAccessor, } from '@sqlrooms/duckdb-core';
|
|
17
|
+
export { arrowTableToJson, createBaseDuckDbConnector, createDbSchemaTrees, createTypedRowAccessor, escapeId, escapeVal, findTableInSchemaTrees, getAllTablesFromSchemaTrees, getArrowColumnTypeCategory, getColValAsNumber, getDuckDbTypeCategory, getSqlErrorWithPointer, getUnqualifiedSqlIdentifier, isNumericDuckType, isQualifiedTableName, joinStatements, literalToSQL, load, loadCSV, loadJSON, loadObjects, loadParquet, loadSpatial, makeLimitQuery, makeQualifiedTableName, parseQualifiedSqlIdentifier, quoteTableReference, resolveTableReference, sanitizeQuery, separateLastStatement, splitSqlStatements, sqlFrom, getFunctionSuggestions, getFunctionDocumentation, type BaseDuckDbConnectorImpl, type BaseDuckDbConnectorOptions, type ColumnNodeObject, type ColumnTypeCategory, type DatabaseNodeObject, type DataTable, type DbSchemaNode, type DuckDbConnector, type FunctionSuggestion, type GroupedFunctionSuggestion, type NodeObject, type QualifiedTableName, type QueryHandle, type QueryOptions, type ResolveTableReferenceResult, type SchemaNodeObject, type SchemaWithTables, type SeparatedStatements, type TableColumn, type TableNodeObject, type TypedRowAccessor, } from '@sqlrooms/duckdb-core';
|
|
17
18
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAC,gBAAgB,EAAC,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAC,aAAa,EAAE,YAAY,EAAC,MAAM,qBAAqB,CAAC;AAErE,OAAO,EACL,wBAAwB,EACxB,eAAe,EACf,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,GAChC,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EACL,8BAA8B,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,+BAA+B,GACrC,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,mCAAmC,EACnC,8BAA8B,EAC9B,6BAA6B,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,GACtB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,iBAAiB,EACjB,KAAK,+BAA+B,EACpC,KAAK,wBAAwB,EAC7B,KAAK,8BAA8B,EACnC,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,GAC7B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAC,cAAc,EAAE,KAAK,oBAAoB,EAAC,MAAM,qBAAqB,CAAC;AAE9E,OAAO,EACL,YAAY,EACZ,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,kBAAkB,GACxB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAC,gBAAgB,EAAC,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAC,aAAa,EAAE,YAAY,EAAC,MAAM,qBAAqB,CAAC;AAErE,OAAO,EACL,wBAAwB,EACxB,eAAe,EACf,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,GAChC,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EACL,8BAA8B,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,+BAA+B,GACrC,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,mCAAmC,EACnC,8BAA8B,EAC9B,6BAA6B,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,GACtB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,iBAAiB,EACjB,KAAK,+BAA+B,EACpC,KAAK,wBAAwB,EAC7B,KAAK,8BAA8B,EACnC,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,GAC7B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAC,cAAc,EAAE,KAAK,oBAAoB,EAAC,MAAM,qBAAqB,CAAC;AAE9E,OAAO,EACL,YAAY,EACZ,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,kBAAkB,GACxB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AACtC,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAE5C,OAAO,EACL,cAAc,EACd,MAAM,EACN,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,GACvB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,gBAAgB,EAChB,yBAAyB,EACzB,mBAAmB,EACnB,sBAAsB,EACtB,QAAQ,EACR,SAAS,EACT,sBAAsB,EACtB,2BAA2B,EAC3B,0BAA0B,EAC1B,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,2BAA2B,EAC3B,iBAAiB,EACjB,oBAAoB,EACpB,cAAc,EACd,YAAY,EACZ,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,WAAW,EACX,WAAW,EACX,WAAW,EACX,cAAc,EACd,sBAAsB,EACtB,2BAA2B,EAC3B,mBAAmB,EACnB,qBAAqB,EACrB,aAAa,EACb,qBAAqB,EACrB,kBAAkB,EAClB,OAAO,EACP,sBAAsB,EACtB,wBAAwB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,0BAA0B,EAC/B,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,yBAAyB,EAC9B,KAAK,UAAU,EACf,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,2BAA2B,EAChC,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,gBAAgB,GACtB,MAAM,uBAAuB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -11,7 +11,8 @@ export { loadSchemaCatalog, } from './loadTableSchemas';
|
|
|
11
11
|
export { useExportToCsv } from './use-export-to-csv';
|
|
12
12
|
export { useCopyAsTsv, } from './use-copy-as-tsv';
|
|
13
13
|
export { useDuckDb } from './useDuckDb';
|
|
14
|
+
export { useDataTable } from './useDataTable';
|
|
14
15
|
export { useDuckDbQuery, useSql, } from './useSql';
|
|
15
16
|
// Re-export from @sqlrooms/duckdb-core
|
|
16
|
-
export { arrowTableToJson, createBaseDuckDbConnector, createDbSchemaTrees, createTypedRowAccessor, escapeId, escapeVal, findTableInSchemaTrees, getAllTablesFromSchemaTrees, getArrowColumnTypeCategory, getColValAsNumber, getDuckDbTypeCategory, getSqlErrorWithPointer, isNumericDuckType, isQualifiedTableName, joinStatements, literalToSQL, load, loadCSV, loadJSON, loadObjects, loadParquet, loadSpatial, makeLimitQuery, makeQualifiedTableName, sanitizeQuery, separateLastStatement, splitSqlStatements, sqlFrom, getFunctionSuggestions, getFunctionDocumentation, } from '@sqlrooms/duckdb-core';
|
|
17
|
+
export { arrowTableToJson, createBaseDuckDbConnector, createDbSchemaTrees, createTypedRowAccessor, escapeId, escapeVal, findTableInSchemaTrees, getAllTablesFromSchemaTrees, getArrowColumnTypeCategory, getColValAsNumber, getDuckDbTypeCategory, getSqlErrorWithPointer, getUnqualifiedSqlIdentifier, isNumericDuckType, isQualifiedTableName, joinStatements, literalToSQL, load, loadCSV, loadJSON, loadObjects, loadParquet, loadSpatial, makeLimitQuery, makeQualifiedTableName, parseQualifiedSqlIdentifier, quoteTableReference, resolveTableReference, sanitizeQuery, separateLastStatement, splitSqlStatements, sqlFrom, getFunctionSuggestions, getFunctionDocumentation, } from '@sqlrooms/duckdb-core';
|
|
17
18
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAC,gBAAgB,EAAC,MAAM,qBAAqB,CAAC;AAGrD,OAAO,EACL,wBAAwB,EACxB,eAAe,EACf,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,GAKtB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EACL,8BAA8B,GAG/B,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,mCAAmC,EACnC,8BAA8B,EAC9B,6BAA6B,GAG9B,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,iBAAiB,GAOlB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAC,cAAc,EAA4B,MAAM,qBAAqB,CAAC;AAE9E,OAAO,EACL,YAAY,GAIb,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAC,gBAAgB,EAAC,MAAM,qBAAqB,CAAC;AAGrD,OAAO,EACL,wBAAwB,EACxB,eAAe,EACf,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,GAKtB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EACL,8BAA8B,GAG/B,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,mCAAmC,EACnC,8BAA8B,EAC9B,6BAA6B,GAG9B,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,iBAAiB,GAOlB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAC,cAAc,EAA4B,MAAM,qBAAqB,CAAC;AAE9E,OAAO,EACL,YAAY,GAIb,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AACtC,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAE5C,OAAO,EACL,cAAc,EACd,MAAM,GAGP,MAAM,UAAU,CAAC;AAElB,uCAAuC;AACvC,OAAO,EACL,gBAAgB,EAChB,yBAAyB,EACzB,mBAAmB,EACnB,sBAAsB,EACtB,QAAQ,EACR,SAAS,EACT,sBAAsB,EACtB,2BAA2B,EAC3B,0BAA0B,EAC1B,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,2BAA2B,EAC3B,iBAAiB,EACjB,oBAAoB,EACpB,cAAc,EACd,YAAY,EACZ,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,WAAW,EACX,WAAW,EACX,WAAW,EACX,cAAc,EACd,sBAAsB,EACtB,2BAA2B,EAC3B,mBAAmB,EACnB,qBAAqB,EACrB,aAAa,EACb,qBAAqB,EACrB,kBAAkB,EAClB,OAAO,EACP,sBAAsB,EACtB,wBAAwB,GAsBzB,MAAM,uBAAuB,CAAC","sourcesContent":["/**\n * {@include ../README.md}\n * @packageDocumentation\n */\n\nexport {DuckDBAccessMode} from '@duckdb/duckdb-wasm';\nexport type {DuckDBBundles, DuckDBConfig} from '@duckdb/duckdb-wasm';\n\nexport {\n isSpatialLoadFileOptions,\n LoadFileOptions,\n SpatialLoadFileOptions,\n} from '@sqlrooms/room-config';\n\nexport {\n createDuckDbConnector,\n createWasmDuckDbConnector,\n isWasmDuckDbConnector,\n type DuckDbConnectorOptions,\n type DuckDbConnectorType,\n type WasmDuckDbConnector,\n type WasmDuckDbConnectorOptions,\n} from './connectors/createDuckDbConnector';\n\nexport {\n createWebSocketDuckDbConnector,\n type WebSocketDuckDbConnector,\n type WebSocketDuckDbConnectorOptions,\n} from './connectors/WebSocketDuckDbConnector';\n\nexport {\n createDuckDbSlice,\n useStoreWithDuckDb,\n createDefaultLoadTableSchemasFilter,\n defaultLoadSchemaCatalogFilter,\n defaultLoadTableSchemasFilter,\n type CreateDuckDbSliceProps,\n type DuckDbSliceState,\n} from './DuckDbSlice';\n\nexport {\n loadSchemaCatalog,\n type LoadSchemaCatalogFilterFunction,\n type LoadSchemaCatalogOptions,\n type LoadTableSchemasFilterFunction,\n type SchemaCatalogFilterEntry,\n type LoadTableSchemasFilter,\n type LoadTableSchemasOptions,\n} from './loadTableSchemas';\n\nexport {useExportToCsv, type UseExportToCsvReturn} from './use-export-to-csv';\n\nexport {\n useCopyAsTsv,\n type CopyAsTsvOptions,\n type CopyAsTsvResult,\n type UseCopyAsTsvReturn,\n} from './use-copy-as-tsv';\n\nexport {useDuckDb} from './useDuckDb';\nexport {useDataTable} from './useDataTable';\n\nexport {\n useDuckDbQuery,\n useSql,\n type DuckDbQueryResult,\n type UseSqlQueryResult,\n} from './useSql';\n\n// Re-export from @sqlrooms/duckdb-core\nexport {\n arrowTableToJson,\n createBaseDuckDbConnector,\n createDbSchemaTrees,\n createTypedRowAccessor,\n escapeId,\n escapeVal,\n findTableInSchemaTrees,\n getAllTablesFromSchemaTrees,\n getArrowColumnTypeCategory,\n getColValAsNumber,\n getDuckDbTypeCategory,\n getSqlErrorWithPointer,\n getUnqualifiedSqlIdentifier,\n isNumericDuckType,\n isQualifiedTableName,\n joinStatements,\n literalToSQL,\n load,\n loadCSV,\n loadJSON,\n loadObjects,\n loadParquet,\n loadSpatial,\n makeLimitQuery,\n makeQualifiedTableName,\n parseQualifiedSqlIdentifier,\n quoteTableReference,\n resolveTableReference,\n sanitizeQuery,\n separateLastStatement,\n splitSqlStatements,\n sqlFrom,\n getFunctionSuggestions,\n getFunctionDocumentation,\n type BaseDuckDbConnectorImpl,\n type BaseDuckDbConnectorOptions,\n type ColumnNodeObject,\n type ColumnTypeCategory,\n type DatabaseNodeObject,\n type DataTable,\n type DbSchemaNode,\n type DuckDbConnector,\n type FunctionSuggestion,\n type GroupedFunctionSuggestion,\n type NodeObject,\n type QualifiedTableName,\n type QueryHandle,\n type QueryOptions,\n type ResolveTableReferenceResult,\n type SchemaNodeObject,\n type SchemaWithTables,\n type SeparatedStatements,\n type TableColumn,\n type TableNodeObject,\n type TypedRowAccessor,\n} from '@sqlrooms/duckdb-core';\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DataTable, QualifiedTableName } from '@sqlrooms/duckdb-core';
|
|
2
|
+
/**
|
|
3
|
+
* Resolves a table reference against the DuckDB table schema cache.
|
|
4
|
+
*
|
|
5
|
+
* String inputs are delegated to `db.findTable`, which parses qualified
|
|
6
|
+
* SQL identifiers such as `main.events` and
|
|
7
|
+
* `"memory"."main"."events.2026"`. Unqualified names resolve in the current
|
|
8
|
+
* schema/database from the last schema refresh.
|
|
9
|
+
*
|
|
10
|
+
* @param tableName - A bare, qualified, or structured table reference.
|
|
11
|
+
* @returns The matching data table, including its loaded columns, or undefined.
|
|
12
|
+
*/
|
|
13
|
+
export declare function useDataTable(tableName: string | QualifiedTableName | undefined): DataTable | undefined;
|
|
14
|
+
//# sourceMappingURL=useDataTable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDataTable.d.ts","sourceRoot":"","sources":["../src/useDataTable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,SAAS,EAAE,kBAAkB,EAAC,MAAM,uBAAuB,CAAC;AAGzE;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,GACjD,SAAS,GAAG,SAAS,CAOvB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useStoreWithDuckDb } from './DuckDbSlice';
|
|
2
|
+
/**
|
|
3
|
+
* Resolves a table reference against the DuckDB table schema cache.
|
|
4
|
+
*
|
|
5
|
+
* String inputs are delegated to `db.findTable`, which parses qualified
|
|
6
|
+
* SQL identifiers such as `main.events` and
|
|
7
|
+
* `"memory"."main"."events.2026"`. Unqualified names resolve in the current
|
|
8
|
+
* schema/database from the last schema refresh.
|
|
9
|
+
*
|
|
10
|
+
* @param tableName - A bare, qualified, or structured table reference.
|
|
11
|
+
* @returns The matching data table, including its loaded columns, or undefined.
|
|
12
|
+
*/
|
|
13
|
+
export function useDataTable(tableName) {
|
|
14
|
+
return useStoreWithDuckDb((state) => {
|
|
15
|
+
if (!tableName) {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
return state.db.findTable(tableName);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=useDataTable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDataTable.js","sourceRoot":"","sources":["../src/useDataTable.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAEjD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,YAAY,CAC1B,SAAkD;IAElD,OAAO,kBAAkB,CAAC,CAAC,KAAK,EAAE,EAAE;QAClC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,KAAK,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type {DataTable, QualifiedTableName} from '@sqlrooms/duckdb-core';\nimport {useStoreWithDuckDb} from './DuckDbSlice';\n\n/**\n * Resolves a table reference against the DuckDB table schema cache.\n *\n * String inputs are delegated to `db.findTable`, which parses qualified\n * SQL identifiers such as `main.events` and\n * `\"memory\".\"main\".\"events.2026\"`. Unqualified names resolve in the current\n * schema/database from the last schema refresh.\n *\n * @param tableName - A bare, qualified, or structured table reference.\n * @returns The matching data table, including its loaded columns, or undefined.\n */\nexport function useDataTable(\n tableName: string | QualifiedTableName | undefined,\n): DataTable | undefined {\n return useStoreWithDuckDb((state) => {\n if (!tableName) {\n return undefined;\n }\n return state.db.findTable(tableName);\n });\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sqlrooms/duckdb",
|
|
3
|
-
"version": "0.29.0-rc.
|
|
3
|
+
"version": "0.29.0-rc.8",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/sqlrooms/sqlrooms.git"
|
|
@@ -26,17 +26,17 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@duckdb/duckdb-wasm": "^1.32.0",
|
|
29
|
-
"@sqlrooms/duckdb-core": "0.29.0-rc.
|
|
30
|
-
"@sqlrooms/room-config": "0.29.0-rc.
|
|
31
|
-
"@sqlrooms/room-store": "0.29.0-rc.
|
|
32
|
-
"@sqlrooms/utils": "0.29.0-rc.
|
|
29
|
+
"@sqlrooms/duckdb-core": "0.29.0-rc.8",
|
|
30
|
+
"@sqlrooms/room-config": "0.29.0-rc.8",
|
|
31
|
+
"@sqlrooms/room-store": "0.29.0-rc.8",
|
|
32
|
+
"@sqlrooms/utils": "0.29.0-rc.8",
|
|
33
33
|
"fast-deep-equal": "^3.1.3",
|
|
34
34
|
"immer": "^11.0.1",
|
|
35
35
|
"zod": "^4.1.8",
|
|
36
36
|
"zustand": "^5.0.8"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@sqlrooms/duckdb-node": "0.29.0-rc.
|
|
39
|
+
"@sqlrooms/duckdb-node": "0.29.0-rc.8",
|
|
40
40
|
"@types/jest": "^30.0.0",
|
|
41
41
|
"jest": "^30.1.3",
|
|
42
42
|
"ts-jest": "^29.4.4"
|
|
@@ -47,5 +47,5 @@
|
|
|
47
47
|
"publishConfig": {
|
|
48
48
|
"access": "public"
|
|
49
49
|
},
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "dcb1a51631c5fa87b49d3e78ae6c0023eccd4189"
|
|
51
51
|
}
|