rindle_sqlite/lib.rs
1//! # rindle-sqlite — the SQLite backend for the [`rindle`] IVM engine
2//!
3//! Split out of the core `rindle` crate so the engine stays std-only / wasm-clean (no
4//! `rusqlite`, no C toolchain). This crate owns the native-server leaf and its
5//! supporting machinery:
6//!
7//! - [`table_source::TableSource`] — a [`rindle::graph::Source`] backed by a SQLite table
8//! (`05`): lazy zero-copy cursor reads + write-through pushes, plugged into a graph
9//! via [`GraphTableSourceExt::add_table_source`].
10//! - [`query_builder`] — the `FetchRequest` → parameterized `SELECT` lowering (`05`).
11//! - [`sqlite`] — the zero-copy `RowStream` cursor + value marshalling.
12//! - [`stmt_cache`] — a prepared-statement cache.
13//! - [`storage`] — the spill-to-SQLite operator storage (`DatabaseStorage` /
14//! `OpStorage`), plugged into a graph via [`rindle::storage::StorageFactory::custom`].
15//!
16//! It links the SAME vendored bedrock SQLite as the rest of the workspace through the
17//! root `[patch.crates-io]` redirect, so no `build.rs` is needed here.
18
19pub mod batch_delta;
20pub mod cost_model;
21pub mod query_builder;
22pub mod sqlite;
23mod stat_fanout;
24pub mod stmt_cache;
25pub mod storage;
26pub mod table_source;
27#[cfg(feature = "testkit")]
28pub mod testkit;
29mod tiebreak;
30
31use rindle::graph::{Graph, NodeId};
32
33pub use batch_delta::{BatchDelta, DeltaBudget, DeltaLookup, DEFAULT_MAX_DELTA_BYTES};
34pub use cost_model::{btree_cost, SqliteCostModel};
35pub use query_builder::{build_select_query, ColumnDef, CompiledQuery, SqliteParam};
36pub use storage::{DatabaseStorage, DatabaseStorageOptions, OpStorage};
37pub use table_source::TableSource;
38// The per-statement SQLite work counters + their shared sink — the `scanned` (work-proxy)
39// number the `rindle analyze query` diagnostic reads back (`ANALYZE-QUERY-DESIGN.md` §3.3).
40// `PlanSink` captures each leaf's fetch SQL and `explain_plan` re-`EXPLAIN`s it for the
41// per-leaf access-path text. Feature-gated so a bare build links no instrumentation.
42#[cfg(feature = "scan-stats")]
43pub use cost_model::explain_plan;
44#[cfg(feature = "scan-stats")]
45pub use table_source::{PlanSink, ScanSink, ScanStats};
46
47/// Adds `add_table_source` to [`rindle::graph::Graph`] — the ergonomic equivalent of the
48/// former inherent `Graph::add_table_source`, now that `TableSource` lives in this
49/// crate. Delegates to the core [`Graph::add_dyn_source`].
50///
51/// ```ignore
52/// use rindle_sqlite::GraphTableSourceExt;
53/// let id = graph.add_table_source(table_source);
54/// ```
55pub trait GraphTableSourceExt {
56 /// Add a SQLite [`TableSource`] as a graph leaf and return its `NodeId`.
57 fn add_table_source(&mut self, source: TableSource) -> NodeId;
58}
59
60impl GraphTableSourceExt for Graph {
61 fn add_table_source(&mut self, source: TableSource) -> NodeId {
62 self.add_dyn_source(Box::new(source))
63 }
64}