sqlite-mumu
A MuMu/Lava plugin to provide fast, native SQLite access with typed params, streaming result-sets, and friendly data-last ergonomics.
Repository: https://gitlab.com/tofo/sqlite-mumu
License: MIT OR Apache-2.0
Engine compatibility: core-mumu = 0.9.0-rc.4 (host builds; not intended for wasm)
What this plugin aims to do
- to expose a minimal, predictable set of
sqlite:*functions to MuMu/Lava - to interoperate cleanly with MuMu values (typed arrays, keyed arrays/objects, iterators)
- to stream
SELECTresults via the coreIteratortype (no giant in-memory buffers) - to bind parameters safely and ergonomically from MuMu arrays (int/float/string/bool/mixed)
- to preserve concrete MuMu types on reads (e.g., integers as
Long, floats asFloat) - to remain “host-only” while exporting a dynamic entrypoint for
extend("sqlite")
On native builds the plugin registers itself through the exported entrypoint Cargo_lock(...) so extend("sqlite") can load it at runtime.
Feature overview
1) Open / Close
-
sqlite:open([path, flags]) → handle:intpath— SQLite file path (e.g.,"/tmp/app.db"; special SQLite URIs are allowed)flags—"ro"(read-only) ·"rw"(read/write) ·"rwc"(read/write create; default)- returns an integer handle for subsequent calls
-
sqlite:close([handle]) → bool- accepts key
"handle"(and synonyms"db","conn") - returns
trueon success; errors if the handle is unknown
- accepts key
Connections are stored internally as Arc<Mutex<rusqlite::Connection>>, ensuring safe, serialized access.
2) Execute queries
sqlite:query([handle, sql, params]) → Iterator | intsql— SQL string (or a single-elementStrArray)params— optional parameters as:IntArray,FloatArray,StrArray,BoolArray, orMixedArray_(Placeholder) maps toNULL
- For
SELECT/PRAGMA/WITH:- returns a MuMu
Iteratorof rows asKeyedArray
(column names preserved as keys; insertion order preserved)
- returns a MuMu
- For
INSERT/UPDATE/DELETE/DDL:- returns an
Int(rows changed) from SQLite’sexecute
- returns an
Type mapping (SQLite → MuMu per column):
NULL→PlaceholderINTEGER→LongREAL→FloatTEXT→SingleStringBLOB→SingleString("[BLOB]")(opaque marker)
Type mapping (MuMu params → SQLite):
Int/Long/IntArray→ integer bindsFloat/FloatArray→ real bindsSingleString/StrArray→ text bindsBool/BoolArray→1/0integer bindsMixedArray— element-wise mapping based on the abovePlaceholder→NULL
Streaming: result rows are yielded on demand. Consume with any iterator-aware tool (e.g., slog, your own collectors, or array/flow helpers).
API surface
All functions use keyed arrays for clarity; handle key synonyms are accepted (handle, db, or conn).
sqlite:open([path:"/tmp/app.db", flags:"rwc"]) → 1000sqlite:query([handle:1000, sql:"SELECT 1 AS n", params:_]) → Iteratorsqlite:close([db:1000]) → true
Error messages are explicit (e.g., "sqlite:query: prepare error: ...", "sqlite:open: 'path' field missing"). When the MuMu interpreter runs with --verbose (or LAVA_VERBOSE=1), the plugin prints extra diagnostics to stderr (e.g., row streaming traces).
Minimal examples
extend("sqlite")
h = sqlite:open([path:"/tmp/example.db", flags:"rwc"])
// DDL / DML return changed-row counts
sqlite:query([handle:h, sql:"CREATE TABLE IF NOT EXISTS t(id INTEGER PRIMARY KEY, name TEXT)"])
sqlite:query([handle:h, sql:"INSERT INTO t(name) VALUES (?)", params:["Ada"]])
sqlite:query([handle:h, sql:"INSERT INTO t(name) VALUES (?)", params:["Ben"]])
// SELECT returns an Iterator of KeyedArray rows
rows = sqlite:query([handle:h, sql:"SELECT id, name FROM t WHERE id > ?", params:[0]])
// Stream to console (one row per poll tick)
slog(rows)
// Clean up
sqlite:close([handle:h])
// Parameter typing: arrays map directly to SQLite binds
h = sqlite:open([path:"/tmp/example.db"])
sqlite:query([handle:h, sql:"UPDATE t SET name = ? WHERE id = ?", params:["Eve", 1]])
sqlite:close([handle:h])
Return & error conventions
sqlite:open— returnsInthandle; errors on invalid flags/path/open failuresqlite:querySELECT/PRAGMA/WITH— returnsIteratorofKeyedArrayrows- other statements — returns
Introws changed - parameters must be representable as SQLite binds; otherwise a descriptive error is returned
sqlite:close— returnsBool(true)if the handle existed, errors otherwise
Iterator exhaustion signals "NO_MORE_DATA" internally; helper functions (e.g., slog) handle this.
Design notes
- Host-only: Uses
rusqlite; not intended for wasm. - Streaming first:
SELECTresults are not fully materialized. - Typed columns: preserves integer/real distinction (
LongvsFloat). - Stable key order: rows are
KeyedArray(insertion-order map). - Diagnostics: verbose logging is gated by the interpreter’s verbosity.
- Platform: on Windows the build enables a bundled SQLite (
libsqlite3-syswithfeatures = ["bundled"]); on Unix-likes it uses the system library by default.
Contributing
Issues and merge requests welcome at:
https://gitlab.com/tofo/sqlite-mumu
Please align changes with the MuMu core conventions:
- keyed-argument APIs
- predictable type mapping (columns & params)
- iterator streaming for result sets
- clear, actionable error messages
License
Licensed under either of:
- MIT license
- Apache License, Version 2.0
at your option.