dirsql 0.3.91__tar.gz → 0.3.93__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.91 → dirsql-0.3.93}/Cargo.lock +1 -1
- {dirsql-0.3.91 → dirsql-0.3.93}/PKG-INFO +1 -1
- {dirsql-0.3.91 → dirsql-0.3.93}/dirsql/_async.py +5 -4
- {dirsql-0.3.91/packages/rust → dirsql-0.3.93}/docs/reference/cli.md +1 -1
- {dirsql-0.3.91/packages/rust → dirsql-0.3.93}/docs/reference/config.md +5 -6
- {dirsql-0.3.91/packages/rust → dirsql-0.3.93}/docs/reference/sdk.md +8 -8
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/Cargo.toml +1 -1
- {dirsql-0.3.91 → dirsql-0.3.93/packages/python}/docs/reference/cli.md +1 -1
- {dirsql-0.3.91 → dirsql-0.3.93/packages/python}/docs/reference/config.md +5 -6
- {dirsql-0.3.91 → dirsql-0.3.93/packages/python}/docs/reference/sdk.md +8 -8
- dirsql-0.3.93/packages/python/e2e-attestations/claude-tackle-540-iju1yi.json +7 -0
- {dirsql-0.3.91/packages/python → dirsql-0.3.93/packages/rust}/docs/reference/cli.md +1 -1
- {dirsql-0.3.91/packages/python → dirsql-0.3.93/packages/rust}/docs/reference/config.md +5 -6
- {dirsql-0.3.91/packages/python → dirsql-0.3.93/packages/rust}/docs/reference/sdk.md +8 -8
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/src/bin/dirsql.rs +7 -6
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/src/config.rs +15 -84
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/src/lib.rs +130 -64
- dirsql-0.3.91/packages/python/e2e-attestation.json +0 -6
- {dirsql-0.3.91 → dirsql-0.3.93}/Cargo.toml +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/README.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/dirsql/__init__.py +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/dirsql/_dirsql.pyi +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/dirsql/cli/__init__.py +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/dirsql/cli/binary_path.py +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/dirsql/cli/is_windows.py +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/dirsql/cli/main.py +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/dirsql/cli/resolve_config_extensions.py +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/dirsql/py.typed +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/dirsql/resolve_config_extensions.py +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/dirsql/resolve_extension.py +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/.vitepress/config.ts +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/AGENTS.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/explanation.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/getting-started.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/howto/define-tables.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/howto/embed.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/howto/load-extension.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/howto/persist.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/howto/skip-files.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/index.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/migrations.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/package.json +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/playwright.config.ts +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/reference/columns.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/reference/hooks.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/reference/http-api.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/tests/integration/home.spec.ts +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/tests/integration/language-flag.spec.ts +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/tests/integration/sidebar.spec.ts +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/tests/unit/config.test.ts +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/tests/unit/lang.test.ts +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/docs/vitest.config.ts +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/README.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/conftest.py +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/.vitepress/config.ts +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/AGENTS.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/explanation.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/getting-started.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/howto/define-tables.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/howto/embed.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/howto/load-extension.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/howto/persist.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/howto/skip-files.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/index.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/migrations.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/package.json +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/playwright.config.ts +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/reference/columns.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/reference/hooks.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/reference/http-api.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/tests/integration/home.spec.ts +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/tests/integration/language-flag.spec.ts +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/tests/integration/sidebar.spec.ts +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/tests/unit/config.test.ts +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/tests/unit/lang.test.ts +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/docs/vitest.config.ts +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/src/lib.rs +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/tests/__init__.py +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/tests/conftest.py +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/tests/e2e/__init__.py +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/tests/integration/__init__.py +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/tests/integration/binding/__init__.py +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/python/tests/integration/hermetic/__init__.py +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/Cargo.toml +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/README.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/benches/db_bench.rs +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/benches/differ_bench.rs +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/benches/matcher_bench.rs +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/benches/scanner_bench.rs +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/docs/explanation.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/docs/getting-started.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/docs/howto/define-tables.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/docs/howto/embed.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/docs/howto/load-extension.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/docs/howto/persist.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/docs/howto/skip-files.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/docs/index.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/docs/migrations.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/docs/reference/columns.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/docs/reference/hooks.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/docs/reference/http-api.md +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/src/cli/execute.rs +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/src/cli/init.rs +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/src/cli/mod.rs +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/src/cli/router.rs +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/src/cli/serialize.rs +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/src/cli/server.rs +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/src/command.rs +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/src/db.rs +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/src/default_config.toml +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/src/differ.rs +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/src/matcher.rs +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/src/persist.rs +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/src/scanner.rs +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/packages/rust/src/watcher.rs +0 -0
- {dirsql-0.3.91 → dirsql-0.3.93}/pyproject.toml +0 -0
|
@@ -53,10 +53,11 @@ class DirSQL:
|
|
|
53
53
|
async for event in db.watch():
|
|
54
54
|
...
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
The index root is the explicit ``root`` when given, else the process
|
|
57
|
+
current working directory. A ``config`` file's location never sets the
|
|
58
|
+
root -- it only supplies tables, ignore patterns, and extensions. There
|
|
59
|
+
is no ``[dirsql].root`` config key. Constructing with neither ``root``
|
|
60
|
+
nor ``config`` roots at the cwd (no error is raised).
|
|
60
61
|
|
|
61
62
|
Pass ``persist=True`` to keep an on-disk SQLite cache (default location:
|
|
62
63
|
``<root>/.dirsql/cache.db``). Override the location with ``persist_path``.
|
|
@@ -45,7 +45,7 @@ requests, closes open `/events` streams, and exits.
|
|
|
45
45
|
|
|
46
46
|
| Flag | Default | Description |
|
|
47
47
|
|---|---|---|
|
|
48
|
-
| `-c, --config <path>` | `./.dirsql.toml` | Path to the [config file](./config.md). The index is rooted at the directory
|
|
48
|
+
| `-c, --config <path>` | `./.dirsql.toml` | Path to the [config file](./config.md). The index is always rooted at the **invocation directory** (the current working directory), regardless of where this file lives — so `--config /elsewhere/.dirsql.toml` still indexes the directory you ran `dirsql` from. When the file does not exist, the server runs in [zero-config mode](#zero-config-mode). |
|
|
49
49
|
| `--host <addr>` | `localhost` | Bind address. |
|
|
50
50
|
| `--port <n>` | `7117` | TCP port to bind. |
|
|
51
51
|
| `--persist [<path>]` | off | Keep the SQLite index on disk between runs so a restart only re-parses files that actually changed. Bare `--persist` caches at `<root>/.dirsql/cache.db`; `--persist <path>` caches at `<path>`. Off by default (the index is ephemeral). Global — also honored by [`dirsql query`](#dirsql-query). See [Keep the index across restarts](../howto/persist.md). |
|
|
@@ -11,16 +11,16 @@ The [CLI](./cli.md) loads `./.dirsql.toml` by default (`--config <path>`
|
|
|
11
11
|
overrides). The [SDKs](./sdk.md) load a config via the `config` constructor
|
|
12
12
|
parameter.
|
|
13
13
|
|
|
14
|
-
**Path resolution.** Relative paths in the config (`
|
|
15
|
-
`
|
|
16
|
-
directory. The
|
|
17
|
-
|
|
14
|
+
**Path resolution.** Relative paths in the config (`[[dirsql.extension]]`
|
|
15
|
+
`path`) resolve against the config file's parent
|
|
16
|
+
directory. The **index root is not a config concern** — it is decided by the
|
|
17
|
+
runner (the CLI's invocation directory, or an SDK's explicit root), never by
|
|
18
|
+
the config file's location. See [`--config`](./cli.md#flags).
|
|
18
19
|
|
|
19
20
|
## `[dirsql]` keys
|
|
20
21
|
|
|
21
22
|
| Key | Type | Default | Description |
|
|
22
23
|
|---|---|---|---|
|
|
23
|
-
| `root` | string | config file's parent directory | Directory to index. Relative values resolve against the config file's parent. An explicit `root` passed to an SDK constructor overrides this (a warning is emitted on stderr). |
|
|
24
24
|
| `ignore` | array of strings | `[]` | Glob patterns matched against root-relative paths. Matched files are skipped entirely — excluded from the initial scan and from watch events. |
|
|
25
25
|
| `pre-query` | string | none | Server-wide command hook: the raw `POST /query` request body is passed to this command as `{args}`, and the plain-text SQL it prints is executed instead of parsing the body as `{"sql": …}`. CLI server only; the SDKs ignore it. Must be non-empty. See [Command hooks](./hooks.md#pre-query). |
|
|
26
26
|
| `post-query` | string | none | Server-wide command hook: each successful `POST /query` result set is handed to this command (as a JSON array on stdin, and as `{args}` up to 96 KiB), and the JSON body it prints is returned instead of the bare row array. CLI server only; the SDKs ignore it. Must be non-empty. See [Command hooks](./hooks.md#post-query). |
|
|
@@ -34,7 +34,6 @@ directory.
|
|
|
34
34
|
|
|
35
35
|
```toml
|
|
36
36
|
[dirsql]
|
|
37
|
-
root = "../data"
|
|
38
37
|
ignore = ["node_modules/**", ".git/**"]
|
|
39
38
|
hook-timeout = 300
|
|
40
39
|
```
|
|
@@ -92,22 +92,22 @@ DirSQL::builder()
|
|
|
92
92
|
|
|
93
93
|
:::
|
|
94
94
|
|
|
95
|
-
Creates a SQLite index over a directory.
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
Creates a SQLite index over a directory. The index root is the explicit
|
|
96
|
+
`root` when given, else the **process cwd** — the `config` file's location
|
|
97
|
+
never sets the root.
|
|
98
98
|
|
|
99
99
|
**Parameters:**
|
|
100
100
|
|
|
101
|
-
- `root` — Directory to index.
|
|
101
|
+
- `root` — Directory to index. When omitted, the index roots at the process
|
|
102
|
+
cwd (even when `config` is supplied).
|
|
102
103
|
- `tables` — Programmatic [`Table`](#table) definitions.
|
|
103
104
|
- `ignore` — Glob patterns matched against root-relative paths; matched
|
|
104
105
|
files are skipped entirely (scan and watch).
|
|
105
106
|
- `config` — Path to a [`.dirsql.toml`](./config.md). Its `[[table]]`
|
|
106
107
|
entries are appended after any programmatic `tables`; its `ignore`
|
|
107
|
-
patterns and `[[dirsql.extension]]` entries are appended likewise
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
value wins and a warning is emitted on stderr.
|
|
108
|
+
patterns and `[[dirsql.extension]]` entries are appended likewise. The
|
|
109
|
+
config file does **not** set the index root: with no explicit `root`, the
|
|
110
|
+
index roots at the process cwd.
|
|
111
111
|
- `persist` — Keep the SQLite index on disk between runs (default off:
|
|
112
112
|
ephemeral, rebuilt every startup). The cache lives at
|
|
113
113
|
`<root>/.dirsql/cache.db` by default; on restart, only files whose stat
|
|
@@ -4,7 +4,7 @@ name = "dirsql-py-ext"
|
|
|
4
4
|
# pypi/maturin handler can rewrite it via `write-version` before
|
|
5
5
|
# `maturin build`. `pyproject.toml` declares `dynamic = ["version"]`
|
|
6
6
|
# and maturin reads this field. Mirrors `packages/rust/Cargo.toml`.
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.93"
|
|
8
8
|
# abi3 note: the `abi3-py311` pyo3 feature (below) builds ONE stable-ABI
|
|
9
9
|
# `cp311-abi3` wheel per platform that loads on every CPython >= 3.11
|
|
10
10
|
# (matching `pyproject.toml`'s `requires-python = ">=3.11"`), instead of
|
|
@@ -45,7 +45,7 @@ requests, closes open `/events` streams, and exits.
|
|
|
45
45
|
|
|
46
46
|
| Flag | Default | Description |
|
|
47
47
|
|---|---|---|
|
|
48
|
-
| `-c, --config <path>` | `./.dirsql.toml` | Path to the [config file](./config.md). The index is rooted at the directory
|
|
48
|
+
| `-c, --config <path>` | `./.dirsql.toml` | Path to the [config file](./config.md). The index is always rooted at the **invocation directory** (the current working directory), regardless of where this file lives — so `--config /elsewhere/.dirsql.toml` still indexes the directory you ran `dirsql` from. When the file does not exist, the server runs in [zero-config mode](#zero-config-mode). |
|
|
49
49
|
| `--host <addr>` | `localhost` | Bind address. |
|
|
50
50
|
| `--port <n>` | `7117` | TCP port to bind. |
|
|
51
51
|
| `--persist [<path>]` | off | Keep the SQLite index on disk between runs so a restart only re-parses files that actually changed. Bare `--persist` caches at `<root>/.dirsql/cache.db`; `--persist <path>` caches at `<path>`. Off by default (the index is ephemeral). Global — also honored by [`dirsql query`](#dirsql-query). See [Keep the index across restarts](../howto/persist.md). |
|
|
@@ -11,16 +11,16 @@ The [CLI](./cli.md) loads `./.dirsql.toml` by default (`--config <path>`
|
|
|
11
11
|
overrides). The [SDKs](./sdk.md) load a config via the `config` constructor
|
|
12
12
|
parameter.
|
|
13
13
|
|
|
14
|
-
**Path resolution.** Relative paths in the config (`
|
|
15
|
-
`
|
|
16
|
-
directory. The
|
|
17
|
-
|
|
14
|
+
**Path resolution.** Relative paths in the config (`[[dirsql.extension]]`
|
|
15
|
+
`path`) resolve against the config file's parent
|
|
16
|
+
directory. The **index root is not a config concern** — it is decided by the
|
|
17
|
+
runner (the CLI's invocation directory, or an SDK's explicit root), never by
|
|
18
|
+
the config file's location. See [`--config`](./cli.md#flags).
|
|
18
19
|
|
|
19
20
|
## `[dirsql]` keys
|
|
20
21
|
|
|
21
22
|
| Key | Type | Default | Description |
|
|
22
23
|
|---|---|---|---|
|
|
23
|
-
| `root` | string | config file's parent directory | Directory to index. Relative values resolve against the config file's parent. An explicit `root` passed to an SDK constructor overrides this (a warning is emitted on stderr). |
|
|
24
24
|
| `ignore` | array of strings | `[]` | Glob patterns matched against root-relative paths. Matched files are skipped entirely — excluded from the initial scan and from watch events. |
|
|
25
25
|
| `pre-query` | string | none | Server-wide command hook: the raw `POST /query` request body is passed to this command as `{args}`, and the plain-text SQL it prints is executed instead of parsing the body as `{"sql": …}`. CLI server only; the SDKs ignore it. Must be non-empty. See [Command hooks](./hooks.md#pre-query). |
|
|
26
26
|
| `post-query` | string | none | Server-wide command hook: each successful `POST /query` result set is handed to this command (as a JSON array on stdin, and as `{args}` up to 96 KiB), and the JSON body it prints is returned instead of the bare row array. CLI server only; the SDKs ignore it. Must be non-empty. See [Command hooks](./hooks.md#post-query). |
|
|
@@ -34,7 +34,6 @@ directory.
|
|
|
34
34
|
|
|
35
35
|
```toml
|
|
36
36
|
[dirsql]
|
|
37
|
-
root = "../data"
|
|
38
37
|
ignore = ["node_modules/**", ".git/**"]
|
|
39
38
|
hook-timeout = 300
|
|
40
39
|
```
|
|
@@ -92,22 +92,22 @@ DirSQL::builder()
|
|
|
92
92
|
|
|
93
93
|
:::
|
|
94
94
|
|
|
95
|
-
Creates a SQLite index over a directory.
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
Creates a SQLite index over a directory. The index root is the explicit
|
|
96
|
+
`root` when given, else the **process cwd** — the `config` file's location
|
|
97
|
+
never sets the root.
|
|
98
98
|
|
|
99
99
|
**Parameters:**
|
|
100
100
|
|
|
101
|
-
- `root` — Directory to index.
|
|
101
|
+
- `root` — Directory to index. When omitted, the index roots at the process
|
|
102
|
+
cwd (even when `config` is supplied).
|
|
102
103
|
- `tables` — Programmatic [`Table`](#table) definitions.
|
|
103
104
|
- `ignore` — Glob patterns matched against root-relative paths; matched
|
|
104
105
|
files are skipped entirely (scan and watch).
|
|
105
106
|
- `config` — Path to a [`.dirsql.toml`](./config.md). Its `[[table]]`
|
|
106
107
|
entries are appended after any programmatic `tables`; its `ignore`
|
|
107
|
-
patterns and `[[dirsql.extension]]` entries are appended likewise
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
value wins and a warning is emitted on stderr.
|
|
108
|
+
patterns and `[[dirsql.extension]]` entries are appended likewise. The
|
|
109
|
+
config file does **not** set the index root: with no explicit `root`, the
|
|
110
|
+
index roots at the process cwd.
|
|
111
111
|
- `persist` — Keep the SQLite index on disk between runs (default off:
|
|
112
112
|
ephemeral, rebuilt every startup). The cache lives at
|
|
113
113
|
`<root>/.dirsql/cache.db` by default; on restart, only files whose stat
|
|
@@ -45,7 +45,7 @@ requests, closes open `/events` streams, and exits.
|
|
|
45
45
|
|
|
46
46
|
| Flag | Default | Description |
|
|
47
47
|
|---|---|---|
|
|
48
|
-
| `-c, --config <path>` | `./.dirsql.toml` | Path to the [config file](./config.md). The index is rooted at the directory
|
|
48
|
+
| `-c, --config <path>` | `./.dirsql.toml` | Path to the [config file](./config.md). The index is always rooted at the **invocation directory** (the current working directory), regardless of where this file lives — so `--config /elsewhere/.dirsql.toml` still indexes the directory you ran `dirsql` from. When the file does not exist, the server runs in [zero-config mode](#zero-config-mode). |
|
|
49
49
|
| `--host <addr>` | `localhost` | Bind address. |
|
|
50
50
|
| `--port <n>` | `7117` | TCP port to bind. |
|
|
51
51
|
| `--persist [<path>]` | off | Keep the SQLite index on disk between runs so a restart only re-parses files that actually changed. Bare `--persist` caches at `<root>/.dirsql/cache.db`; `--persist <path>` caches at `<path>`. Off by default (the index is ephemeral). Global — also honored by [`dirsql query`](#dirsql-query). See [Keep the index across restarts](../howto/persist.md). |
|
|
@@ -11,16 +11,16 @@ The [CLI](./cli.md) loads `./.dirsql.toml` by default (`--config <path>`
|
|
|
11
11
|
overrides). The [SDKs](./sdk.md) load a config via the `config` constructor
|
|
12
12
|
parameter.
|
|
13
13
|
|
|
14
|
-
**Path resolution.** Relative paths in the config (`
|
|
15
|
-
`
|
|
16
|
-
directory. The
|
|
17
|
-
|
|
14
|
+
**Path resolution.** Relative paths in the config (`[[dirsql.extension]]`
|
|
15
|
+
`path`) resolve against the config file's parent
|
|
16
|
+
directory. The **index root is not a config concern** — it is decided by the
|
|
17
|
+
runner (the CLI's invocation directory, or an SDK's explicit root), never by
|
|
18
|
+
the config file's location. See [`--config`](./cli.md#flags).
|
|
18
19
|
|
|
19
20
|
## `[dirsql]` keys
|
|
20
21
|
|
|
21
22
|
| Key | Type | Default | Description |
|
|
22
23
|
|---|---|---|---|
|
|
23
|
-
| `root` | string | config file's parent directory | Directory to index. Relative values resolve against the config file's parent. An explicit `root` passed to an SDK constructor overrides this (a warning is emitted on stderr). |
|
|
24
24
|
| `ignore` | array of strings | `[]` | Glob patterns matched against root-relative paths. Matched files are skipped entirely — excluded from the initial scan and from watch events. |
|
|
25
25
|
| `pre-query` | string | none | Server-wide command hook: the raw `POST /query` request body is passed to this command as `{args}`, and the plain-text SQL it prints is executed instead of parsing the body as `{"sql": …}`. CLI server only; the SDKs ignore it. Must be non-empty. See [Command hooks](./hooks.md#pre-query). |
|
|
26
26
|
| `post-query` | string | none | Server-wide command hook: each successful `POST /query` result set is handed to this command (as a JSON array on stdin, and as `{args}` up to 96 KiB), and the JSON body it prints is returned instead of the bare row array. CLI server only; the SDKs ignore it. Must be non-empty. See [Command hooks](./hooks.md#post-query). |
|
|
@@ -34,7 +34,6 @@ directory.
|
|
|
34
34
|
|
|
35
35
|
```toml
|
|
36
36
|
[dirsql]
|
|
37
|
-
root = "../data"
|
|
38
37
|
ignore = ["node_modules/**", ".git/**"]
|
|
39
38
|
hook-timeout = 300
|
|
40
39
|
```
|
|
@@ -92,22 +92,22 @@ DirSQL::builder()
|
|
|
92
92
|
|
|
93
93
|
:::
|
|
94
94
|
|
|
95
|
-
Creates a SQLite index over a directory.
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
Creates a SQLite index over a directory. The index root is the explicit
|
|
96
|
+
`root` when given, else the **process cwd** — the `config` file's location
|
|
97
|
+
never sets the root.
|
|
98
98
|
|
|
99
99
|
**Parameters:**
|
|
100
100
|
|
|
101
|
-
- `root` — Directory to index.
|
|
101
|
+
- `root` — Directory to index. When omitted, the index roots at the process
|
|
102
|
+
cwd (even when `config` is supplied).
|
|
102
103
|
- `tables` — Programmatic [`Table`](#table) definitions.
|
|
103
104
|
- `ignore` — Glob patterns matched against root-relative paths; matched
|
|
104
105
|
files are skipped entirely (scan and watch).
|
|
105
106
|
- `config` — Path to a [`.dirsql.toml`](./config.md). Its `[[table]]`
|
|
106
107
|
entries are appended after any programmatic `tables`; its `ignore`
|
|
107
|
-
patterns and `[[dirsql.extension]]` entries are appended likewise
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
value wins and a warning is emitted on stderr.
|
|
108
|
+
patterns and `[[dirsql.extension]]` entries are appended likewise. The
|
|
109
|
+
config file does **not** set the index root: with no explicit `root`, the
|
|
110
|
+
index roots at the process cwd.
|
|
111
111
|
- `persist` — Keep the SQLite index on disk between runs (default off:
|
|
112
112
|
ephemeral, rebuilt every startup). The cache lives at
|
|
113
113
|
`<root>/.dirsql/cache.db` by default; on restart, only files whose stat
|
|
@@ -34,9 +34,9 @@ struct Cli {
|
|
|
34
34
|
command: Option<Command>,
|
|
35
35
|
|
|
36
36
|
/// Path to the config file (default: `./.dirsql.toml`). The index is
|
|
37
|
-
/// rooted at the directory
|
|
38
|
-
/// not exist, a default `files` table is
|
|
39
|
-
/// and by the `query` subcommand.
|
|
37
|
+
/// rooted at the invocation directory (cwd), not this file's location
|
|
38
|
+
/// (#540). When the file does not exist, a default `files` table is
|
|
39
|
+
/// served. Used by server mode and by the `query` subcommand.
|
|
40
40
|
#[arg(short = 'c', long, default_value = "./.dirsql.toml", global = true)]
|
|
41
41
|
config: PathBuf,
|
|
42
42
|
|
|
@@ -238,9 +238,10 @@ fn load_state(cli: &Cli) -> AppState {
|
|
|
238
238
|
return load_default_state(cli, config_path);
|
|
239
239
|
}
|
|
240
240
|
|
|
241
|
-
// Canonicalize so
|
|
242
|
-
// absolute — `notify`
|
|
243
|
-
// paths like `./`.
|
|
241
|
+
// Canonicalize so config-relative paths (extension libraries, hook
|
|
242
|
+
// working directories) resolve against an absolute parent — `notify` and
|
|
243
|
+
// the hook subprocesses misbehave with relative paths like `./`. The
|
|
244
|
+
// index root itself is the invocation cwd (#540), not derived from here.
|
|
244
245
|
let resolved = match config_path.canonicalize() {
|
|
245
246
|
Ok(p) => p,
|
|
246
247
|
Err(err) => {
|
|
@@ -68,16 +68,13 @@ impl std::fmt::Display for Source {
|
|
|
68
68
|
/// Order-significant; at least one entry is required and a single entry is
|
|
69
69
|
/// returned unchanged. List-shaped config (`[[table]]`, `[[dirsql.extension]]`,
|
|
70
70
|
/// `ignore`) concatenates in input order. A table-name collision anywhere in
|
|
71
|
-
/// the combined set errors, naming both sources. Single-valued keys
|
|
72
|
-
/// `pre-query`, `post-query`, `hook-timeout`) defined by more than
|
|
71
|
+
/// the combined set errors, naming both sources. Single-valued keys
|
|
72
|
+
/// (`pre-query`, `post-query`, `hook-timeout`) defined by more than
|
|
73
73
|
/// one config error, naming both sources — no silent shadowing, no precedence;
|
|
74
74
|
/// defined in exactly one config they merge through unchanged.
|
|
75
75
|
///
|
|
76
76
|
/// Tables whose DDL yields no parseable table name are concatenated without a
|
|
77
77
|
/// collision check; `Db::create_table` rejects them downstream.
|
|
78
|
-
///
|
|
79
|
-
/// Plugin whitelist enforcement ("a fragment may not set `root`") is the
|
|
80
|
-
/// discovery layer's job, per fragment, before calling this.
|
|
81
78
|
pub fn combine_configs(configs: &[(Source, Config)]) -> Result<Config> {
|
|
82
79
|
let (first, rest) = configs.split_first().ok_or(ConfigError::NoConfigs)?;
|
|
83
80
|
if rest.is_empty() {
|
|
@@ -90,7 +87,6 @@ pub fn combine_configs(configs: &[(Source, Config)]) -> Result<Config> {
|
|
|
90
87
|
let mut table_sources: std::collections::HashMap<String, &Source> =
|
|
91
88
|
std::collections::HashMap::new();
|
|
92
89
|
|
|
93
|
-
let mut root: Option<(&Source, PathBuf)> = None;
|
|
94
90
|
let mut pre_query: Option<(&Source, String)> = None;
|
|
95
91
|
let mut post_query: Option<(&Source, String)> = None;
|
|
96
92
|
let mut hook_timeout: Option<(&Source, Duration)> = None;
|
|
@@ -111,7 +107,6 @@ pub fn combine_configs(configs: &[(Source, Config)]) -> Result<Config> {
|
|
|
111
107
|
ignore.extend(config.ignore.iter().cloned());
|
|
112
108
|
extensions.extend(config.extensions.iter().cloned());
|
|
113
109
|
|
|
114
|
-
merge_single("root", &mut root, config.root.as_ref(), source)?;
|
|
115
110
|
merge_single(
|
|
116
111
|
"pre-query",
|
|
117
112
|
&mut pre_query,
|
|
@@ -133,7 +128,6 @@ pub fn combine_configs(configs: &[(Source, Config)]) -> Result<Config> {
|
|
|
133
128
|
}
|
|
134
129
|
|
|
135
130
|
Ok(Config {
|
|
136
|
-
root: root.map(|(_, value)| value),
|
|
137
131
|
ignore,
|
|
138
132
|
tables,
|
|
139
133
|
extensions,
|
|
@@ -167,11 +161,6 @@ fn merge_single<'a, T: Clone>(
|
|
|
167
161
|
/// Parsed configuration from a `.dirsql.toml` file.
|
|
168
162
|
#[derive(Debug, Clone)]
|
|
169
163
|
pub struct Config {
|
|
170
|
-
/// Optional root directory override. When absent, callers derive the
|
|
171
|
-
/// root from the config file's own location. When present, it is taken
|
|
172
|
-
/// relative to the config file's parent (so a config at
|
|
173
|
-
/// `/proj/.dirsql.toml` with `root = "docs"` scans `/proj/docs`).
|
|
174
|
-
pub root: Option<PathBuf>,
|
|
175
164
|
pub ignore: Vec<String>,
|
|
176
165
|
pub tables: Vec<TableConfig>,
|
|
177
166
|
/// SQLite extensions to load at startup, declared via
|
|
@@ -249,7 +238,6 @@ struct RawConfig {
|
|
|
249
238
|
#[derive(Deserialize, Default)]
|
|
250
239
|
#[serde(deny_unknown_fields)]
|
|
251
240
|
struct RawDirsql {
|
|
252
|
-
root: Option<PathBuf>,
|
|
253
241
|
ignore: Option<Vec<String>>,
|
|
254
242
|
extension: Option<Vec<RawExtension>>,
|
|
255
243
|
#[serde(rename = "pre-query")]
|
|
@@ -288,7 +276,6 @@ pub fn load_config_str(content: &str) -> Result<Config> {
|
|
|
288
276
|
let raw: RawConfig = toml::from_str(content)?;
|
|
289
277
|
|
|
290
278
|
let d = raw.dirsql.unwrap_or_default();
|
|
291
|
-
let root = d.root;
|
|
292
279
|
let ignore = d.ignore.unwrap_or_default();
|
|
293
280
|
let raw_extensions = d.extension.unwrap_or_default();
|
|
294
281
|
let raw_pre_query = d.pre_query;
|
|
@@ -348,7 +335,6 @@ pub fn load_config_str(content: &str) -> Result<Config> {
|
|
|
348
335
|
}
|
|
349
336
|
|
|
350
337
|
Ok(Config {
|
|
351
|
-
root,
|
|
352
338
|
ignore,
|
|
353
339
|
tables,
|
|
354
340
|
extensions,
|
|
@@ -463,45 +449,6 @@ glob = "*.json"
|
|
|
463
449
|
assert!(matches!(err, ConfigError::Io(_)), "got: {err:?}");
|
|
464
450
|
}
|
|
465
451
|
|
|
466
|
-
#[test]
|
|
467
|
-
fn optional_root_parses_when_present() {
|
|
468
|
-
let toml = r#"
|
|
469
|
-
[dirsql]
|
|
470
|
-
root = "docs"
|
|
471
|
-
|
|
472
|
-
[[table]]
|
|
473
|
-
ddl = "CREATE TABLE t (path TEXT)"
|
|
474
|
-
glob = "*.json"
|
|
475
|
-
"#;
|
|
476
|
-
let config = load_config_str(toml).unwrap();
|
|
477
|
-
assert_eq!(config.root.as_deref(), Some(Path::new("docs")));
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
#[test]
|
|
481
|
-
fn root_absent_by_default() {
|
|
482
|
-
let toml = r#"
|
|
483
|
-
[[table]]
|
|
484
|
-
ddl = "CREATE TABLE t (path TEXT)"
|
|
485
|
-
glob = "*.json"
|
|
486
|
-
"#;
|
|
487
|
-
let config = load_config_str(toml).unwrap();
|
|
488
|
-
assert!(config.root.is_none());
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
#[test]
|
|
492
|
-
fn root_can_be_absolute() {
|
|
493
|
-
let toml = r#"
|
|
494
|
-
[dirsql]
|
|
495
|
-
root = "/tmp/data"
|
|
496
|
-
|
|
497
|
-
[[table]]
|
|
498
|
-
ddl = "CREATE TABLE t (path TEXT)"
|
|
499
|
-
glob = "*.json"
|
|
500
|
-
"#;
|
|
501
|
-
let config = load_config_str(toml).unwrap();
|
|
502
|
-
assert_eq!(config.root.as_deref(), Some(Path::new("/tmp/data")));
|
|
503
|
-
}
|
|
504
|
-
|
|
505
452
|
#[test]
|
|
506
453
|
fn persist_key_is_rejected_as_unknown() {
|
|
507
454
|
// Persistence moved to the `--persist` CLI flag; the TOML key is gone.
|
|
@@ -585,6 +532,19 @@ glbo = "typo"
|
|
|
585
532
|
assert!(err.to_string().contains("glbo"), "got: {err}");
|
|
586
533
|
}
|
|
587
534
|
|
|
535
|
+
#[test]
|
|
536
|
+
fn root_key_in_dirsql_section_is_rejected() {
|
|
537
|
+
// `root` is no longer a config key (#540): the runner owns the index
|
|
538
|
+
// root. An old config carrying it fails loudly, naming the key.
|
|
539
|
+
let toml = r#"
|
|
540
|
+
[dirsql]
|
|
541
|
+
root = "docs"
|
|
542
|
+
"#;
|
|
543
|
+
let err = load_config_str(toml).unwrap_err();
|
|
544
|
+
assert!(matches!(err, ConfigError::Toml(_)), "got: {err:?}");
|
|
545
|
+
assert!(err.to_string().contains("root"), "got: {err}");
|
|
546
|
+
}
|
|
547
|
+
|
|
588
548
|
#[test]
|
|
589
549
|
fn unknown_key_in_extension_is_rejected() {
|
|
590
550
|
// A misspelled `[[dirsql.extension]]` key (`entrypont`) errors.
|
|
@@ -807,7 +767,6 @@ post-query = " "
|
|
|
807
767
|
fn combine_singleton_returns_config_unchanged() {
|
|
808
768
|
let config = cfg(r#"
|
|
809
769
|
[dirsql]
|
|
810
|
-
root = "docs"
|
|
811
770
|
ignore = ["*.tmp"]
|
|
812
771
|
pre-query = "to_sql {args}"
|
|
813
772
|
post-query = "jq '{results: .}'"
|
|
@@ -821,7 +780,6 @@ ddl = "CREATE TABLE t (path TEXT)"
|
|
|
821
780
|
glob = "*.json"
|
|
822
781
|
"#);
|
|
823
782
|
let merged = combine_configs(&[(src("/proj/.dirsql.toml"), config.clone())]).unwrap();
|
|
824
|
-
assert_eq!(merged.root, config.root);
|
|
825
783
|
assert_eq!(merged.ignore, config.ignore);
|
|
826
784
|
assert_eq!(merged.extensions, config.extensions);
|
|
827
785
|
assert_eq!(merged.pre_query, config.pre_query);
|
|
@@ -1007,33 +965,6 @@ glob = "c/*.json"
|
|
|
1007
965
|
assert_eq!(merged.post_query.as_deref(), Some("jq -c ."));
|
|
1008
966
|
}
|
|
1009
967
|
|
|
1010
|
-
#[test]
|
|
1011
|
-
fn combine_root_in_two_configs_errors_naming_both_sources() {
|
|
1012
|
-
let a = cfg("[dirsql]\nroot = \"docs\"\n");
|
|
1013
|
-
let b = cfg("[dirsql]\nroot = \"data\"\n");
|
|
1014
|
-
let err = combine_configs(&[(src("/a"), a), (src("/b"), b)]).unwrap_err();
|
|
1015
|
-
match &err {
|
|
1016
|
-
ConfigError::ConflictingKey { key, first, second } => {
|
|
1017
|
-
assert_eq!(*key, "root");
|
|
1018
|
-
assert_eq!(first, &src("/a"));
|
|
1019
|
-
assert_eq!(second, &src("/b"));
|
|
1020
|
-
}
|
|
1021
|
-
other => panic!("got: {other:?}"),
|
|
1022
|
-
}
|
|
1023
|
-
let msg = err.to_string();
|
|
1024
|
-
assert!(msg.contains("'root'"), "got: {msg}");
|
|
1025
|
-
assert!(msg.contains("/a"), "got: {msg}");
|
|
1026
|
-
assert!(msg.contains("/b"), "got: {msg}");
|
|
1027
|
-
}
|
|
1028
|
-
|
|
1029
|
-
#[test]
|
|
1030
|
-
fn combine_root_in_one_config_merges_through() {
|
|
1031
|
-
let a = cfg("[dirsql]\nignore = [\"a/**\"]\n");
|
|
1032
|
-
let b = cfg("[dirsql]\nroot = \"docs\"\n");
|
|
1033
|
-
let merged = combine_configs(&[(src("/a"), a), (src("/b"), b)]).unwrap();
|
|
1034
|
-
assert_eq!(merged.root.as_deref(), Some(Path::new("docs")));
|
|
1035
|
-
}
|
|
1036
|
-
|
|
1037
968
|
#[test]
|
|
1038
969
|
fn combine_error_display_includes_package_source_verbatim() {
|
|
1039
970
|
let a = cfg("[[table]]\nddl = \"CREATE TABLE t (x TEXT)\"\nglob = \"a/*.json\"\n");
|