Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Library API (Rust)

mq-db is usable directly as a Rust library, without shelling out to the CLI.

[dependencies]
mq-db = "0.1"
#![allow(unused)]
fn main() {
use mq_db::{DocumentStore, SqlEngine, MqEngine, block::BlockType};

// ── Build in memory ──────────────────────────────────────────────────────────
let mut store = DocumentStore::new();
store.add_file("docs/DESIGN.md")?;
store.add_str("# Hello\n\n## Architecture\n\nDetails\n")?;

// Chainable query API — zone-map skip + interval scope + block predicates
let chunks = store.query()
    .documents(|doc| doc.zone_maps.heading_contents.contains("Architecture"))
    .under_heading("Architecture", Some(2))
    .filter(|b| matches!(b.block_type, BlockType::Paragraph | BlockType::Code))
    .blocks();

// SQL engine (custom sqlparser-based evaluator — no SQLite dependency)
let engine = SqlEngine::new(&store)?;
let out = engine.execute(
    "SELECT content FROM blocks WHERE block_type = 'heading' ORDER BY pre"
)?;
print!("{}", out.to_table());

// mq engine
let results = MqEngine::eval_store(".h1", &store)?;

// Structural lint
let violations = store.query().lint_heading_followed_by(2, &[BlockType::List]);

// ── Persist / load ───────────────────────────────────────────────────────────
store.save("store.mq-db")?;

// Full load — all blocks read into memory, indexes built on first SqlEngine use
let store = DocumentStore::load("store.mq-db")?;

// Lazy open — catalog only; call load_all_blocks() + load_all_indexes() before SQL
let mut store = DocumentStore::open("store.mq-db")?;
store.load_all_blocks()?;
store.load_all_indexes()?;

// Catalog-only — for metadata commands (list, stats) that don't need block data
let store = DocumentStore::load_catalog_only("store.mq-db")?;
}

Loading strategies

FunctionLoadsUse for
DocumentStore::new()Nothing (empty, in-memory)Building a store from scratch
DocumentStore::load()Catalog + all blocks + indexesOne-shot CLI queries
DocumentStore::open()Catalog only, lazilyLong-lived processes that defer block/index loading
DocumentStore::load_catalog_only()Catalog onlylist / stats-style metadata commands

When using open(), call load_all_blocks() and load_all_indexes() before running any SqlEngine query.

Query builder

store.query() returns a chainable builder that applies the same three index layers used by the SQL engine, in order:

  1. .documents(|doc| ...) — zone-map predicate, skips whole documents
  2. .under_heading(title, depth) / interval-scope helpers — narrows to a (pre, post) range
  3. .filter(|block| ...) — per-block predicate over the remaining candidates
  4. .blocks() — materializes the final Vec<&Block>

See Index Layers for how each layer works.