Skip to content

API Reference

Online: https://thekevinscott.github.io/dirsql/api/

DirSQL

Import

python
from dirsql import DirSQL
rust
use dirsql::DirSQL;
typescript
import { DirSQL } from 'dirsql';

Constructor

python
DirSQL(
    root: str | None = None,
    *,
    tables: list[Table] | None = None,
    ignore: list[str] | None = None,
    config: str | None = None,
)
rust
DirSQL::builder()
    .root(root)                 // optional
    .tables(tables)             // optional; append with .table(t)
    .ignore(patterns)           // optional
    .config(config_toml_path)   // optional
    .build()                    // -> Result<DirSQL>
typescript
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 if config is supplied.
  • tables -- List of Table definitions. 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.toml config file. Its [[table]] entries are appended to any programmatic tables; its [dirsql].ignore patterns are appended to any explicit ignore; its optional [dirsql].root supplies the root directory when root is not passed explicitly.

Methods

ready

python
await db.ready() -> None
rust
db.ready().await -> Result<()>
typescript
await db.ready  // awaitable property

Wait for the initial scan to complete. Re-raises any exception from the scan. Safe to call multiple times.

query

python
await db.query(sql: str) -> list[dict]
rust
db.query(sql: &str) -> Result<Vec<HashMap<String, Value>>>
typescript
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

python
async for event in db.watch():  # AsyncIterator[RowEvent]
    ...
rust
let mut stream = db.watch();  // impl Stream<Item = RowEvent>
while let Some(event) = stream.next().await { ... }
typescript
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

python
vars(db) -> dict
rust
db.config() -> DirSQLConfig
typescript
JSON.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 }. 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

python
from dirsql import Table
rust
use dirsql::Table;
typescript
import { Table } from 'dirsql';

Constructor

python
Table(*, ddl: str, glob: str, extract: Callable[[str], list[dict]])
rust
Table::new(ddl: &str, glob: &str, extract: fn(&str) -> Vec<Value>)
typescript
new Table({ ddl: string, glob: string, extract: (path: string) => Record<string, unknown>[] })

Defines a mapping from files to SQLite table rows.

Parameters:

  • ddl -- A CREATE TABLE statement. 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 absolute filesystem path of the matched file. dirsql does not read file contents; a callback that needs the file body reads path itself. Returns a list of dicts/maps mapping column names to values. Return an empty list to skip a file.

Attributes:

  • ddl -- The DDL string (read-only).
  • glob -- The glob pattern (read-only).

RowEvent

Import

python
from dirsql import RowEvent
rust
use dirsql::RowEvent;
typescript
import { RowEvent } from 'dirsql';

Emitted by the watch stream. Represents a change to a row in the database caused by a filesystem event.

Attributes:

AttributePythonRustTypeScript
Table nametable: strtable: Stringtable: string
Actionaction: straction: Actionaction: string
Current/new rowrow: dict | Nonerow: Option<HashMap>row?: Record
Previous rowold_row: dict | Noneold_row: Option<HashMap>oldRow?: Record
Error messageerror: str | Noneerror: Option<String>error?: string
File pathfile_path: str | Nonefile_path: Option<String>filePath?: string

Action values: "insert", "update", "delete", "error".

Released under the MIT License.