@sqlrooms/sql-editor 0.27.0-rc.1 → 0.27.0-rc.3
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/dist/SqlEditor.d.ts.map +1 -1
- package/dist/SqlEditor.js +7 -1
- package/dist/SqlEditor.js.map +1 -1
- package/dist/SqlEditorSlice.d.ts +4 -1
- package/dist/SqlEditorSlice.d.ts.map +1 -1
- package/dist/SqlEditorSlice.js +37 -14
- package/dist/SqlEditorSlice.js.map +1 -1
- package/dist/SqlMonacoEditor.d.ts +10 -2
- package/dist/SqlMonacoEditor.d.ts.map +1 -1
- package/dist/SqlMonacoEditor.js +101 -68
- package/dist/SqlMonacoEditor.js.map +1 -1
- package/dist/components/CreateTableModal.d.ts +1 -1
- package/dist/components/CreateTableModal.d.ts.map +1 -1
- package/dist/components/CreateTableModal.js +81 -6
- package/dist/components/CreateTableModal.js.map +1 -1
- package/dist/components/QueryEditorPanelActions.d.ts.map +1 -1
- package/dist/components/QueryEditorPanelActions.js +7 -3
- package/dist/components/QueryEditorPanelActions.js.map +1 -1
- package/dist/components/QueryEditorPanelTabsList.d.ts.map +1 -1
- package/dist/components/QueryEditorPanelTabsList.js +1 -1
- package/dist/components/QueryEditorPanelTabsList.js.map +1 -1
- package/dist/components/QueryResultPanel.d.ts +16 -1
- package/dist/components/QueryResultPanel.d.ts.map +1 -1
- package/dist/components/QueryResultPanel.js +80 -10
- package/dist/components/QueryResultPanel.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +10 -10
package/dist/SqlEditor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlEditor.d.ts","sourceRoot":"","sources":["../src/SqlEditor.tsx"],"names":[],"mappings":"AAOA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAGnD,OAAO,EAAC,gBAAgB,EAAC,MAAM,+BAA+B,CAAC;AAE/D,OAAO,EAEL,wBAAwB,EACzB,MAAM,kCAAkC,CAAC;AAG1C,MAAM,MAAM,cAAc,GAAG;IAC3B;;0EAEsE;IACtE,MAAM,CAAC,EAAE,wBAAwB,CAAC,QAAQ,CAAC,CAAC;IAC5C,kDAAkD;IAClD,MAAM,EAAE,OAAO,CAAC;IAChB,uEAAuE;IACvE,kBAAkB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACrC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,IAAI,CACrB,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,EAC7C,YAAY,GAAG,kBAAkB,CAClC,CAAC;IACF,0DAA0D;IAC1D,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,QAAA,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"SqlEditor.d.ts","sourceRoot":"","sources":["../src/SqlEditor.tsx"],"names":[],"mappings":"AAOA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAGnD,OAAO,EAAC,gBAAgB,EAAC,MAAM,+BAA+B,CAAC;AAE/D,OAAO,EAEL,wBAAwB,EACzB,MAAM,kCAAkC,CAAC;AAG1C,MAAM,MAAM,cAAc,GAAG;IAC3B;;0EAEsE;IACtE,MAAM,CAAC,EAAE,wBAAwB,CAAC,QAAQ,CAAC,CAAC;IAC5C,kDAAkD;IAClD,MAAM,EAAE,OAAO,CAAC;IAChB,uEAAuE;IACvE,kBAAkB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACrC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,IAAI,CACrB,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,EAC7C,YAAY,GAAG,kBAAkB,CAClC,CAAC;IACF,0DAA0D;IAC1D,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,QAAA,MAAM,SAAS,4CAiFb,CAAC;AAGH,eAAe,SAAS,CAAC"}
|
package/dist/SqlEditor.js
CHANGED
|
@@ -10,7 +10,13 @@ import { TableStructurePanel, } from './components/TableStructurePanel';
|
|
|
10
10
|
import { useStoreWithSqlEditor } from './SqlEditorSlice';
|
|
11
11
|
const SqlEditor = React.memo((props) => {
|
|
12
12
|
const { schema = '*', documentationPanel, queryResultProps } = props;
|
|
13
|
-
const lastQuery = useStoreWithSqlEditor((
|
|
13
|
+
const lastQuery = useStoreWithSqlEditor((s) => {
|
|
14
|
+
const selectedId = s.sqlEditor.config.selectedQueryId;
|
|
15
|
+
const qr = s.sqlEditor.queryResultsById[selectedId];
|
|
16
|
+
if (qr?.status === 'success' && qr?.type === 'select')
|
|
17
|
+
return qr.query;
|
|
18
|
+
return s.sqlEditor.getCurrentQuery();
|
|
19
|
+
});
|
|
14
20
|
// UI state
|
|
15
21
|
const [showDocs, setShowDocs] = useState(false);
|
|
16
22
|
const [createTableModalOpen, setCreateTableModalOpen] = useState(false);
|
package/dist/SqlEditor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlEditor.js","sourceRoot":"","sources":["../src/SqlEditor.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,MAAM,EACN,eAAe,EACf,cAAc,EACd,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAC,QAAQ,EAAC,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,EAAE,EAAC,WAAW,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AACnD,OAAO,gBAAgB,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAC,gBAAgB,EAAC,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAC,gBAAgB,EAAC,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAC,eAAe,EAAC,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EACL,mBAAmB,GAEpB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAC,qBAAqB,EAAC,MAAM,kBAAkB,CAAC;AAuBvD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAiB,CAAC,KAAK,EAAE,EAAE;IACrD,MAAM,EAAC,MAAM,GAAG,GAAG,EAAE,kBAAkB,EAAE,gBAAgB,EAAC,GAAG,KAAK,CAAC;IAEnE,MAAM,SAAS,GAAG,qBAAqB,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"SqlEditor.js","sourceRoot":"","sources":["../src/SqlEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Button,\n ResizableHandle,\n ResizablePanel,\n ResizablePanelGroup,\n} from '@sqlrooms/ui';\nimport {PlusIcon} from 'lucide-react';\nimport React, {useCallback, useState} from 'react';\nimport CreateTableModal from './components/CreateTableModal';\nimport {QueryEditorPanel} from './components/QueryEditorPanel';\nimport {QueryResultPanel} from './components/QueryResultPanel';\nimport {SqlEditorHeader} from './components/SqlEditorHeader';\nimport {\n TableStructurePanel,\n TableStructurePanelProps,\n} from './components/TableStructurePanel';\nimport {useStoreWithSqlEditor} from './SqlEditorSlice';\n\nexport type SqlEditorProps = {\n /** The database schema to use. Defaults to '*'.\n * If '*' is provided, all tables will be shown.\n * If a function is provided, it will be used to filter the tables. */\n schema?: TableStructurePanelProps['schema'];\n /** Whether the SQL editor is currently visible */\n isOpen: boolean;\n /** Optional component to render SQL documentation in the side panel */\n documentationPanel?: React.ReactNode;\n /**\n * Props forwarded to `QueryResultPanel` to configure result behavior.\n * This provides a single entry point for table interactions.\n */\n queryResultProps?: Pick<\n React.ComponentProps<typeof QueryResultPanel>,\n 'onRowClick' | 'onRowDoubleClick'\n >;\n /** Callback fired when the SQL editor should be closed */\n onClose: () => void;\n};\n\nconst SqlEditor = React.memo<SqlEditorProps>((props) => {\n const {schema = '*', documentationPanel, queryResultProps} = props;\n\n const lastQuery = useStoreWithSqlEditor((s) => {\n const selectedId = s.sqlEditor.config.selectedQueryId;\n const qr = s.sqlEditor.queryResultsById[selectedId];\n if (qr?.status === 'success' && qr?.type === 'select') return qr.query;\n return s.sqlEditor.getCurrentQuery();\n });\n // UI state\n const [showDocs, setShowDocs] = useState(false);\n const [createTableModalOpen, setCreateTableModalOpen] = useState(false);\n\n // Handlers\n const handleToggleDocs = useCallback((show: boolean) => {\n setShowDocs(show);\n }, []);\n\n const handleCreateTable = useCallback(() => {\n setCreateTableModalOpen(true);\n }, []);\n\n return (\n <div className=\"relative flex h-full w-full flex-col overflow-hidden\">\n <SqlEditorHeader\n title=\"SQL Editor\"\n showDocs={showDocs}\n documentationPanel={documentationPanel}\n onToggleDocs={handleToggleDocs}\n />\n <div className=\"bg-muted h-full flex-grow\">\n <ResizablePanelGroup direction=\"horizontal\" className=\"h-full\">\n <ResizablePanel defaultSize={showDocs ? 70 : 100}>\n <ResizablePanelGroup direction=\"vertical\" className=\"h-full\">\n <ResizablePanel defaultSize={50} className=\"flex flex-row\">\n <ResizablePanelGroup direction=\"horizontal\">\n <ResizablePanel defaultSize={20}>\n <TableStructurePanel schema={schema} />\n </ResizablePanel>\n <ResizableHandle withHandle />\n <ResizablePanel defaultSize={80}>\n <QueryEditorPanel />\n </ResizablePanel>\n </ResizablePanelGroup>\n </ResizablePanel>\n <ResizableHandle withHandle />\n <ResizablePanel defaultSize={50}>\n <QueryResultPanel\n onRowClick={queryResultProps?.onRowClick}\n onRowDoubleClick={queryResultProps?.onRowDoubleClick}\n renderActions={() => (\n <div className=\"flex gap-2\">\n <Button size=\"xs\" onClick={handleCreateTable}>\n <PlusIcon className=\"h-4 w-4\" />\n New table\n </Button>\n </div>\n )}\n />\n </ResizablePanel>\n </ResizablePanelGroup>\n </ResizablePanel>\n {showDocs && (\n <>\n <ResizableHandle withHandle />\n <ResizablePanel defaultSize={30}>\n {documentationPanel}\n </ResizablePanel>\n </>\n )}\n </ResizablePanelGroup>\n </div>\n <CreateTableModal\n query={lastQuery}\n isOpen={createTableModalOpen}\n onClose={() => setCreateTableModalOpen(false)}\n allowMultipleStatements={true}\n showSchemaSelection={true}\n />\n </div>\n );\n});\nSqlEditor.displayName = 'SqlEditor';\n\nexport default SqlEditor;\n"]}
|
package/dist/SqlEditorSlice.d.ts
CHANGED
|
@@ -29,7 +29,10 @@ export declare function isQueryWithResult(queryResult: QueryResult | undefined):
|
|
|
29
29
|
export type SqlEditorSliceState = {
|
|
30
30
|
sqlEditor: {
|
|
31
31
|
config: SqlEditorSliceConfig;
|
|
32
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Query results keyed by queryId (tab id).
|
|
34
|
+
*/
|
|
35
|
+
queryResultsById: Record<string, QueryResult | undefined>;
|
|
33
36
|
/** @deprecated */
|
|
34
37
|
selectedTable?: string;
|
|
35
38
|
/** @deprecated Use `useStoreWithSqlEditor((s) => s.db.isRefreshingTableSchemas)` instead. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlEditorSlice.d.ts","sourceRoot":"","sources":["../src/SqlEditorSlice.tsx"],"names":[],"mappings":"AAQA,OAAO,EAGL,mBAAmB,EACnB,YAAY,EAEb,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,oBAAoB,EACrB,MAAM,6BAA6B,CAAC;AAErC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAKtC,MAAM,MAAM,WAAW,GACnB;IAAC,MAAM,EAAE,SAAS,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,eAAe,CAAA;CAAC,GAC1E;IAAC,MAAM,EAAE,SAAS,CAAA;CAAC,GACnB;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,GAChC;IACE,MAAM,EAAE,SAAS,CAAC;IAClB,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IACtC,MAAM,EAAE,KAAK,CAAC,KAAK,GAAG,SAAS,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,kBAAkB,EAAE,MAAM,CAAC;CAC5B,GACD;IACE,MAAM,EAAE,SAAS,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,kBAAkB,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEN,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,WAAW,GAAG,SAAS,GACnC,WAAW,IAAI,WAAW,GAAG;IAC9B,MAAM,EAAE,SAAS,CAAC;IAClB,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;CACvC,CAOA;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE;QACT,MAAM,EAAE,oBAAoB,CAAC;QAE7B,
|
|
1
|
+
{"version":3,"file":"SqlEditorSlice.d.ts","sourceRoot":"","sources":["../src/SqlEditorSlice.tsx"],"names":[],"mappings":"AAQA,OAAO,EAGL,mBAAmB,EACnB,YAAY,EAEb,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,oBAAoB,EACrB,MAAM,6BAA6B,CAAC;AAErC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAKtC,MAAM,MAAM,WAAW,GACnB;IAAC,MAAM,EAAE,SAAS,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,eAAe,CAAA;CAAC,GAC1E;IAAC,MAAM,EAAE,SAAS,CAAA;CAAC,GACnB;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,GAChC;IACE,MAAM,EAAE,SAAS,CAAC;IAClB,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IACtC,MAAM,EAAE,KAAK,CAAC,KAAK,GAAG,SAAS,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,kBAAkB,EAAE,MAAM,CAAC;CAC5B,GACD;IACE,MAAM,EAAE,SAAS,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,kBAAkB,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEN,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,WAAW,GAAG,SAAS,GACnC,WAAW,IAAI,WAAW,GAAG;IAC9B,MAAM,EAAE,SAAS,CAAC;IAClB,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;CACvC,CAOA;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE;QACT,MAAM,EAAE,oBAAoB,CAAC;QAE7B;;WAEG;QACH,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,CAAC,CAAC;QAC1D,mBAAmB;QACnB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,6FAA6F;QAC7F,eAAe,EAAE,OAAO,CAAC;QACzB,kBAAkB;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;QAErB,gBAAgB,EAAE,MAAM,CAAC;QACzB,4CAA4C;QAC5C,uBAAuB,EAAE,MAAM,EAAE,CAAC;QAElC;;WAEG;QACH,SAAS,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI,CAAC;QAE9C;;WAEG;QACH,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAE/C;;WAEG;QACH,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;QAEzC;;WAEG;QACH,iBAAiB,IAAI,IAAI,CAAC;QAE1B;;;WAGG;QACH,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAElE;;;WAGG;QACH,cAAc,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG;YACrC,EAAE,EAAE,MAAM,CAAC;YACX,IAAI,EAAE,MAAM,CAAC;YACb,KAAK,EAAE,MAAM,CAAC;SACf,CAAC;QAEF;;;WAGG;QACH,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAEtC;;;;WAIG;QACH,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAEvD;;;WAGG;QACH,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAErC;;;WAGG;QACH,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAEpC;;;WAGG;QACH,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAEpC;;;;WAIG;QACH,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QAE1D;;;WAGG;QACH,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAE1C;;WAEG;QACH,eAAe,IAAI,MAAM,CAAC;QAE1B,kBAAkB;QAClB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;QAE7C,iBAAiB,IAAI,IAAI,CAAC;QAE1B,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;KAC1C,CAAC;CACH,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,EACnC,MAAuC,EACvC,gBAAsB,EACtB,uBAA0C,GAC3C,GAAE;IACD,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B,GAAG,YAAY,CAAC,mBAAmB,CAAC,CAwYzC;AAED,KAAK,sBAAsB,GAAG,mBAAmB,GAAG,mBAAmB,CAAC;AAExE,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,QAAQ,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,CAAC,GAC7C,CAAC,CAIH"}
|
package/dist/SqlEditorSlice.js
CHANGED
|
@@ -18,6 +18,7 @@ export function createSqlEditorSlice({ config = createDefaultSqlEditorConfig(),
|
|
|
18
18
|
sqlEditor: {
|
|
19
19
|
config,
|
|
20
20
|
// Initialize runtime state
|
|
21
|
+
queryResultsById: {},
|
|
21
22
|
isTablesLoading: false,
|
|
22
23
|
queryResultLimit,
|
|
23
24
|
queryResultLimitOptions,
|
|
@@ -36,10 +37,12 @@ export function createSqlEditorSlice({ config = createDefaultSqlEditorConfig(),
|
|
|
36
37
|
},
|
|
37
38
|
createQueryTab: (initialQuery = '') => {
|
|
38
39
|
const sqlEditorConfig = get().sqlEditor.config;
|
|
40
|
+
const now = Date.now();
|
|
39
41
|
const newQuery = {
|
|
40
42
|
id: createId(),
|
|
41
43
|
name: generateUniqueName('Untitled', sqlEditorConfig.queries.map((q) => q.name)),
|
|
42
44
|
query: initialQuery,
|
|
45
|
+
lastOpenedAt: now,
|
|
43
46
|
};
|
|
44
47
|
set((state) => produce(state, (draft) => {
|
|
45
48
|
draft.sqlEditor.config.queries.push(newQuery);
|
|
@@ -62,6 +65,8 @@ export function createSqlEditorSlice({ config = createDefaultSqlEditorConfig(),
|
|
|
62
65
|
set((state) => produce(state, (draft) => {
|
|
63
66
|
draft.sqlEditor.config.queries = filteredQueries;
|
|
64
67
|
draft.sqlEditor.config.openTabs = openTabs.filter((id) => id !== queryId);
|
|
68
|
+
const { [queryId]: _removed, ...rest } = draft.sqlEditor.queryResultsById;
|
|
69
|
+
draft.sqlEditor.queryResultsById = rest;
|
|
65
70
|
// If we deleted the selected query, select another one
|
|
66
71
|
if (wasSelected) {
|
|
67
72
|
const newOpenTabs = draft.sqlEditor.config.openTabs;
|
|
@@ -74,6 +79,10 @@ export function createSqlEditorSlice({ config = createDefaultSqlEditorConfig(),
|
|
|
74
79
|
const newSelectedId = newOpenTabs[newIndex];
|
|
75
80
|
if (newSelectedId) {
|
|
76
81
|
draft.sqlEditor.config.selectedQueryId = newSelectedId;
|
|
82
|
+
const newSelectedQuery = draft.sqlEditor.config.queries.find((q) => q.id === newSelectedId);
|
|
83
|
+
if (newSelectedQuery) {
|
|
84
|
+
newSelectedQuery.lastOpenedAt = Date.now();
|
|
85
|
+
}
|
|
77
86
|
}
|
|
78
87
|
}
|
|
79
88
|
else if (remainingQueries.length > 0) {
|
|
@@ -82,6 +91,7 @@ export function createSqlEditorSlice({ config = createDefaultSqlEditorConfig(),
|
|
|
82
91
|
if (queryToOpen) {
|
|
83
92
|
draft.sqlEditor.config.openTabs.push(queryToOpen.id);
|
|
84
93
|
draft.sqlEditor.config.selectedQueryId = queryToOpen.id;
|
|
94
|
+
queryToOpen.lastOpenedAt = Date.now();
|
|
85
95
|
}
|
|
86
96
|
}
|
|
87
97
|
}
|
|
@@ -107,6 +117,10 @@ export function createSqlEditorSlice({ config = createDefaultSqlEditorConfig(),
|
|
|
107
117
|
draft.sqlEditor.config.openTabs.push(queryId);
|
|
108
118
|
}
|
|
109
119
|
draft.sqlEditor.config.selectedQueryId = queryId;
|
|
120
|
+
const query = draft.sqlEditor.config.queries.find((q) => q.id === queryId);
|
|
121
|
+
if (query) {
|
|
122
|
+
query.lastOpenedAt = Date.now();
|
|
123
|
+
}
|
|
110
124
|
}));
|
|
111
125
|
},
|
|
112
126
|
setOpenTabs: (tabIds) => {
|
|
@@ -125,6 +139,10 @@ export function createSqlEditorSlice({ config = createDefaultSqlEditorConfig(),
|
|
|
125
139
|
setSelectedQueryId: (queryId) => {
|
|
126
140
|
set((state) => produce(state, (draft) => {
|
|
127
141
|
draft.sqlEditor.config.selectedQueryId = queryId;
|
|
142
|
+
const query = draft.sqlEditor.config.queries.find((q) => q.id === queryId);
|
|
143
|
+
if (query) {
|
|
144
|
+
query.lastOpenedAt = Date.now();
|
|
145
|
+
}
|
|
128
146
|
}));
|
|
129
147
|
},
|
|
130
148
|
getCurrentQuery: () => {
|
|
@@ -140,25 +158,21 @@ export function createSqlEditorSlice({ config = createDefaultSqlEditorConfig(),
|
|
|
140
158
|
}));
|
|
141
159
|
},
|
|
142
160
|
clearQueryResults: () => {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
...state,
|
|
146
|
-
sqlEditor: {
|
|
147
|
-
...state.sqlEditor,
|
|
148
|
-
queryResults: null,
|
|
149
|
-
queryError: undefined,
|
|
150
|
-
},
|
|
161
|
+
set((state) => produce(state, (draft) => {
|
|
162
|
+
draft.sqlEditor.queryResultsById = {};
|
|
151
163
|
}));
|
|
152
164
|
},
|
|
153
165
|
parseAndRunCurrentQuery: async () => get().sqlEditor.parseAndRunQuery(get().sqlEditor.getCurrentQuery()),
|
|
154
166
|
abortCurrentQuery: () => {
|
|
155
|
-
const
|
|
167
|
+
const selectedQueryId = get().sqlEditor.config.selectedQueryId;
|
|
168
|
+
const currentResult = get().sqlEditor.queryResultsById[selectedQueryId];
|
|
156
169
|
if (currentResult?.status === 'loading' && currentResult.controller) {
|
|
157
170
|
currentResult.controller.abort();
|
|
158
171
|
}
|
|
159
172
|
set((state) => produce(state, (draft) => {
|
|
160
|
-
|
|
161
|
-
|
|
173
|
+
const result = draft.sqlEditor.queryResultsById[selectedQueryId];
|
|
174
|
+
if (result?.status === 'loading') {
|
|
175
|
+
result.isBeingAborted = true;
|
|
162
176
|
}
|
|
163
177
|
}));
|
|
164
178
|
},
|
|
@@ -168,7 +182,9 @@ export function createSqlEditorSlice({ config = createDefaultSqlEditorConfig(),
|
|
|
168
182
|
}));
|
|
169
183
|
},
|
|
170
184
|
parseAndRunQuery: async (query) => {
|
|
171
|
-
|
|
185
|
+
const selectedQueryId = get().sqlEditor.config.selectedQueryId;
|
|
186
|
+
const existingResult = get().sqlEditor.queryResultsById[selectedQueryId];
|
|
187
|
+
if (existingResult?.status === 'loading') {
|
|
172
188
|
throw new Error('Query already running');
|
|
173
189
|
}
|
|
174
190
|
if (!query.trim()) {
|
|
@@ -179,7 +195,7 @@ export function createSqlEditorSlice({ config = createDefaultSqlEditorConfig(),
|
|
|
179
195
|
// First update loading state and clear results
|
|
180
196
|
set((state) => produce(state, (draft) => {
|
|
181
197
|
draft.sqlEditor.selectedTable = undefined;
|
|
182
|
-
draft.sqlEditor.
|
|
198
|
+
draft.sqlEditor.queryResultsById[selectedQueryId] = {
|
|
183
199
|
status: 'loading',
|
|
184
200
|
isBeingAborted: false,
|
|
185
201
|
controller: queryController,
|
|
@@ -279,9 +295,16 @@ export function createSqlEditorSlice({ config = createDefaultSqlEditorConfig(),
|
|
|
279
295
|
};
|
|
280
296
|
}
|
|
281
297
|
}
|
|
298
|
+
// Update state without Immer since Arrow Tables don't play well with drafts.
|
|
282
299
|
set((state) => ({
|
|
283
300
|
...state,
|
|
284
|
-
sqlEditor: {
|
|
301
|
+
sqlEditor: {
|
|
302
|
+
...state.sqlEditor,
|
|
303
|
+
queryResultsById: {
|
|
304
|
+
...state.sqlEditor.queryResultsById,
|
|
305
|
+
[selectedQueryId]: queryResult,
|
|
306
|
+
},
|
|
307
|
+
},
|
|
285
308
|
}));
|
|
286
309
|
},
|
|
287
310
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlEditorSlice.js","sourceRoot":"","sources":["../src/SqlEditorSlice.tsx"],"names":[],"mappings":"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","sourcesContent":["import {createId} from '@paralleldrive/cuid2';\nimport {\n DuckDbSliceState,\n getSqlErrorWithPointer,\n joinStatements,\n makeLimitQuery,\n separateLastStatement,\n} from '@sqlrooms/duckdb';\nimport {\n BaseRoomStoreState,\n createSlice,\n RoomShellSliceState,\n StateCreator,\n useBaseRoomShellStore,\n} from '@sqlrooms/room-shell';\nimport {\n createDefaultSqlEditorConfig,\n SqlEditorSliceConfig,\n} from '@sqlrooms/sql-editor-config';\nimport {generateUniqueName} from '@sqlrooms/utils';\nimport * as arrow from 'apache-arrow';\nimport {csvFormat} from 'd3-dsv';\nimport {saveAs} from 'file-saver';\nimport {produce} from 'immer';\n\nexport type QueryResult =\n | {status: 'loading'; isBeingAborted?: boolean; controller: AbortController}\n | {status: 'aborted'}\n | {status: 'error'; error: string}\n | {\n status: 'success';\n type: 'pragma' | 'explain' | 'select';\n result: arrow.Table | undefined;\n query: string;\n lastQueryStatement: string;\n }\n | {\n status: 'success';\n type: 'exec';\n query: string;\n lastQueryStatement: string;\n };\n\nexport function isQueryWithResult(\n queryResult: QueryResult | undefined,\n): queryResult is QueryResult & {\n status: 'success';\n type: 'pragma' | 'explain' | 'select';\n} {\n return (\n queryResult?.status === 'success' &&\n (queryResult.type === 'pragma' ||\n queryResult.type === 'explain' ||\n queryResult.type === 'select')\n );\n}\n\nexport type SqlEditorSliceState = {\n sqlEditor: {\n config: SqlEditorSliceConfig;\n // Runtime state\n queryResult?: QueryResult;\n /** @deprecated */\n selectedTable?: string;\n /** @deprecated Use `useStoreWithSqlEditor((s) => s.db.isRefreshingTableSchemas)` instead. */\n isTablesLoading: boolean;\n /** @deprecated */\n tablesError?: string;\n\n queryResultLimit: number;\n /** Options for the result limit dropdown */\n queryResultLimitOptions: number[];\n\n /**\n * Set the config for the sql editor slice.\n */\n setConfig(config: SqlEditorSliceConfig): void;\n\n /**\n * Run the currently selected query.\n */\n parseAndRunQuery(query: string): Promise<void>;\n\n /**\n * Run the currently selected query.\n */\n parseAndRunCurrentQuery(): Promise<void>;\n\n /**\n * Abort the currently running query.\n */\n abortCurrentQuery(): void;\n\n /**\n * Export query results to CSV.\n * @deprecated Use `useExportToCsv` from `@sqlrooms/duckdb` instead.\n */\n exportResultsToCsv(results: arrow.Table, filename?: string): void;\n\n /**\n * Create a new query tab.\n * @param initialQuery - Optional initial query text.\n */\n createQueryTab(initialQuery?: string): {\n id: string;\n name: string;\n query: string;\n };\n\n /**\n * Delete a query tab.\n * @param queryId - The ID of the query to delete.\n */\n deleteQueryTab(queryId: string): void;\n\n /**\n * Rename a query tab.\n * @param queryId - The ID of the query to rename.\n * @param newName - The new name for the query.\n */\n renameQueryTab(queryId: string, newName: string): void;\n\n /**\n * Close a query tab.\n * @param queryId - The ID of the query to close.\n */\n closeQueryTab(queryId: string): void;\n\n /**\n * Open a closed tab id.\n * @param queryId - The ID of the query to open.\n */\n openQueryTab(queryId: string): void;\n\n /**\n * Set the list of open tab IDs. Used for reordering or opening tabs.\n * @param tabIds - The new list of open tab IDs.\n */\n setOpenTabs(tabIds: string[]): void;\n\n /**\n * Update the SQL text for a query.\n * @param queryId - The ID of the query to update.\n * @param queryText - The new SQL text.\n */\n updateQueryText(queryId: string, queryText: string): void;\n\n /**\n * Set the selected query tab.\n * @param queryId - The ID of the query to select.\n */\n setSelectedQueryId(queryId: string): void;\n\n /**\n * Get the currently selected query's SQL text.\n */\n getCurrentQuery(): string;\n\n /** @deprecated */\n selectTable(table: string | undefined): void;\n\n clearQueryResults(): void;\n\n setQueryResultLimit(limit: number): void;\n };\n};\n\nexport function createSqlEditorSlice({\n config = createDefaultSqlEditorConfig(),\n queryResultLimit = 100,\n queryResultLimitOptions = [100, 500, 1000],\n}: {\n config?: SqlEditorSliceConfig;\n queryResultLimit?: number;\n queryResultLimitOptions?: number[];\n} = {}): StateCreator<SqlEditorSliceState> {\n return createSlice<\n SqlEditorSliceState,\n BaseRoomStoreState & DuckDbSliceState & SqlEditorSliceState\n >((set, get) => {\n return {\n sqlEditor: {\n config,\n // Initialize runtime state\n isTablesLoading: false,\n queryResultLimit,\n queryResultLimitOptions,\n\n setConfig: (config) => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.config = config;\n }),\n );\n },\n\n exportResultsToCsv: (results, filename) => {\n if (!results) return;\n const blob = new Blob([csvFormat(results.toArray())], {\n type: 'text/plain;charset=utf-8',\n });\n saveAs(blob, filename || `export-${createId().substring(0, 5)}.csv`);\n },\n\n createQueryTab: (initialQuery = '') => {\n const sqlEditorConfig = get().sqlEditor.config;\n const newQuery = {\n id: createId(),\n name: generateUniqueName(\n 'Untitled',\n sqlEditorConfig.queries.map((q) => q.name),\n ),\n query: initialQuery,\n };\n\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.config.queries.push(newQuery);\n draft.sqlEditor.config.openTabs.push(newQuery.id);\n draft.sqlEditor.config.selectedQueryId = newQuery.id;\n }),\n );\n\n return newQuery;\n },\n\n deleteQueryTab: (queryId) => {\n const sqlEditorConfig = get().sqlEditor.config;\n const queries = sqlEditorConfig.queries;\n const openTabs = sqlEditorConfig.openTabs;\n\n if (queries.length <= 1) {\n // Don't delete the last query\n return;\n }\n\n const wasSelected = sqlEditorConfig.selectedQueryId === queryId;\n const deletingOpenIndex = openTabs.indexOf(queryId);\n const filteredQueries = queries.filter((q) => q.id !== queryId);\n\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.config.queries = filteredQueries;\n draft.sqlEditor.config.openTabs = openTabs.filter(\n (id) => id !== queryId,\n );\n\n // If we deleted the selected query, select another one\n if (wasSelected) {\n const newOpenTabs = draft.sqlEditor.config.openTabs;\n const remainingQueries = draft.sqlEditor.config.queries;\n\n if (newOpenTabs.length > 0) {\n // Select from remaining open tabs\n const newIndex =\n deletingOpenIndex === 0\n ? 0\n : Math.min(deletingOpenIndex - 1, newOpenTabs.length - 1);\n const newSelectedId = newOpenTabs[newIndex];\n if (newSelectedId) {\n draft.sqlEditor.config.selectedQueryId = newSelectedId;\n }\n } else if (remainingQueries.length > 0) {\n // No open tabs left, open a closed query\n const queryToOpen = remainingQueries[0];\n if (queryToOpen) {\n draft.sqlEditor.config.openTabs.push(queryToOpen.id);\n draft.sqlEditor.config.selectedQueryId = queryToOpen.id;\n }\n }\n }\n }),\n );\n },\n\n renameQueryTab: (queryId, newName) => {\n set((state) =>\n produce(state, (draft) => {\n const query = draft.sqlEditor.config.queries.find(\n (q) => q.id === queryId,\n );\n if (query) {\n query.name = newName || query.name;\n }\n }),\n );\n },\n\n closeQueryTab: (queryId) => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.config.openTabs =\n draft.sqlEditor.config.openTabs.filter((id) => id !== queryId);\n }),\n );\n },\n\n openQueryTab: (queryId) => {\n set((state) =>\n produce(state, (draft) => {\n if (!draft.sqlEditor.config.openTabs.includes(queryId)) {\n draft.sqlEditor.config.openTabs.push(queryId);\n }\n draft.sqlEditor.config.selectedQueryId = queryId;\n }),\n );\n },\n\n setOpenTabs: (tabIds) => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.config.openTabs = tabIds;\n }),\n );\n },\n\n updateQueryText: (queryId, queryText) => {\n set((state) =>\n produce(state, (draft) => {\n const query = draft.sqlEditor.config.queries.find(\n (q) => q.id === queryId,\n );\n if (query) {\n query.query = queryText;\n }\n }),\n );\n },\n\n setSelectedQueryId: (queryId) => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.config.selectedQueryId = queryId;\n }),\n );\n },\n\n getCurrentQuery: () => {\n const sqlEditorConfig = get().sqlEditor.config;\n const selectedId = sqlEditorConfig.selectedQueryId;\n const query = sqlEditorConfig.queries.find(\n (q) => q.id === selectedId,\n );\n return query?.query || '';\n },\n\n /** @deprecated */\n selectTable: (table) => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.selectedTable = table;\n }),\n );\n },\n\n clearQueryResults: () => {\n // Update state without using Immer for the Table type\n set((state) => ({\n ...state,\n sqlEditor: {\n ...state.sqlEditor,\n queryResults: null,\n queryError: undefined,\n },\n }));\n },\n\n parseAndRunCurrentQuery: async (): Promise<void> =>\n get().sqlEditor.parseAndRunQuery(get().sqlEditor.getCurrentQuery()),\n\n abortCurrentQuery: () => {\n const currentResult = get().sqlEditor.queryResult;\n if (currentResult?.status === 'loading' && currentResult.controller) {\n currentResult.controller.abort();\n }\n\n set((state) =>\n produce(state, (draft) => {\n if (draft.sqlEditor.queryResult?.status === 'loading') {\n draft.sqlEditor.queryResult.isBeingAborted = true;\n }\n }),\n );\n },\n\n setQueryResultLimit: (limit) => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.queryResultLimit = limit;\n }),\n );\n },\n\n parseAndRunQuery: async (query): Promise<void> => {\n if (get().sqlEditor.queryResult?.status === 'loading') {\n throw new Error('Query already running');\n }\n if (!query.trim()) {\n return;\n }\n\n // Create abort controller for this query execution\n const queryController = new AbortController();\n\n // First update loading state and clear results\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.selectedTable = undefined;\n draft.sqlEditor.queryResult = {\n status: 'loading',\n isBeingAborted: false,\n controller: queryController,\n };\n }),\n );\n\n let queryResult: QueryResult;\n try {\n const connector = await get().db.getConnector();\n const signal = queryController.signal;\n\n const {precedingStatements, lastStatement: lastQueryStatement} =\n separateLastStatement(query);\n const hasMultipleStatements = precedingStatements.length > 0;\n\n if (signal.aborted) {\n throw new Error('Query aborted');\n }\n\n const parsedLastStatement =\n await get().db.sqlSelectToJson(lastQueryStatement);\n\n if (signal.aborted) {\n throw new Error('Query aborted');\n }\n\n const isValidSelectQuery = !parsedLastStatement.error;\n\n if (isValidSelectQuery) {\n // Add limit to the last statement\n const limitedLastStatement = makeLimitQuery(lastQueryStatement, {\n sanitize: false, // should already be sanitized\n limit: get().sqlEditor.queryResultLimit,\n });\n const queryWithLimit = joinStatements(\n precedingStatements,\n limitedLastStatement,\n );\n const result = await connector.query(queryWithLimit, {signal});\n queryResult = {\n status: 'success',\n type: 'select',\n query,\n lastQueryStatement,\n result,\n };\n } else {\n // Run the complete query as it is\n if (\n parsedLastStatement.error &&\n parsedLastStatement.error_type !== 'not implemented'\n ) {\n throw (\n `${parsedLastStatement.error_type} ${parsedLastStatement.error_subtype}: ${parsedLastStatement.error_message}` +\n `\\n${getSqlErrorWithPointer(lastQueryStatement, Number(parsedLastStatement.position)).formatted}`\n );\n }\n\n const result = await connector.query(query, {signal});\n // EXPLAIN and PRAGMA are not detected as select queries\n // and we cannot wrap them in a SELECT * FROM,\n // but we can still execute them and return the result\n if (/^(EXPLAIN)/i.test(lastQueryStatement)) {\n queryResult = {\n status: 'success',\n type: 'explain',\n query,\n lastQueryStatement,\n result,\n };\n } else if (/^(PRAGMA)/i.test(lastQueryStatement)) {\n queryResult = {\n status: 'success',\n type: 'pragma',\n query,\n lastQueryStatement,\n result,\n };\n } else {\n queryResult = {\n status: 'success',\n type: 'exec',\n query,\n lastQueryStatement,\n };\n }\n }\n if (signal.aborted) {\n throw new Error('Query aborted');\n }\n // Refresh table schemas if there are multiple statements or if the\n // last statement is not a select query\n if (hasMultipleStatements || !isValidSelectQuery) {\n get().db.refreshTableSchemas();\n }\n if (signal.aborted) {\n throw new Error('Query aborted');\n }\n } catch (e) {\n console.error(e);\n const errorMessage = e instanceof Error ? e.message : String(e);\n if (\n errorMessage === 'Query aborted' ||\n queryController.signal.aborted\n ) {\n queryResult = {status: 'aborted'};\n } else {\n queryResult = {\n status: 'error',\n error: errorMessage,\n };\n }\n }\n\n set((state) => ({\n ...state,\n sqlEditor: {...state.sqlEditor, queryResult},\n }));\n },\n },\n } satisfies SqlEditorSliceState;\n });\n}\n\ntype RoomStateWithSqlEditor = RoomShellSliceState & SqlEditorSliceState;\n\nexport function useStoreWithSqlEditor<T>(\n selector: (state: RoomStateWithSqlEditor) => T,\n): T {\n return useBaseRoomShellStore<RoomShellSliceState, T>((state) =>\n selector(state as unknown as RoomStateWithSqlEditor),\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SqlEditorSlice.js","sourceRoot":"","sources":["../src/SqlEditorSlice.tsx"],"names":[],"mappings":"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","sourcesContent":["import {createId} from '@paralleldrive/cuid2';\nimport {\n DuckDbSliceState,\n getSqlErrorWithPointer,\n joinStatements,\n makeLimitQuery,\n separateLastStatement,\n} from '@sqlrooms/duckdb';\nimport {\n BaseRoomStoreState,\n createSlice,\n RoomShellSliceState,\n StateCreator,\n useBaseRoomShellStore,\n} from '@sqlrooms/room-shell';\nimport {\n createDefaultSqlEditorConfig,\n SqlEditorSliceConfig,\n} from '@sqlrooms/sql-editor-config';\nimport {generateUniqueName} from '@sqlrooms/utils';\nimport * as arrow from 'apache-arrow';\nimport {csvFormat} from 'd3-dsv';\nimport {saveAs} from 'file-saver';\nimport {produce} from 'immer';\n\nexport type QueryResult =\n | {status: 'loading'; isBeingAborted?: boolean; controller: AbortController}\n | {status: 'aborted'}\n | {status: 'error'; error: string}\n | {\n status: 'success';\n type: 'pragma' | 'explain' | 'select';\n result: arrow.Table | undefined;\n query: string;\n lastQueryStatement: string;\n }\n | {\n status: 'success';\n type: 'exec';\n query: string;\n lastQueryStatement: string;\n };\n\nexport function isQueryWithResult(\n queryResult: QueryResult | undefined,\n): queryResult is QueryResult & {\n status: 'success';\n type: 'pragma' | 'explain' | 'select';\n} {\n return (\n queryResult?.status === 'success' &&\n (queryResult.type === 'pragma' ||\n queryResult.type === 'explain' ||\n queryResult.type === 'select')\n );\n}\n\nexport type SqlEditorSliceState = {\n sqlEditor: {\n config: SqlEditorSliceConfig;\n // Runtime state\n /**\n * Query results keyed by queryId (tab id).\n */\n queryResultsById: Record<string, QueryResult | undefined>;\n /** @deprecated */\n selectedTable?: string;\n /** @deprecated Use `useStoreWithSqlEditor((s) => s.db.isRefreshingTableSchemas)` instead. */\n isTablesLoading: boolean;\n /** @deprecated */\n tablesError?: string;\n\n queryResultLimit: number;\n /** Options for the result limit dropdown */\n queryResultLimitOptions: number[];\n\n /**\n * Set the config for the sql editor slice.\n */\n setConfig(config: SqlEditorSliceConfig): void;\n\n /**\n * Run the currently selected query.\n */\n parseAndRunQuery(query: string): Promise<void>;\n\n /**\n * Run the currently selected query.\n */\n parseAndRunCurrentQuery(): Promise<void>;\n\n /**\n * Abort the currently running query.\n */\n abortCurrentQuery(): void;\n\n /**\n * Export query results to CSV.\n * @deprecated Use `useExportToCsv` from `@sqlrooms/duckdb` instead.\n */\n exportResultsToCsv(results: arrow.Table, filename?: string): void;\n\n /**\n * Create a new query tab.\n * @param initialQuery - Optional initial query text.\n */\n createQueryTab(initialQuery?: string): {\n id: string;\n name: string;\n query: string;\n };\n\n /**\n * Delete a query tab.\n * @param queryId - The ID of the query to delete.\n */\n deleteQueryTab(queryId: string): void;\n\n /**\n * Rename a query tab.\n * @param queryId - The ID of the query to rename.\n * @param newName - The new name for the query.\n */\n renameQueryTab(queryId: string, newName: string): void;\n\n /**\n * Close a query tab.\n * @param queryId - The ID of the query to close.\n */\n closeQueryTab(queryId: string): void;\n\n /**\n * Open a closed tab id.\n * @param queryId - The ID of the query to open.\n */\n openQueryTab(queryId: string): void;\n\n /**\n * Set the list of open tab IDs. Used for reordering or opening tabs.\n * @param tabIds - The new list of open tab IDs.\n */\n setOpenTabs(tabIds: string[]): void;\n\n /**\n * Update the SQL text for a query.\n * @param queryId - The ID of the query to update.\n * @param queryText - The new SQL text.\n */\n updateQueryText(queryId: string, queryText: string): void;\n\n /**\n * Set the selected query tab.\n * @param queryId - The ID of the query to select.\n */\n setSelectedQueryId(queryId: string): void;\n\n /**\n * Get the currently selected query's SQL text.\n */\n getCurrentQuery(): string;\n\n /** @deprecated */\n selectTable(table: string | undefined): void;\n\n clearQueryResults(): void;\n\n setQueryResultLimit(limit: number): void;\n };\n};\n\nexport function createSqlEditorSlice({\n config = createDefaultSqlEditorConfig(),\n queryResultLimit = 100,\n queryResultLimitOptions = [100, 500, 1000],\n}: {\n config?: SqlEditorSliceConfig;\n queryResultLimit?: number;\n queryResultLimitOptions?: number[];\n} = {}): StateCreator<SqlEditorSliceState> {\n return createSlice<\n SqlEditorSliceState,\n BaseRoomStoreState & DuckDbSliceState & SqlEditorSliceState\n >((set, get) => {\n return {\n sqlEditor: {\n config,\n // Initialize runtime state\n queryResultsById: {},\n isTablesLoading: false,\n queryResultLimit,\n queryResultLimitOptions,\n\n setConfig: (config) => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.config = config;\n }),\n );\n },\n\n exportResultsToCsv: (results, filename) => {\n if (!results) return;\n const blob = new Blob([csvFormat(results.toArray())], {\n type: 'text/plain;charset=utf-8',\n });\n saveAs(blob, filename || `export-${createId().substring(0, 5)}.csv`);\n },\n\n createQueryTab: (initialQuery = '') => {\n const sqlEditorConfig = get().sqlEditor.config;\n const now = Date.now();\n const newQuery = {\n id: createId(),\n name: generateUniqueName(\n 'Untitled',\n sqlEditorConfig.queries.map((q) => q.name),\n ),\n query: initialQuery,\n lastOpenedAt: now,\n };\n\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.config.queries.push(newQuery);\n draft.sqlEditor.config.openTabs.push(newQuery.id);\n draft.sqlEditor.config.selectedQueryId = newQuery.id;\n }),\n );\n\n return newQuery;\n },\n\n deleteQueryTab: (queryId) => {\n const sqlEditorConfig = get().sqlEditor.config;\n const queries = sqlEditorConfig.queries;\n const openTabs = sqlEditorConfig.openTabs;\n\n if (queries.length <= 1) {\n // Don't delete the last query\n return;\n }\n\n const wasSelected = sqlEditorConfig.selectedQueryId === queryId;\n const deletingOpenIndex = openTabs.indexOf(queryId);\n const filteredQueries = queries.filter((q) => q.id !== queryId);\n\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.config.queries = filteredQueries;\n draft.sqlEditor.config.openTabs = openTabs.filter(\n (id) => id !== queryId,\n );\n const {[queryId]: _removed, ...rest} =\n draft.sqlEditor.queryResultsById;\n draft.sqlEditor.queryResultsById = rest;\n\n // If we deleted the selected query, select another one\n if (wasSelected) {\n const newOpenTabs = draft.sqlEditor.config.openTabs;\n const remainingQueries = draft.sqlEditor.config.queries;\n\n if (newOpenTabs.length > 0) {\n // Select from remaining open tabs\n const newIndex =\n deletingOpenIndex === 0\n ? 0\n : Math.min(deletingOpenIndex - 1, newOpenTabs.length - 1);\n const newSelectedId = newOpenTabs[newIndex];\n if (newSelectedId) {\n draft.sqlEditor.config.selectedQueryId = newSelectedId;\n const newSelectedQuery =\n draft.sqlEditor.config.queries.find(\n (q) => q.id === newSelectedId,\n );\n if (newSelectedQuery) {\n newSelectedQuery.lastOpenedAt = Date.now();\n }\n }\n } else if (remainingQueries.length > 0) {\n // No open tabs left, open a closed query\n const queryToOpen = remainingQueries[0];\n if (queryToOpen) {\n draft.sqlEditor.config.openTabs.push(queryToOpen.id);\n draft.sqlEditor.config.selectedQueryId = queryToOpen.id;\n queryToOpen.lastOpenedAt = Date.now();\n }\n }\n }\n }),\n );\n },\n\n renameQueryTab: (queryId, newName) => {\n set((state) =>\n produce(state, (draft) => {\n const query = draft.sqlEditor.config.queries.find(\n (q) => q.id === queryId,\n );\n if (query) {\n query.name = newName || query.name;\n }\n }),\n );\n },\n\n closeQueryTab: (queryId) => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.config.openTabs =\n draft.sqlEditor.config.openTabs.filter((id) => id !== queryId);\n }),\n );\n },\n\n openQueryTab: (queryId) => {\n set((state) =>\n produce(state, (draft) => {\n if (!draft.sqlEditor.config.openTabs.includes(queryId)) {\n draft.sqlEditor.config.openTabs.push(queryId);\n }\n draft.sqlEditor.config.selectedQueryId = queryId;\n const query = draft.sqlEditor.config.queries.find(\n (q) => q.id === queryId,\n );\n if (query) {\n query.lastOpenedAt = Date.now();\n }\n }),\n );\n },\n\n setOpenTabs: (tabIds) => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.config.openTabs = tabIds;\n }),\n );\n },\n\n updateQueryText: (queryId, queryText) => {\n set((state) =>\n produce(state, (draft) => {\n const query = draft.sqlEditor.config.queries.find(\n (q) => q.id === queryId,\n );\n if (query) {\n query.query = queryText;\n }\n }),\n );\n },\n\n setSelectedQueryId: (queryId) => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.config.selectedQueryId = queryId;\n const query = draft.sqlEditor.config.queries.find(\n (q) => q.id === queryId,\n );\n if (query) {\n query.lastOpenedAt = Date.now();\n }\n }),\n );\n },\n\n getCurrentQuery: () => {\n const sqlEditorConfig = get().sqlEditor.config;\n const selectedId = sqlEditorConfig.selectedQueryId;\n const query = sqlEditorConfig.queries.find(\n (q) => q.id === selectedId,\n );\n return query?.query || '';\n },\n\n /** @deprecated */\n selectTable: (table) => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.selectedTable = table;\n }),\n );\n },\n\n clearQueryResults: () => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.queryResultsById = {};\n }),\n );\n },\n\n parseAndRunCurrentQuery: async (): Promise<void> =>\n get().sqlEditor.parseAndRunQuery(get().sqlEditor.getCurrentQuery()),\n\n abortCurrentQuery: () => {\n const selectedQueryId = get().sqlEditor.config.selectedQueryId;\n const currentResult =\n get().sqlEditor.queryResultsById[selectedQueryId];\n if (currentResult?.status === 'loading' && currentResult.controller) {\n currentResult.controller.abort();\n }\n\n set((state) =>\n produce(state, (draft) => {\n const result = draft.sqlEditor.queryResultsById[selectedQueryId];\n if (result?.status === 'loading') {\n result.isBeingAborted = true;\n }\n }),\n );\n },\n\n setQueryResultLimit: (limit) => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.queryResultLimit = limit;\n }),\n );\n },\n\n parseAndRunQuery: async (query): Promise<void> => {\n const selectedQueryId = get().sqlEditor.config.selectedQueryId;\n const existingResult =\n get().sqlEditor.queryResultsById[selectedQueryId];\n if (existingResult?.status === 'loading') {\n throw new Error('Query already running');\n }\n if (!query.trim()) {\n return;\n }\n\n // Create abort controller for this query execution\n const queryController = new AbortController();\n\n // First update loading state and clear results\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.selectedTable = undefined;\n draft.sqlEditor.queryResultsById[selectedQueryId] = {\n status: 'loading',\n isBeingAborted: false,\n controller: queryController,\n };\n }),\n );\n\n let queryResult: QueryResult;\n try {\n const connector = await get().db.getConnector();\n const signal = queryController.signal;\n\n const {precedingStatements, lastStatement: lastQueryStatement} =\n separateLastStatement(query);\n const hasMultipleStatements = precedingStatements.length > 0;\n\n if (signal.aborted) {\n throw new Error('Query aborted');\n }\n\n const parsedLastStatement =\n await get().db.sqlSelectToJson(lastQueryStatement);\n\n if (signal.aborted) {\n throw new Error('Query aborted');\n }\n\n const isValidSelectQuery = !parsedLastStatement.error;\n\n if (isValidSelectQuery) {\n // Add limit to the last statement\n const limitedLastStatement = makeLimitQuery(lastQueryStatement, {\n sanitize: false, // should already be sanitized\n limit: get().sqlEditor.queryResultLimit,\n });\n const queryWithLimit = joinStatements(\n precedingStatements,\n limitedLastStatement,\n );\n const result = await connector.query(queryWithLimit, {signal});\n queryResult = {\n status: 'success',\n type: 'select',\n query,\n lastQueryStatement,\n result,\n };\n } else {\n // Run the complete query as it is\n if (\n parsedLastStatement.error &&\n parsedLastStatement.error_type !== 'not implemented'\n ) {\n throw (\n `${parsedLastStatement.error_type} ${parsedLastStatement.error_subtype}: ${parsedLastStatement.error_message}` +\n `\\n${getSqlErrorWithPointer(lastQueryStatement, Number(parsedLastStatement.position)).formatted}`\n );\n }\n\n const result = await connector.query(query, {signal});\n // EXPLAIN and PRAGMA are not detected as select queries\n // and we cannot wrap them in a SELECT * FROM,\n // but we can still execute them and return the result\n if (/^(EXPLAIN)/i.test(lastQueryStatement)) {\n queryResult = {\n status: 'success',\n type: 'explain',\n query,\n lastQueryStatement,\n result,\n };\n } else if (/^(PRAGMA)/i.test(lastQueryStatement)) {\n queryResult = {\n status: 'success',\n type: 'pragma',\n query,\n lastQueryStatement,\n result,\n };\n } else {\n queryResult = {\n status: 'success',\n type: 'exec',\n query,\n lastQueryStatement,\n };\n }\n }\n if (signal.aborted) {\n throw new Error('Query aborted');\n }\n // Refresh table schemas if there are multiple statements or if the\n // last statement is not a select query\n if (hasMultipleStatements || !isValidSelectQuery) {\n get().db.refreshTableSchemas();\n }\n if (signal.aborted) {\n throw new Error('Query aborted');\n }\n } catch (e) {\n console.error(e);\n const errorMessage = e instanceof Error ? e.message : String(e);\n if (\n errorMessage === 'Query aborted' ||\n queryController.signal.aborted\n ) {\n queryResult = {status: 'aborted'};\n } else {\n queryResult = {\n status: 'error',\n error: errorMessage,\n };\n }\n }\n\n // Update state without Immer since Arrow Tables don't play well with drafts.\n set((state) => ({\n ...state,\n sqlEditor: {\n ...state.sqlEditor,\n queryResultsById: {\n ...state.sqlEditor.queryResultsById,\n [selectedQueryId]: queryResult,\n },\n },\n }));\n },\n },\n } satisfies SqlEditorSliceState;\n });\n}\n\ntype RoomStateWithSqlEditor = RoomShellSliceState & SqlEditorSliceState;\n\nexport function useStoreWithSqlEditor<T>(\n selector: (state: RoomStateWithSqlEditor) => T,\n): T {\n return useBaseRoomShellStore<RoomShellSliceState, T>((state) =>\n selector(state as unknown as RoomStateWithSqlEditor),\n );\n}\n"]}
|
|
@@ -4,11 +4,19 @@ import type { DataTable, DuckDbConnector } from '@sqlrooms/duckdb';
|
|
|
4
4
|
export interface SqlMonacoEditorProps extends Omit<MonacoEditorProps, 'language'> {
|
|
5
5
|
connector?: DuckDbConnector;
|
|
6
6
|
/**
|
|
7
|
-
* Custom SQL keywords to add to the completion provider
|
|
7
|
+
* Custom SQL keywords to add to the completion provider.
|
|
8
|
+
*
|
|
9
|
+
* Note: syntax highlighting is global and uses the built-in DuckDB dialect
|
|
10
|
+
* (`DUCKDB_KEYWORDS` / `DUCKDB_FUNCTIONS`) to avoid per-editor global reconfiguration
|
|
11
|
+
* (which can cause flashing). These are currently **completion-only**.
|
|
8
12
|
*/
|
|
9
13
|
customKeywords?: string[];
|
|
10
14
|
/**
|
|
11
|
-
* Custom SQL functions to add to the completion provider
|
|
15
|
+
* Custom SQL functions to add to the completion provider.
|
|
16
|
+
*
|
|
17
|
+
* Note: syntax highlighting is global and uses the built-in DuckDB dialect
|
|
18
|
+
* (`DUCKDB_KEYWORDS` / `DUCKDB_FUNCTIONS`) to avoid per-editor global reconfiguration
|
|
19
|
+
* (which can cause flashing). These are currently **completion-only**.
|
|
12
20
|
*/
|
|
13
21
|
customFunctions?: string[];
|
|
14
22
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlMonacoEditor.d.ts","sourceRoot":"","sources":["../src/SqlMonacoEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAgD,MAAM,OAAO,CAAC;AAErE,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,yBAAyB,CAAC;AAQ/D,OAAO,KAAK,EAAC,SAAS,EAAE,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAGjE,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAChD,iBAAiB,EACjB,UAAU,CACX;IACC,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B
|
|
1
|
+
{"version":3,"file":"SqlMonacoEditor.d.ts","sourceRoot":"","sources":["../src/SqlMonacoEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAgD,MAAM,OAAO,CAAC;AAErE,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,yBAAyB,CAAC;AAQ/D,OAAO,KAAK,EAAC,SAAS,EAAE,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAGjE,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAChD,iBAAiB,EACjB,UAAU,CACX;IACC,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B;;OAEG;IACH,YAAY,CAAC,EAAE,SAAS,EAAE,CAAC;IAC3B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM;QACvB,YAAY,EAAE,SAAS,EAAE,CAAC;KAC3B,CAAC;CACH;AA2ND;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAiG1D,CAAC"}
|
package/dist/SqlMonacoEditor.js
CHANGED
|
@@ -9,39 +9,46 @@ const EDITOR_OPTIONS = {
|
|
|
9
9
|
formatOnType: true,
|
|
10
10
|
wordWrap: 'on',
|
|
11
11
|
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
12
|
+
// Singleton guards to prevent re-registration on every editor mount (causes flashing)
|
|
13
|
+
let sqlLanguageConfigured = false;
|
|
14
|
+
let sqlCompletionProviderDisposable = null;
|
|
15
|
+
// Per-model context store so multiple SqlMonacoEditor instances don't clobber each other.
|
|
16
|
+
// WeakMap is used so entries can be GC'd in long-lived apps.
|
|
17
|
+
const sqlCompletionContextByModel = new WeakMap();
|
|
18
|
+
function ensureSqlLanguageConfigured(monaco) {
|
|
19
|
+
if (sqlLanguageConfigured)
|
|
20
|
+
return;
|
|
21
|
+
sqlLanguageConfigured = true;
|
|
22
|
+
if (!monaco.languages.getLanguages().some((lang) => lang.id === 'sql')) {
|
|
23
|
+
monaco.languages.register({ id: 'sql' });
|
|
24
|
+
}
|
|
25
|
+
// Tokenization is GLOBAL. Keep it stable for DuckDB to avoid global re-tokenization
|
|
26
|
+
// when multiple SqlMonacoEditors exist (tabs/modals) which can cause flashing.
|
|
27
|
+
monaco.languages.setMonarchTokensProvider('sql', {
|
|
28
|
+
...SQL_LANGUAGE_CONFIGURATION,
|
|
29
|
+
keywords: DUCKDB_KEYWORDS,
|
|
30
|
+
builtinFunctions: DUCKDB_FUNCTIONS,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function ensureSqlCompletionProvider(monaco) {
|
|
34
|
+
if (sqlCompletionProviderDisposable)
|
|
35
|
+
return;
|
|
36
|
+
sqlCompletionProviderDisposable =
|
|
37
|
+
monaco.languages.registerCompletionItemProvider('sql', {
|
|
38
38
|
triggerCharacters: [' ', '.', ',', '(', '='],
|
|
39
39
|
provideCompletionItems: async (model, position) => {
|
|
40
40
|
try {
|
|
41
|
+
const ctx = sqlCompletionContextByModel.get(model) ?? {
|
|
42
|
+
connector: undefined,
|
|
43
|
+
tableSchemas: [],
|
|
44
|
+
getLatestSchemas: undefined,
|
|
45
|
+
customKeywords: [],
|
|
46
|
+
customFunctions: [],
|
|
47
|
+
};
|
|
41
48
|
// Get the latest schemas if the callback is provided
|
|
42
|
-
let currentSchemas = tableSchemas;
|
|
43
|
-
if (
|
|
44
|
-
const latest =
|
|
49
|
+
let currentSchemas = ctx.tableSchemas;
|
|
50
|
+
if (ctx.getLatestSchemas) {
|
|
51
|
+
const latest = ctx.getLatestSchemas();
|
|
45
52
|
currentSchemas = latest.tableSchemas;
|
|
46
53
|
}
|
|
47
54
|
const suggestions = [];
|
|
@@ -63,8 +70,8 @@ export const SqlMonacoEditor = ({ connector, customKeywords = [], customFunction
|
|
|
63
70
|
// Check if we're after a table name and period to prioritize column suggestions
|
|
64
71
|
const isColumnContext = /\b(\w+)\.\w*$/.test(textBeforeCursor);
|
|
65
72
|
// Combine keywords and functions with custom ones
|
|
66
|
-
const keywords = [...DUCKDB_KEYWORDS, ...customKeywords];
|
|
67
|
-
const functions = [...DUCKDB_FUNCTIONS, ...customFunctions];
|
|
73
|
+
const keywords = [...DUCKDB_KEYWORDS, ...ctx.customKeywords];
|
|
74
|
+
const functions = [...DUCKDB_FUNCTIONS, ...ctx.customFunctions];
|
|
68
75
|
// Add keyword suggestions (if not in a specific context)
|
|
69
76
|
if (!isColumnContext) {
|
|
70
77
|
keywords.forEach((keyword) => {
|
|
@@ -90,8 +97,8 @@ export const SqlMonacoEditor = ({ connector, customKeywords = [], customFunction
|
|
|
90
97
|
sortText: isTableContext ? 'z' + func : 'b' + func, // Lower priority in table context
|
|
91
98
|
});
|
|
92
99
|
});
|
|
93
|
-
if (connector) {
|
|
94
|
-
const functionSuggestions = await getFunctionSuggestions(connector, word.word);
|
|
100
|
+
if (ctx.connector) {
|
|
101
|
+
const functionSuggestions = await getFunctionSuggestions(ctx.connector, word.word);
|
|
95
102
|
for (const { name, documentation } of functionSuggestions) {
|
|
96
103
|
suggestions.push({
|
|
97
104
|
label: name,
|
|
@@ -170,9 +177,7 @@ export const SqlMonacoEditor = ({ connector, customKeywords = [], customFunction
|
|
|
170
177
|
});
|
|
171
178
|
}
|
|
172
179
|
});
|
|
173
|
-
return {
|
|
174
|
-
suggestions,
|
|
175
|
-
};
|
|
180
|
+
return { suggestions };
|
|
176
181
|
}
|
|
177
182
|
catch (error) {
|
|
178
183
|
console.error('Error in SQL completion provider:', error);
|
|
@@ -180,46 +185,74 @@ export const SqlMonacoEditor = ({ connector, customKeywords = [], customFunction
|
|
|
180
185
|
}
|
|
181
186
|
},
|
|
182
187
|
});
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* A Monaco editor for editing SQL with DuckDB syntax highlighting and autocompletion
|
|
191
|
+
* This is an internal component used by SqlEditor
|
|
192
|
+
*/
|
|
193
|
+
export const SqlMonacoEditor = ({ connector, customKeywords = [], customFunctions = [], tableSchemas = [], getLatestSchemas, onMount, className, options, ...restProps }) => {
|
|
194
|
+
const modelRef = useRef(null);
|
|
195
|
+
// Update per-model context when props change
|
|
187
196
|
useEffect(() => {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
197
|
+
const model = modelRef.current;
|
|
198
|
+
if (!model)
|
|
199
|
+
return;
|
|
200
|
+
sqlCompletionContextByModel.set(model, {
|
|
201
|
+
connector,
|
|
202
|
+
tableSchemas,
|
|
203
|
+
getLatestSchemas,
|
|
204
|
+
customKeywords,
|
|
205
|
+
customFunctions,
|
|
206
|
+
});
|
|
207
|
+
}, [
|
|
208
|
+
connector,
|
|
209
|
+
tableSchemas,
|
|
210
|
+
getLatestSchemas,
|
|
211
|
+
customKeywords,
|
|
212
|
+
customFunctions,
|
|
213
|
+
]);
|
|
214
|
+
// Backstop cleanup: if the React component unmounts before Monaco disposes the model,
|
|
215
|
+
// ensure we don't hold on to context longer than necessary.
|
|
216
|
+
useEffect(() => {
|
|
217
|
+
return () => {
|
|
218
|
+
const model = modelRef.current;
|
|
219
|
+
if (model)
|
|
220
|
+
sqlCompletionContextByModel.delete(model);
|
|
221
|
+
};
|
|
222
|
+
}, []);
|
|
192
223
|
// Handle editor mounting to configure SQL language features
|
|
193
224
|
const handleEditorDidMount = useCallback((editor, monaco) => {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
225
|
+
ensureSqlLanguageConfigured(monaco);
|
|
226
|
+
ensureSqlCompletionProvider(monaco);
|
|
227
|
+
const model = editor.getModel?.();
|
|
228
|
+
if (model) {
|
|
229
|
+
modelRef.current = model;
|
|
230
|
+
sqlCompletionContextByModel.set(model, {
|
|
231
|
+
connector,
|
|
232
|
+
tableSchemas,
|
|
233
|
+
getLatestSchemas,
|
|
234
|
+
customKeywords,
|
|
235
|
+
customFunctions,
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
// Cleanup on dispose
|
|
239
|
+
if (model) {
|
|
240
|
+
editor.onDidDispose(() => {
|
|
241
|
+
sqlCompletionContextByModel.delete(model);
|
|
242
|
+
});
|
|
200
243
|
}
|
|
201
|
-
// Combine keywords and functions with custom ones
|
|
202
|
-
const keywords = [...DUCKDB_KEYWORDS, ...customKeywords];
|
|
203
|
-
const functions = [...DUCKDB_FUNCTIONS, ...customFunctions];
|
|
204
|
-
// Set the language configuration
|
|
205
|
-
monaco.languages.setMonarchTokensProvider('sql', {
|
|
206
|
-
...SQL_LANGUAGE_CONFIGURATION,
|
|
207
|
-
keywords,
|
|
208
|
-
builtinFunctions: functions,
|
|
209
|
-
}); // Using 'as any' to bypass the type checking issue
|
|
210
|
-
// Register the completion provider
|
|
211
|
-
registerCompletionProvider();
|
|
212
|
-
// Store the disposable to clean up later if needed
|
|
213
|
-
editor.onDidDispose(() => {
|
|
214
|
-
if (disposableRef.current) {
|
|
215
|
-
disposableRef.current.dispose();
|
|
216
|
-
}
|
|
217
|
-
});
|
|
218
244
|
// Call the original onMount if provided
|
|
219
245
|
if (onMount) {
|
|
220
246
|
onMount(editor, monaco);
|
|
221
247
|
}
|
|
222
|
-
}, [
|
|
248
|
+
}, [
|
|
249
|
+
connector,
|
|
250
|
+
customKeywords,
|
|
251
|
+
customFunctions,
|
|
252
|
+
getLatestSchemas,
|
|
253
|
+
onMount,
|
|
254
|
+
tableSchemas,
|
|
255
|
+
]);
|
|
223
256
|
const combinedOptions = useMemo(() => ({
|
|
224
257
|
...EDITOR_OPTIONS,
|
|
225
258
|
...options,
|