dirsql 0.3.60__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.
Files changed (184) hide show
  1. {dirsql-0.3.60 → dirsql-0.3.61}/Cargo.lock +1 -1
  2. {dirsql-0.3.60 → dirsql-0.3.61}/PKG-INFO +1 -1
  3. dirsql-0.3.61/docs/.vitepress/config.ts +86 -0
  4. {dirsql-0.3.60 → dirsql-0.3.61}/docs/AGENTS.md +15 -12
  5. dirsql-0.3.61/docs/explanation.md +5 -0
  6. dirsql-0.3.61/docs/getting-started.md +257 -0
  7. dirsql-0.3.61/docs/howto/columns-from-paths.md +63 -0
  8. dirsql-0.3.61/docs/howto/define-tables.md +70 -0
  9. dirsql-0.3.61/docs/howto/embed.md +196 -0
  10. dirsql-0.3.61/docs/howto/extract-from-contents.md +90 -0
  11. dirsql-0.3.61/docs/howto/load-extension.md +91 -0
  12. dirsql-0.3.61/docs/howto/persist.md +52 -0
  13. dirsql-0.3.61/docs/howto/react-to-changes.md +67 -0
  14. dirsql-0.3.61/docs/howto/search-by-meaning.md +148 -0
  15. dirsql-0.3.61/docs/howto/skip-files.md +60 -0
  16. {dirsql-0.3.60/packages/python → dirsql-0.3.61}/docs/index.md +0 -1
  17. dirsql-0.3.61/docs/migrations.md +5 -0
  18. dirsql-0.3.61/docs/reference/cli.md +132 -0
  19. dirsql-0.3.61/docs/reference/columns.md +68 -0
  20. dirsql-0.3.61/docs/reference/config.md +166 -0
  21. dirsql-0.3.61/docs/reference/hooks.md +141 -0
  22. dirsql-0.3.61/docs/reference/http-api.md +120 -0
  23. dirsql-0.3.61/docs/reference/sdk.md +357 -0
  24. {dirsql-0.3.60 → dirsql-0.3.61}/docs/tests/integration/language-flag.spec.ts +4 -1
  25. dirsql-0.3.61/docs/tests/integration/sidebar.spec.ts +97 -0
  26. dirsql-0.3.61/docs/tests/unit/config.test.ts +102 -0
  27. {dirsql-0.3.60 → dirsql-0.3.61}/packages/python/Cargo.toml +1 -1
  28. dirsql-0.3.61/packages/python/docs/.vitepress/config.ts +86 -0
  29. {dirsql-0.3.60 → dirsql-0.3.61}/packages/python/docs/AGENTS.md +15 -12
  30. dirsql-0.3.61/packages/python/docs/explanation.md +5 -0
  31. dirsql-0.3.61/packages/python/docs/getting-started.md +257 -0
  32. dirsql-0.3.61/packages/python/docs/howto/columns-from-paths.md +63 -0
  33. dirsql-0.3.61/packages/python/docs/howto/define-tables.md +70 -0
  34. dirsql-0.3.61/packages/python/docs/howto/embed.md +196 -0
  35. dirsql-0.3.61/packages/python/docs/howto/extract-from-contents.md +90 -0
  36. dirsql-0.3.61/packages/python/docs/howto/load-extension.md +91 -0
  37. dirsql-0.3.61/packages/python/docs/howto/persist.md +52 -0
  38. dirsql-0.3.61/packages/python/docs/howto/react-to-changes.md +67 -0
  39. dirsql-0.3.61/packages/python/docs/howto/search-by-meaning.md +148 -0
  40. dirsql-0.3.61/packages/python/docs/howto/skip-files.md +60 -0
  41. {dirsql-0.3.60 → dirsql-0.3.61/packages/python}/docs/index.md +0 -1
  42. dirsql-0.3.61/packages/python/docs/migrations.md +5 -0
  43. dirsql-0.3.61/packages/python/docs/reference/cli.md +132 -0
  44. dirsql-0.3.61/packages/python/docs/reference/columns.md +68 -0
  45. dirsql-0.3.61/packages/python/docs/reference/config.md +166 -0
  46. dirsql-0.3.61/packages/python/docs/reference/hooks.md +141 -0
  47. dirsql-0.3.61/packages/python/docs/reference/http-api.md +120 -0
  48. dirsql-0.3.61/packages/python/docs/reference/sdk.md +357 -0
  49. {dirsql-0.3.60 → dirsql-0.3.61}/packages/python/docs/tests/integration/language-flag.spec.ts +4 -1
  50. dirsql-0.3.61/packages/python/docs/tests/integration/sidebar.spec.ts +97 -0
  51. dirsql-0.3.61/packages/python/docs/tests/unit/config.test.ts +102 -0
  52. {dirsql-0.3.60 → dirsql-0.3.61}/packages/python/e2e-attestation.json +2 -2
  53. {dirsql-0.3.60 → dirsql-0.3.61}/packages/rust/Cargo.toml +1 -1
  54. dirsql-0.3.61/packages/rust/docs/explanation.md +5 -0
  55. dirsql-0.3.61/packages/rust/docs/getting-started.md +257 -0
  56. dirsql-0.3.61/packages/rust/docs/howto/columns-from-paths.md +63 -0
  57. dirsql-0.3.61/packages/rust/docs/howto/define-tables.md +70 -0
  58. dirsql-0.3.61/packages/rust/docs/howto/embed.md +196 -0
  59. dirsql-0.3.61/packages/rust/docs/howto/extract-from-contents.md +90 -0
  60. dirsql-0.3.61/packages/rust/docs/howto/load-extension.md +91 -0
  61. dirsql-0.3.61/packages/rust/docs/howto/persist.md +52 -0
  62. dirsql-0.3.61/packages/rust/docs/howto/react-to-changes.md +67 -0
  63. dirsql-0.3.61/packages/rust/docs/howto/search-by-meaning.md +148 -0
  64. dirsql-0.3.61/packages/rust/docs/howto/skip-files.md +60 -0
  65. {dirsql-0.3.60 → dirsql-0.3.61}/packages/rust/docs/index.md +0 -1
  66. dirsql-0.3.61/packages/rust/docs/migrations.md +5 -0
  67. dirsql-0.3.61/packages/rust/docs/reference/cli.md +132 -0
  68. dirsql-0.3.61/packages/rust/docs/reference/columns.md +68 -0
  69. dirsql-0.3.61/packages/rust/docs/reference/config.md +166 -0
  70. dirsql-0.3.61/packages/rust/docs/reference/hooks.md +141 -0
  71. dirsql-0.3.61/packages/rust/docs/reference/http-api.md +120 -0
  72. dirsql-0.3.61/packages/rust/docs/reference/sdk.md +357 -0
  73. {dirsql-0.3.60 → dirsql-0.3.61}/packages/rust/src/db.rs +147 -1
  74. dirsql-0.3.60/docs/.vitepress/config.ts +0 -80
  75. dirsql-0.3.60/docs/api/index.md +0 -238
  76. dirsql-0.3.60/docs/cli/config.md +0 -435
  77. dirsql-0.3.60/docs/cli/http-api.md +0 -115
  78. dirsql-0.3.60/docs/cli/index.md +0 -75
  79. dirsql-0.3.60/docs/cli/init.md +0 -84
  80. dirsql-0.3.60/docs/cli/server.md +0 -60
  81. dirsql-0.3.60/docs/getting-started.md +0 -190
  82. dirsql-0.3.60/docs/guide/async.md +0 -268
  83. dirsql-0.3.60/docs/guide/crdt.md +0 -161
  84. dirsql-0.3.60/docs/guide/persistence.md +0 -177
  85. dirsql-0.3.60/docs/guide/querying.md +0 -221
  86. dirsql-0.3.60/docs/guide/tables.md +0 -269
  87. dirsql-0.3.60/docs/guide/watching.md +0 -273
  88. dirsql-0.3.60/docs/migrations.md +0 -8
  89. dirsql-0.3.60/docs/tests/integration/sidebar.spec.ts +0 -46
  90. dirsql-0.3.60/docs/tests/unit/config.test.ts +0 -49
  91. dirsql-0.3.60/packages/python/docs/.vitepress/config.ts +0 -80
  92. dirsql-0.3.60/packages/python/docs/api/index.md +0 -238
  93. dirsql-0.3.60/packages/python/docs/cli/config.md +0 -435
  94. dirsql-0.3.60/packages/python/docs/cli/http-api.md +0 -115
  95. dirsql-0.3.60/packages/python/docs/cli/index.md +0 -75
  96. dirsql-0.3.60/packages/python/docs/cli/init.md +0 -84
  97. dirsql-0.3.60/packages/python/docs/cli/server.md +0 -60
  98. dirsql-0.3.60/packages/python/docs/getting-started.md +0 -190
  99. dirsql-0.3.60/packages/python/docs/guide/async.md +0 -268
  100. dirsql-0.3.60/packages/python/docs/guide/crdt.md +0 -161
  101. dirsql-0.3.60/packages/python/docs/guide/persistence.md +0 -177
  102. dirsql-0.3.60/packages/python/docs/guide/querying.md +0 -221
  103. dirsql-0.3.60/packages/python/docs/guide/tables.md +0 -269
  104. dirsql-0.3.60/packages/python/docs/guide/watching.md +0 -273
  105. dirsql-0.3.60/packages/python/docs/migrations.md +0 -8
  106. dirsql-0.3.60/packages/python/docs/tests/integration/sidebar.spec.ts +0 -46
  107. dirsql-0.3.60/packages/python/docs/tests/unit/config.test.ts +0 -49
  108. dirsql-0.3.60/packages/rust/docs/api/index.md +0 -238
  109. dirsql-0.3.60/packages/rust/docs/cli/config.md +0 -435
  110. dirsql-0.3.60/packages/rust/docs/cli/http-api.md +0 -115
  111. dirsql-0.3.60/packages/rust/docs/cli/index.md +0 -75
  112. dirsql-0.3.60/packages/rust/docs/cli/init.md +0 -84
  113. dirsql-0.3.60/packages/rust/docs/cli/server.md +0 -60
  114. dirsql-0.3.60/packages/rust/docs/getting-started.md +0 -190
  115. dirsql-0.3.60/packages/rust/docs/guide/async.md +0 -268
  116. dirsql-0.3.60/packages/rust/docs/guide/crdt.md +0 -161
  117. dirsql-0.3.60/packages/rust/docs/guide/persistence.md +0 -177
  118. dirsql-0.3.60/packages/rust/docs/guide/querying.md +0 -221
  119. dirsql-0.3.60/packages/rust/docs/guide/tables.md +0 -269
  120. dirsql-0.3.60/packages/rust/docs/guide/watching.md +0 -273
  121. dirsql-0.3.60/packages/rust/docs/migrations.md +0 -8
  122. {dirsql-0.3.60 → dirsql-0.3.61}/Cargo.toml +0 -0
  123. {dirsql-0.3.60 → dirsql-0.3.61}/README.md +0 -0
  124. {dirsql-0.3.60 → dirsql-0.3.61}/dirsql/__init__.py +0 -0
  125. {dirsql-0.3.60 → dirsql-0.3.61}/dirsql/_async.py +0 -0
  126. {dirsql-0.3.60 → dirsql-0.3.61}/dirsql/_dirsql.pyi +0 -0
  127. {dirsql-0.3.60 → dirsql-0.3.61}/dirsql/cli/__init__.py +0 -0
  128. {dirsql-0.3.60 → dirsql-0.3.61}/dirsql/cli/binary_path.py +0 -0
  129. {dirsql-0.3.60 → dirsql-0.3.61}/dirsql/cli/interpret/__init__.py +0 -0
  130. {dirsql-0.3.60 → dirsql-0.3.61}/dirsql/cli/is_windows.py +0 -0
  131. {dirsql-0.3.60 → dirsql-0.3.61}/dirsql/cli/main.py +0 -0
  132. {dirsql-0.3.60 → dirsql-0.3.61}/dirsql/cli/resolve_config_extensions.py +0 -0
  133. {dirsql-0.3.60 → dirsql-0.3.61}/dirsql/py.typed +0 -0
  134. {dirsql-0.3.60 → dirsql-0.3.61}/dirsql/resolve_config_extensions.py +0 -0
  135. {dirsql-0.3.60 → dirsql-0.3.61}/dirsql/resolve_extension.py +0 -0
  136. {dirsql-0.3.60 → dirsql-0.3.61}/docs/.claude/CLAUDE.md +0 -0
  137. {dirsql-0.3.60 → dirsql-0.3.61}/docs/.vitepress/theme/index.ts +0 -0
  138. {dirsql-0.3.60 → dirsql-0.3.61}/docs/.vitepress/theme/lang.ts +0 -0
  139. {dirsql-0.3.60 → dirsql-0.3.61}/docs/package.json +0 -0
  140. {dirsql-0.3.60 → dirsql-0.3.61}/docs/playwright.config.ts +0 -0
  141. {dirsql-0.3.60 → dirsql-0.3.61}/docs/pnpm-lock.yaml +0 -0
  142. {dirsql-0.3.60 → dirsql-0.3.61}/docs/pnpm-workspace.yaml +0 -0
  143. {dirsql-0.3.60 → dirsql-0.3.61}/docs/tests/integration/home.spec.ts +0 -0
  144. {dirsql-0.3.60 → dirsql-0.3.61}/docs/tests/unit/lang.test.ts +0 -0
  145. {dirsql-0.3.60 → dirsql-0.3.61}/docs/vitest.config.ts +0 -0
  146. {dirsql-0.3.60 → dirsql-0.3.61}/packages/python/README.md +0 -0
  147. {dirsql-0.3.60 → dirsql-0.3.61}/packages/python/conftest.py +0 -0
  148. {dirsql-0.3.60 → dirsql-0.3.61}/packages/python/docs/.claude/CLAUDE.md +0 -0
  149. {dirsql-0.3.60 → dirsql-0.3.61}/packages/python/docs/.vitepress/theme/index.ts +0 -0
  150. {dirsql-0.3.60 → dirsql-0.3.61}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
  151. {dirsql-0.3.60 → dirsql-0.3.61}/packages/python/docs/package.json +0 -0
  152. {dirsql-0.3.60 → dirsql-0.3.61}/packages/python/docs/playwright.config.ts +0 -0
  153. {dirsql-0.3.60 → dirsql-0.3.61}/packages/python/docs/pnpm-lock.yaml +0 -0
  154. {dirsql-0.3.60 → dirsql-0.3.61}/packages/python/docs/pnpm-workspace.yaml +0 -0
  155. {dirsql-0.3.60 → dirsql-0.3.61}/packages/python/docs/tests/integration/home.spec.ts +0 -0
  156. {dirsql-0.3.60 → dirsql-0.3.61}/packages/python/docs/tests/unit/lang.test.ts +0 -0
  157. {dirsql-0.3.60 → dirsql-0.3.61}/packages/python/docs/vitest.config.ts +0 -0
  158. {dirsql-0.3.60 → dirsql-0.3.61}/packages/python/src/lib.rs +0 -0
  159. {dirsql-0.3.60 → dirsql-0.3.61}/packages/python/tests/__init__.py +0 -0
  160. {dirsql-0.3.60 → dirsql-0.3.61}/packages/python/tests/binding/__init__.py +0 -0
  161. {dirsql-0.3.60 → dirsql-0.3.61}/packages/python/tests/conftest.py +0 -0
  162. {dirsql-0.3.60 → dirsql-0.3.61}/packages/python/tests/e2e/__init__.py +0 -0
  163. {dirsql-0.3.60 → dirsql-0.3.61}/packages/python/tests/integration/__init__.py +0 -0
  164. {dirsql-0.3.60 → dirsql-0.3.61}/packages/python/tests/smoke/__init__.py +0 -0
  165. {dirsql-0.3.60 → dirsql-0.3.61}/packages/rust/README.md +0 -0
  166. {dirsql-0.3.60 → dirsql-0.3.61}/packages/rust/benches/db_bench.rs +0 -0
  167. {dirsql-0.3.60 → dirsql-0.3.61}/packages/rust/benches/differ_bench.rs +0 -0
  168. {dirsql-0.3.60 → dirsql-0.3.61}/packages/rust/benches/matcher_bench.rs +0 -0
  169. {dirsql-0.3.60 → dirsql-0.3.61}/packages/rust/benches/scanner_bench.rs +0 -0
  170. {dirsql-0.3.60 → dirsql-0.3.61}/packages/rust/src/bin/dirsql.rs +0 -0
  171. {dirsql-0.3.60 → dirsql-0.3.61}/packages/rust/src/cli/init.rs +0 -0
  172. {dirsql-0.3.60 → dirsql-0.3.61}/packages/rust/src/cli/mod.rs +0 -0
  173. {dirsql-0.3.60 → dirsql-0.3.61}/packages/rust/src/cli/router.rs +0 -0
  174. {dirsql-0.3.60 → dirsql-0.3.61}/packages/rust/src/cli/serialize.rs +0 -0
  175. {dirsql-0.3.60 → dirsql-0.3.61}/packages/rust/src/cli/server.rs +0 -0
  176. {dirsql-0.3.60 → dirsql-0.3.61}/packages/rust/src/command.rs +0 -0
  177. {dirsql-0.3.60 → dirsql-0.3.61}/packages/rust/src/config.rs +0 -0
  178. {dirsql-0.3.60 → dirsql-0.3.61}/packages/rust/src/differ.rs +0 -0
  179. {dirsql-0.3.60 → dirsql-0.3.61}/packages/rust/src/lib.rs +0 -0
  180. {dirsql-0.3.60 → dirsql-0.3.61}/packages/rust/src/matcher.rs +0 -0
  181. {dirsql-0.3.60 → dirsql-0.3.61}/packages/rust/src/persist.rs +0 -0
  182. {dirsql-0.3.60 → dirsql-0.3.61}/packages/rust/src/scanner.rs +0 -0
  183. {dirsql-0.3.60 → dirsql-0.3.61}/packages/rust/src/watcher.rs +0 -0
  184. {dirsql-0.3.60 → dirsql-0.3.61}/pyproject.toml +0 -0
@@ -500,7 +500,7 @@ dependencies = [
500
500
 
501
501
  [[package]]
502
502
  name = "dirsql-py-ext"
503
- version = "0.3.60"
503
+ version = "0.3.61"
504
504
  dependencies = [
505
505
  "dirsql",
506
506
  "pyo3",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dirsql
3
- Version: 0.3.60
3
+ Version: 0.3.61
4
4
  Requires-Dist: pytest>=8 ; extra == 'dev'
5
5
  Requires-Dist: pytest-describe>=2 ; extra == 'dev'
6
6
  Requires-Dist: pytest-asyncio>=0.23 ; extra == 'dev'
@@ -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
+ })
@@ -47,21 +47,24 @@ secondary audience and appear **only in Reference**, plus the single
47
47
  Target tree (the spec for #353; existing pages are *quarried* into it, not
48
48
  migrated -- a page survives only if a slot wants its content):
49
49
 
50
- - **Tutorial** -- one lesson: *Your first dirsql database*. The reader
51
- performs every step and sees output at each one; success is
52
- author-guaranteed (toy dataset, no branching).
53
- - **How-to Guides** -- goal-named recipes: define tables for your files;
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
54
  derive columns from file paths; extract rows from file contents
55
55
  (`on-file`); search documents by meaning; skip files; load a SQLite
56
56
  extension; keep the index across restarts; react to file changes; embed
57
57
  `dirsql` in an application.
58
- - **Reference** -- CLI flags and defaults; the complete `.dirsql.toml`
59
- schema; the command hook contract (placeholders, stdout protocol, exit
60
- codes, timeouts); virtual columns and glob captures; the HTTP API;
61
- per-language SDK pages (the sole SDK home).
62
- - **Explanation** -- one page: how `dirsql` thinks (the filesystem is the
63
- source of truth; the database is a derived, ephemeral, read-only view;
64
- reconcile and diffing). Its canonical home is the root `ARCHITECTURE.md`;
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`;
65
68
  #374 surfaces it via an include page, the same mechanism
66
69
  `docs/migrations.md` uses for `MIGRATIONS.md`. Edit the root file, never
67
70
  a rendered include.
@@ -90,6 +93,6 @@ Working rules:
90
93
  directories don't re-scan on every startup."
91
94
  - Wrap `dirsql` in backticks in all prose text
92
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
93
- - Internal links use relative paths (e.g., `./guide/tables.md`)
96
+ - Internal links use relative paths (e.g., `./howto/define-tables.md`)
94
97
  - The VitePress config is at `docs/.vitepress/config.ts`
95
98
  - The site is deployed under the `/dirsql/` base path
@@ -0,0 +1,5 @@
1
+ ---
2
+ title: How dirsql thinks
3
+ ---
4
+
5
+ <!--@include: ../ARCHITECTURE.md-->
@@ -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).