Skip to main content

Crate spg_embedded

Crate spg_embedded 

Source
Expand description

§spg-embedded

Ergonomic embedded-mode entry point for SPG. Wraps the spg-engine execution layer for in-process applications that don’t want to spin up a TCP listener / fork to the spg-server binary.

§Quick start

use spg_embedded::Database;

// On-disk, durable. WAL fsynced per commit; auto-checkpoint
// at 4 MiB WAL by default.
let mut db = Database::open_path("/data/app.db").unwrap();
db.execute("CREATE TABLE users (id INT NOT NULL, name TEXT)").unwrap();
db.execute("INSERT INTO users VALUES (1, 'alice')").unwrap();
let rows = db.query("SELECT name FROM users WHERE id = 1").unwrap();
for row in &rows {
    println!("{:?}", row);
}

§Production checklist (v7.5)

  • Persistence: Database::open_path(p) writes a crash-consistent WAL + periodic checkpoint snapshot. The on-disk format is byte-identical to what spg-server produces, so a database can move between modes without conversion.
  • Durability: every execute() that mutates calls fsync before returning Ok. There is no group commit in embedded mode — every commit pays one fsync. If you need batch throughput, wrap multiple statements in Database::with_transaction which fsyncs only at commit.
  • Concurrency: Database is Send but not Sync. Share across threads via Arc<Mutex<Database>>. The single-writer model is intentional — see STABILITY § A1.
  • Background work: Database::spawn_background_freezer moves cold rows to disk-resident segments while you keep serving requests. It runs in a dedicated thread; drop the returned FreezerHandle (or call stop()) for clean shutdown.
  • Errors: all public enums (EngineError, QueryResult, Value) are #[non_exhaustive]. Match them with a wildcard arm so future v7.x releases can add variants without breaking your code.

§Panic contract

  • No execute() / query() call panics on user input. Malformed SQL, type mismatches, missing tables — all return Err(EngineError::…). If you observe a panic on a user-controlled string, that is a bug; file an issue.
  • The library panics only on internal invariant violations (e.g., catalog snapshot magic mismatch, WAL record CRC sentinel corruption that survived the boot- time validation). These represent silent disk corruption and an unwind would leak inconsistent state, so the release profile uses panic = abort — your host process dies fast rather than continuing on poisoned data.
  • If you cannot tolerate panic = abort, build with --profile release-dbg (keeps unwind tables) and use std::panic::catch_unwind at your application boundary.

§Why a separate crate?

spg-engine is no_std-compatible (vendored alloc-only). The embedded-mode entry point uses std (filesystem, threading), so it lives in its own crate to keep the no_std boundary clean.

Macros§

spg_row
v7.3.0 — declarative macro that generates FromSpgRow impl for a user struct. Avoids proc-macro deps (syn/quote/proc-macro2) so the workspace’s 0-deps policy holds; the trade-off vs #[derive(SpgRow)] is that the macro takes the entire struct definition (fields + types) as input rather than annotating an existing struct.

Structs§

ColumnSchema
Database
Embedded SPG database handle. Owns an Engine + provides ergonomic wrappers around execute and query. Drops the engine on Drop — no WAL flush / fsync, because v6.10.3 is in-memory only.
EmbeddedMetrics
v7.7.5 — observability snapshot returned by Database::metrics. Plain data, no allocations beyond what the struct itself takes; cheap to construct and cheap to serialise.
Engine
FreezerHandle
v7.2.1 — handle returned by spawn_background_freezer. Drop signals the worker thread to wind down + joins it, so a Database (or its shared Arc<Mutex<Database>>) can safely drop after the handle does.
FreezerOptions
v7.2.1 — knobs for Database::spawn_background_freezer.
Statement
v7.16.0 — handle for a parsed-and-planned SQL statement. Hand off to Database::execute_prepared / Database::query_prepared with a &[Value] slice carrying the bind parameters (PG-style $1, $2, … positional). Cheap to Clone; the underlying AST is shared by handle copies and cloned per bind call by the engine’s executor.

Enums§

DataType
Runtime type tags. Vector { dim, encoding } / Varchar(max) / Char(size) are parameterised; the parameter travels with both the column schema and the on-wire serialised representation.
EngineError
All errors the engine can return.
ParsedStatement
QueryResult
Result of executing one statement.
Value
A row-cell value, including SQL NULL. Float uses f64; NaN compares non-equal to itself (PG behaviour) — PartialEq is derived so callers must opt into NaN-aware comparison if they need stronger guarantees.

Traits§

FromSpgRow
v6.10.3 — trait that maps a row’s columns onto a user struct’s fields. v7.3.0 ships the spg_row! declarative macro that generates impl FromSpgRow for YourStruct from a struct definition (no proc-macro, no syn/quote/ proc-macro2 deps — the workspace’s “0 external deps” policy holds).
FromSpgValue
v7.3.0 — per-column decoder used by spg_row!. Surface covers every numeric / text / bytes / bool variant in Value, plus Option<T> for nullable columns.

Functions§

revert_wal_to_seq
v7.7.6 — replay the first to_seq records of the WAL at wal_path into a fresh engine and write the resulting catalog snapshot to out_db_path. Same semantics as spg revert --wal … --to-seq N --out … from the CLI: