sqlite-hub 0.11.1 → 0.16.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.
Files changed (52) hide show
  1. package/README.md +52 -13
  2. package/database.sqlite +0 -0
  3. package/frontend/js/api.js +64 -12
  4. package/frontend/js/app.js +723 -37
  5. package/frontend/js/components/emptyState.js +42 -46
  6. package/frontend/js/components/modal.js +526 -2
  7. package/frontend/js/components/queryEditor.js +12 -3
  8. package/frontend/js/components/queryResults.js +79 -17
  9. package/frontend/js/components/rowEditorPanel.js +345 -12
  10. package/frontend/js/components/sidebar.js +106 -23
  11. package/frontend/js/components/tableDesignerEditor.js +69 -11
  12. package/frontend/js/store.js +437 -26
  13. package/frontend/js/utils/copyColumnExport.js +117 -0
  14. package/frontend/js/utils/exportFilenames.js +32 -0
  15. package/frontend/js/utils/filePathPreview.js +315 -0
  16. package/frontend/js/utils/format.js +1 -1
  17. package/frontend/js/utils/rowEditorJson.js +65 -0
  18. package/frontend/js/utils/sqlFormatter.js +691 -0
  19. package/frontend/js/utils/tableDesigner.js +178 -6
  20. package/frontend/js/utils/textCellStats.js +20 -0
  21. package/frontend/js/utils/timestampPreview.js +264 -0
  22. package/frontend/js/views/charts.js +3 -1
  23. package/frontend/js/views/data.js +39 -4
  24. package/frontend/js/views/editor.js +50 -1
  25. package/frontend/js/views/settings.js +1 -4
  26. package/frontend/js/views/structure.js +154 -212
  27. package/frontend/styles/base.css +6 -0
  28. package/frontend/styles/components.css +463 -2
  29. package/frontend/styles/structure-graph.css +0 -3
  30. package/frontend/styles/tailwind.generated.css +1 -1
  31. package/frontend/styles/tokens.css +95 -95
  32. package/package.json +2 -3
  33. package/server/routes/export.js +97 -12
  34. package/server/services/sqlite/dataBrowserService.js +2 -68
  35. package/server/services/sqlite/exportService.js +74 -15
  36. package/server/services/sqlite/introspection.js +209 -1
  37. package/server/services/sqlite/sqlExecutor.js +31 -0
  38. package/server/services/sqlite/tableDesigner/changeAnalysis.js +25 -1
  39. package/server/services/sqlite/tableDesigner/schemaMapping.js +105 -10
  40. package/server/services/sqlite/tableDesigner/validation.js +60 -2
  41. package/server/services/sqlite/tableDesignerService.js +1 -1
  42. package/server/services/sqlite/tableFilter.js +75 -0
  43. package/server/utils/csv.js +30 -4
  44. package/tests/check-constraint-options.test.js +90 -0
  45. package/tests/export-filenames.test.js +34 -0
  46. package/tests/file-path-preview.test.js +165 -0
  47. package/tests/row-editor-json.test.js +82 -0
  48. package/tests/row-editor-timestamp-preview.test.js +192 -0
  49. package/tests/sql-formatter.test.js +173 -0
  50. package/tests/sql-highlight.test.js +38 -0
  51. package/tests/table-designer-v2-unique-constraints.test.js +78 -0
  52. package/tests/text-cell-stats.test.js +38 -0
package/README.md CHANGED
@@ -13,11 +13,16 @@ Many database tools are powerful, but feel oversized when all you want is to ins
13
13
  SQLite Hub keeps that workflow sharp:
14
14
 
15
15
  - browse tables and rows
16
- - inspect schema and structure
17
- - edit records in place
18
- - export tables and query results as CSV
16
+ - filter, sort, page through, and export table data
17
+ - inspect schema, structure, and relationships
18
+ - edit records in place with an SQL diff preview before saving
19
+ - export tables and query results as CSV, TSV, Markdown, or duplicate them as a table
20
+ - copy result columns with formatting, headers, first-10 previews, TXT export, and Markdown todo export
21
+ - switch between recent databases with sidebar quick picks
19
22
  - create simple local backups of the active database
20
- - run SQL in a syntax-highlighted editor
23
+ - run and format SQL in a syntax-highlighted editor with history, messages, and performance metrics
24
+ - turn query-history results into local charts
25
+ - create and edit tables with a live SQL preview
21
26
  - stay local and move fast
22
27
 
23
28
  ## Features
@@ -26,25 +31,59 @@ SQLite Hub keeps that workflow sharp:
26
31
 
27
32
  ![](./frontend/assets/mockups/structure.png)
28
33
 
29
- Inspect tables, columns, types, and schema details without losing pace. Visualized in a graph.
34
+ Inspect tables, columns, types, indexes, foreign keys, and schema details without losing pace. The graph view visualizes relationships, the table list is searchable, and SQLite Hub remembers the last selected table while you move between views.
30
35
 
31
36
  ### Data browser
32
37
 
33
38
  ![](./frontend/assets/mockups/data.png)
34
39
 
35
- Scan rows, sort fast, move through local data quickly, and export full tables as CSV.
40
+ Scan rows, sort fast, move through local data quickly, and export full tables as CSV, TSV, or Markdown. The Data browser also supports duplicating exports as a new table, table search, page sizes up to 250 rows, and advanced filters with column/operator/value controls. Text filters support case-insensitive `contains`, `not contains`, and exact `equals` matching.
36
41
 
37
42
  ### Row editing
38
43
 
39
44
  ![](./frontend/assets/mockups/data_row_editor.png)
40
45
 
41
- Open one record, edit it in place, commit, continue.
46
+ Open one record, edit it in place, preview the SQL diff, then commit. SQLite Hub only enables row edits when it can target a stable row identity safely.
42
47
 
43
48
  ### SQL editor
44
49
 
45
50
  ![](./frontend/assets/mockups/sql_editor.png)
46
51
 
47
- Write queries in a syntax-highlighted editor, inspect results in the same workflow, and export result sets as CSV.
52
+ Write queries in a syntax-highlighted editor, format SQL with the editor Format button, inspect results in the same workflow, and export result sets as CSV, TSV, Markdown, or duplicate them as a table. Query drafts survive reloads, query history can be searched and saved, and direct single-table `SELECT` results can be edited from the result grid.
53
+
54
+ Result column menus include copy actions for a full column, a column with header, or the first 10 values. The same modal can preview the output, copy it, export it as TXT, or turn a column into Markdown todo items.
55
+
56
+ The bottom panel keeps separate tabs for:
57
+
58
+ - Results
59
+ - Performance, including execution time, statement count, returned rows, affected rows, and serialized result memory size
60
+ - Messages, including the executed query and statement updates/errors
61
+
62
+ Potentially destructive statements are tracked in query history, and SQLite Hub keeps the active result tab instead of forcing you back to Results after every execution.
63
+
64
+ ### Query history
65
+
66
+ SQLite Hub stores query history per database. You can search SQL, titles, and notes; mark useful queries as saved; re-run previous queries; and execute saved queries from the CLI.
67
+
68
+ ### Charts
69
+
70
+ Create charts from chartable `SELECT` query-history entries. Charts can be saved per query, reopened later, and rendered from live query results.
71
+
72
+ ### Table Designer
73
+
74
+ Create and edit SQLite tables from the UI. The Table Designer includes a searchable table list, column controls, CSV import drafting, and a live SQL preview that can be hidden or shown.
75
+
76
+ ### Media Tagging
77
+
78
+ Configure a media table, tag table, and mapping table, then work through a tagging queue for image, video, and audio assets. The workflow supports preview controls, skipped items, parent tags, and applying selected tags to the current media row.
79
+
80
+ ### UI preferences
81
+
82
+ SQLite Hub remembers common workspace preferences in local storage, including hidden panels, selected editor tabs, query drafts, chart panels, table row size, and Table Designer preview visibility.
83
+
84
+ ### Database quick picks
85
+
86
+ 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.
48
87
 
49
88
  ### Simple backups
50
89
 
@@ -69,7 +108,7 @@ brew install sqlite-hub
69
108
  npm install -g sqlite-hub
70
109
  ```
71
110
 
72
- ## alternative port
111
+ ## Alternative port
73
112
 
74
113
  ```bash
75
114
  sqlite-hub --port:4174
@@ -132,7 +171,7 @@ sqlite-hub --database:Unit-00 --sqleditor
132
171
  Execute a specific saved query by name:
133
172
 
134
173
  ```bash
135
- sqlite-hub --database:Unit-00 --sqleditor:"15min Posting Buckets withoud id 96"
174
+ sqlite-hub --database:Unit-00 --sqleditor:"15min Posting Buckets without id 96"
136
175
  ```
137
176
 
138
177
  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).
@@ -152,7 +191,7 @@ This searches the query history for the given database, finds the matching saved
152
191
  | `--database:name --sqleditor` | List all saved queries for a database |
153
192
  | `--database:name --sqleditor:"query"` | Execute a saved query by name |
154
193
 
155
- ### sqleditor
194
+ ### SQL editor CLI example
156
195
 
157
196
  ![](/frontend/assets/mockups/sql_editor_croped.png)
158
197
 
@@ -162,7 +201,7 @@ In the screenshot above, you can see a saved query from the SQL editor. You can
162
201
  sqlite-hub --database:Unit-00 --sqleditor:"Group by creation Year"
163
202
  ```
164
203
 
165
- which returns
204
+ Example output:
166
205
 
167
206
  ```bash
168
207
  Executing: Group by creation Year
@@ -184,4 +223,4 @@ Results:
184
223
 
185
224
  ## Changelog
186
225
 
187
- [Changelog](/changelog.md)
226
+ [Changelog](./docs/changelog.md)
File without changes
@@ -46,7 +46,7 @@ async function download(path, options = {}) {
46
46
  const blob = await response.blob();
47
47
  const disposition = response.headers.get("content-disposition") ?? "";
48
48
  const match = disposition.match(/filename="([^"]+)"/i);
49
- const filename = match?.[1] ?? options.fallbackFilename ?? "export.csv";
49
+ const filename = String(options.filename ?? "").trim() || match?.[1] || options.fallbackFilename || "export.csv";
50
50
  const url = URL.createObjectURL(blob);
51
51
  const link = document.createElement("a");
52
52
 
@@ -419,22 +419,74 @@ export function patchSettings(settings) {
419
419
  });
420
420
  }
421
421
 
422
- export function downloadQueryCsv(sql) {
423
- return download("/api/export/query.csv", {
422
+ const TEXT_EXPORT_EXTENSIONS = {
423
+ csv: "csv",
424
+ tsv: "tsv",
425
+ md: "md",
426
+ };
427
+
428
+ function normalizeTextExportFormat(format) {
429
+ const normalized = String(format ?? "csv").toLowerCase();
430
+ return TEXT_EXPORT_EXTENSIONS[normalized] ? normalized : "csv";
431
+ }
432
+
433
+ export function getQueryExport(sql, format = "csv") {
434
+ return request("/api/export/query", {
435
+ method: "POST",
436
+ body: {
437
+ sql,
438
+ format: normalizeTextExportFormat(format),
439
+ },
440
+ });
441
+ }
442
+
443
+ export function downloadQueryExport(sql, format = "csv", options = {}) {
444
+ const normalizedFormat = normalizeTextExportFormat(format);
445
+ const extension = TEXT_EXPORT_EXTENSIONS[normalizedFormat];
446
+
447
+ return download(`/api/export/query.${extension}`, {
424
448
  method: "POST",
425
449
  body: { sql },
426
- fallbackFilename: "query-results.csv",
450
+ fallbackFilename: `query-results.${extension}`,
451
+ filename: options.filename,
427
452
  });
428
453
  }
429
454
 
430
- export function downloadTableCsv(tableName, options = {}) {
431
- return download("/api/export/table.csv", {
455
+ export function downloadQueryCsv(sql) {
456
+ return downloadQueryExport(sql, "csv");
457
+ }
458
+
459
+ function buildTableExportBody(tableName, options = {}) {
460
+ return {
461
+ tableName,
462
+ sortColumn: options.sortColumn,
463
+ sortDirection: options.sortDirection,
464
+ filterColumn: options.filterColumn,
465
+ filterOperator: options.filterOperator,
466
+ filterValue: options.filterValue,
467
+ format: normalizeTextExportFormat(options.format),
468
+ };
469
+ }
470
+
471
+ export function getTableExport(tableName, options = {}) {
472
+ return request("/api/export/table", {
432
473
  method: "POST",
433
- body: {
434
- tableName,
435
- sortColumn: options.sortColumn,
436
- sortDirection: options.sortDirection,
437
- },
438
- fallbackFilename: `${tableName || "table"}.csv`,
474
+ body: buildTableExportBody(tableName, options),
439
475
  });
440
476
  }
477
+
478
+ export function downloadTableExport(tableName, options = {}) {
479
+ const normalizedFormat = normalizeTextExportFormat(options.format);
480
+ const extension = TEXT_EXPORT_EXTENSIONS[normalizedFormat];
481
+
482
+ return download(`/api/export/table.${extension}`, {
483
+ method: "POST",
484
+ body: buildTableExportBody(tableName, { ...options, format: normalizedFormat }),
485
+ fallbackFilename: `${tableName || "table"}.${extension}`,
486
+ filename: options.filename,
487
+ });
488
+ }
489
+
490
+ export function downloadTableCsv(tableName, options = {}) {
491
+ return downloadTableExport(tableName, { ...options, format: "csv" });
492
+ }