@sqlrooms/sql-editor 0.28.0-rc.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -377
- package/dist/SqlEditorSlice.d.ts +2 -0
- package/dist/SqlEditorSlice.d.ts.map +1 -1
- package/dist/SqlEditorSlice.js +261 -2
- package/dist/SqlEditorSlice.js.map +1 -1
- package/dist/components/RenameSqlQueryModal.d.ts.map +1 -1
- package/dist/components/RenameSqlQueryModal.js +0 -1
- package/dist/components/RenameSqlQueryModal.js.map +1 -1
- package/package.json +10 -10
package/README.md
CHANGED
|
@@ -1,435 +1,117 @@
|
|
|
1
|
-
|
|
1
|
+
SQL editor UI and state slice for SQLRooms apps.
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This package provides:
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- 🔍 **Advanced SQL Editing**: Monaco-based SQL editor with syntax highlighting and auto-completion
|
|
10
|
-
- 📊 **Data Visualization**: View query results in interactive data tables
|
|
11
|
-
- 📑 **Multiple Tabs**: Support for multiple query tabs with save/rename/delete functionality
|
|
12
|
-
- 🔄 **State Management**: Zustand-based state management for SQL editor state
|
|
13
|
-
- 📦 **Table Management**: Browser for tables in the database with schema information
|
|
14
|
-
- 📤 **Data Export**: Export query results to CSV files
|
|
15
|
-
- 📝 **Documentation**: Optional documentation panel for SQL reference
|
|
5
|
+
- `createSqlEditorSlice()` for query tabs, execution, and results state
|
|
6
|
+
- `SqlEditor` and `SqlEditorModal` UI
|
|
7
|
+
- `SqlMonacoEditor` standalone SQL editor
|
|
8
|
+
- helpers/components for query results, table structure, and SQL data sources
|
|
16
9
|
|
|
17
10
|
## Installation
|
|
18
11
|
|
|
19
12
|
```bash
|
|
20
|
-
npm install @sqlrooms/sql-editor
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Basic Usage
|
|
24
|
-
|
|
25
|
-
### SqlEditor and SqlEditorModal Components
|
|
26
|
-
|
|
27
|
-
These components must be used within a `RoomShell` which provides the room store context as they rely on the SQLRooms store:
|
|
28
|
-
|
|
29
|
-
```tsx
|
|
30
|
-
import {RoomShell} from '@sqlrooms/room-shell';
|
|
31
|
-
import {SqlEditorModal} from '@sqlrooms/sql-editor';
|
|
32
|
-
import {useDisclosure} from '@sqlrooms/ui';
|
|
33
|
-
import {TerminalIcon} from 'lucide-react';
|
|
34
|
-
import {roomStore} from './store';
|
|
35
|
-
|
|
36
|
-
function MyApp() {
|
|
37
|
-
const sqlEditorDisclosure = useDisclosure();
|
|
38
|
-
|
|
39
|
-
return (
|
|
40
|
-
<RoomShell className="h-screen" roomStore={roomStore}>
|
|
41
|
-
<RoomShell.Sidebar>
|
|
42
|
-
<RoomShell.SidebarButton
|
|
43
|
-
title="SQL Editor"
|
|
44
|
-
onClick={sqlEditorDisclosure.onToggle}
|
|
45
|
-
isSelected={false}
|
|
46
|
-
icon={TerminalIcon}
|
|
47
|
-
/>
|
|
48
|
-
</RoomShell.Sidebar>
|
|
49
|
-
<RoomShell.LayoutComposer />
|
|
50
|
-
<RoomShell.LoadingProgress />
|
|
51
|
-
<SqlEditorModal
|
|
52
|
-
isOpen={sqlEditorDisclosure.isOpen}
|
|
53
|
-
onClose={sqlEditorDisclosure.onClose}
|
|
54
|
-
/>
|
|
55
|
-
</RoomShell>
|
|
56
|
-
);
|
|
57
|
-
}
|
|
13
|
+
npm install @sqlrooms/sql-editor @sqlrooms/room-shell @sqlrooms/duckdb @sqlrooms/ui
|
|
58
14
|
```
|
|
59
15
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
The SQL Editor requires a properly configured store with the SQL Editor slice:
|
|
16
|
+
## Store setup
|
|
63
17
|
|
|
64
18
|
```tsx
|
|
65
19
|
import {
|
|
66
20
|
createRoomShellSlice,
|
|
67
21
|
createRoomStore,
|
|
68
|
-
|
|
22
|
+
RoomShellSliceState,
|
|
69
23
|
} from '@sqlrooms/room-shell';
|
|
70
|
-
import {
|
|
71
|
-
import {
|
|
72
|
-
createDefaultSqlEditorConfig,
|
|
73
|
-
createSqlEditorSlice,
|
|
74
|
-
SqlEditorSliceConfig,
|
|
75
|
-
SqlEditorSliceState,
|
|
76
|
-
} from '@sqlrooms/sql-editor';
|
|
77
|
-
import {z} from 'zod';
|
|
78
|
-
|
|
79
|
-
// Define combined config schema
|
|
80
|
-
export const RoomConfig = BaseRoomConfig.merge(SqlEditorSliceConfig);
|
|
81
|
-
export type RoomConfig = z.infer<typeof RoomConfig>;
|
|
24
|
+
import {createSqlEditorSlice, SqlEditorSliceState} from '@sqlrooms/sql-editor';
|
|
82
25
|
|
|
83
|
-
|
|
84
|
-
export type RoomState = RoomState<RoomConfig> & SqlEditorSliceState;
|
|
26
|
+
type RoomState = RoomShellSliceState & SqlEditorSliceState;
|
|
85
27
|
|
|
86
|
-
|
|
87
|
-
export const {roomStore, useRoomStore} = createRoomStore<RoomConfig, RoomState>(
|
|
28
|
+
export const {roomStore, useRoomStore} = createRoomStore<RoomState>(
|
|
88
29
|
(set, get, store) => ({
|
|
89
|
-
|
|
90
|
-
...createRoomShellSlice<RoomConfig>({
|
|
30
|
+
...createRoomShellSlice({
|
|
91
31
|
config: {
|
|
92
|
-
|
|
32
|
+
dataSources: [
|
|
33
|
+
{
|
|
34
|
+
type: 'url',
|
|
35
|
+
tableName: 'earthquakes',
|
|
36
|
+
url: 'https://huggingface.co/datasets/sqlrooms/earthquakes/resolve/main/earthquakes.parquet',
|
|
37
|
+
},
|
|
38
|
+
],
|
|
93
39
|
},
|
|
94
40
|
})(set, get, store),
|
|
95
|
-
|
|
96
|
-
// Sql editor slice
|
|
97
41
|
...createSqlEditorSlice()(set, get, store),
|
|
98
42
|
}),
|
|
99
43
|
);
|
|
100
44
|
```
|
|
101
45
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
Unlike the full SQL Editor components, the `SqlMonacoEditor` can be used as a standalone component without requiring the store:
|
|
105
|
-
|
|
106
|
-
```tsx
|
|
107
|
-
import {SqlMonacoEditor} from '@sqlrooms/sql-editor';
|
|
108
|
-
import {useState} from 'react';
|
|
109
|
-
|
|
110
|
-
function SimpleSqlEditor() {
|
|
111
|
-
const [query, setQuery] = useState('SELECT * FROM products');
|
|
112
|
-
|
|
113
|
-
const handleExecute = () => {
|
|
114
|
-
// Execute the query using your own logic
|
|
115
|
-
console.log('Executing query:', query);
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
return (
|
|
119
|
-
<>
|
|
120
|
-
<SqlMonacoEditor value={query} onChange={setQuery} height="400px" />
|
|
121
|
-
<button onClick={handleExecute}>Execute</button>
|
|
122
|
-
</>
|
|
123
|
-
);
|
|
124
|
-
}
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
### With Custom Documentation Panel
|
|
128
|
-
|
|
129
|
-
Adding a custom documentation panel to the SQL Editor:
|
|
46
|
+
## Render SQL editor modal
|
|
130
47
|
|
|
131
48
|
```tsx
|
|
49
|
+
import {RoomShell} from '@sqlrooms/room-shell';
|
|
132
50
|
import {SqlEditorModal} from '@sqlrooms/sql-editor';
|
|
133
51
|
import {useDisclosure} from '@sqlrooms/ui';
|
|
134
|
-
import {
|
|
52
|
+
import {TerminalIcon} from 'lucide-react';
|
|
135
53
|
import {roomStore} from './store';
|
|
136
54
|
|
|
137
|
-
function
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
// Custom documentation component
|
|
141
|
-
const Documentation = () => (
|
|
142
|
-
<div className="p-4">
|
|
143
|
-
<h2 className="mb-4 text-xl font-bold">SQL Reference</h2>
|
|
144
|
-
<div className="space-y-4">
|
|
145
|
-
<div>
|
|
146
|
-
<h3 className="text-lg font-semibold">SELECT</h3>
|
|
147
|
-
<p>Retrieves data from a table</p>
|
|
148
|
-
<pre className="mt-2 rounded bg-gray-100 p-2">
|
|
149
|
-
SELECT column1, column2 FROM table_name;
|
|
150
|
-
</pre>
|
|
151
|
-
</div>
|
|
152
|
-
{/* More documentation items */}
|
|
153
|
-
</div>
|
|
154
|
-
</div>
|
|
155
|
-
);
|
|
55
|
+
export function App() {
|
|
56
|
+
const sqlEditor = useDisclosure();
|
|
156
57
|
|
|
157
58
|
return (
|
|
158
|
-
<
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
59
|
+
<RoomShell roomStore={roomStore} className="h-screen">
|
|
60
|
+
<RoomShell.Sidebar>
|
|
61
|
+
<RoomShell.SidebarButton
|
|
62
|
+
title="SQL Editor"
|
|
63
|
+
icon={TerminalIcon}
|
|
64
|
+
isSelected={sqlEditor.isOpen}
|
|
65
|
+
onClick={sqlEditor.onToggle}
|
|
66
|
+
/>
|
|
67
|
+
</RoomShell.Sidebar>
|
|
68
|
+
<RoomShell.LayoutComposer />
|
|
69
|
+
<SqlEditorModal isOpen={sqlEditor.isOpen} onClose={sqlEditor.onClose} />
|
|
70
|
+
</RoomShell>
|
|
163
71
|
);
|
|
164
72
|
}
|
|
165
73
|
```
|
|
166
74
|
|
|
167
|
-
##
|
|
168
|
-
|
|
169
|
-
The SQL editor provides a Zustand slice for managing state. Here's how to set it up:
|
|
170
|
-
|
|
171
|
-
### Using in a Combined SQLRooms Store
|
|
172
|
-
|
|
173
|
-
This approach is recommended when integrating multiple SQLRooms components:
|
|
75
|
+
## Run queries programmatically
|
|
174
76
|
|
|
175
77
|
```tsx
|
|
176
|
-
import {
|
|
177
|
-
|
|
178
|
-
createDefaultSqlEditorConfig,
|
|
179
|
-
SqlEditorSliceState,
|
|
180
|
-
SqlEditorSliceConfig,
|
|
181
|
-
} from '@sqlrooms/sql-editor';
|
|
182
|
-
import {
|
|
183
|
-
createRoomShellSlice,
|
|
184
|
-
createRoomStore,
|
|
185
|
-
RoomState,
|
|
186
|
-
RoomShell,
|
|
187
|
-
} from '@sqlrooms/room-shell';
|
|
188
|
-
import {BaseRoomConfig} from '@sqlrooms/room-config';
|
|
189
|
-
import {z} from 'zod';
|
|
190
|
-
|
|
191
|
-
// 1. Define combined config schema
|
|
192
|
-
export const RoomConfig = BaseRoomConfig.merge(SqlEditorSliceConfig);
|
|
193
|
-
export type RoomConfig = z.infer<typeof RoomConfig>;
|
|
194
|
-
|
|
195
|
-
// 2. Define combined state type
|
|
196
|
-
export type RoomState = RoomState<RoomConfig> & SqlEditorSliceState;
|
|
197
|
-
|
|
198
|
-
// 3. Create combined store
|
|
199
|
-
export const {roomStore, useRoomStore} = createRoomStore<RoomConfig, RoomState>(
|
|
200
|
-
(set, get, store) => ({
|
|
201
|
-
// Base room slice
|
|
202
|
-
...createRoomShellSlice<RoomConfig>({
|
|
203
|
-
config: {
|
|
204
|
-
title: 'SQL Workspace',
|
|
205
|
-
},
|
|
206
|
-
})(set, get, store),
|
|
207
|
-
|
|
208
|
-
// Sql editor slice
|
|
209
|
-
...createSqlEditorSlice()(set, get, store),
|
|
210
|
-
}),
|
|
211
|
-
);
|
|
78
|
+
import {useRoomStore} from './store';
|
|
79
|
+
import {Button} from '@sqlrooms/ui';
|
|
212
80
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
const runQuery = useRoomStore((state) => state.sqlEditor.runQuery);
|
|
217
|
-
const createQueryTab = useRoomStore(
|
|
218
|
-
(state) => state.sqlEditor.createQueryTab,
|
|
219
|
-
);
|
|
81
|
+
function RunQueryButton() {
|
|
82
|
+
const parseAndRunQuery = useRoomStore((state) => state.sqlEditor.parseAndRunQuery);
|
|
83
|
+
const createQueryTab = useRoomStore((state) => state.sqlEditor.createQueryTab);
|
|
220
84
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
runQuery('SELECT * FROM users LIMIT 10');
|
|
85
|
+
const run = async () => {
|
|
86
|
+
createQueryTab('SELECT COUNT(*) AS total FROM earthquakes');
|
|
87
|
+
await parseAndRunQuery('SELECT COUNT(*) AS total FROM earthquakes');
|
|
225
88
|
};
|
|
226
89
|
|
|
227
|
-
return (
|
|
228
|
-
<RoomShell roomStore={roomStore}>
|
|
229
|
-
<div>
|
|
230
|
-
<button onClick={handleExecute}>Run Query</button>
|
|
231
|
-
<SqlEditorModal isOpen={true} onClose={() => {}} />
|
|
232
|
-
</div>
|
|
233
|
-
</RoomShell>
|
|
234
|
-
);
|
|
90
|
+
return <Button onClick={() => void run()}>Run query</Button>;
|
|
235
91
|
}
|
|
236
92
|
```
|
|
237
93
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
- `sqlEditor.runQuery(query: string)`: Execute a SQL query
|
|
241
|
-
- `sqlEditor.createQueryTab(initialQuery?: string)`: Create a new query tab
|
|
242
|
-
- `sqlEditor.deleteQueryTab(queryId: string)`: Delete a query tab
|
|
243
|
-
- `sqlEditor.renameQueryTab(queryId: string, newName: string)`: Rename a query tab
|
|
244
|
-
- `sqlEditor.updateQueryText(queryId: string, queryText: string)`: Update query text
|
|
245
|
-
- `sqlEditor.setSelectedQueryId(queryId: string)`: Set the selected query tab
|
|
246
|
-
- `sqlEditor.getCurrentQuery(defaultQuery?: string)`: Get current query text
|
|
247
|
-
|
|
248
|
-
## Available Components
|
|
249
|
-
|
|
250
|
-
### SqlEditor
|
|
94
|
+
## Standalone editor (without SQLRooms store)
|
|
251
95
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
```tsx
|
|
255
|
-
import {SqlEditor} from '@sqlrooms/sql-editor';
|
|
256
|
-
import {RoomShell} from '@sqlrooms/room-shell';
|
|
257
|
-
import {roomStore} from './store';
|
|
258
|
-
|
|
259
|
-
<RoomShell roomStore={roomStore}>
|
|
260
|
-
<SqlEditor
|
|
261
|
-
isOpen={boolean}
|
|
262
|
-
onClose={() => void}
|
|
263
|
-
schema="main"
|
|
264
|
-
documentationPanel={ReactNode}
|
|
265
|
-
/>
|
|
266
|
-
</RoomShell>
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
### SqlMonacoEditor
|
|
270
|
-
|
|
271
|
-
A standalone SQL-specific Monaco editor component. Can be used independently without RoomShell.
|
|
96
|
+
`SqlMonacoEditor` can be used independently:
|
|
272
97
|
|
|
273
98
|
```tsx
|
|
274
99
|
import {SqlMonacoEditor} from '@sqlrooms/sql-editor';
|
|
275
100
|
import {useState} from 'react';
|
|
276
101
|
|
|
277
|
-
function
|
|
278
|
-
const [
|
|
279
|
-
|
|
280
|
-
const handleExecute = () => {
|
|
281
|
-
// Execute the query using your own logic
|
|
282
|
-
console.log('Executing query:', query);
|
|
283
|
-
};
|
|
284
|
-
|
|
285
|
-
return (
|
|
286
|
-
<>
|
|
287
|
-
<SqlMonacoEditor value={query} onChange={setQuery} height="400px" />
|
|
288
|
-
<button onClick={handleExecute}>Execute</button>
|
|
289
|
-
</>
|
|
290
|
-
);
|
|
291
|
-
}
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
### SqlEditorModal
|
|
295
|
-
|
|
296
|
-
A modal wrapper around the SQL editor. Must be used within a RoomShell.
|
|
297
|
-
|
|
298
|
-
```tsx
|
|
299
|
-
import {SqlEditorModal} from '@sqlrooms/sql-editor';
|
|
300
|
-
import {useDisclosure} from '@sqlrooms/ui';
|
|
301
|
-
import {RoomShell} from '@sqlrooms/room-shell';
|
|
302
|
-
import {roomStore} from './store';
|
|
303
|
-
|
|
304
|
-
function EditorWithModal() {
|
|
305
|
-
const {isOpen, onOpen, onClose} = useDisclosure();
|
|
306
|
-
|
|
307
|
-
return (
|
|
308
|
-
<RoomShell roomStore={roomStore}>
|
|
309
|
-
<button onClick={onOpen}>Open SQL Editor</button>
|
|
310
|
-
<SqlEditorModal isOpen={isOpen} onClose={onClose} />
|
|
311
|
-
</RoomShell>
|
|
312
|
-
);
|
|
102
|
+
export function StandaloneEditor() {
|
|
103
|
+
const [sql, setSql] = useState('SELECT 1');
|
|
104
|
+
return <SqlMonacoEditor value={sql} onChange={(v) => setSql(v ?? '')} height="320px" />;
|
|
313
105
|
}
|
|
314
106
|
```
|
|
315
107
|
|
|
316
|
-
|
|
108
|
+
## Related packages
|
|
317
109
|
|
|
318
|
-
|
|
110
|
+
- `@sqlrooms/sql-editor-config` for persisted SQL editor config schema
|
|
111
|
+
- `@sqlrooms/duckdb` for query execution and table state
|
|
112
|
+
- `@sqlrooms/schema-tree` for database tree rendering
|
|
319
113
|
|
|
320
|
-
|
|
321
|
-
import {CreateTableModal} from '@sqlrooms/sql-editor';
|
|
322
|
-
import {useDisclosure} from '@sqlrooms/ui';
|
|
323
|
-
import {RoomShell} from '@sqlrooms/room-shell';
|
|
324
|
-
import {roomStore} from './store';
|
|
325
|
-
import {useRoomStore} from './store';
|
|
326
|
-
|
|
327
|
-
function TableCreator() {
|
|
328
|
-
const {isOpen, onOpen, onClose} = useDisclosure();
|
|
329
|
-
const addOrUpdateSqlQueryDataSource = useRoomStore(
|
|
330
|
-
(state) => state.room.addOrUpdateSqlQueryDataSource,
|
|
331
|
-
);
|
|
332
|
-
|
|
333
|
-
return (
|
|
334
|
-
<RoomShell roomStore={roomStore}>
|
|
335
|
-
<button onClick={onOpen}>Create Table from Results</button>
|
|
336
|
-
<CreateTableModal
|
|
337
|
-
isOpen={isOpen}
|
|
338
|
-
onClose={onClose}
|
|
339
|
-
onAddOrUpdateSqlQuery={addOrUpdateSqlQueryDataSource}
|
|
340
|
-
query="SELECT * FROM users"
|
|
341
|
-
/>
|
|
342
|
-
</RoomShell>
|
|
343
|
-
);
|
|
344
|
-
}
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
### SqlQueryDataSourcesPanel
|
|
348
|
-
|
|
349
|
-
A panel showing available data sources for SQL queries. Must be used within a RoomShell.
|
|
350
|
-
|
|
351
|
-
```tsx
|
|
352
|
-
import {SqlQueryDataSourcesPanel} from '@sqlrooms/sql-editor';
|
|
353
|
-
import {RoomShell} from '@sqlrooms/room-shell';
|
|
354
|
-
import {roomStore} from './store';
|
|
355
|
-
|
|
356
|
-
<RoomShell roomStore={roomStore}>
|
|
357
|
-
<SqlQueryDataSourcesPanel
|
|
358
|
-
onSelectTable={(tableName) => {
|
|
359
|
-
console.log(`Selected table: ${tableName}`);
|
|
360
|
-
}}
|
|
361
|
-
/>
|
|
362
|
-
</RoomShell>;
|
|
363
|
-
```
|
|
364
|
-
|
|
365
|
-
## Props
|
|
366
|
-
|
|
367
|
-
### SqlEditor Props
|
|
368
|
-
|
|
369
|
-
| Prop | Type | Default | Description |
|
|
370
|
-
| ------------------ | --------- | --------- | ------------------------------------- |
|
|
371
|
-
| isOpen | boolean | - | Whether the editor is open |
|
|
372
|
-
| onClose | function | - | Callback when the editor is closed |
|
|
373
|
-
| schema | string | 'main' | Default schema to use for queries |
|
|
374
|
-
| documentationPanel | ReactNode | undefined | Custom documentation panel to display |
|
|
375
|
-
|
|
376
|
-
### SqlMonacoEditor Props
|
|
377
|
-
|
|
378
|
-
| Prop | Type | Default | Description |
|
|
379
|
-
| ---------------- | ----------- | ------- | --------------------------------------- |
|
|
380
|
-
| value | string | '' | The SQL query text |
|
|
381
|
-
| onChange | function | - | Callback when the query text changes |
|
|
382
|
-
| height | string | '300px' | Height of the editor |
|
|
383
|
-
| readOnly | boolean | false | Whether the editor is read-only |
|
|
384
|
-
| theme | string | 'dark' | Editor theme ('dark' or 'light') |
|
|
385
|
-
| tableSchemas | DataTable[] | [] | Table schemas for autocompletion |
|
|
386
|
-
| customKeywords | string[] | [] | Custom SQL keywords for autocompletion |
|
|
387
|
-
| customFunctions | string[] | [] | Custom SQL functions for autocompletion |
|
|
388
|
-
| getLatestSchemas | function | - | Callback to get latest table schemas |
|
|
389
|
-
| className | string | - | Additional CSS class names |
|
|
390
|
-
| options | object | - | Monaco editor options |
|
|
391
|
-
| onMount | function | - | Callback when editor is mounted |
|
|
392
|
-
|
|
393
|
-
### SqlEditorModal Props
|
|
394
|
-
|
|
395
|
-
| Prop | Type | Default | Description |
|
|
396
|
-
| ------------------ | --------- | --------- | ------------------------------------- |
|
|
397
|
-
| isOpen | boolean | - | Whether the modal is open |
|
|
398
|
-
| onClose | function | - | Callback when the modal is closed |
|
|
399
|
-
| schema | string | 'main' | Default schema to use for queries |
|
|
400
|
-
| documentationPanel | ReactNode | undefined | Custom documentation panel to display |
|
|
401
|
-
|
|
402
|
-
### CreateTableModal Props
|
|
403
|
-
|
|
404
|
-
| Prop | Type | Default | Description |
|
|
405
|
-
| --------------------- | -------- | ------- | --------------------------------- |
|
|
406
|
-
| isOpen | boolean | - | Whether the modal is open |
|
|
407
|
-
| onClose | function | - | Callback when the modal is closed |
|
|
408
|
-
| onAddOrUpdateSqlQuery | function | - | Callback when a table is created |
|
|
409
|
-
| query | string | - | SQL query that generated the data |
|
|
410
|
-
|
|
411
|
-
## Configuration
|
|
412
|
-
|
|
413
|
-
The SQL editor can be configured through the Zustand store.
|
|
414
|
-
|
|
415
|
-
```tsx
|
|
416
|
-
const config = createDefaultSqlEditorConfig();
|
|
417
|
-
// Customize if needed
|
|
418
|
-
sqlEditor.config.queries = [
|
|
419
|
-
{id: 'default', name: 'Untitled', query: 'SELECT * FROM users LIMIT 10;'},
|
|
420
|
-
];
|
|
421
|
-
sqlEditor.config.selectedQueryId = 'default';
|
|
422
|
-
|
|
423
|
-
// Use in store creation
|
|
424
|
-
const {roomStore} = createRoomStore({
|
|
425
|
-
...createRoomShellSlice({
|
|
426
|
-
config: {
|
|
427
|
-
...config,
|
|
428
|
-
// other config options
|
|
429
|
-
},
|
|
430
|
-
}),
|
|
431
|
-
...createSqlEditorSlice(),
|
|
432
|
-
});
|
|
433
|
-
```
|
|
114
|
+
## Example apps
|
|
434
115
|
|
|
435
|
-
|
|
116
|
+
- https://github.com/sqlrooms/examples/tree/main/query
|
|
117
|
+
- https://github.com/sqlrooms/examples/tree/main/query-websocket
|
package/dist/SqlEditorSlice.d.ts
CHANGED
|
@@ -28,6 +28,8 @@ export declare function isQueryWithResult(queryResult: QueryResult | undefined):
|
|
|
28
28
|
};
|
|
29
29
|
export type SqlEditorSliceState = {
|
|
30
30
|
sqlEditor: {
|
|
31
|
+
initialize?: () => Promise<void>;
|
|
32
|
+
destroy?: () => Promise<void>;
|
|
31
33
|
config: SqlEditorSliceConfig;
|
|
32
34
|
/**
|
|
33
35
|
* Query results keyed by queryId (tab id).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlEditorSlice.d.ts","sourceRoot":"","sources":["../src/SqlEditorSlice.tsx"],"names":[],"mappings":"AAQA,OAAO,
|
|
1
|
+
{"version":3,"file":"SqlEditorSlice.d.ts","sourceRoot":"","sources":["../src/SqlEditorSlice.tsx"],"names":[],"mappings":"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"}
|
package/dist/SqlEditorSlice.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { createId } from '@paralleldrive/cuid2';
|
|
2
2
|
import { getSqlErrorWithPointer, joinStatements, makeLimitQuery, separateLastStatement, } from '@sqlrooms/duckdb';
|
|
3
|
-
import { createSlice, useBaseRoomShellStore, } from '@sqlrooms/room-shell';
|
|
3
|
+
import { createSlice, registerCommandsForOwner, unregisterCommandsForOwner, useBaseRoomShellStore, } from '@sqlrooms/room-shell';
|
|
4
4
|
import { createDefaultSqlEditorConfig, } from '@sqlrooms/sql-editor-config';
|
|
5
5
|
import { generateUniqueName } from '@sqlrooms/utils';
|
|
6
6
|
import { csvFormat } from 'd3-dsv';
|
|
7
7
|
import { saveAs } from 'file-saver';
|
|
8
8
|
import { produce } from 'immer';
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
const SQL_EDITOR_COMMAND_OWNER = '@sqlrooms/sql-editor';
|
|
9
11
|
export function isQueryWithResult(queryResult) {
|
|
10
12
|
return (queryResult?.status === 'success' &&
|
|
11
13
|
(queryResult.type === 'pragma' ||
|
|
@@ -13,9 +15,15 @@ export function isQueryWithResult(queryResult) {
|
|
|
13
15
|
queryResult.type === 'select'));
|
|
14
16
|
}
|
|
15
17
|
export function createSqlEditorSlice({ config = createDefaultSqlEditorConfig(), queryResultLimit = 100, queryResultLimitOptions = [100, 500, 1000], } = {}) {
|
|
16
|
-
return createSlice((set, get) => {
|
|
18
|
+
return createSlice((set, get, store) => {
|
|
17
19
|
return {
|
|
18
20
|
sqlEditor: {
|
|
21
|
+
initialize: async () => {
|
|
22
|
+
registerCommandsForOwner(store, SQL_EDITOR_COMMAND_OWNER, createSqlEditorCommands());
|
|
23
|
+
},
|
|
24
|
+
destroy: async () => {
|
|
25
|
+
unregisterCommandsForOwner(store, SQL_EDITOR_COMMAND_OWNER);
|
|
26
|
+
},
|
|
19
27
|
config,
|
|
20
28
|
// Initialize runtime state
|
|
21
29
|
queryResultsById: {},
|
|
@@ -311,6 +319,257 @@ export function createSqlEditorSlice({ config = createDefaultSqlEditorConfig(),
|
|
|
311
319
|
};
|
|
312
320
|
});
|
|
313
321
|
}
|
|
322
|
+
const SqlEditorRunQueryCommandInput = z.object({
|
|
323
|
+
query: z.string().describe('SQL query text to run.'),
|
|
324
|
+
});
|
|
325
|
+
const SqlEditorTabIdInput = z.object({
|
|
326
|
+
queryId: z.string().describe('ID of the query tab.'),
|
|
327
|
+
});
|
|
328
|
+
const SqlEditorRenameTabInput = z.object({
|
|
329
|
+
queryId: z.string().describe('ID of the query tab to rename.'),
|
|
330
|
+
name: z.string().min(1).describe('New tab name.'),
|
|
331
|
+
});
|
|
332
|
+
const SqlEditorResultLimitInput = z.object({
|
|
333
|
+
limit: z.number().int().positive().describe('Row limit for query results.'),
|
|
334
|
+
});
|
|
335
|
+
function createSqlEditorCommands() {
|
|
336
|
+
const ensureQueryTabExists = (state, queryId) => {
|
|
337
|
+
if (!state.sqlEditor.config.queries.some((query) => query.id === queryId)) {
|
|
338
|
+
throw new Error(`Unknown query tab "${queryId}".`);
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
return [
|
|
342
|
+
{
|
|
343
|
+
id: 'sql-editor.run-current-query',
|
|
344
|
+
name: 'Run current query',
|
|
345
|
+
description: 'Execute the selected SQL query tab',
|
|
346
|
+
group: 'SQL Editor',
|
|
347
|
+
keywords: ['sql', 'run', 'execute', 'query'],
|
|
348
|
+
metadata: {
|
|
349
|
+
readOnly: false,
|
|
350
|
+
idempotent: false,
|
|
351
|
+
riskLevel: 'medium',
|
|
352
|
+
},
|
|
353
|
+
ui: {
|
|
354
|
+
shortcut: 'Mod+Enter',
|
|
355
|
+
},
|
|
356
|
+
isEnabled: ({ getState }) => {
|
|
357
|
+
const state = getState();
|
|
358
|
+
const selectedQueryId = state.sqlEditor.config.selectedQueryId;
|
|
359
|
+
const queryResult = state.sqlEditor.queryResultsById[selectedQueryId];
|
|
360
|
+
return (queryResult?.status !== 'loading' &&
|
|
361
|
+
state.sqlEditor.getCurrentQuery().trim().length > 0);
|
|
362
|
+
},
|
|
363
|
+
execute: async ({ getState }) => {
|
|
364
|
+
await getState().sqlEditor.parseAndRunCurrentQuery();
|
|
365
|
+
return {
|
|
366
|
+
success: true,
|
|
367
|
+
commandId: 'sql-editor.run-current-query',
|
|
368
|
+
message: 'Executed current query.',
|
|
369
|
+
};
|
|
370
|
+
},
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
id: 'sql-editor.run-query',
|
|
374
|
+
name: 'Run query text',
|
|
375
|
+
description: 'Execute an explicitly provided SQL query',
|
|
376
|
+
group: 'SQL Editor',
|
|
377
|
+
keywords: ['sql', 'run', 'execute', 'query', 'text'],
|
|
378
|
+
inputSchema: SqlEditorRunQueryCommandInput,
|
|
379
|
+
inputDescription: 'Provide query SQL to execute.',
|
|
380
|
+
metadata: {
|
|
381
|
+
readOnly: false,
|
|
382
|
+
idempotent: false,
|
|
383
|
+
riskLevel: 'medium',
|
|
384
|
+
},
|
|
385
|
+
execute: async ({ getState }, input) => {
|
|
386
|
+
const { query } = input;
|
|
387
|
+
await getState().sqlEditor.parseAndRunQuery(query);
|
|
388
|
+
return {
|
|
389
|
+
success: true,
|
|
390
|
+
commandId: 'sql-editor.run-query',
|
|
391
|
+
message: 'Executed SQL query.',
|
|
392
|
+
};
|
|
393
|
+
},
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
id: 'sql-editor.abort-current-query',
|
|
397
|
+
name: 'Abort current query',
|
|
398
|
+
description: 'Cancel the currently running SQL query',
|
|
399
|
+
group: 'SQL Editor',
|
|
400
|
+
keywords: ['sql', 'abort', 'cancel', 'query'],
|
|
401
|
+
metadata: {
|
|
402
|
+
readOnly: false,
|
|
403
|
+
idempotent: true,
|
|
404
|
+
riskLevel: 'low',
|
|
405
|
+
},
|
|
406
|
+
isEnabled: ({ getState }) => {
|
|
407
|
+
const state = getState();
|
|
408
|
+
const selectedQueryId = state.sqlEditor.config.selectedQueryId;
|
|
409
|
+
return (state.sqlEditor.queryResultsById[selectedQueryId]?.status ===
|
|
410
|
+
'loading');
|
|
411
|
+
},
|
|
412
|
+
execute: ({ getState }) => {
|
|
413
|
+
getState().sqlEditor.abortCurrentQuery();
|
|
414
|
+
return {
|
|
415
|
+
success: true,
|
|
416
|
+
commandId: 'sql-editor.abort-current-query',
|
|
417
|
+
message: 'Abort signal sent to current query.',
|
|
418
|
+
};
|
|
419
|
+
},
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
id: 'sql-editor.create-query-tab',
|
|
423
|
+
name: 'Create query tab',
|
|
424
|
+
description: 'Open a new SQL query tab',
|
|
425
|
+
group: 'SQL Editor',
|
|
426
|
+
keywords: ['sql', 'tab', 'new', 'query'],
|
|
427
|
+
metadata: {
|
|
428
|
+
readOnly: false,
|
|
429
|
+
idempotent: false,
|
|
430
|
+
riskLevel: 'low',
|
|
431
|
+
},
|
|
432
|
+
execute: ({ getState }) => {
|
|
433
|
+
const newTab = getState().sqlEditor.createQueryTab();
|
|
434
|
+
return {
|
|
435
|
+
success: true,
|
|
436
|
+
commandId: 'sql-editor.create-query-tab',
|
|
437
|
+
message: `Created query tab "${newTab.name}".`,
|
|
438
|
+
data: {
|
|
439
|
+
queryId: newTab.id,
|
|
440
|
+
},
|
|
441
|
+
};
|
|
442
|
+
},
|
|
443
|
+
},
|
|
444
|
+
{
|
|
445
|
+
id: 'sql-editor.select-query-tab',
|
|
446
|
+
name: 'Select query tab',
|
|
447
|
+
description: 'Switch active SQL query tab by ID',
|
|
448
|
+
group: 'SQL Editor',
|
|
449
|
+
keywords: ['sql', 'tab', 'select', 'switch'],
|
|
450
|
+
inputSchema: SqlEditorTabIdInput,
|
|
451
|
+
inputDescription: 'Provide queryId to activate.',
|
|
452
|
+
metadata: {
|
|
453
|
+
readOnly: false,
|
|
454
|
+
idempotent: true,
|
|
455
|
+
riskLevel: 'low',
|
|
456
|
+
},
|
|
457
|
+
validateInput: (input, { getState }) => {
|
|
458
|
+
ensureQueryTabExists(getState(), input.queryId);
|
|
459
|
+
},
|
|
460
|
+
execute: ({ getState }, input) => {
|
|
461
|
+
const { queryId } = input;
|
|
462
|
+
getState().sqlEditor.setSelectedQueryId(queryId);
|
|
463
|
+
return {
|
|
464
|
+
success: true,
|
|
465
|
+
commandId: 'sql-editor.select-query-tab',
|
|
466
|
+
message: `Selected query tab "${queryId}".`,
|
|
467
|
+
};
|
|
468
|
+
},
|
|
469
|
+
},
|
|
470
|
+
{
|
|
471
|
+
id: 'sql-editor.rename-query-tab',
|
|
472
|
+
name: 'Rename query tab',
|
|
473
|
+
description: 'Rename a SQL query tab by ID',
|
|
474
|
+
group: 'SQL Editor',
|
|
475
|
+
keywords: ['sql', 'tab', 'rename'],
|
|
476
|
+
inputSchema: SqlEditorRenameTabInput,
|
|
477
|
+
inputDescription: 'Provide queryId and name.',
|
|
478
|
+
metadata: {
|
|
479
|
+
readOnly: false,
|
|
480
|
+
idempotent: true,
|
|
481
|
+
riskLevel: 'low',
|
|
482
|
+
},
|
|
483
|
+
validateInput: (input, { getState }) => {
|
|
484
|
+
ensureQueryTabExists(getState(), input.queryId);
|
|
485
|
+
},
|
|
486
|
+
execute: ({ getState }, input) => {
|
|
487
|
+
const { queryId, name } = input;
|
|
488
|
+
getState().sqlEditor.renameQueryTab(queryId, name);
|
|
489
|
+
return {
|
|
490
|
+
success: true,
|
|
491
|
+
commandId: 'sql-editor.rename-query-tab',
|
|
492
|
+
message: `Renamed query tab "${queryId}".`,
|
|
493
|
+
};
|
|
494
|
+
},
|
|
495
|
+
},
|
|
496
|
+
{
|
|
497
|
+
id: 'sql-editor.delete-query-tab',
|
|
498
|
+
name: 'Delete query tab',
|
|
499
|
+
description: 'Delete a SQL query tab by ID',
|
|
500
|
+
group: 'SQL Editor',
|
|
501
|
+
keywords: ['sql', 'tab', 'delete', 'remove'],
|
|
502
|
+
inputSchema: SqlEditorTabIdInput,
|
|
503
|
+
inputDescription: 'Provide queryId to delete.',
|
|
504
|
+
metadata: {
|
|
505
|
+
readOnly: false,
|
|
506
|
+
idempotent: true,
|
|
507
|
+
riskLevel: 'medium',
|
|
508
|
+
requiresConfirmation: true,
|
|
509
|
+
},
|
|
510
|
+
validateInput: (input, { getState }) => {
|
|
511
|
+
const state = getState();
|
|
512
|
+
ensureQueryTabExists(state, input.queryId);
|
|
513
|
+
if (state.sqlEditor.config.queries.length <= 1) {
|
|
514
|
+
throw new Error('Cannot delete the last remaining query tab.');
|
|
515
|
+
}
|
|
516
|
+
},
|
|
517
|
+
execute: ({ getState }, input) => {
|
|
518
|
+
const { queryId } = input;
|
|
519
|
+
getState().sqlEditor.deleteQueryTab(queryId);
|
|
520
|
+
return {
|
|
521
|
+
success: true,
|
|
522
|
+
commandId: 'sql-editor.delete-query-tab',
|
|
523
|
+
message: `Deleted query tab "${queryId}".`,
|
|
524
|
+
};
|
|
525
|
+
},
|
|
526
|
+
},
|
|
527
|
+
{
|
|
528
|
+
id: 'sql-editor.clear-query-results',
|
|
529
|
+
name: 'Clear query results',
|
|
530
|
+
description: 'Clear all cached SQL query results',
|
|
531
|
+
group: 'SQL Editor',
|
|
532
|
+
keywords: ['sql', 'clear', 'results'],
|
|
533
|
+
metadata: {
|
|
534
|
+
readOnly: false,
|
|
535
|
+
idempotent: true,
|
|
536
|
+
riskLevel: 'low',
|
|
537
|
+
},
|
|
538
|
+
isEnabled: ({ getState }) => Object.keys(getState().sqlEditor.queryResultsById).length > 0,
|
|
539
|
+
execute: ({ getState }) => {
|
|
540
|
+
getState().sqlEditor.clearQueryResults();
|
|
541
|
+
return {
|
|
542
|
+
success: true,
|
|
543
|
+
commandId: 'sql-editor.clear-query-results',
|
|
544
|
+
message: 'Cleared query results.',
|
|
545
|
+
};
|
|
546
|
+
},
|
|
547
|
+
},
|
|
548
|
+
{
|
|
549
|
+
id: 'sql-editor.set-result-limit',
|
|
550
|
+
name: 'Set query result limit',
|
|
551
|
+
description: 'Set max rows returned for query result previews',
|
|
552
|
+
group: 'SQL Editor',
|
|
553
|
+
keywords: ['sql', 'limit', 'rows', 'result'],
|
|
554
|
+
inputSchema: SqlEditorResultLimitInput,
|
|
555
|
+
inputDescription: 'Provide positive integer limit.',
|
|
556
|
+
metadata: {
|
|
557
|
+
readOnly: false,
|
|
558
|
+
idempotent: true,
|
|
559
|
+
riskLevel: 'low',
|
|
560
|
+
},
|
|
561
|
+
execute: ({ getState }, input) => {
|
|
562
|
+
const { limit } = input;
|
|
563
|
+
getState().sqlEditor.setQueryResultLimit(limit);
|
|
564
|
+
return {
|
|
565
|
+
success: true,
|
|
566
|
+
commandId: 'sql-editor.set-result-limit',
|
|
567
|
+
message: `Set query result limit to ${limit}.`,
|
|
568
|
+
};
|
|
569
|
+
},
|
|
570
|
+
},
|
|
571
|
+
];
|
|
572
|
+
}
|
|
314
573
|
export function useStoreWithSqlEditor(selector) {
|
|
315
574
|
return useBaseRoomShellStore((state) => selector(state));
|
|
316
575
|
}
|
|
@@ -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 /**\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"]}
|
|
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 registerCommandsForOwner,\n RoomCommand,\n RoomShellSliceState,\n StateCreator,\n unregisterCommandsForOwner,\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';\nimport {z} from 'zod';\n\nconst SQL_EDITOR_COMMAND_OWNER = '@sqlrooms/sql-editor';\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 initialize?: () => Promise<void>;\n destroy?: () => Promise<void>;\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, store) => {\n return {\n sqlEditor: {\n initialize: async () => {\n registerCommandsForOwner(\n store,\n SQL_EDITOR_COMMAND_OWNER,\n createSqlEditorCommands(),\n );\n },\n destroy: async () => {\n unregisterCommandsForOwner(store, SQL_EDITOR_COMMAND_OWNER);\n },\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\ntype SqlEditorCommandStoreState = BaseRoomStoreState &\n DuckDbSliceState &\n SqlEditorSliceState;\n\nconst SqlEditorRunQueryCommandInput = z.object({\n query: z.string().describe('SQL query text to run.'),\n});\ntype SqlEditorRunQueryCommandInput = z.infer<\n typeof SqlEditorRunQueryCommandInput\n>;\n\nconst SqlEditorTabIdInput = z.object({\n queryId: z.string().describe('ID of the query tab.'),\n});\ntype SqlEditorTabIdInput = z.infer<typeof SqlEditorTabIdInput>;\n\nconst SqlEditorRenameTabInput = z.object({\n queryId: z.string().describe('ID of the query tab to rename.'),\n name: z.string().min(1).describe('New tab name.'),\n});\ntype SqlEditorRenameTabInput = z.infer<typeof SqlEditorRenameTabInput>;\n\nconst SqlEditorResultLimitInput = z.object({\n limit: z.number().int().positive().describe('Row limit for query results.'),\n});\ntype SqlEditorResultLimitInput = z.infer<typeof SqlEditorResultLimitInput>;\n\nfunction createSqlEditorCommands(): RoomCommand<SqlEditorCommandStoreState>[] {\n const ensureQueryTabExists = (\n state: SqlEditorCommandStoreState,\n queryId: string,\n ) => {\n if (!state.sqlEditor.config.queries.some((query) => query.id === queryId)) {\n throw new Error(`Unknown query tab \"${queryId}\".`);\n }\n };\n\n return [\n {\n id: 'sql-editor.run-current-query',\n name: 'Run current query',\n description: 'Execute the selected SQL query tab',\n group: 'SQL Editor',\n keywords: ['sql', 'run', 'execute', 'query'],\n metadata: {\n readOnly: false,\n idempotent: false,\n riskLevel: 'medium',\n },\n ui: {\n shortcut: 'Mod+Enter',\n },\n isEnabled: ({getState}) => {\n const state = getState();\n const selectedQueryId = state.sqlEditor.config.selectedQueryId;\n const queryResult = state.sqlEditor.queryResultsById[selectedQueryId];\n return (\n queryResult?.status !== 'loading' &&\n state.sqlEditor.getCurrentQuery().trim().length > 0\n );\n },\n execute: async ({getState}) => {\n await getState().sqlEditor.parseAndRunCurrentQuery();\n return {\n success: true,\n commandId: 'sql-editor.run-current-query',\n message: 'Executed current query.',\n };\n },\n },\n {\n id: 'sql-editor.run-query',\n name: 'Run query text',\n description: 'Execute an explicitly provided SQL query',\n group: 'SQL Editor',\n keywords: ['sql', 'run', 'execute', 'query', 'text'],\n inputSchema: SqlEditorRunQueryCommandInput,\n inputDescription: 'Provide query SQL to execute.',\n metadata: {\n readOnly: false,\n idempotent: false,\n riskLevel: 'medium',\n },\n execute: async ({getState}, input) => {\n const {query} = input as SqlEditorRunQueryCommandInput;\n await getState().sqlEditor.parseAndRunQuery(query);\n return {\n success: true,\n commandId: 'sql-editor.run-query',\n message: 'Executed SQL query.',\n };\n },\n },\n {\n id: 'sql-editor.abort-current-query',\n name: 'Abort current query',\n description: 'Cancel the currently running SQL query',\n group: 'SQL Editor',\n keywords: ['sql', 'abort', 'cancel', 'query'],\n metadata: {\n readOnly: false,\n idempotent: true,\n riskLevel: 'low',\n },\n isEnabled: ({getState}) => {\n const state = getState();\n const selectedQueryId = state.sqlEditor.config.selectedQueryId;\n return (\n state.sqlEditor.queryResultsById[selectedQueryId]?.status ===\n 'loading'\n );\n },\n execute: ({getState}) => {\n getState().sqlEditor.abortCurrentQuery();\n return {\n success: true,\n commandId: 'sql-editor.abort-current-query',\n message: 'Abort signal sent to current query.',\n };\n },\n },\n {\n id: 'sql-editor.create-query-tab',\n name: 'Create query tab',\n description: 'Open a new SQL query tab',\n group: 'SQL Editor',\n keywords: ['sql', 'tab', 'new', 'query'],\n metadata: {\n readOnly: false,\n idempotent: false,\n riskLevel: 'low',\n },\n execute: ({getState}) => {\n const newTab = getState().sqlEditor.createQueryTab();\n return {\n success: true,\n commandId: 'sql-editor.create-query-tab',\n message: `Created query tab \"${newTab.name}\".`,\n data: {\n queryId: newTab.id,\n },\n };\n },\n },\n {\n id: 'sql-editor.select-query-tab',\n name: 'Select query tab',\n description: 'Switch active SQL query tab by ID',\n group: 'SQL Editor',\n keywords: ['sql', 'tab', 'select', 'switch'],\n inputSchema: SqlEditorTabIdInput,\n inputDescription: 'Provide queryId to activate.',\n metadata: {\n readOnly: false,\n idempotent: true,\n riskLevel: 'low',\n },\n validateInput: (input, {getState}) => {\n ensureQueryTabExists(\n getState(),\n (input as SqlEditorTabIdInput).queryId,\n );\n },\n execute: ({getState}, input) => {\n const {queryId} = input as SqlEditorTabIdInput;\n getState().sqlEditor.setSelectedQueryId(queryId);\n return {\n success: true,\n commandId: 'sql-editor.select-query-tab',\n message: `Selected query tab \"${queryId}\".`,\n };\n },\n },\n {\n id: 'sql-editor.rename-query-tab',\n name: 'Rename query tab',\n description: 'Rename a SQL query tab by ID',\n group: 'SQL Editor',\n keywords: ['sql', 'tab', 'rename'],\n inputSchema: SqlEditorRenameTabInput,\n inputDescription: 'Provide queryId and name.',\n metadata: {\n readOnly: false,\n idempotent: true,\n riskLevel: 'low',\n },\n validateInput: (input, {getState}) => {\n ensureQueryTabExists(\n getState(),\n (input as SqlEditorRenameTabInput).queryId,\n );\n },\n execute: ({getState}, input) => {\n const {queryId, name} = input as SqlEditorRenameTabInput;\n getState().sqlEditor.renameQueryTab(queryId, name);\n return {\n success: true,\n commandId: 'sql-editor.rename-query-tab',\n message: `Renamed query tab \"${queryId}\".`,\n };\n },\n },\n {\n id: 'sql-editor.delete-query-tab',\n name: 'Delete query tab',\n description: 'Delete a SQL query tab by ID',\n group: 'SQL Editor',\n keywords: ['sql', 'tab', 'delete', 'remove'],\n inputSchema: SqlEditorTabIdInput,\n inputDescription: 'Provide queryId to delete.',\n metadata: {\n readOnly: false,\n idempotent: true,\n riskLevel: 'medium',\n requiresConfirmation: true,\n },\n validateInput: (input, {getState}) => {\n const state = getState();\n ensureQueryTabExists(state, (input as SqlEditorTabIdInput).queryId);\n if (state.sqlEditor.config.queries.length <= 1) {\n throw new Error('Cannot delete the last remaining query tab.');\n }\n },\n execute: ({getState}, input) => {\n const {queryId} = input as SqlEditorTabIdInput;\n getState().sqlEditor.deleteQueryTab(queryId);\n return {\n success: true,\n commandId: 'sql-editor.delete-query-tab',\n message: `Deleted query tab \"${queryId}\".`,\n };\n },\n },\n {\n id: 'sql-editor.clear-query-results',\n name: 'Clear query results',\n description: 'Clear all cached SQL query results',\n group: 'SQL Editor',\n keywords: ['sql', 'clear', 'results'],\n metadata: {\n readOnly: false,\n idempotent: true,\n riskLevel: 'low',\n },\n isEnabled: ({getState}) =>\n Object.keys(getState().sqlEditor.queryResultsById).length > 0,\n execute: ({getState}) => {\n getState().sqlEditor.clearQueryResults();\n return {\n success: true,\n commandId: 'sql-editor.clear-query-results',\n message: 'Cleared query results.',\n };\n },\n },\n {\n id: 'sql-editor.set-result-limit',\n name: 'Set query result limit',\n description: 'Set max rows returned for query result previews',\n group: 'SQL Editor',\n keywords: ['sql', 'limit', 'rows', 'result'],\n inputSchema: SqlEditorResultLimitInput,\n inputDescription: 'Provide positive integer limit.',\n metadata: {\n readOnly: false,\n idempotent: true,\n riskLevel: 'low',\n },\n execute: ({getState}, input) => {\n const {limit} = input as SqlEditorResultLimitInput;\n getState().sqlEditor.setQueryResultLimit(limit);\n return {\n success: true,\n commandId: 'sql-editor.set-result-limit',\n message: `Set query result limit to ${limit}.`,\n };\n },\n },\n ];\n}\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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RenameSqlQueryModal.d.ts","sourceRoot":"","sources":["../../src/components/RenameSqlQueryModal.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAWvC,QAAA,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC;IAClC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC,
|
|
1
|
+
{"version":3,"file":"RenameSqlQueryModal.d.ts","sourceRoot":"","sources":["../../src/components/RenameSqlQueryModal.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAWvC,QAAA,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC;IAClC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC,CAwDA,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
|
|
@@ -9,7 +9,6 @@ const formSchema = z.object({
|
|
|
9
9
|
});
|
|
10
10
|
const RenameSqlQueryModal = ({ isOpen, onClose, initialName, onRename }) => {
|
|
11
11
|
const form = useForm({
|
|
12
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
13
12
|
resolver: zodResolver(formSchema),
|
|
14
13
|
defaultValues: {
|
|
15
14
|
queryName: initialName,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RenameSqlQueryModal.js","sourceRoot":"","sources":["../../src/components/RenameSqlQueryModal.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,MAAM,EACN,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,MAAM,EACN,IAAI,EACJ,WAAW,EACX,SAAS,EACT,QAAQ,EACR,SAAS,EACT,WAAW,EACX,KAAK,EACL,iBAAiB,GAClB,MAAM,cAAc,CAAC;AACtB,OAAc,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AACvC,OAAO,EAAC,OAAO,EAAC,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAC,WAAW,EAAC,MAAM,yBAAyB,CAAC;AAEpD,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,wBAAwB,CAAC;CACvD,CAAC,CAAC;AAIH,MAAM,mBAAmB,GAKpB,CAAC,EAAC,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAC,EAAE,EAAE;IAChD,MAAM,IAAI,GAAG,OAAO,CAAW;QAC7B,
|
|
1
|
+
{"version":3,"file":"RenameSqlQueryModal.js","sourceRoot":"","sources":["../../src/components/RenameSqlQueryModal.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,MAAM,EACN,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,MAAM,EACN,IAAI,EACJ,WAAW,EACX,SAAS,EACT,QAAQ,EACR,SAAS,EACT,WAAW,EACX,KAAK,EACL,iBAAiB,GAClB,MAAM,cAAc,CAAC;AACtB,OAAc,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AACvC,OAAO,EAAC,OAAO,EAAC,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAC,WAAW,EAAC,MAAM,yBAAyB,CAAC;AAEpD,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,wBAAwB,CAAC;CACvD,CAAC,CAAC;AAIH,MAAM,mBAAmB,GAKpB,CAAC,EAAC,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAC,EAAE,EAAE;IAChD,MAAM,IAAI,GAAG,OAAO,CAAW;QAC7B,QAAQ,EAAE,WAAW,CAAC,UAAiB,CAAC;QACxC,aAAa,EAAE;YACb,SAAS,EAAE,WAAW;SACvB;KACF,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC,KAAK,CAAC,EAAC,SAAS,EAAE,WAAW,EAAC,CAAC,CAAC;QACvC,CAAC;IACH,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC;IAEhC,SAAS,QAAQ,CAAC,MAAgB;QAChC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC3B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,CACL,KAAC,MAAM,IAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,OAAO,EAAE,YAC9D,MAAC,aAAa,eACZ,MAAC,YAAY,eACX,KAAC,WAAW,yBAAqB,EACjC,KAAC,iBAAiB,kDAAoD,IACzD,EACf,KAAC,IAAI,OAAK,IAAI,YACZ,gBAAM,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAC,WAAW,aAChE,KAAC,SAAS,IACR,OAAO,EAAE,IAAI,CAAC,OAAO,EACrB,IAAI,EAAC,WAAW,EAChB,MAAM,EAAE,CAAC,EAAC,KAAK,EAAC,EAAE,EAAE,CAAC,CACnB,MAAC,QAAQ,eACP,KAAC,SAAS,6BAAuB,EACjC,KAAC,WAAW,cACV,KAAC,KAAK,OACA,KAAK,EACT,SAAS,QACT,WAAW,EAAC,kBAAkB,GAC9B,GACU,EACd,KAAC,WAAW,KAAG,IACN,CACZ,GACD,EACF,MAAC,YAAY,eACX,KAAC,MAAM,IAAC,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAC,SAAS,EAAC,OAAO,EAAE,OAAO,uBAE/C,EACT,KAAC,MAAM,IAAC,IAAI,EAAC,QAAQ,qBAAc,IACtB,IACV,GACF,IACO,GACT,CACV,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,mBAAmB,CAAC","sourcesContent":["import {\n Dialog,\n DialogContent,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Button,\n Form,\n FormControl,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n Input,\n DialogDescription,\n} from '@sqlrooms/ui';\nimport React, {useEffect} from 'react';\nimport {useForm} from 'react-hook-form';\nimport * as z from 'zod';\nimport {zodResolver} from '@hookform/resolvers/zod';\n\nconst formSchema = z.object({\n queryName: z.string().min(1, 'Query name is required'),\n});\n\ntype FormData = z.infer<typeof formSchema>;\n\nconst RenameSqlQueryModal: React.FC<{\n isOpen: boolean;\n onClose: () => void;\n initialName: string;\n onRename: (newName: string) => void;\n}> = ({isOpen, onClose, initialName, onRename}) => {\n const form = useForm<FormData>({\n resolver: zodResolver(formSchema as any),\n defaultValues: {\n queryName: initialName,\n },\n });\n\n useEffect(() => {\n if (isOpen) {\n form.reset({queryName: initialName});\n }\n }, [isOpen, initialName, form]);\n\n function onSubmit(values: FormData) {\n onRename(values.queryName);\n onClose();\n }\n\n return (\n <Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Rename</DialogTitle>\n <DialogDescription>Rename the query to a new name.</DialogDescription>\n </DialogHeader>\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-4\">\n <FormField\n control={form.control}\n name=\"queryName\"\n render={({field}) => (\n <FormItem>\n <FormLabel>Query Name</FormLabel>\n <FormControl>\n <Input\n {...field}\n autoFocus\n placeholder=\"Enter query name\"\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n <DialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={onClose}>\n Cancel\n </Button>\n <Button type=\"submit\">Save</Button>\n </DialogFooter>\n </form>\n </Form>\n </DialogContent>\n </Dialog>\n );\n};\n\nexport default RenameSqlQueryModal;\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sqlrooms/sql-editor",
|
|
3
|
-
"version": "0.28.0
|
|
3
|
+
"version": "0.28.0",
|
|
4
4
|
"author": "SQLRooms Contributors",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -29,14 +29,14 @@
|
|
|
29
29
|
"@hookform/resolvers": "^5.0.0",
|
|
30
30
|
"@monaco-editor/react": "^4.7.0",
|
|
31
31
|
"@paralleldrive/cuid2": "^3.0.0",
|
|
32
|
-
"@sqlrooms/data-table": "0.28.0
|
|
33
|
-
"@sqlrooms/duckdb": "0.28.0
|
|
34
|
-
"@sqlrooms/monaco-editor": "0.28.0
|
|
35
|
-
"@sqlrooms/room-shell": "0.28.0
|
|
36
|
-
"@sqlrooms/schema-tree": "0.28.0
|
|
37
|
-
"@sqlrooms/sql-editor-config": "0.28.0
|
|
38
|
-
"@sqlrooms/ui": "0.28.0
|
|
39
|
-
"@sqlrooms/utils": "0.28.0
|
|
32
|
+
"@sqlrooms/data-table": "0.28.0",
|
|
33
|
+
"@sqlrooms/duckdb": "0.28.0",
|
|
34
|
+
"@sqlrooms/monaco-editor": "0.28.0",
|
|
35
|
+
"@sqlrooms/room-shell": "0.28.0",
|
|
36
|
+
"@sqlrooms/schema-tree": "0.28.0",
|
|
37
|
+
"@sqlrooms/sql-editor-config": "0.28.0",
|
|
38
|
+
"@sqlrooms/ui": "0.28.0",
|
|
39
|
+
"@sqlrooms/utils": "0.28.0",
|
|
40
40
|
"@tanstack/react-table": "^8.21.3",
|
|
41
41
|
"d3-dsv": "^3.0.1",
|
|
42
42
|
"file-saver": "^2.0.5",
|
|
@@ -58,5 +58,5 @@
|
|
|
58
58
|
"@types/react": "^19.1.13",
|
|
59
59
|
"@types/react-dom": "^19.1.9"
|
|
60
60
|
},
|
|
61
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "dcac54f8adf77240e293c93d224a0ce9fd8142a9"
|
|
62
62
|
}
|