feat(engines): the sqlite kv engine — the default engine, first SQL-backed (wave 3)
Implements the sqlite kv-tier engine per ADR-003/007/010 §1 behind feature `sqlite` (default-on): the B5 row shape (key BLOB PK / value BLOB / size INTEGER NOT NULL), INSERT OR IGNORE CAS first-writer-wins on both put forms, the EXISTS has probe, the materializing cursor body with len() from the size column, the degenerate in-memory stage with both hygiene forms, the indexed-column size probe (plan-tested), the no-tables-yet virgin-store read tolerance (tested against a tableless database file), WAL + synchronous=NORMAL verified at open, prepare_cached discipline, and every rusqlite operation in spawn_blocking under the recorded single-connection posture. Task: tasks/engine-sqlite.md (status: completed). The engine-state window family and store construction remain in their own tasks. Verification: - cargo test — 58 pass (11 new sqlite in-module tests) - cargo clippy --all-targets -- -D warnings — clean - cargo fmt --check — clean - cargo check --no-default-features — green
This commit is contained in:
1 parent
758ccfb359
commit
908fb5d2dd
2 files changed
+939
-5
No files matched your search
+49
-3
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: engine-sqlite
|
||||
name: sqlite kv engine — the default engine
|
||||
status: pending
|
||||
status: completed
|
||||
depends_on: []
|
||||
scope: narrow
|
||||
risk: medium
|
||||
@@ -111,8 +111,54 @@ in-module unit tests only.
|
||||
|
||||
## Notes
|
||||
|
||||
> To be filled by implementation agent
|
||||
Recorded design points landed in the module doc (`src/sqlite.rs`):
|
||||
|
||||
- **Schema-creation timing:** the constructor runs `CREATE TABLE IF
|
||||
NOT EXISTS` at open. The virgin-store tolerance itself is an
|
||||
engine-level read-path property independent of that timing —
|
||||
unit-tested against a genuinely tableless database file via a
|
||||
`#[cfg(test)]` `new_tableless` constructor. The tolerance is
|
||||
deliberately read-only: a write against a tableless database surfaces
|
||||
the engine error rather than silently creating schema (tested).
|
||||
- **WAL engagement is verified at open, not assumed:** the constructor
|
||||
probes `PRAGMA journal_mode = WAL` and errors when WAL cannot be
|
||||
engaged (in-memory databases included — tested). The pragma posture
|
||||
(WAL persistent + synchronous NORMAL per-connection) is asserted in
|
||||
the pragma test on the backend's own single connection.
|
||||
- **Error mapping:** the no-tables-yet discriminant is a stringly check
|
||||
on rusqlite's Display ("no such table") — stringly by nature, the
|
||||
stable surface sqlite itself guarantees. `delete` maps it to
|
||||
`Error::Missing` (rows-affected discipline holds for the virgin
|
||||
form); `put` propagates it as `Error::Io`.
|
||||
- **size metadata-only proof:** exactness is asserted for large/absent
|
||||
keys and `EXPLAIN QUERY PLAN` asserts the probe searches the key's
|
||||
index (`USING INDEX`) — never a scan or value load.
|
||||
- Connection posture: one connection behind a short-held
|
||||
`parking_lot::Mutex`, shared with staging handouts via `Arc` (a
|
||||
staging commit must see the same table); the engine `Clone`s. All
|
||||
rusqlite I/O in `spawn_blocking` via a local `blocking` helper (the
|
||||
local.rs pattern); cursor/staging read bodies are in-memory after
|
||||
materialization and need no blocking.
|
||||
- `EXPLAIN QUERY PLAN` calls must bind the `?1` parameter even though
|
||||
they do not execute — sqlite enforces the bind count at step time.
|
||||
|
||||
## Summary
|
||||
|
||||
> To be filled on completion
|
||||
The `sqlite` kv engine shipped complete behind feature `sqlite`
|
||||
(default-on): the row shape `blobs (key BLOB PRIMARY KEY, value BLOB,
|
||||
size INTEGER NOT NULL)` (POC #5 B5 adapted), `INSERT OR IGNORE` CAS
|
||||
first-writer-wins on both put forms, the EXISTS `has` probe, the
|
||||
materializing cursor body with `len()` from the size column, the
|
||||
degenerate in-memory stage committed through the whole-value row write
|
||||
with both hygiene forms, the indexed-column `size` probe, complete
|
||||
`list`, and the no-tables-yet read tolerance. WAL + synchronous=NORMAL
|
||||
set and verified at open; `prepare_cached` discipline throughout; every
|
||||
rusqlite operation in `spawn_blocking`; single-writer posture recorded
|
||||
in the module doc. Eleven in-module tests green (method contract, list
|
||||
completeness, cursor contract, empty entry, staged round-trip incl.
|
||||
both dedup forms, both hygiene forms, pragma posture, WAL-engagement
|
||||
rejection, size/index plan, tableless virgin store). `cargo test` 58
|
||||
pass, `cargo clippy --all-targets -- -D warnings` clean, `cargo fmt
|
||||
--check` clean, `cargo check --no-default-features` green. Engine-state
|
||||
window family and store construction remain in their own tasks
|
||||
(`engine-sqlite-window`, `store-sqlite-construction`).
|
||||
Reference in new issue
Block a user