dirsql 0.4.67 → 0.4.69
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/getting-started.md +8 -7
- package/docs/howto/define-tables.md +2 -2
- package/docs/howto/persist.md +7 -11
- package/docs/howto/query-without-config.md +2 -2
- package/docs/reference/cli.md +5 -9
- package/docs/reference/config.md +4 -4
- package/docs/reference/hooks.md +10 -11
- package/docs/reference/path-tables.md +16 -17
- package/package.json +6 -6
package/docs/getting-started.md
CHANGED
|
@@ -68,11 +68,11 @@ this directory anyway — from inside `my-notes`, run one command:
|
|
|
68
68
|
::: code-group
|
|
69
69
|
|
|
70
70
|
```bash [npm]
|
|
71
|
-
npx dirsql "SELECT COUNT(*) AS files FROM '
|
|
71
|
+
npx dirsql "SELECT COUNT(*) AS files FROM './**'"
|
|
72
72
|
```
|
|
73
73
|
|
|
74
74
|
```bash [PyPI]
|
|
75
|
-
uvx dirsql "SELECT COUNT(*) AS files FROM '
|
|
75
|
+
uvx dirsql "SELECT COUNT(*) AS files FROM './**'"
|
|
76
76
|
```
|
|
77
77
|
|
|
78
78
|
:::
|
|
@@ -91,10 +91,11 @@ files
|
|
|
91
91
|
Three files, three rows. That one command scanned the directory, handed
|
|
92
92
|
SQLite one row per file, ran your SQL, and printed the answer.
|
|
93
93
|
|
|
94
|
-
There is no named table here — you never declared one. `'
|
|
94
|
+
There is no named table here — you never declared one. `'./**'` is a
|
|
95
95
|
[path-table](./reference/path-tables.md): a quoted path written where a table
|
|
96
|
-
name goes. `'
|
|
97
|
-
in
|
|
96
|
+
name goes. `'./**'` means every file under the directory you ran the command
|
|
97
|
+
in, at any depth; `'./'` alone would list only the files directly inside it,
|
|
98
|
+
like `ls`. The path *is* the query.
|
|
98
99
|
|
|
99
100
|
## 3. Select some columns
|
|
100
101
|
|
|
@@ -105,11 +106,11 @@ pretty-print. Ask for two columns instead of a count:
|
|
|
105
106
|
::: code-group
|
|
106
107
|
|
|
107
108
|
```bash [npm]
|
|
108
|
-
npx dirsql query "SELECT path, size FROM '
|
|
109
|
+
npx dirsql query "SELECT path, size FROM './**' ORDER BY path" | jq
|
|
109
110
|
```
|
|
110
111
|
|
|
111
112
|
```bash [PyPI]
|
|
112
|
-
uvx dirsql query "SELECT path, size FROM '
|
|
113
|
+
uvx dirsql query "SELECT path, size FROM './**' ORDER BY path" | jq
|
|
113
114
|
```
|
|
114
115
|
|
|
115
116
|
:::
|
|
@@ -116,8 +116,8 @@ templates, with the trigger mistakes that fail silently, are in
|
|
|
116
116
|
|
|
117
117
|
## Going further
|
|
118
118
|
|
|
119
|
-
- The parser mechanics — placeholders, stdout protocol,
|
|
120
|
-
|
|
119
|
+
- The parser mechanics — placeholders, stdout protocol, failure semantics —
|
|
120
|
+
are the [`on-file` hook contract](../reference/hooks.md#on-file);
|
|
121
121
|
[Extract rows from file contents](./extract-from-contents.md) is the fuller
|
|
122
122
|
recipe.
|
|
123
123
|
- Your directory layout encodes data (authors, dates, IDs)? Split the path in
|
package/docs/howto/persist.md
CHANGED
|
@@ -4,8 +4,8 @@ By default the database is ephemeral: rebuilt from your files on every
|
|
|
4
4
|
startup and discarded on exit. The [`--persist [PATH]`](../reference/cli.md#dirsql-server)
|
|
5
5
|
flag keeps the SQLite index on disk instead, so a restart only re-parses
|
|
6
6
|
files that actually changed — the difference between seconds and
|
|
7
|
-
milliseconds on large trees, and between re-running and skipping expensive
|
|
8
|
-
[`on-file`](./extract-from-contents.md)
|
|
7
|
+
milliseconds on large trees, and between re-running and skipping an expensive
|
|
8
|
+
declared-table [`on-file`](./extract-from-contents.md) command.
|
|
9
9
|
|
|
10
10
|
Whether and where to cache is a machine-local operational choice — it
|
|
11
11
|
belongs to the command you run, not to the shared `.dirsql.toml`. That is
|
|
@@ -58,15 +58,11 @@ exactly what a non-persistent startup does.
|
|
|
58
58
|
A run that changes nothing writes nothing: the cache file is read and left
|
|
59
59
|
exactly as it was.
|
|
60
60
|
|
|
61
|
-
This covers
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
them parses afresh rather than serving rows the current command never
|
|
67
|
-
produced. A *stat* path-table caches nothing, because there is nothing to
|
|
68
|
-
save: its columns are the metadata the scan already collected, and `content`
|
|
69
|
-
is read live by design.
|
|
61
|
+
This covers declared tables, which keep their indexed rows. A
|
|
62
|
+
[path-table](../reference/path-tables.md) is not cached: a *stat* path-table
|
|
63
|
+
has nothing to save, since its columns are the metadata the scan already
|
|
64
|
+
collected and `content` is read live by design, and a path-table parsed with
|
|
65
|
+
`--on-file` runs its parser on every start.
|
|
70
66
|
|
|
71
67
|
Persistence is a startup-time optimization, not a change in meaning: the
|
|
72
68
|
database remains a derived view of your files, and queries return the same
|
|
@@ -67,5 +67,5 @@ why indexes belong to only one of them, are in
|
|
|
67
67
|
- Paths outside the root resolve too — `'/var/log/*.log'`, `'../notes'`,
|
|
68
68
|
`'~/notes/*.md'` — reporting absolute paths
|
|
69
69
|
([path-tables reference](../reference/path-tables.md#paths-outside-the-index-root)).
|
|
70
|
-
- `node_modules/` and `.git/` are skipped by default so a bare `'
|
|
71
|
-
drown in machinery ([skip rules](../reference/path-tables.md#skip-rules)).
|
|
70
|
+
- `node_modules/` and `.git/` are skipped by default so a bare `'./**'` does
|
|
71
|
+
not drown in machinery ([skip rules](../reference/path-tables.md#skip-rules)).
|
package/docs/reference/cli.md
CHANGED
|
@@ -88,7 +88,7 @@ front.
|
|
|
88
88
|
### Output format
|
|
89
89
|
|
|
90
90
|
Rows go where they are useful: a **table** when stdout is a terminal, the
|
|
91
|
-
**JSON array** when it is piped or redirected. `SELECT * FROM '
|
|
91
|
+
**JSON array** when it is piped or redirected. `SELECT * FROM './**'` in a
|
|
92
92
|
5000-file tree should not put a 5000-element JSON array in front of a person,
|
|
93
93
|
and `dirsql "…" | jq` should not have to parse a table.
|
|
94
94
|
|
|
@@ -223,11 +223,7 @@ every statement, so it is reported once and exits `1` before the first prompt.
|
|
|
223
223
|
| Code | Meaning |
|
|
224
224
|
|---|---|
|
|
225
225
|
| `0` | Clean EOF (Ctrl-D, `exit`, `quit`, or the end of a piped script) — **including when statements failed**. Matches interactive `sqlite3`; use [`dirsql query`](#dirsql-query) when a script needs a statement's exit status. |
|
|
226
|
-
| `1` | The index could not be built (a bad `-c`, an unresolvable `--on-file`), or stdin could not be read. Nothing was executed. |
|
|
227
|
-
|
|
228
|
-
`23` (partial scan) is not produced here: skipped files are reported before the
|
|
229
|
-
first prompt, and a session's exit code describes the session rather than one
|
|
230
|
-
scan.
|
|
226
|
+
| `1` | The index could not be built (a bad `-c`, an unresolvable `--on-file`, a failed `on-file` command), or stdin could not be read. Nothing was executed. |
|
|
231
227
|
|
|
232
228
|
## `dirsql server`
|
|
233
229
|
|
|
@@ -283,7 +279,7 @@ curl -s localhost:7117/query -H 'content-type: application/json' \
|
|
|
283
279
|
```
|
|
284
280
|
|
|
285
281
|
Earlier versions served an implicit table named `files` here. It is gone; a
|
|
286
|
-
`SELECT ... FROM files` with no config now fails and points at `FROM '
|
|
282
|
+
`SELECT ... FROM files` with no config now fails and points at `FROM './**'`.
|
|
287
283
|
|
|
288
284
|
Passing a config with `-c` fully overrules this default. A `-c` naming a file
|
|
289
285
|
that does not exist is an error (not a fallback to the default); a config that
|
|
@@ -403,8 +399,8 @@ takes, with the same `auto` default. A one-shot query is usually piped, so
|
|
|
403
399
|
## `dirsql init`
|
|
404
400
|
|
|
405
401
|
Writes a starter `.dirsql.toml` as a scaffold to edit. It does **not**
|
|
406
|
-
duplicate the zero-config floor (`SELECT * FROM '
|
|
407
|
-
with no config); instead it shows the **escalation**: one named `[[table]]`
|
|
402
|
+
duplicate the zero-config floor (`SELECT * FROM './**'` already lists every
|
|
403
|
+
file with no config); instead it shows the **escalation**: one named `[[table]]`
|
|
408
404
|
with a glob, a schema, and a real `on-file` hook that pulls structured rows
|
|
409
405
|
out of your files.
|
|
410
406
|
|
package/docs/reference/config.md
CHANGED
|
@@ -330,9 +330,9 @@ integral number → `INTEGER`, any other number → `REAL`; a string → `TEXT`;
|
|
|
330
330
|
nested array or object → its JSON text as `TEXT`.
|
|
331
331
|
|
|
332
332
|
A row's columns are exactly the keys the command emits, narrowed to the DDL;
|
|
333
|
-
dirsql merges nothing else in. Output that is not a JSON array of objects
|
|
334
|
-
|
|
335
|
-
|
|
333
|
+
dirsql merges nothing else in. Output that is not a JSON array of objects fails
|
|
334
|
+
the table, and a failed table fails the build (see
|
|
335
|
+
[failure semantics](./hooks.md#failure-semantics)).
|
|
336
336
|
|
|
337
337
|
## Composing multiple configs
|
|
338
338
|
|
|
@@ -396,7 +396,7 @@ SDKs raise/reject) when:
|
|
|
396
396
|
- A `[[table]]` entry omits `on-file` (or it is empty/whitespace). The error
|
|
397
397
|
names the offending glob and points at the fix:
|
|
398
398
|
|
|
399
|
-
> `[[table]] '**/*.md' has no on-file hook, so every row would be all-NULL. Add an `on-file` hook that emits the columns, or, for stat columns with no code, query the path directly: `FROM '
|
|
399
|
+
> `[[table]] '**/*.md' has no on-file hook, so every row would be all-NULL. Add an `on-file` hook that emits the columns, or, for stat columns with no code, query the path directly: `FROM './**'``
|
|
400
400
|
|
|
401
401
|
- A `[[dirsql.extension]]` entry omits `path`, or `path` is empty.
|
|
402
402
|
- A `[[dirsql.function]]` entry omits `name`, `command`, or `args` (or
|
package/docs/reference/hooks.md
CHANGED
|
@@ -69,8 +69,8 @@ on-file = "timeout 30 my-extractor"
|
|
|
69
69
|
```
|
|
70
70
|
|
|
71
71
|
When the wrapper kills an overrunning command, the run exits non-zero and
|
|
72
|
-
the ordinary [failure semantics](#failure-semantics) apply — the
|
|
73
|
-
|
|
72
|
+
the ordinary [failure semantics](#failure-semantics) apply — the table's
|
|
73
|
+
command failed, so the build fails.
|
|
74
74
|
|
|
75
75
|
::: warning Windows
|
|
76
76
|
Windows's built-in `timeout` command is a *sleep*, not a bound — it cannot
|
|
@@ -94,18 +94,17 @@ A hook run fails when the command:
|
|
|
94
94
|
- exits zero but prints no non-empty stdout line,
|
|
95
95
|
- or prints output that does not parse as a JSON array of row objects.
|
|
96
96
|
|
|
97
|
-
What a failure *means*:
|
|
98
|
-
|
|
99
|
-
The
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
`strict` counts as the same kind of failure.
|
|
97
|
+
What a failure *means*: the command ran once for the whole table, so its
|
|
98
|
+
failure is the table's, and a table that cannot be filled fails the build.
|
|
99
|
+
The error names the table and carries the command's exit status and stderr
|
|
100
|
+
tail; the CLI prints it and exits `1`. A row the table rejects under `strict`
|
|
101
|
+
counts as the same kind of failure.
|
|
103
102
|
|
|
104
103
|
## `on-file` contract
|
|
105
104
|
|
|
106
|
-
Runs once per file matched by the table's `glob`, at
|
|
107
|
-
every watched change. The command reads the
|
|
108
|
-
array of row objects; see [`[[table]]`](./config.md#table) for the
|
|
105
|
+
Runs once per table, over every file matched by the table's `glob`, at
|
|
106
|
+
initial scan and on every watched change. The command reads the files itself
|
|
107
|
+
and prints a JSON array of row objects; see [`[[table]]`](./config.md#table) for the
|
|
109
108
|
row-mapping rules.
|
|
110
109
|
|
|
111
110
|
The same command is attachable two ways, over the same contract: the
|
|
@@ -35,14 +35,16 @@ Two consequences follow directly:
|
|
|
35
35
|
A `./` path is relative to the **index root** — the directory dirsql is
|
|
36
36
|
indexing, not your shell's working directory.
|
|
37
37
|
|
|
38
|
-
**
|
|
39
|
-
|
|
38
|
+
**A directory name is one level, like `ls`.** Naming a directory lists the
|
|
39
|
+
files directly inside it and no deeper; `*` matches one level and `**` any
|
|
40
|
+
depth, as in the shell.
|
|
40
41
|
|
|
41
42
|
| You write | dirsql scans |
|
|
42
43
|
| --- | --- |
|
|
43
|
-
| `'./'` |
|
|
44
|
-
| `'./docs'` |
|
|
45
|
-
| `'./*'` |
|
|
44
|
+
| `'./'` | files directly inside the index root, and no deeper |
|
|
45
|
+
| `'./docs'`, `'./docs/'` | files directly inside `docs/` |
|
|
46
|
+
| `'./*'` | the same as `'./'` |
|
|
47
|
+
| `'./**'` | every file under the index root, recursively |
|
|
46
48
|
| `'./docs/*.md'` | markdown files directly inside `docs/` |
|
|
47
49
|
| `'./docs/**/*.md'` | markdown files at any depth under `docs/` |
|
|
48
50
|
| `'./notes/today.md'` | exactly that one file — one file is one row |
|
|
@@ -87,6 +89,7 @@ Three other prefixes resolve, with their usual shell meanings:
|
|
|
87
89
|
| `'../notes'` | relative to the index root's parent |
|
|
88
90
|
| `'~/notes/*.md'` | relative to your home directory |
|
|
89
91
|
|
|
92
|
+
A directory named this way is one level too; `'../notes/**'` descends.
|
|
90
93
|
`..` is folded out textually, not followed through symlinks, so the directory
|
|
91
94
|
scanned is a function of the string you wrote.
|
|
92
95
|
|
|
@@ -156,18 +159,14 @@ placeholder, same timeout. Its output *is* the table:
|
|
|
156
159
|
across the emitted rows. The stat columns (`path`, `size`, …) are **not**
|
|
157
160
|
reachable on a parsed path-table — a parser that wants the path emits it (it
|
|
158
161
|
has the paths). The two modes stay cleanly separate.
|
|
159
|
-
- **
|
|
160
|
-
exit, timeout, or no output) or whose output is not a
|
|
161
|
-
|
|
162
|
-
|
|
162
|
+
- **A parser failure is the table's failure.** A run that fails (spawn,
|
|
163
|
+
non-zero exit, a `timeout(1)` kill, or no output) or whose output is not a
|
|
164
|
+
JSON array of rows fails the query with an error naming the table; there is
|
|
165
|
+
no partial table.
|
|
163
166
|
- **The skip rules still apply.** A parsed scan honors the same `node_modules`
|
|
164
167
|
/`.git`/`ignore` rules a stat scan does (see below).
|
|
165
|
-
-
|
|
166
|
-
[persistent cache](/howto/persist)
|
|
167
|
-
against its stat metadata, so a later run over an unchanged tree serves the
|
|
168
|
-
rows from the cache and spawns no process. Change the file, the glob, the
|
|
169
|
-
parser command, or the dirsql version and that file (or that whole table) is
|
|
170
|
-
parsed again.
|
|
168
|
+
- **The parser runs on every start.** A parsed path-table is not kept in the
|
|
169
|
+
[persistent cache](/howto/persist); declared tables are.
|
|
171
170
|
|
|
172
171
|
`--on-file` applies to **every** path-table in the query and may be given **at
|
|
173
172
|
most once**. For different parsers per file set, define named tables in a
|
|
@@ -216,7 +215,7 @@ A path-table scan applies the same [`ignore`](/reference/config) patterns your
|
|
|
216
215
|
declared tables use — matched against root-relative paths under the same
|
|
217
216
|
[glob rule](/reference/config#glob-rule) as the path itself, `*` one level and
|
|
218
217
|
`**` any depth — plus two built-in defaults so a zero-config
|
|
219
|
-
`SELECT * FROM '
|
|
218
|
+
`SELECT * FROM './**'` does not drown in machinery:
|
|
220
219
|
|
|
221
220
|
- `**/node_modules/**`
|
|
222
221
|
- `**/.git/**`
|
|
@@ -246,7 +245,7 @@ Skip rules are judged from the directory the scan starts in, so pointing at a
|
|
|
246
245
|
skipped directory — built-in or gitignored — still scans it:
|
|
247
246
|
|
|
248
247
|
```sql
|
|
249
|
-
SELECT path FROM '
|
|
248
|
+
SELECT path FROM './**'; -- no node_modules rows
|
|
250
249
|
SELECT path FROM './node_modules/*/package.json'; -- scans it anyway
|
|
251
250
|
SELECT path FROM './dist'; -- scans dist/ even when gitignored
|
|
252
251
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dirsql",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.69",
|
|
4
4
|
"description": "Ephemeral SQL index over a local directory",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "https://github.com/thekevinscott/dirsql",
|
|
@@ -221,10 +221,10 @@
|
|
|
221
221
|
]
|
|
222
222
|
},
|
|
223
223
|
"optionalDependencies": {
|
|
224
|
-
"@dirsql/lib-linux-x64-gnu": "0.4.
|
|
225
|
-
"@dirsql/lib-linux-arm64-gnu": "0.4.
|
|
226
|
-
"@dirsql/lib-darwin-x64": "0.4.
|
|
227
|
-
"@dirsql/lib-darwin-arm64": "0.4.
|
|
228
|
-
"@dirsql/lib-win32-x64-msvc": "0.4.
|
|
224
|
+
"@dirsql/lib-linux-x64-gnu": "0.4.69",
|
|
225
|
+
"@dirsql/lib-linux-arm64-gnu": "0.4.69",
|
|
226
|
+
"@dirsql/lib-darwin-x64": "0.4.69",
|
|
227
|
+
"@dirsql/lib-darwin-arm64": "0.4.69",
|
|
228
|
+
"@dirsql/lib-win32-x64-msvc": "0.4.69"
|
|
229
229
|
}
|
|
230
230
|
}
|