Expand description
First-class SQLite connector (CONN-08), gated behind the sqlite feature.
Ships SqliteConnector — a real rusqlite-backed SqlConnector impl —
alongside the test-only pub(crate) MockSqlConnector fixture (Open Question
#3): the two coexist, the mock is NOT removed.
First-class public SQLite connector (CONN-08) behind the sqlite feature.
Promotes spike 005’s sqlite_backend reference impl into a public
SqliteConnector type backed by rusqlite (with the bundled feature —
pure-Rust, no system SQLite, no Docker per the project’s no-Docker rule). It
implements the full 3-method SqlConnector trait surface (CONN-01):
SqlConnector::dialect, SqlConnector::execute, and
SqlConnector::schema_text.
§Internal architecture (RESEARCH §1.4)
The connection is held as Arc<Mutex<rusqlite::Connection>> where Mutex
is std::sync::Mutex (NOT tokio::sync::Mutex). Every sync rusqlite
call runs inside tokio::task::spawn_blocking, and the mutex is locked
ONLY inside that blocking closure — so the async runtime is never blocked.
The spike’s schema_blob cache is dropped: SqlConnector::schema_text
fetches DDL fresh from sqlite_master on each call. The overhead is
negligible and it avoids stale-schema bugs after CREATE TABLE via
SqlConnector::execute.
§Placeholder convention
execute() routes the SQL through translate_placeholders for
Dialect::Sqlite, which is identity on the SQL text but yields the
ordered_params binding order. SQLite recognises :name named
placeholders; bind values are looked up by name and bound via
raw_bind_parameter, never concatenated into the statement (T-84-04-01).
§Example
let conn = SqliteConnector::open_in_memory().unwrap();
assert_eq!(conn.dialect(), Dialect::Sqlite);
let rows = conn.execute("SELECT 1 AS x", &[]).await.unwrap();
assert_eq!(rows[0]["x"], serde_json::json!(1));Structs§
- Sqlite
Connector - First-class SQLite connector backed by a bundled
rusqliteconnection.