sqlite-hub 1.1.1 → 1.2.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 +17 -196
- package/bin/sqlite-hub.js +7 -2
- package/frontend/js/api.js +60 -0
- package/frontend/js/app.js +201 -5
- package/frontend/js/components/dropdownButton.js +92 -0
- package/frontend/js/components/modal.js +991 -876
- package/frontend/js/components/queryEditor.js +24 -15
- package/frontend/js/components/queryHistoryDetail.js +20 -1
- package/frontend/js/components/queryHistoryHeader.js +3 -2
- package/frontend/js/components/queryResults.js +1 -1
- package/frontend/js/components/rowEditorPanel.js +53 -13
- package/frontend/js/components/sidebar.js +1 -0
- package/frontend/js/components/topNav.js +1 -4
- package/frontend/js/components/workspaceOpenDropdown.js +52 -0
- package/frontend/js/router.js +2 -0
- package/frontend/js/store.js +450 -38
- package/frontend/js/utils/emailPreview.js +28 -0
- package/frontend/js/utils/markdownDocuments.js +17 -1
- package/frontend/js/utils/riskySql.js +165 -0
- package/frontend/js/views/backups.js +204 -0
- package/frontend/js/views/charts.js +1 -1
- package/frontend/js/views/data.js +42 -16
- package/frontend/js/views/documents.js +184 -154
- package/frontend/js/views/settings.js +1 -0
- package/frontend/js/views/structure.js +47 -33
- package/frontend/js/views/tableDesigner.js +23 -0
- package/frontend/styles/components.css +133 -0
- package/frontend/styles/tailwind.generated.css +1 -1
- package/frontend/styles/tokens.css +1 -0
- package/frontend/styles/views.css +33 -21
- package/package.json +2 -1
- package/server/routes/backups.js +120 -0
- package/server/routes/connections.js +26 -3
- package/server/routes/externalApi.js +6 -2
- package/server/server.js +3 -1
- package/server/services/databaseCommandService.js +4 -3
- package/server/services/sqlite/backupService.js +497 -66
- package/server/services/sqlite/connectionManager.js +2 -2
- package/server/services/sqlite/importService.js +25 -0
- package/server/services/sqlite/sqlExecutor.js +2 -0
- package/server/services/storage/appStateStore.js +379 -88
- package/tests/api-token-auth.test.js +45 -2
- package/tests/backup-manager.test.js +140 -0
- package/tests/backups-view.test.js +70 -0
- package/tests/charts-height-preset-storage.test.js +60 -0
- package/tests/charts-route-state.test.js +144 -0
- package/tests/cli-service-delegation.test.js +97 -0
- package/tests/connection-removal.test.js +52 -0
- package/tests/database-command-service.test.js +37 -2
- package/tests/documents-view.test.js +132 -0
- package/tests/dropdown-button.test.js +101 -0
- package/tests/email-preview.test.js +89 -0
- package/tests/markdown-documents.test.js +24 -0
- package/tests/query-editor.test.js +28 -0
- package/tests/query-history-detail.test.js +37 -0
- package/tests/query-history-header.test.js +30 -0
- package/tests/risky-sql.test.js +30 -0
- package/tests/row-editor-null-values.test.js +53 -0
- package/tests/settings-view.test.js +1 -0
- package/tests/structure-view.test.js +60 -0
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ SQLite Hub keeps that workflow sharp:
|
|
|
23
23
|
- copy result columns with formatting, headers, first-10 previews, TXT export, and Markdown todo export
|
|
24
24
|
- keep database-scoped Markdown documents with previews, autosave, imports, exports, and saved-query inserts
|
|
25
25
|
- switch between recent databases with sidebar quick picks
|
|
26
|
-
- create
|
|
26
|
+
- create verified local backups of the active database and get safety prompts before risky operations
|
|
27
27
|
- run and format SQL in a syntax-highlighted editor with history, messages, and performance metrics
|
|
28
28
|
- keep large interactive query results bounded while full exports remain available
|
|
29
29
|
- turn query-history results into local charts
|
|
@@ -176,9 +176,18 @@ The Settings view reports the installed SQLite Hub version and the actual SQLite
|
|
|
176
176
|
|
|
177
177
|
The active database footer in the sidebar opens a quick-pick panel with the five most recent databases, so you can switch databases without going back to the Connections view.
|
|
178
178
|
|
|
179
|
-
###
|
|
179
|
+
### Backup Manager
|
|
180
180
|
|
|
181
|
-
Create
|
|
181
|
+
Create verified local backups of the active SQLite database, review backup metadata, edit backup notes, download backup files, restore verified backups, and delete managed backups from the Backups view. SQLite Hub stores backup files under its local app-state backup directory by connection id and keeps a `manifest.json` beside each database's backup files. Each backup is created through SQLite's backup API, hashed with SHA-256, and verified with `PRAGMA quick_check` before it is marked as verified.
|
|
182
|
+
|
|
183
|
+
SQLite Hub also proposes a safety backup before operations that can be hard to undo:
|
|
184
|
+
|
|
185
|
+
- SQL Editor execution when the statement set contains `DROP TABLE`, `ALTER TABLE`, `CREATE TABLE`, `CREATE INDEX`, `CREATE VIEW`, `CREATE TRIGGER`, `DROP INDEX`, `DROP VIEW`, `DROP TRIGGER`, `REINDEX`, or `VACUUM`.
|
|
186
|
+
- SQL Editor execution with multiple schema-affecting statements in one run; this is treated as a migration and suggests a `Before migration` backup.
|
|
187
|
+
- SQL import into the currently active database when the dump is larger than 5 MB or contains more than 1,000 parsed SQL statements.
|
|
188
|
+
- Restore from a managed backup, because the current active database file will be replaced.
|
|
189
|
+
|
|
190
|
+
The safety dialog lets you create the backup and continue, continue without creating one, or cancel the operation.
|
|
182
191
|
|
|
183
192
|
### Local-first
|
|
184
193
|
|
|
@@ -205,200 +214,12 @@ npm install -g sqlite-hub
|
|
|
205
214
|
sqlite-hub --port:4174
|
|
206
215
|
```
|
|
207
216
|
|
|
208
|
-
## CLI
|
|
209
|
-
|
|
210
|
-
SQLite Hub ships with a built-in CLI that lets you start the app or query information about your imported databases directly from the terminal.
|
|
211
|
-
|
|
212
|
-
### Start the app
|
|
213
|
-
|
|
214
|
-
```bash
|
|
215
|
-
sqlite-hub # start on default port 4173
|
|
216
|
-
sqlite-hub --port:4174 # start on a custom port
|
|
217
|
-
sqlite-hub --open # open SQLite Hub in the browser
|
|
218
|
-
sqlite-hub --info # show port, URL, versions, and update status
|
|
219
|
-
sqlite-hub --help # show help text
|
|
220
|
-
sqlite-hub --version # show version number
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
### List all imported databases
|
|
224
|
-
|
|
225
|
-
```bash
|
|
226
|
-
sqlite-hub --database
|
|
227
|
-
sqlite-hub -d
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
Shows an overview of all databases that have been opened in SQLite Hub, including:
|
|
231
|
-
|
|
232
|
-
- database name/label
|
|
233
|
-
- file path
|
|
234
|
-
- file size
|
|
235
|
-
- last opened timestamp
|
|
236
|
-
- read-only status
|
|
237
|
-
|
|
238
|
-
### Query specific database details
|
|
239
|
-
|
|
240
|
-
Retrieve details about a single database by its name (case-insensitive):
|
|
241
|
-
|
|
242
|
-
```bash
|
|
243
|
-
sqlite-hub --database:Billly --path # get the file path
|
|
244
|
-
sqlite-hub --database:Billly --size # get the file size
|
|
245
|
-
sqlite-hub --database:Billly --lastopened # get last opened timestamp
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
### List all tables in a database
|
|
249
|
-
|
|
250
|
-
```bash
|
|
251
|
-
sqlite-hub --database:Billly --tables
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
Opens the database in read-only mode and prints all table names, sorted alphabetically.
|
|
255
|
-
|
|
256
|
-
### Inspect a table
|
|
257
|
-
|
|
258
|
-
```bash
|
|
259
|
-
sqlite-hub --database:Billly --table:companies
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
Prints table metadata such as columns, primary keys, foreign keys, indexes, row count, and row identity strategy.
|
|
263
|
-
|
|
264
|
-
### SQL Editor - Raw SQL And Saved Queries
|
|
265
|
-
|
|
266
|
-
Execute raw SQL through the same SQL Editor execution path used by the app:
|
|
267
|
-
|
|
268
|
-
```bash
|
|
269
|
-
sqlite-hub --database:Unit-00 --query:"SELECT * FROM companies LIMIT 10"
|
|
270
|
-
sqlite-hub --database:Unit-00 --query:"SELECT * FROM companies LIMIT 10" --store:"Company Sample"
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
Raw CLI queries are recorded in Query History. Add `--store:"name"` to title the
|
|
274
|
-
history item and mark it as saved. Raw SQL execution is rejected when the target
|
|
275
|
-
database is marked read-only.
|
|
276
|
-
|
|
277
|
-
List all saved queries for a database:
|
|
278
|
-
|
|
279
|
-
```bash
|
|
280
|
-
sqlite-hub --database:Unit-00 --queries
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
Execute a specific saved query by name:
|
|
284
|
-
|
|
285
|
-
```bash
|
|
286
|
-
sqlite-hub --database:Unit-00 --execute:"15min Posting Buckets without id 96"
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
This searches the query history for the given database, finds the matching saved query by title, executes it, and returns all results with metadata (row count, columns, timing, and data).
|
|
290
|
-
|
|
291
|
-
Show the saved query SQL without executing it:
|
|
292
|
-
|
|
293
|
-
```bash
|
|
294
|
-
sqlite-hub --database:Unit-00 --saved-query:"Stock Winners"
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
Show the saved notes for a query:
|
|
298
|
-
|
|
299
|
-
```bash
|
|
300
|
-
sqlite-hub --database:Unit-00 --notes:"TOP25 Loser and Winner EOD, T1, T3, T5"
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
Export a saved query using the same CSV, TSV, Markdown, and JSON export logic as the SQL Editor:
|
|
304
|
-
|
|
305
|
-
```bash
|
|
306
|
-
sqlite-hub --database:Unit-00 --export:"Stock Winners" --format:csv
|
|
307
|
-
sqlite-hub --database:Unit-00 --export:"Stock Winners" --format:tsv
|
|
308
|
-
sqlite-hub --database:Unit-00 --export:"Stock Winners" --format:md
|
|
309
|
-
sqlite-hub --database:Unit-00 --export:"Stock Winners" --format:json
|
|
310
|
-
```
|
|
311
|
-
|
|
312
|
-
The export is written to the current working directory using the generated query export filename.
|
|
217
|
+
## CLI
|
|
313
218
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
```bash
|
|
319
|
-
sqlite-hub --database:Unit-00 --documents
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
Print one document's Markdown content:
|
|
323
|
-
|
|
324
|
-
```bash
|
|
325
|
-
sqlite-hub --database:Unit-00 --documents:"Research Notes"
|
|
326
|
-
```
|
|
327
|
-
|
|
328
|
-
Export one document as a `.md` file into the current working directory:
|
|
329
|
-
|
|
330
|
-
```bash
|
|
331
|
-
sqlite-hub --database:Unit-00 --documents:"Research Notes" --export
|
|
332
|
-
sqlite-hub --database:Unit-00 --documents:"Research Notes--export"
|
|
333
|
-
```
|
|
334
|
-
|
|
335
|
-
Documents can be matched by id, filename, title, or a partial filename/title match.
|
|
336
|
-
|
|
337
|
-
### Row JSON export
|
|
338
|
-
|
|
339
|
-
Export a single row as JSON by primary key or rowid, using the same row-shaping logic as the Row Editor:
|
|
340
|
-
|
|
341
|
-
```bash
|
|
342
|
-
sqlite-hub --database:Unit-00 --table:companies --export:0a754aba373d34972998792a0be4333c
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
### Available flags
|
|
346
|
-
|
|
347
|
-
| Flag | Description |
|
|
348
|
-
| --------------------------------------------------------------- | ----------------------------------------------- |
|
|
349
|
-
| `--help`, `-h` | Show help text |
|
|
350
|
-
| `--version`, `-v` | Show version number |
|
|
351
|
-
| `--info` | Show port, URL, versions, and update status |
|
|
352
|
-
| `--open` | Open SQLite Hub in the browser |
|
|
353
|
-
| `--port:PORT` | Start the server on a custom port |
|
|
354
|
-
| `--database`, `-d` | List all imported databases |
|
|
355
|
-
| `--database:name` | Select a database by name or id |
|
|
356
|
-
| `--database:name --path` | Get the file path of a database |
|
|
357
|
-
| `--database:name --size` | Get the size of a database |
|
|
358
|
-
| `--database:name --lastopened` | Get the last opened timestamp |
|
|
359
|
-
| `--database:name --tables` | Get all table names from a database |
|
|
360
|
-
| `--database:name --queries` | List saved queries for a database |
|
|
361
|
-
| `--database:name --query:"sql"` | Execute raw SQL and record it in Query History |
|
|
362
|
-
| `--database:name --query:"sql" --store:"name"` | Save a raw query in Query History with a name |
|
|
363
|
-
| `--database:name --execute:"query"` | Execute a saved query by name |
|
|
364
|
-
| `--database:name --saved-query:"query"` | Print a saved query by name |
|
|
365
|
-
| `--database:name --notes:"query"` | Print saved notes for a query |
|
|
366
|
-
| `--database:name --export:"query" --format:csv\|tsv\|md\|json` | Set query export format |
|
|
367
|
-
| `--database:name --documents` | List Markdown documents for a database |
|
|
368
|
-
| `--database:name --documents:"document"` | Print a document's Markdown content |
|
|
369
|
-
| `--database:name --documents:"document" --export` | Export a document as Markdown |
|
|
370
|
-
| `--database:name --table:"table"` | Print table metadata |
|
|
371
|
-
| `--database:name --table:"table" --export:"pk"` | Export one row as JSON |
|
|
372
|
-
|
|
373
|
-
Legacy aliases such as `--database-path:name`, `--database-size:name`, `--database-lastopened:name`, `--database-tables:name`, and `--database:name --sqleditor:"query"` still work.
|
|
374
|
-
|
|
375
|
-
### SQL editor CLI example
|
|
376
|
-
|
|
377
|
-
Saved queries created in the graphical SQL Editor can also be executed through the CLI. To execute one, run:
|
|
378
|
-
|
|
379
|
-
```bash
|
|
380
|
-
sqlite-hub --database:Unit-00 --execute:"Group by creation Year"
|
|
381
|
-
```
|
|
382
|
-
|
|
383
|
-
Example output:
|
|
384
|
-
|
|
385
|
-
```bash
|
|
386
|
-
Executing: Group by creation Year
|
|
387
|
-
SQL: SELECT STRFTIME('%Y', creation_time, 'unixepoch') AS creation_year, COUNT(*) AS channel_count FROM channels WHERE creation_time IS NOT NU...
|
|
388
|
-
────────────────────────────────────────────────────────────
|
|
389
|
-
|
|
390
|
-
Statement count: 1
|
|
391
|
-
Timing: 1ms
|
|
392
|
-
|
|
393
|
-
Statement 1 (resultSet):
|
|
394
|
-
Rows: 3
|
|
395
|
-
Columns: creation_year, channel_count
|
|
396
|
-
|
|
397
|
-
Results:
|
|
398
|
-
[0] 2024 | 11
|
|
399
|
-
[1] 2025 | 47
|
|
400
|
-
[2] 2026 | 40
|
|
401
|
-
```
|
|
219
|
+
SQLite Hub ships with a built-in CLI for starting the app, inspecting imported
|
|
220
|
+
databases, executing raw or saved SQL, exporting query results, exporting single
|
|
221
|
+
rows as JSON, and working with Markdown documents. See the
|
|
222
|
+
[CLI documentation](./docs/CLI.md) for commands, flags, and examples.
|
|
402
223
|
|
|
403
224
|
## API
|
|
404
225
|
|
package/bin/sqlite-hub.js
CHANGED
|
@@ -566,7 +566,9 @@ function printExecutionResult(result) {
|
|
|
566
566
|
}
|
|
567
567
|
|
|
568
568
|
function executeSavedQuery({ databaseService, conn, queryName }) {
|
|
569
|
-
const { query: matchingQuery, result } = databaseService.executeSavedQuery(conn.id, queryName
|
|
569
|
+
const { query: matchingQuery, result } = databaseService.executeSavedQuery(conn.id, queryName, {
|
|
570
|
+
executedBy: "cli",
|
|
571
|
+
});
|
|
570
572
|
|
|
571
573
|
console.log(`\nExecuting: ${getQueryTitle(matchingQuery)}`);
|
|
572
574
|
console.log(`SQL: ${matchingQuery.previewSql || matchingQuery.rawSql}`);
|
|
@@ -576,7 +578,10 @@ function executeSavedQuery({ databaseService, conn, queryName }) {
|
|
|
576
578
|
}
|
|
577
579
|
|
|
578
580
|
function executeRawQuery({ databaseService, conn, sql, storeName = null }) {
|
|
579
|
-
const { result, storedQuery } = databaseService.executeRawQuery(conn.id, sql, {
|
|
581
|
+
const { result, storedQuery } = databaseService.executeRawQuery(conn.id, sql, {
|
|
582
|
+
storeName,
|
|
583
|
+
executedBy: "cli",
|
|
584
|
+
});
|
|
580
585
|
|
|
581
586
|
console.log(`\nExecuting raw SQL against: ${conn.label}`);
|
|
582
587
|
console.log('─'.repeat(60));
|
package/frontend/js/api.js
CHANGED
|
@@ -105,6 +105,13 @@ export function importSql(payload) {
|
|
|
105
105
|
});
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
+
export function previewImportSql(payload) {
|
|
109
|
+
return request("/api/connections/import-sql/preview", {
|
|
110
|
+
method: "POST",
|
|
111
|
+
body: payload,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
108
115
|
export function selectActiveConnection(id) {
|
|
109
116
|
return request("/api/connections/select-active", {
|
|
110
117
|
method: "POST",
|
|
@@ -131,6 +138,59 @@ export function createActiveConnectionBackup() {
|
|
|
131
138
|
});
|
|
132
139
|
}
|
|
133
140
|
|
|
141
|
+
export function getBackups(options = {}) {
|
|
142
|
+
const params = new URLSearchParams();
|
|
143
|
+
|
|
144
|
+
if (options.all) {
|
|
145
|
+
params.set("all", "true");
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const query = params.toString();
|
|
149
|
+
return request(`/api/backups${query ? `?${query}` : ""}`);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export function getBackup(backupId) {
|
|
153
|
+
return request(`/api/backups/${encodeURIComponent(backupId)}`);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function createBackup(payload = {}) {
|
|
157
|
+
return request("/api/backups", {
|
|
158
|
+
method: "POST",
|
|
159
|
+
body: payload,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export function updateBackup(backupId, payload = {}) {
|
|
164
|
+
return request(`/api/backups/${encodeURIComponent(backupId)}`, {
|
|
165
|
+
method: "PATCH",
|
|
166
|
+
body: payload,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export function restoreBackup(backupId) {
|
|
171
|
+
return request(`/api/backups/${encodeURIComponent(backupId)}/restore`, {
|
|
172
|
+
method: "POST",
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export function verifyBackup(backupId) {
|
|
177
|
+
return request(`/api/backups/${encodeURIComponent(backupId)}/verify`, {
|
|
178
|
+
method: "POST",
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export function deleteBackup(backupId) {
|
|
183
|
+
return request(`/api/backups/${encodeURIComponent(backupId)}`, {
|
|
184
|
+
method: "DELETE",
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export function downloadBackup(backupId) {
|
|
189
|
+
return download(`/api/backups/${encodeURIComponent(backupId)}/download`, {
|
|
190
|
+
fallbackFilename: "backup.sqlite",
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
134
194
|
export function getOverview() {
|
|
135
195
|
return request("/api/db/overview");
|
|
136
196
|
}
|