dirsql 0.3.59__tar.gz → 0.3.61__tar.gz
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.
- {dirsql-0.3.59 → dirsql-0.3.61}/Cargo.lock +1 -1
- {dirsql-0.3.59 → dirsql-0.3.61}/PKG-INFO +1 -1
- dirsql-0.3.61/docs/.vitepress/config.ts +86 -0
- dirsql-0.3.61/docs/AGENTS.md +98 -0
- dirsql-0.3.61/docs/explanation.md +5 -0
- dirsql-0.3.61/docs/getting-started.md +257 -0
- dirsql-0.3.61/docs/howto/columns-from-paths.md +63 -0
- dirsql-0.3.61/docs/howto/define-tables.md +70 -0
- dirsql-0.3.61/docs/howto/embed.md +196 -0
- dirsql-0.3.61/docs/howto/extract-from-contents.md +90 -0
- dirsql-0.3.61/docs/howto/load-extension.md +91 -0
- dirsql-0.3.61/docs/howto/persist.md +52 -0
- dirsql-0.3.61/docs/howto/react-to-changes.md +67 -0
- dirsql-0.3.61/docs/howto/search-by-meaning.md +148 -0
- dirsql-0.3.61/docs/howto/skip-files.md +60 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/docs/index.md +0 -1
- dirsql-0.3.61/docs/migrations.md +5 -0
- dirsql-0.3.61/docs/reference/cli.md +132 -0
- dirsql-0.3.61/docs/reference/columns.md +68 -0
- dirsql-0.3.61/docs/reference/config.md +166 -0
- dirsql-0.3.61/docs/reference/hooks.md +141 -0
- dirsql-0.3.61/docs/reference/http-api.md +120 -0
- dirsql-0.3.61/docs/reference/sdk.md +357 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/docs/tests/integration/language-flag.spec.ts +4 -1
- dirsql-0.3.61/docs/tests/integration/sidebar.spec.ts +97 -0
- dirsql-0.3.61/docs/tests/unit/config.test.ts +102 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/Cargo.toml +1 -1
- dirsql-0.3.61/packages/python/docs/.vitepress/config.ts +86 -0
- dirsql-0.3.61/packages/python/docs/AGENTS.md +98 -0
- dirsql-0.3.61/packages/python/docs/explanation.md +5 -0
- dirsql-0.3.61/packages/python/docs/getting-started.md +257 -0
- dirsql-0.3.61/packages/python/docs/howto/columns-from-paths.md +63 -0
- dirsql-0.3.61/packages/python/docs/howto/define-tables.md +70 -0
- dirsql-0.3.61/packages/python/docs/howto/embed.md +196 -0
- dirsql-0.3.61/packages/python/docs/howto/extract-from-contents.md +90 -0
- dirsql-0.3.61/packages/python/docs/howto/load-extension.md +91 -0
- dirsql-0.3.61/packages/python/docs/howto/persist.md +52 -0
- dirsql-0.3.61/packages/python/docs/howto/react-to-changes.md +67 -0
- dirsql-0.3.61/packages/python/docs/howto/search-by-meaning.md +148 -0
- dirsql-0.3.61/packages/python/docs/howto/skip-files.md +60 -0
- {dirsql-0.3.59/packages/rust → dirsql-0.3.61/packages/python}/docs/index.md +0 -1
- dirsql-0.3.61/packages/python/docs/migrations.md +5 -0
- dirsql-0.3.61/packages/python/docs/reference/cli.md +132 -0
- dirsql-0.3.61/packages/python/docs/reference/columns.md +68 -0
- dirsql-0.3.61/packages/python/docs/reference/config.md +166 -0
- dirsql-0.3.61/packages/python/docs/reference/hooks.md +141 -0
- dirsql-0.3.61/packages/python/docs/reference/http-api.md +120 -0
- dirsql-0.3.61/packages/python/docs/reference/sdk.md +357 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/docs/tests/integration/language-flag.spec.ts +4 -1
- dirsql-0.3.61/packages/python/docs/tests/integration/sidebar.spec.ts +97 -0
- dirsql-0.3.61/packages/python/docs/tests/unit/config.test.ts +102 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/e2e-attestation.json +2 -2
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/Cargo.toml +1 -1
- dirsql-0.3.61/packages/rust/docs/explanation.md +5 -0
- dirsql-0.3.61/packages/rust/docs/getting-started.md +257 -0
- dirsql-0.3.61/packages/rust/docs/howto/columns-from-paths.md +63 -0
- dirsql-0.3.61/packages/rust/docs/howto/define-tables.md +70 -0
- dirsql-0.3.61/packages/rust/docs/howto/embed.md +196 -0
- dirsql-0.3.61/packages/rust/docs/howto/extract-from-contents.md +90 -0
- dirsql-0.3.61/packages/rust/docs/howto/load-extension.md +91 -0
- dirsql-0.3.61/packages/rust/docs/howto/persist.md +52 -0
- dirsql-0.3.61/packages/rust/docs/howto/react-to-changes.md +67 -0
- dirsql-0.3.61/packages/rust/docs/howto/search-by-meaning.md +148 -0
- dirsql-0.3.61/packages/rust/docs/howto/skip-files.md +60 -0
- {dirsql-0.3.59/packages/python → dirsql-0.3.61/packages/rust}/docs/index.md +0 -1
- dirsql-0.3.61/packages/rust/docs/migrations.md +5 -0
- dirsql-0.3.61/packages/rust/docs/reference/cli.md +132 -0
- dirsql-0.3.61/packages/rust/docs/reference/columns.md +68 -0
- dirsql-0.3.61/packages/rust/docs/reference/config.md +166 -0
- dirsql-0.3.61/packages/rust/docs/reference/hooks.md +141 -0
- dirsql-0.3.61/packages/rust/docs/reference/http-api.md +120 -0
- dirsql-0.3.61/packages/rust/docs/reference/sdk.md +357 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/db.rs +198 -371
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/persist.rs +8 -7
- dirsql-0.3.59/docs/.vitepress/config.ts +0 -80
- dirsql-0.3.59/docs/AGENTS.md +0 -63
- dirsql-0.3.59/docs/api/index.md +0 -238
- dirsql-0.3.59/docs/cli/config.md +0 -435
- dirsql-0.3.59/docs/cli/http-api.md +0 -115
- dirsql-0.3.59/docs/cli/index.md +0 -75
- dirsql-0.3.59/docs/cli/init.md +0 -84
- dirsql-0.3.59/docs/cli/server.md +0 -60
- dirsql-0.3.59/docs/getting-started.md +0 -190
- dirsql-0.3.59/docs/guide/async.md +0 -268
- dirsql-0.3.59/docs/guide/crdt.md +0 -161
- dirsql-0.3.59/docs/guide/persistence.md +0 -177
- dirsql-0.3.59/docs/guide/querying.md +0 -221
- dirsql-0.3.59/docs/guide/tables.md +0 -269
- dirsql-0.3.59/docs/guide/watching.md +0 -273
- dirsql-0.3.59/docs/migrations.md +0 -8
- dirsql-0.3.59/docs/tests/integration/sidebar.spec.ts +0 -46
- dirsql-0.3.59/docs/tests/unit/config.test.ts +0 -49
- dirsql-0.3.59/packages/python/docs/.vitepress/config.ts +0 -80
- dirsql-0.3.59/packages/python/docs/AGENTS.md +0 -63
- dirsql-0.3.59/packages/python/docs/api/index.md +0 -238
- dirsql-0.3.59/packages/python/docs/cli/config.md +0 -435
- dirsql-0.3.59/packages/python/docs/cli/http-api.md +0 -115
- dirsql-0.3.59/packages/python/docs/cli/index.md +0 -75
- dirsql-0.3.59/packages/python/docs/cli/init.md +0 -84
- dirsql-0.3.59/packages/python/docs/cli/server.md +0 -60
- dirsql-0.3.59/packages/python/docs/getting-started.md +0 -190
- dirsql-0.3.59/packages/python/docs/guide/async.md +0 -268
- dirsql-0.3.59/packages/python/docs/guide/crdt.md +0 -161
- dirsql-0.3.59/packages/python/docs/guide/persistence.md +0 -177
- dirsql-0.3.59/packages/python/docs/guide/querying.md +0 -221
- dirsql-0.3.59/packages/python/docs/guide/tables.md +0 -269
- dirsql-0.3.59/packages/python/docs/guide/watching.md +0 -273
- dirsql-0.3.59/packages/python/docs/migrations.md +0 -8
- dirsql-0.3.59/packages/python/docs/tests/integration/sidebar.spec.ts +0 -46
- dirsql-0.3.59/packages/python/docs/tests/unit/config.test.ts +0 -49
- dirsql-0.3.59/packages/rust/docs/api/index.md +0 -238
- dirsql-0.3.59/packages/rust/docs/cli/config.md +0 -435
- dirsql-0.3.59/packages/rust/docs/cli/http-api.md +0 -115
- dirsql-0.3.59/packages/rust/docs/cli/index.md +0 -75
- dirsql-0.3.59/packages/rust/docs/cli/init.md +0 -84
- dirsql-0.3.59/packages/rust/docs/cli/server.md +0 -60
- dirsql-0.3.59/packages/rust/docs/getting-started.md +0 -190
- dirsql-0.3.59/packages/rust/docs/guide/async.md +0 -268
- dirsql-0.3.59/packages/rust/docs/guide/crdt.md +0 -161
- dirsql-0.3.59/packages/rust/docs/guide/persistence.md +0 -177
- dirsql-0.3.59/packages/rust/docs/guide/querying.md +0 -221
- dirsql-0.3.59/packages/rust/docs/guide/tables.md +0 -269
- dirsql-0.3.59/packages/rust/docs/guide/watching.md +0 -273
- dirsql-0.3.59/packages/rust/docs/migrations.md +0 -8
- {dirsql-0.3.59 → dirsql-0.3.61}/Cargo.toml +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/README.md +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/dirsql/__init__.py +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/dirsql/_async.py +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/dirsql/_dirsql.pyi +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/dirsql/cli/__init__.py +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/dirsql/cli/binary_path.py +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/dirsql/cli/interpret/__init__.py +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/dirsql/cli/is_windows.py +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/dirsql/cli/main.py +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/dirsql/cli/resolve_config_extensions.py +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/dirsql/py.typed +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/dirsql/resolve_config_extensions.py +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/dirsql/resolve_extension.py +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/docs/package.json +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/docs/playwright.config.ts +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/docs/tests/integration/home.spec.ts +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/docs/tests/unit/lang.test.ts +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/docs/vitest.config.ts +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/README.md +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/conftest.py +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/docs/package.json +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/docs/playwright.config.ts +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/docs/tests/integration/home.spec.ts +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/docs/tests/unit/lang.test.ts +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/docs/vitest.config.ts +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/src/lib.rs +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/tests/__init__.py +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/tests/binding/__init__.py +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/tests/conftest.py +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/tests/e2e/__init__.py +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/tests/integration/__init__.py +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/tests/smoke/__init__.py +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/README.md +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/benches/db_bench.rs +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/benches/differ_bench.rs +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/benches/matcher_bench.rs +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/benches/scanner_bench.rs +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/bin/dirsql.rs +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/cli/init.rs +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/cli/mod.rs +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/cli/router.rs +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/cli/serialize.rs +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/cli/server.rs +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/command.rs +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/config.rs +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/differ.rs +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/lib.rs +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/matcher.rs +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/scanner.rs +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/watcher.rs +0 -0
- {dirsql-0.3.59 → dirsql-0.3.61}/pyproject.toml +0 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { defineConfig } from 'vitepress'
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
title: 'dirsql',
|
|
5
|
+
description: 'Ephemeral SQL index over a local directory. Watches a filesystem, ingests structured files into an in-memory SQLite database, and exposes a SQL query interface.',
|
|
6
|
+
base: '/dirsql/',
|
|
7
|
+
|
|
8
|
+
themeConfig: {
|
|
9
|
+
search: {
|
|
10
|
+
provider: 'local'
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
// The nav mirrors the four Diataxis groups exactly (#353/#387). Type is
|
|
14
|
+
// the only organizational axis -- no product-area tabs (the old `CLI`
|
|
15
|
+
// tab is gone).
|
|
16
|
+
nav: [
|
|
17
|
+
{ text: 'Tutorial', link: '/getting-started' },
|
|
18
|
+
{ text: 'How-to Guides', link: '/howto/define-tables' },
|
|
19
|
+
{ text: 'Reference', link: '/reference/cli' },
|
|
20
|
+
{ text: 'Explanation', link: '/explanation' },
|
|
21
|
+
{ text: 'GitHub', link: 'https://github.com/thekevinscott/dirsql' }
|
|
22
|
+
],
|
|
23
|
+
|
|
24
|
+
// A single global sidebar shown on every page, mirroring the four
|
|
25
|
+
// Diataxis groups. There is intentionally no path-scoped (e.g.
|
|
26
|
+
// `/howto/`) key: a path-scoped sidebar swaps the whole tree out, which
|
|
27
|
+
// deletes the other sections when you enter one (see #301). Keep one
|
|
28
|
+
// sidebar.
|
|
29
|
+
sidebar: {
|
|
30
|
+
'/': [
|
|
31
|
+
{
|
|
32
|
+
text: 'Tutorial',
|
|
33
|
+
items: [
|
|
34
|
+
{ text: 'Your first dirsql database', link: '/getting-started' }
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
text: 'How-to Guides',
|
|
39
|
+
items: [
|
|
40
|
+
{ text: 'Define tables for your files', link: '/howto/define-tables' },
|
|
41
|
+
{ text: 'Derive columns from file paths', link: '/howto/columns-from-paths' },
|
|
42
|
+
{ text: 'Extract rows from file contents', link: '/howto/extract-from-contents' },
|
|
43
|
+
{ text: 'Search documents by meaning', link: '/howto/search-by-meaning' },
|
|
44
|
+
{ text: "Skip files you don't want indexed", link: '/howto/skip-files' },
|
|
45
|
+
{ text: 'Load a SQLite extension', link: '/howto/load-extension' },
|
|
46
|
+
{ text: 'Keep the index across restarts', link: '/howto/persist' },
|
|
47
|
+
{ text: 'React to file changes', link: '/howto/react-to-changes' },
|
|
48
|
+
{ text: 'Embed dirsql in your application', link: '/howto/embed' }
|
|
49
|
+
]
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
text: 'Reference',
|
|
53
|
+
items: [
|
|
54
|
+
{ text: 'CLI', link: '/reference/cli' },
|
|
55
|
+
{ text: 'Configuration File', link: '/reference/config' },
|
|
56
|
+
{ text: 'Command Hooks', link: '/reference/hooks' },
|
|
57
|
+
{ text: 'Virtual Columns & Glob Captures', link: '/reference/columns' },
|
|
58
|
+
{ text: 'HTTP API', link: '/reference/http-api' },
|
|
59
|
+
{ text: 'SDK', link: '/reference/sdk' },
|
|
60
|
+
{ text: 'Migrations', link: '/migrations' }
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
text: 'Explanation',
|
|
65
|
+
items: [
|
|
66
|
+
{ text: 'How dirsql thinks', link: '/explanation' }
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
]
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
outline: {
|
|
73
|
+
level: [2, 3],
|
|
74
|
+
label: 'On this page'
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
socialLinks: [
|
|
78
|
+
{ icon: 'github', link: 'https://github.com/thekevinscott/dirsql' }
|
|
79
|
+
],
|
|
80
|
+
|
|
81
|
+
footer: {
|
|
82
|
+
message: 'Released under the MIT License.',
|
|
83
|
+
copyright: 'Copyright 2024-present'
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
})
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Documentation Development
|
|
2
|
+
|
|
3
|
+
Instructions for agents working on `dirsql` documentation.
|
|
4
|
+
|
|
5
|
+
## Stack
|
|
6
|
+
|
|
7
|
+
The docs site uses [VitePress](https://vitepress.dev/). Source files are in `docs/` at the project root.
|
|
8
|
+
|
|
9
|
+
## Running locally
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
cd docs
|
|
13
|
+
pnpm install
|
|
14
|
+
pnpm dev
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
This starts a local dev server (default: `http://localhost:5173/dirsql/`). The site hot-reloads on file changes.
|
|
18
|
+
|
|
19
|
+
## Building
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
cd docs
|
|
23
|
+
pnpm build
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The build must succeed before pushing. VitePress will fail on broken links, missing assets, and syntax errors in markdown.
|
|
27
|
+
|
|
28
|
+
## Testing changes
|
|
29
|
+
|
|
30
|
+
Before pushing any docs changes:
|
|
31
|
+
|
|
32
|
+
1. Run `pnpm build` in `docs/` and confirm it exits cleanly
|
|
33
|
+
2. Spot-check the built output with `pnpm preview`
|
|
34
|
+
3. Verify sidebar navigation, code blocks, and internal links render correctly
|
|
35
|
+
|
|
36
|
+
## Structure
|
|
37
|
+
|
|
38
|
+
The docs follow the [Diataxis](https://diataxis.fr/) framework. **Type is
|
|
39
|
+
the only organizational axis** -- there are no product-area sections (no
|
|
40
|
+
"CLI" section; #353). The nav and the sidebar mirror the four types exactly.
|
|
41
|
+
|
|
42
|
+
The **primary reader is the CLI user**: someone with a directory of files,
|
|
43
|
+
one command (`uvx` / `npx dirsql`), and a `.dirsql.toml`. The SDKs are the
|
|
44
|
+
secondary audience and appear **only in Reference**, plus the single
|
|
45
|
+
"Embed `dirsql` in your application" how-to.
|
|
46
|
+
|
|
47
|
+
Target tree (the spec for #353; existing pages are *quarried* into it, not
|
|
48
|
+
migrated -- a page survives only if a slot wants its content):
|
|
49
|
+
|
|
50
|
+
- **Tutorial** (`getting-started.md`) -- one lesson: *Your first dirsql
|
|
51
|
+
database*. The reader performs every step and sees output at each one;
|
|
52
|
+
success is author-guaranteed (toy dataset, no branching).
|
|
53
|
+
- **How-to Guides** (`howto/`) -- goal-named recipes: define tables for your files;
|
|
54
|
+
derive columns from file paths; extract rows from file contents
|
|
55
|
+
(`on-file`); search documents by meaning; skip files; load a SQLite
|
|
56
|
+
extension; keep the index across restarts; react to file changes; embed
|
|
57
|
+
`dirsql` in an application.
|
|
58
|
+
- **Reference** (`reference/`) -- CLI flags and defaults; the complete
|
|
59
|
+
`.dirsql.toml` schema; the command hook contract (placeholders, stdout
|
|
60
|
+
protocol, exit codes, timeouts); virtual columns and glob captures; the
|
|
61
|
+
HTTP API; the SDK page (`reference/sdk.md`, one page with
|
|
62
|
+
Python/TypeScript/Rust code-groups -- the sole SDK home); plus the
|
|
63
|
+
Migrations include (`migrations.md`).
|
|
64
|
+
- **Explanation** (`explanation.md`) -- one page: how `dirsql` thinks (the
|
|
65
|
+
filesystem is the source of truth; the database is a derived, ephemeral,
|
|
66
|
+
read-only view; reconcile and diffing). Its canonical home is the root
|
|
67
|
+
`ARCHITECTURE.md`;
|
|
68
|
+
#374 surfaces it via an include page, the same mechanism
|
|
69
|
+
`docs/migrations.md` uses for `MIGRATIONS.md`. Edit the root file, never
|
|
70
|
+
a rendered include.
|
|
71
|
+
|
|
72
|
+
Working rules:
|
|
73
|
+
|
|
74
|
+
- **Facts live once, in Reference.** Tutorials and how-tos link to reference
|
|
75
|
+
material; they never re-list constructor parameters or duplicate API tables.
|
|
76
|
+
- **A how-to opens with a 1-2 line goal/motivation statement.** Deep
|
|
77
|
+
rationale (tradeoffs, alternatives considered, theory) moves to Explanation
|
|
78
|
+
only when it is substantial enough to stand alone and is reused across
|
|
79
|
+
pages. Do not manufacture stub pages for a paragraph of "why".
|
|
80
|
+
- **Tutorial vs how-to:** a tutorial is a lesson along a path the author
|
|
81
|
+
guarantees; a how-to serves a competent reader pursuing their own goal.
|
|
82
|
+
- **One global sidebar.** Never add a path-scoped sidebar key -- it swaps
|
|
83
|
+
out the whole tree and hides every other section while inside one (#301;
|
|
84
|
+
see the comment above `sidebar` in `config.ts`).
|
|
85
|
+
|
|
86
|
+
## Conventions
|
|
87
|
+
|
|
88
|
+
- **Lead with the use case.** Open each feature description with *why* a
|
|
89
|
+
reader would reach for it before *how* it works. Don't frame a feature
|
|
90
|
+
by what an adjacent feature can't do.
|
|
91
|
+
*Don't:* "Persistence avoids the thing the default mode can't do..."
|
|
92
|
+
*Do:* "Persistence keeps the SQLite index on disk between runs so large
|
|
93
|
+
directories don't re-scan on every startup."
|
|
94
|
+
- Wrap `dirsql` in backticks in all prose text
|
|
95
|
+
- Use VitePress [code group](https://vitepress.dev/guide/markdown#code-groups) syntax (`::: code-group`) for multi-language examples with `Python`, `Rust`, and `TypeScript` tabs
|
|
96
|
+
- Internal links use relative paths (e.g., `./howto/define-tables.md`)
|
|
97
|
+
- The VitePress config is at `docs/.vitepress/config.ts`
|
|
98
|
+
- The site is deployed under the `/dirsql/` base path
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# Your first dirsql database
|
|
2
|
+
|
|
3
|
+
In this tutorial you will turn a directory of three tiny markdown files into
|
|
4
|
+
a SQL database you can query over HTTP — without writing any code. You will:
|
|
5
|
+
|
|
6
|
+
1. Create the directory and files.
|
|
7
|
+
2. Start `dirsql` with zero configuration and query it with `curl`.
|
|
8
|
+
3. Define your own table in a `.dirsql.toml` and query the new shape.
|
|
9
|
+
|
|
10
|
+
It takes about five minutes.
|
|
11
|
+
|
|
12
|
+
**You need:** a terminal with `curl` and [`jq`](https://jqlang.org/), and
|
|
13
|
+
Node ≥ 20.11 (for `npx`). Every `npx dirsql` step below also has a `uvx`
|
|
14
|
+
tab that behaves identically, if you prefer Python tooling
|
|
15
|
+
([`uv`](https://docs.astral.sh/uv/)).
|
|
16
|
+
|
|
17
|
+
## 1. Create three files
|
|
18
|
+
|
|
19
|
+
Make a working directory with two subfolders — one per note author:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
mkdir -p my-notes/notes/alice my-notes/notes/bob
|
|
23
|
+
cd my-notes
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Create the three notes by pasting each block exactly as shown:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
cat > notes/alice/welcome.md <<'EOF'
|
|
30
|
+
# Welcome
|
|
31
|
+
|
|
32
|
+
Start here. This folder is about to become a database.
|
|
33
|
+
EOF
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
cat > notes/alice/ideas.md <<'EOF'
|
|
38
|
+
# Ideas
|
|
39
|
+
|
|
40
|
+
- query files with SQL
|
|
41
|
+
- watch for changes
|
|
42
|
+
EOF
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
cat > notes/bob/reading-list.md <<'EOF'
|
|
47
|
+
# Reading list
|
|
48
|
+
|
|
49
|
+
- The SQLite file format
|
|
50
|
+
EOF
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Check that all three files are in place:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
find notes -type f | sort
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
notes/alice/ideas.md
|
|
61
|
+
notes/alice/welcome.md
|
|
62
|
+
notes/bob/reading-list.md
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 2. Start the server
|
|
66
|
+
|
|
67
|
+
From inside `my-notes`, start `dirsql`:
|
|
68
|
+
|
|
69
|
+
::: code-group
|
|
70
|
+
|
|
71
|
+
```bash [npm]
|
|
72
|
+
npx dirsql
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
```bash [PyPI]
|
|
76
|
+
uvx dirsql
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
:::
|
|
80
|
+
|
|
81
|
+
The first run downloads the package (`npx` asks for confirmation — answer
|
|
82
|
+
`y`; `uvx` prints download progress), then the server starts:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
Running at localhost:7117
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
That one command scanned the directory, built an in-memory SQLite database
|
|
89
|
+
with one row per file, and started an HTTP server. Leave it running and
|
|
90
|
+
open a **second terminal** for the next step.
|
|
91
|
+
|
|
92
|
+
## 3. Query your files
|
|
93
|
+
|
|
94
|
+
You gave `dirsql` no configuration, so it serves a single default table
|
|
95
|
+
named `files` ([zero-config mode](./reference/cli.md#zero-config-mode)).
|
|
96
|
+
Ask it how many rows it has:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
curl -s http://localhost:7117/query \
|
|
100
|
+
-H 'content-type: application/json' \
|
|
101
|
+
-d '{"sql":"SELECT COUNT(*) AS files FROM files"}'
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
[{"files":3}]
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Three files, three rows. The response is always a JSON array of row
|
|
109
|
+
objects ([HTTP API](./reference/http-api.md)) — from here on we pipe it
|
|
110
|
+
through `jq` to pretty-print. Now select some columns:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
curl -s http://localhost:7117/query \
|
|
114
|
+
-H 'content-type: application/json' \
|
|
115
|
+
-d '{"sql":"SELECT _path, _size FROM files ORDER BY _path"}' \
|
|
116
|
+
| jq
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
```json
|
|
120
|
+
[
|
|
121
|
+
{
|
|
122
|
+
"_path": "notes/alice/ideas.md",
|
|
123
|
+
"_size": 52
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"_path": "notes/alice/welcome.md",
|
|
127
|
+
"_size": 66
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"_path": "notes/bob/reading-list.md",
|
|
131
|
+
"_size": 41
|
|
132
|
+
}
|
|
133
|
+
]
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
`_path` and `_size` are two of the built-in file columns `dirsql` collects
|
|
137
|
+
for every file — see [virtual columns](./reference/columns.md#virtual-columns)
|
|
138
|
+
for the full list. (The `_size` values are byte counts; they match the
|
|
139
|
+
output above because you pasted the files exactly.)
|
|
140
|
+
|
|
141
|
+
You have a working SQL database over your files. Next, teach it the
|
|
142
|
+
structure your folders already encode.
|
|
143
|
+
|
|
144
|
+
## 4. Define a table
|
|
145
|
+
|
|
146
|
+
Look at the paths again: `notes/alice/ideas.md`, `notes/bob/reading-list.md`
|
|
147
|
+
— the author's name is a directory segment. A config file can capture it as
|
|
148
|
+
a real column.
|
|
149
|
+
|
|
150
|
+
In your second terminal, still inside `my-notes`, create a `.dirsql.toml`:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
cat > .dirsql.toml <<'EOF'
|
|
154
|
+
[[table]]
|
|
155
|
+
ddl = "CREATE TABLE notes (author TEXT, _basename TEXT, _size INTEGER)"
|
|
156
|
+
glob = "notes/{author}/*.md"
|
|
157
|
+
EOF
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Two keys define the table:
|
|
161
|
+
|
|
162
|
+
- `glob` selects which files feed the table, and `{author}` is a
|
|
163
|
+
[glob capture](./reference/columns.md#glob-captures): whatever directory
|
|
164
|
+
name matches that segment becomes the row's `author` value.
|
|
165
|
+
- `ddl` is ordinary `CREATE TABLE` SQL naming the columns you want to keep.
|
|
166
|
+
|
|
167
|
+
## 5. Restart and query the new shape
|
|
168
|
+
|
|
169
|
+
Config is read at startup, so go back to the **first terminal**, stop the
|
|
170
|
+
server with `Ctrl-C`, and start it again:
|
|
171
|
+
|
|
172
|
+
::: code-group
|
|
173
|
+
|
|
174
|
+
```bash [npm]
|
|
175
|
+
npx dirsql
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
```bash [PyPI]
|
|
179
|
+
uvx dirsql
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
:::
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
Running at localhost:7117
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
This time `dirsql` found your `.dirsql.toml` and served the `notes` table
|
|
189
|
+
you defined instead of the default `files` table. Query it from the second
|
|
190
|
+
terminal:
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
curl -s http://localhost:7117/query \
|
|
194
|
+
-H 'content-type: application/json' \
|
|
195
|
+
-d '{"sql":"SELECT author, _basename, _size FROM notes ORDER BY author, _basename"}' \
|
|
196
|
+
| jq
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
```json
|
|
200
|
+
[
|
|
201
|
+
{
|
|
202
|
+
"_basename": "ideas.md",
|
|
203
|
+
"_size": 52,
|
|
204
|
+
"author": "alice"
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"_basename": "welcome.md",
|
|
208
|
+
"_size": 66,
|
|
209
|
+
"author": "alice"
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"_basename": "reading-list.md",
|
|
213
|
+
"_size": 41,
|
|
214
|
+
"author": "bob"
|
|
215
|
+
}
|
|
216
|
+
]
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Every row now carries an `author` column extracted from its path — no
|
|
220
|
+
extraction code, just a glob. And it is a real SQL column, so you can
|
|
221
|
+
aggregate on it:
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
curl -s http://localhost:7117/query \
|
|
225
|
+
-H 'content-type: application/json' \
|
|
226
|
+
-d '{"sql":"SELECT author, COUNT(*) AS notes FROM notes GROUP BY author"}' \
|
|
227
|
+
| jq
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
```json
|
|
231
|
+
[
|
|
232
|
+
{
|
|
233
|
+
"author": "alice",
|
|
234
|
+
"notes": 2
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
"author": "bob",
|
|
238
|
+
"notes": 1
|
|
239
|
+
}
|
|
240
|
+
]
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
That's the whole loop: files in a directory, a declarative table on top,
|
|
244
|
+
SQL over HTTP.
|
|
245
|
+
|
|
246
|
+
## Where to go next
|
|
247
|
+
|
|
248
|
+
- [Configuration file](./reference/config.md) — the complete `.dirsql.toml`
|
|
249
|
+
reference: more tables, ignore patterns, persistence, hooks.
|
|
250
|
+
- [CLI](./reference/cli.md) — flags like `--port` and `--config`, plus
|
|
251
|
+
`dirsql init`.
|
|
252
|
+
- [HTTP API](./reference/http-api.md) — `POST /query` in full, plus
|
|
253
|
+
`GET /events`, a live stream of row changes as files change.
|
|
254
|
+
- [SDK](./reference/sdk.md) — embed `dirsql` in a Python, Rust, or
|
|
255
|
+
TypeScript program instead of running the server.
|
|
256
|
+
- Why is the database rebuilt from your files on every startup? See
|
|
257
|
+
[how `dirsql` thinks](./explanation.md).
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Derive columns from file paths
|
|
2
|
+
|
|
3
|
+
Directory layouts often encode real data — an author, a year, a thread ID —
|
|
4
|
+
as path segments. A `{name}` capture in a table's glob turns such a segment
|
|
5
|
+
into a queryable column, no extraction code required.
|
|
6
|
+
|
|
7
|
+
## 1. Name the segment in the glob
|
|
8
|
+
|
|
9
|
+
Suppose photos are filed by year and month:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
photos/2024/05/beach.jpg
|
|
13
|
+
photos/2024/11/hike.jpg
|
|
14
|
+
photos/2025/01/snow.jpg
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Capture both directory levels in `.dirsql.toml`:
|
|
18
|
+
|
|
19
|
+
```toml
|
|
20
|
+
[[table]]
|
|
21
|
+
ddl = "CREATE TABLE photos (year TEXT, month TEXT, _basename TEXT)"
|
|
22
|
+
glob = "photos/{year}/{month}/*.jpg"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
A capture only populates a column when the DDL declares one with the same
|
|
26
|
+
name — here `year` and `month`. The capture rules (valid names, matching
|
|
27
|
+
within one path segment) are in
|
|
28
|
+
[glob captures](../reference/columns.md#glob-captures).
|
|
29
|
+
|
|
30
|
+
## 2. Query the captured columns
|
|
31
|
+
|
|
32
|
+
Start the server (`npx dirsql` / `uvx dirsql`) and query:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
curl -s http://localhost:7117/query \
|
|
36
|
+
-H 'content-type: application/json' \
|
|
37
|
+
-d '{"sql":"SELECT year, month, _basename FROM photos ORDER BY year, month"}'
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
[{"_basename":"beach.jpg","month":"05","year":"2024"},{"_basename":"hike.jpg","month":"11","year":"2024"},{"_basename":"snow.jpg","month":"01","year":"2025"}]
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Captures are real SQL columns, so aggregation works:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
curl -s http://localhost:7117/query \
|
|
48
|
+
-H 'content-type: application/json' \
|
|
49
|
+
-d '{"sql":"SELECT year, COUNT(*) AS photos FROM photos GROUP BY year"}'
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
[{"photos":2,"year":"2024"},{"photos":1,"year":"2025"}]
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Going further
|
|
57
|
+
|
|
58
|
+
- Captures combine freely with [virtual columns](../reference/columns.md#virtual-columns)
|
|
59
|
+
(`_basename` above) — both are filesystem facts merged onto every row.
|
|
60
|
+
- The [tutorial](../getting-started.md) walks the same idea with an
|
|
61
|
+
`{author}` capture, starting from zero.
|
|
62
|
+
- When the value you need lives inside the file rather than in its path,
|
|
63
|
+
see [Extract rows from file contents](./extract-from-contents.md).
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Define tables for your files
|
|
2
|
+
|
|
3
|
+
Map a glob of files to a named SQL table so you query exactly the files you
|
|
4
|
+
care about, with exactly the columns you care about — instead of the
|
|
5
|
+
catch-all `files` table that [zero-config mode](../reference/cli.md#zero-config-mode)
|
|
6
|
+
serves.
|
|
7
|
+
|
|
8
|
+
## 1. Create a config next to your files
|
|
9
|
+
|
|
10
|
+
Suppose your blog posts live under `posts/`, one markdown file each. In the
|
|
11
|
+
directory you want to index, create a `.dirsql.toml` with one
|
|
12
|
+
[`[[table]]`](../reference/config.md#table) entry:
|
|
13
|
+
|
|
14
|
+
```toml
|
|
15
|
+
[[table]]
|
|
16
|
+
ddl = "CREATE TABLE posts (_path TEXT, _size INTEGER, _mtime INTEGER)"
|
|
17
|
+
glob = "posts/**/*.md"
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
- `glob` selects the files: every `.md` under `posts/`, at any depth,
|
|
21
|
+
relative to the directory containing the config.
|
|
22
|
+
- `ddl` is a plain SQLite `CREATE TABLE` naming the columns you want. Here
|
|
23
|
+
all three are [virtual columns](../reference/columns.md#virtual-columns) —
|
|
24
|
+
filesystem facts `dirsql` computes for every file. Facts are opt-in by
|
|
25
|
+
DDL: only the ones you declare become columns.
|
|
26
|
+
|
|
27
|
+
## 2. Start the server and query
|
|
28
|
+
|
|
29
|
+
::: code-group
|
|
30
|
+
|
|
31
|
+
```bash [npm]
|
|
32
|
+
npx dirsql
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
```bash [PyPI]
|
|
36
|
+
uvx dirsql
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
:::
|
|
40
|
+
|
|
41
|
+
Each matched file is one row:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
curl -s http://localhost:7117/query \
|
|
45
|
+
-H 'content-type: application/json' \
|
|
46
|
+
-d '{"sql":"SELECT _path, _size FROM posts ORDER BY _path"}'
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
[{"_path":"posts/2024/hello.md","_size":21},{"_path":"posts/2025/again.md","_size":55}]
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Files that don't match the glob (a `README.txt` next to `posts/`, say) are
|
|
54
|
+
simply not in the table. Once a config file exists, it fully replaces the
|
|
55
|
+
zero-config default — only the tables you define are served.
|
|
56
|
+
|
|
57
|
+
## Multiple tables
|
|
58
|
+
|
|
59
|
+
Add one `[[table]]` entry per table. When a file matches several globs, the
|
|
60
|
+
first matching table wins — see [`[[table]]`](../reference/config.md#table)
|
|
61
|
+
for that and the remaining keys (`strict`, `on-file`).
|
|
62
|
+
|
|
63
|
+
## Going further
|
|
64
|
+
|
|
65
|
+
- Your directory layout encodes data (authors, dates, IDs)? Capture path
|
|
66
|
+
segments as columns — [Derive columns from file paths](./columns-from-paths.md).
|
|
67
|
+
- Need columns from *inside* the files? A plain table never reads file
|
|
68
|
+
contents — [Extract rows from file contents](./extract-from-contents.md).
|
|
69
|
+
- Why one row per file, rebuilt from disk? See
|
|
70
|
+
[how `dirsql` thinks](../explanation.md).
|