sqlite-mumu 0.2.0-rc.4

sqlite-mumu is a plugin for the mumu ecosystem
Documentation

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 SELECT results via the core Iterator type (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 as Float)
  • 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:int

    • path — 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 true on success; errors if the handle is unknown

Connections are stored internally as Arc<Mutex<rusqlite::Connection>>, ensuring safe, serialized access.

2) Execute queries

  • sqlite:query([handle, sql, params]) → Iterator | int
    • sql — SQL string (or a single-element StrArray)
    • params — optional parameters as:
      • IntArray, FloatArray, StrArray, BoolArray, or MixedArray
      • _ (Placeholder) maps to NULL
    • For SELECT/PRAGMA/WITH:
      • returns a MuMu Iterator of rows as KeyedArray
        (column names preserved as keys; insertion order preserved)
    • For INSERT/UPDATE/DELETE/DDL:
      • returns an Int (rows changed) from SQLite’s execute

Type mapping (SQLite → MuMu per column):

  • NULLPlaceholder
  • INTEGERLong
  • REALFloat
  • TEXTSingleString
  • BLOBSingleString("[BLOB]") (opaque marker)

Type mapping (MuMu params → SQLite):

  • Int/Long/IntArray → integer binds
  • Float/FloatArray → real binds
  • SingleString/StrArray → text binds
  • Bool/BoolArray1/0 integer binds
  • MixedArray — element-wise mapping based on the above
  • PlaceholderNULL

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"]) → 1000
  • sqlite:query([handle:1000, sql:"SELECT 1 AS n", params:_]) → Iterator
  • sqlite: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 — returns Int handle; errors on invalid flags/path/open failure
  • sqlite:query
    • SELECT/PRAGMA/WITH — returns Iterator of KeyedArray rows
    • other statements — returns Int rows changed
    • parameters must be representable as SQLite binds; otherwise a descriptive error is returned
  • sqlite:close — returns Bool(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: SELECT results are not fully materialized.
  • Typed columns: preserves integer/real distinction (Long vs Float).
  • 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-sys with features = ["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.