dirsql 0.4.22 → 0.4.23
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/dist/core.d.ts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/table.d.ts +7 -1
- package/dist/table.js +2 -1
- package/docs/getting-started.md +1 -0
- package/docs/howto/columns-from-paths.md +1 -0
- package/docs/howto/define-tables.md +1 -0
- package/docs/howto/embed.md +3 -0
- package/docs/howto/extract-from-contents.md +2 -0
- package/docs/howto/parse-files-into-columns.md +1 -0
- package/docs/howto/react-to-changes.md +1 -0
- package/docs/howto/skip-files.md +1 -0
- package/docs/howto/write-a-plugin.md +1 -0
- package/docs/index.md +3 -0
- package/docs/reference/config.md +16 -2
- package/docs/reference/sdk.md +11 -8
- package/package.json +6 -6
- package/dist/parse-table-name.d.ts +0 -8
- package/dist/parse-table-name.js +0 -15
package/dist/core.d.ts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/table.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
/** Definition of a SQL-indexed table backed by files on disk. */
|
|
2
2
|
export interface TableDef {
|
|
3
|
+
/**
|
|
4
|
+
* The table's SQL name, declared rather than derived from `ddl`. The `ddl`
|
|
5
|
+
* must create a table by this name; a mismatch is a load-time error.
|
|
6
|
+
*/
|
|
7
|
+
name: string;
|
|
3
8
|
/** SQL DDL statement, e.g. `CREATE TABLE users (name TEXT, age INTEGER)`. */
|
|
4
9
|
ddl: string;
|
|
5
10
|
/** Glob pattern (relative to the DirSQL root) for files backing this table. */
|
|
@@ -16,7 +21,7 @@ export interface TableDef {
|
|
|
16
21
|
}
|
|
17
22
|
/**
|
|
18
23
|
* Thin class wrapper around {@link TableDef} for parity with the Python
|
|
19
|
-
* `Table(ddl=..., glob=..., on_file=...)` and Rust `Table::new(...)`
|
|
24
|
+
* `Table(name=..., ddl=..., glob=..., on_file=...)` and Rust `Table::new(...)`
|
|
20
25
|
* constructors. `new Table({...})` is structurally identical to a plain
|
|
21
26
|
* object literal satisfying `TableDef` — anything accepting `TableDef[]`
|
|
22
27
|
* (e.g. {@link DirSQL}'s `tables` option) takes either form.
|
|
@@ -27,6 +32,7 @@ export interface TableDef {
|
|
|
27
32
|
* `strict` to `undefined` under `useDefineForClassFields`.
|
|
28
33
|
*/
|
|
29
34
|
export declare class Table implements TableDef {
|
|
35
|
+
readonly name: string;
|
|
30
36
|
readonly ddl: string;
|
|
31
37
|
readonly glob: string;
|
|
32
38
|
readonly onFile: (filePath: string) => Record<string, unknown>[];
|
package/dist/table.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// unit test instead of an exemption (#239).
|
|
5
5
|
/**
|
|
6
6
|
* Thin class wrapper around {@link TableDef} for parity with the Python
|
|
7
|
-
* `Table(ddl=..., glob=..., on_file=...)` and Rust `Table::new(...)`
|
|
7
|
+
* `Table(name=..., ddl=..., glob=..., on_file=...)` and Rust `Table::new(...)`
|
|
8
8
|
* constructors. `new Table({...})` is structurally identical to a plain
|
|
9
9
|
* object literal satisfying `TableDef` — anything accepting `TableDef[]`
|
|
10
10
|
* (e.g. {@link DirSQL}'s `tables` option) takes either form.
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
export class Table {
|
|
18
18
|
constructor(def) {
|
|
19
|
+
this.name = def.name;
|
|
19
20
|
this.ddl = def.ddl;
|
|
20
21
|
this.glob = def.glob;
|
|
21
22
|
this.onFile = def.onFile;
|
package/docs/getting-started.md
CHANGED
package/docs/howto/embed.md
CHANGED
|
@@ -60,6 +60,7 @@ async def main() -> None:
|
|
|
60
60
|
"./comments-root",
|
|
61
61
|
tables=[
|
|
62
62
|
Table(
|
|
63
|
+
name="comments",
|
|
63
64
|
ddl="CREATE TABLE comments (thread TEXT, author TEXT, body TEXT)",
|
|
64
65
|
glob="comments/*/*.json",
|
|
65
66
|
on_file=on_file,
|
|
@@ -83,6 +84,7 @@ const db = new DirSQL({
|
|
|
83
84
|
root: "./comments-root",
|
|
84
85
|
tables: [
|
|
85
86
|
{
|
|
87
|
+
name: "comments",
|
|
86
88
|
ddl: "CREATE TABLE comments (thread TEXT, author TEXT, body TEXT)",
|
|
87
89
|
glob: "comments/*/*.json",
|
|
88
90
|
onFile: (path) => [
|
|
@@ -129,6 +131,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
|
129
131
|
let db = DirSQL::builder()
|
|
130
132
|
.root("./comments-root")
|
|
131
133
|
.table(Table::new(
|
|
134
|
+
"comments",
|
|
132
135
|
"CREATE TABLE comments (thread TEXT, author TEXT, body TEXT)",
|
|
133
136
|
"comments/*/*.json",
|
|
134
137
|
on_file,
|
|
@@ -18,6 +18,7 @@ stdout works. With [`jq`](https://jqlang.org/):
|
|
|
18
18
|
|
|
19
19
|
```toml
|
|
20
20
|
[[table]]
|
|
21
|
+
name = "books"
|
|
21
22
|
ddl = "CREATE TABLE books (title TEXT, author TEXT, year INTEGER)"
|
|
22
23
|
glob = "books/*.json"
|
|
23
24
|
on-file = "jq -c '[{title, author, year}]' {path}"
|
|
@@ -53,6 +54,7 @@ row per line, slurp it:
|
|
|
53
54
|
|
|
54
55
|
```toml
|
|
55
56
|
[[table]]
|
|
57
|
+
name = "events"
|
|
56
58
|
ddl = "CREATE TABLE events (event TEXT, user TEXT)"
|
|
57
59
|
glob = "logs/*.jsonl"
|
|
58
60
|
on-file = "jq -c -s '.' {path}"
|
package/docs/howto/skip-files.md
CHANGED
|
@@ -22,6 +22,7 @@ Exclude the noise in `.dirsql.toml`:
|
|
|
22
22
|
ignore = ["notes/drafts/**", "**/*.tmp"]
|
|
23
23
|
|
|
24
24
|
[[table]]
|
|
25
|
+
name = "notes"
|
|
25
26
|
ddl = "CREATE TABLE notes (basename TEXT)"
|
|
26
27
|
glob = "notes/**/*"
|
|
27
28
|
on-file = '''sh -c 'printf "[{\"basename\":\"%s\"}]" "${1##*/}"' sh {path}'''
|
|
@@ -108,6 +108,7 @@ path = "sqlite_vec"
|
|
|
108
108
|
entrypoint = "sqlite3_vec_init"
|
|
109
109
|
|
|
110
110
|
[[table]]
|
|
111
|
+
name = "notes"
|
|
111
112
|
ddl = "CREATE TABLE notes (path TEXT, text TEXT, embedding TEXT)"
|
|
112
113
|
glob = "notes/*.md"
|
|
113
114
|
on-file = "uv run --with model2vec python embed.py {path} {root}"
|
package/docs/index.md
CHANGED
|
@@ -34,6 +34,7 @@ db = DirSQL(
|
|
|
34
34
|
"./my-project",
|
|
35
35
|
tables=[
|
|
36
36
|
Table(
|
|
37
|
+
name="records",
|
|
37
38
|
ddl="CREATE TABLE records (name TEXT, size INTEGER, type TEXT)",
|
|
38
39
|
glob="data/*.json",
|
|
39
40
|
on_file=lambda path: [json.loads(open(path, encoding="utf-8").read())],
|
|
@@ -52,6 +53,7 @@ let db = DirSQL::new(
|
|
|
52
53
|
"./my-project",
|
|
53
54
|
vec![
|
|
54
55
|
Table::new(
|
|
56
|
+
"records",
|
|
55
57
|
"CREATE TABLE records (name TEXT, size INTEGER, type TEXT)",
|
|
56
58
|
"data/*.json",
|
|
57
59
|
|path| vec![serde_json::from_str(&std::fs::read_to_string(path).unwrap()).unwrap()],
|
|
@@ -70,6 +72,7 @@ const db = new DirSQL({
|
|
|
70
72
|
root: './my-project',
|
|
71
73
|
tables: [
|
|
72
74
|
new Table({
|
|
75
|
+
name: 'records',
|
|
73
76
|
ddl: 'CREATE TABLE records (name TEXT, size INTEGER, type TEXT)',
|
|
74
77
|
glob: 'data/*.json',
|
|
75
78
|
onFile: (path) => [JSON.parse(readFileSync(path, 'utf8'))],
|
package/docs/reference/config.md
CHANGED
|
@@ -166,7 +166,8 @@ what its required `on-file` command emits — dirsql injects nothing (see
|
|
|
166
166
|
|
|
167
167
|
| Key | Required | Description |
|
|
168
168
|
|---|---|---|
|
|
169
|
-
| `
|
|
169
|
+
| `name` | yes | The table's SQL name — the name you query it by. Declared, never derived from `ddl`: dirsql does not read the DDL text. The `ddl` must create a table by this name; if it doesn't, loading fails. |
|
|
170
|
+
| `ddl` | yes | A SQLite `CREATE TABLE` statement, run verbatim. Only the columns declared here are kept; keys the `on-file` command emits that are not declared are dropped. |
|
|
170
171
|
| `glob` | yes | Glob pattern matched against root-relative paths. Every table whose glob matches a file receives that file's rows — a file can populate multiple tables. A `{name}` segment is rewritten to `*` (it matches one path segment but captures nothing). |
|
|
171
172
|
| `on-file` | **yes** | A command run once per matched file; its stdout (a JSON array of row objects) becomes the file's rows. Must be non-empty. A `[[table]]` with no `on-file` is a load error (see [parse errors](#parse-errors)). See [Command hooks](./hooks.md#on-file). |
|
|
172
173
|
| `strict` | no (default `false`) | When `true`, rows whose keys do not exactly match the declared columns are rejected with an error: extra keys error, and every declared column must be supplied by the `on-file` output. When `false`, extra keys are dropped and missing columns become `NULL`. |
|
|
@@ -180,11 +181,13 @@ instead of declaring a table.
|
|
|
180
181
|
|
|
181
182
|
```toml
|
|
182
183
|
[[table]]
|
|
184
|
+
name = "comments"
|
|
183
185
|
ddl = "CREATE TABLE comments (path TEXT, author TEXT, body TEXT)"
|
|
184
186
|
glob = "_comments/*/*.jsonl"
|
|
185
187
|
on-file = "jq -c -s '.' {path}"
|
|
186
188
|
|
|
187
189
|
[[table]]
|
|
190
|
+
name = "papers"
|
|
188
191
|
ddl = "CREATE TABLE papers (paper_id TEXT, title TEXT)"
|
|
189
192
|
glob = "**/meta.json"
|
|
190
193
|
on-file = "uv run python extract_papers.py {path}"
|
|
@@ -241,7 +244,16 @@ SDKs raise/reject) when:
|
|
|
241
244
|
- The TOML is malformed.
|
|
242
245
|
- Any table contains an unknown key (top level, `[dirsql]`, `[[table]]`, or
|
|
243
246
|
`[[dirsql.extension]]`). The error names the offending key.
|
|
244
|
-
- A `[[table]]` entry omits `ddl` or `
|
|
247
|
+
- A `[[table]]` entry omits `name`, `ddl`, or `glob` (or `name` is
|
|
248
|
+
empty/whitespace).
|
|
249
|
+
- A `[[table]]` entry's `ddl` runs but creates no table by its `name`. The
|
|
250
|
+
error carries the entry's name and points at the fix:
|
|
251
|
+
|
|
252
|
+
> `table 'messages': its `ddl` ran but created no table called 'messages'. Set `name` to the table the `ddl` creates.`
|
|
253
|
+
|
|
254
|
+
dirsql asks SQLite's catalog rather than interpreting the DDL, so quoted
|
|
255
|
+
(`CREATE TABLE "messages"`), schema-qualified (`main.messages`) and
|
|
256
|
+
`IF NOT EXISTS` forms all match a plain `name = "messages"`.
|
|
245
257
|
- A `[[table]]` entry omits `on-file` (or it is empty/whitespace). The error
|
|
246
258
|
names the offending glob and points at the fix:
|
|
247
259
|
|
|
@@ -275,11 +287,13 @@ deterministic = true
|
|
|
275
287
|
timeout = "600s"
|
|
276
288
|
|
|
277
289
|
[[table]]
|
|
290
|
+
name = "comments"
|
|
278
291
|
ddl = "CREATE TABLE comments (author TEXT, body TEXT)"
|
|
279
292
|
glob = "_comments/*/*.jsonl"
|
|
280
293
|
on-file = "jq -c -s '.' {path}"
|
|
281
294
|
|
|
282
295
|
[[table]]
|
|
296
|
+
name = "documents"
|
|
283
297
|
ddl = "CREATE TABLE documents (title TEXT, summary TEXT)"
|
|
284
298
|
glob = "**/index.md"
|
|
285
299
|
on-file = "uv run python extract_doc.py {path}"
|
package/docs/reference/sdk.md
CHANGED
|
@@ -317,27 +317,30 @@ rather than waiting — an intentional, language-idiomatic difference.
|
|
|
317
317
|
::: code-group
|
|
318
318
|
|
|
319
319
|
```python [Python]
|
|
320
|
-
Table(*, ddl: str, glob: str, on_file: Callable[[str], list[dict]], strict: bool = False)
|
|
320
|
+
Table(*, name: str, ddl: str, glob: str, on_file: Callable[[str], list[dict]], strict: bool = False)
|
|
321
321
|
```
|
|
322
322
|
|
|
323
323
|
```typescript [TypeScript]
|
|
324
|
-
new Table({ ddl, glob, onFile, strict? })
|
|
324
|
+
new Table({ name, ddl, glob, onFile, strict? })
|
|
325
325
|
// or a plain object — TableDef and Table are interchangeable:
|
|
326
|
-
{ ddl: string, glob: string, onFile: (path: string) => Record<string, unknown>[], strict?: boolean }
|
|
326
|
+
{ name: string, ddl: string, glob: string, onFile: (path: string) => Record<string, unknown>[], strict?: boolean }
|
|
327
327
|
```
|
|
328
328
|
|
|
329
329
|
```rust [Rust]
|
|
330
|
-
Table::new(ddl, glob, on_file) // on_file: Fn(&str) -> Vec<Row>, infallible
|
|
331
|
-
Table::try_new(ddl, glob, on_file) // on_file: Fn(&str) -> Result<Vec<Row>, _>
|
|
332
|
-
Table::strict(ddl, glob, on_file) // Table::new with strict = true
|
|
330
|
+
Table::new(name, ddl, glob, on_file) // on_file: Fn(&str) -> Vec<Row>, infallible
|
|
331
|
+
Table::try_new(name, ddl, glob, on_file) // on_file: Fn(&str) -> Result<Vec<Row>, _>
|
|
332
|
+
Table::strict(name, ddl, glob, on_file) // Table::new with strict = true
|
|
333
333
|
```
|
|
334
334
|
|
|
335
335
|
:::
|
|
336
336
|
|
|
337
337
|
Maps files to table rows.
|
|
338
338
|
|
|
339
|
-
- `
|
|
340
|
-
|
|
339
|
+
- `name` — The table's SQL name, declared rather than derived from `ddl`.
|
|
340
|
+
Must be unique across all tables. Building fails if the `ddl` creates no
|
|
341
|
+
table by this name (checked against SQLite's catalog, before any file is
|
|
342
|
+
indexed).
|
|
343
|
+
- `ddl` — A SQLite `CREATE TABLE` statement, run verbatim.
|
|
341
344
|
- `glob` — Glob pattern matched against root-relative paths. Every table whose
|
|
342
345
|
glob matches a file receives that file's rows — a file can populate multiple
|
|
343
346
|
tables. A `{name}` segment is rewritten to `*` (it matches one path segment
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dirsql",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.23",
|
|
4
4
|
"description": "Ephemeral SQL index over a local directory",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "https://github.com/thekevinscott/dirsql",
|
|
@@ -213,10 +213,10 @@
|
|
|
213
213
|
]
|
|
214
214
|
},
|
|
215
215
|
"optionalDependencies": {
|
|
216
|
-
"@dirsql/lib-linux-x64-gnu": "0.4.
|
|
217
|
-
"@dirsql/lib-linux-arm64-gnu": "0.4.
|
|
218
|
-
"@dirsql/lib-darwin-x64": "0.4.
|
|
219
|
-
"@dirsql/lib-darwin-arm64": "0.4.
|
|
220
|
-
"@dirsql/lib-win32-x64-msvc": "0.4.
|
|
216
|
+
"@dirsql/lib-linux-x64-gnu": "0.4.23",
|
|
217
|
+
"@dirsql/lib-linux-arm64-gnu": "0.4.23",
|
|
218
|
+
"@dirsql/lib-darwin-x64": "0.4.23",
|
|
219
|
+
"@dirsql/lib-darwin-arm64": "0.4.23",
|
|
220
|
+
"@dirsql/lib-win32-x64-msvc": "0.4.23"
|
|
221
221
|
}
|
|
222
222
|
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Parse the table name out of a `CREATE TABLE <name> (...)` DDL.
|
|
3
|
-
*
|
|
4
|
-
* Returns `null` for a DDL the parser doesn't recognize. Backed by the
|
|
5
|
-
* core Rust implementation (`dirsql::db::parse_table_name`) so the JS
|
|
6
|
-
* SDK and the orchestrator agree on table-name resolution.
|
|
7
|
-
*/
|
|
8
|
-
export declare function parseTableName(ddl: string): string | null;
|
package/dist/parse-table-name.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
// `parseTableName` — table-name resolution delegated to the Rust core.
|
|
2
|
-
//
|
|
3
|
-
// Split out of the public barrel (`index.ts`) so it carries a colocated
|
|
4
|
-
// unit test instead of an exemption (#239).
|
|
5
|
-
import { getCore } from "./core.js";
|
|
6
|
-
/**
|
|
7
|
-
* Parse the table name out of a `CREATE TABLE <name> (...)` DDL.
|
|
8
|
-
*
|
|
9
|
-
* Returns `null` for a DDL the parser doesn't recognize. Backed by the
|
|
10
|
-
* core Rust implementation (`dirsql::db::parse_table_name`) so the JS
|
|
11
|
-
* SDK and the orchestrator agree on table-name resolution.
|
|
12
|
-
*/
|
|
13
|
-
export function parseTableName(ddl) {
|
|
14
|
-
return getCore().parseTableName(ddl);
|
|
15
|
-
}
|