API Reference
DirSQL
Import
from dirsql import DirSQLuse dirsql::DirSQL;import { DirSQL } from 'dirsql';Constructor
DirSQL(
root: str | None = None,
*,
tables: list[Table] | None = None,
ignore: list[str] | None = None,
config: str | None = None,
extensions: list[dict] | None = None, # [{ "path": str, "entrypoint"?: str }]
)DirSQL::builder()
.root(root) // optional
.tables(tables) // optional; append with .table(t)
.ignore(patterns) // optional
.config(config_toml_path) // optional
.extensions(extensions) // optional; Extension { path, entrypoint }
.build() // -> Result<DirSQL>new DirSQL(configPath: string)
// or
new DirSQL({
root?: string,
tables?: TableDef[],
ignore?: string[],
config?: string,
})Creates an in-memory SQLite index over the given directory. At least one of root or config must be supplied.
When both root and config are supplied -- or when config declares [dirsql].root -- the explicit root wins and a warning is emitted on stderr. A [dirsql].root declared in the config file is resolved relative to the config file's parent directory.
In Python, the constructor starts scanning in a background thread and returns immediately. Call await db.ready() before querying. In Rust, .build() scans synchronously; use .build_async() (via AsyncDirSQL) for the tokio-driven equivalent. In TypeScript, scanning starts immediately and db.ready resolves when the scan finishes.
Parameters:
root-- Path to the directory to index. Optional ifconfigis supplied.tables-- List ofTabledefinitions. Each defines a SQLite table, a glob pattern, and an extract function.ignore-- Optional list of glob patterns. Files matching any ignore pattern are skipped regardless of table globs.config-- Optional path to a.dirsql.tomlconfig file. Its[[table]]entries are appended to any programmatictables; its[dirsql].ignorepatterns are appended to any explicitignore; its optional[dirsql].rootsupplies the root directory whenrootis not passed explicitly; its[[dirsql.extension]]entries are appended to any programmaticextensions.extensions-- Optional SQLite extensions to load onto the connection at startup, before any table DDL (enable → load → disable, so the SQLload_extension()function is never left exposed). Each entry pairs a shared-librarypathwith an optionalentrypointinit-symbol override (Python:{ "path", "entrypoint"? }dicts; Rust:Extension { path, entrypoint }). Programmatic entries load first, then any[[dirsql.extension]]fromconfig. Available in the Python and Rust SDKs; the TypeScript constructor parameter is tracked in #230. See Loading extensions.
Methods
ready
await db.ready() -> Nonedb.ready().await -> Result<()>await db.ready // awaitable propertyWait for the initial scan to complete. Re-raises any exception from the scan. Safe to call multiple times.
query
await db.query(sql: str) -> list[dict]db.query(sql: &str) -> Result<Vec<HashMap<String, Value>>>await db.query(sql: string): Promise<Record<string, unknown>[]>Execute a SQL query against the in-memory database. Returns results keyed by column name. Internal tracking columns (_dirsql_file_path, _dirsql_row_index) are excluded from results.
watch
async for event in db.watch(): # AsyncIterator[RowEvent]
...let mut stream = db.watch(); // impl Stream<Item = RowEvent>
while let Some(event) = stream.next().await { ... }for await (const event of db.watch()) { // AsyncIterable<RowEvent>
...
}Returns an async iterable of RowEvent objects. The file watcher starts automatically on first iteration. The iterator never terminates on its own.
serialization
vars(db) -> dictdb.config() -> DirSQLConfigJSON.stringify(db) // via db.toJSON()Returns the resolved construction state as a JSON-compatible value with fields root, tables, ignore, persist, persist_path (camelCase persistPath in TypeScript). Each table is { ddl, glob, strict }. The Python and Rust snapshots also include extensions -- an array of { path, entrypoint } (empty when none are configured); the TypeScript toJSON snapshot will gain it with #230. Excludes the original config path (already merged into root / tables / ignore), per-table extract, and per-table name. Available immediately after construction in Python and TypeScript; Rust's sync build() returns a ready instance.
Table
Import
from dirsql import Tableuse dirsql::Table;import { Table } from 'dirsql';Constructor
Table(*, ddl: str, glob: str, extract: Callable[[str], list[dict]], strict: bool = False)// Row = HashMap<String, Value>
Table::new(ddl: &str, glob: &str, extract: fn(&str) -> Vec<HashMap<String, Value>>)new Table({ ddl: string, glob: string, extract: (path: string) => Record<string, unknown>[] })Defines a mapping from files to SQLite table rows.
Parameters:
ddl-- ACREATE TABLEstatement. The table name is parsed from this DDL.glob-- A glob pattern matched against file paths relative to the root directory.extract-- A callable(path) -> list[dict]. Receives the path of the matched file -- relative to the scan root, or absolute whenrootis absolute.dirsqldoes not read file contents; a callback that needs the file body readspathitself. Returns a list of dicts/maps mapping column names to values. Return an empty list to skip a file.strict-- Optional (defaultFalse). Controls row/schema validation. In the default relaxed mode, extra row keys are dropped and missing columns becomeNULL. WhenTrue, every row key must be a valid column identifier and any extra or missing key raises an error. Surfaced in serialization above as part of each table's{ ddl, glob, strict }.
Attributes:
ddl-- The DDL string (read-only).glob-- The glob pattern (read-only).
RowEvent
Import
from dirsql import RowEventuse dirsql::RowEvent;import type { RowEvent } from 'dirsql';Emitted by the watch stream. Represents a change to a row in the database caused by a filesystem event.
Attributes:
| Attribute | Python | Rust | TypeScript |
|---|---|---|---|
| Table name | table: str | table: String | table: string |
| Action | action: str | action: Action | action: string |
| Current/new row | row: dict | None | row: Option<HashMap> | row?: Record |
| Previous row | old_row: dict | None | old_row: Option<HashMap> | oldRow?: Record |
| Error message | error: str | None | error: Option<String> | error?: string |
| File path | file_path: str | None | file_path: Option<String> | filePath?: string |
Action values: "insert", "update", "delete", "error".