Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Embedded database

oxgraph-db is a standalone, OxGraph-native database engine built directly on the topology substrate. It owns durable database identity, cataloged physical projections, typed properties and indexes, native OxQL execution, and embedded transaction semantics — while the foundation crates stay storage- and meaning-neutral.

It is the engine oxcode stores its code graph in.

Add it

cargo add oxgraph-db

The same engine is reachable through the umbrella crate's db feature (cargo add oxgraph --features db); depending on oxgraph-db directly is the common path for database-only consumers.

A first database

A database is a directory. You create or open it, do all mutation inside a single-writer transaction that commits atomically, and read through a snapshot reader. Relations carry roles; a projection turns chosen relation types into a binary graph (or hypergraph) you can traverse, rank, and query.

use std::collections::BTreeSet;
 
use oxgraph_db::{
    Db, GraphProjectionDefinition, Key, PageRankConfig, ProjectionDefinition, PropertyFamily,
    PropertySubject, PropertyType, QueryValue, Text, Walk,
};
 
fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut db = Db::create("graph.oxgdb")?;
 
    // One write transaction. It commits atomically when the closure returns Ok,
    // and rolls back on Err.
    let ((alice, calls), _outcome) = db.write(|w| {
        let source = w.register_role("source")?;
        let target = w.register_role("target")?;
        let calls_type = w.register_relation_type("Calls")?;
        let name = w.register_property_key("name", PropertyFamily::Element, PropertyType::Text)?;
 
        let alice = w.create_element()?;
        let bob = w.create_element()?;
        w.set(PropertySubject::Element(alice), Key::<Text>::from_id(name), "alice".to_owned())?;
        w.set(PropertySubject::Element(bob), Key::<Text>::from_id(name), "bob".to_owned())?;
 
        // A directed relation alice -> bob, expressed as two role-typed incidences.
        let edge = w.create_relation()?;
        w.set_relation_type(edge, calls_type)?;
        w.create_incidence(edge, alice, source)?;
        w.create_incidence(edge, bob, target)?;
 
        // A graph projection exposes the Calls relations as a binary graph.
        let calls = w.define_projection(ProjectionDefinition::Graph(GraphProjectionDefinition {
            name: "calls".to_owned(),
            relation_types: BTreeSet::from([calls_type]),
            source_role: source,
            target_role: target,
        }))?;
 
        Ok((alice, calls))
    })?;
 
    let read = db.reader();
 
    // OxQL: resolve elements by property.
    let prepared = db.prepare("MATCH ELEMENTS WHERE name = 'alice'")?;
    for row in read.run(&prepared)?.rows() {
        if let [QueryValue::Element(id)] = row.values.as_slice() {
            println!("matched element {}", id.get());
        }
    }
 
    // Traverse the projection: alice -> bob.
    let walk = read.walk(calls, &[alice], Walk::default())?;
    println!("reached {} nodes from alice", walk.nodes().len());
 
    // Personalized PageRank, seeded on alice, over the same projection.
    let ranked = read.personalized_pagerank(calls, &[alice], PageRankConfig::new(0.85, 1e-6, 100))?;
    println!("top element: {:?}", ranked.first().map(|(id, _)| id.get()));
 
    Ok(())
}

Transactions and isolation

  • Single writer. Db::write takes the writer lock for the duration of the closure; a second concurrent write is rejected with WriterLockHeld. The closure returns a value and a CommitOutcome; returning Err rolls the transaction back.
  • Snapshot readers. Db::reader pins a consistent snapshot. A reader keeps observing its pinned state across later commits (MVCC isolation); a fresh reader sees the new state.

Projections

A projection names a physical graph or hypergraph view over the catalog:

  • ProjectionDefinition::Graph — a binary graph over relation types with a source and target role. BFS, PageRank, longest-path, and WALK/NEIGHBORS run over it.
  • ProjectionDefinition::Hypergraph — a directed hypergraph over relation types with source and target role sets.

OxQL

Prepare a query, then run it against a reader. The engine accepts element and relation matching, label and typed-property predicates (with AND/OR and parentheses), and graph walks over a named projection.

CATALOG
MATCH ELEMENTS
MATCH ELEMENTS HAS LABEL <label>
MATCH ELEMENTS WHERE <property> = '<value>'
MATCH ELEMENTS WHERE <property> >= <number> AND ( <a> OR <b> )
MATCH RELATIONS TYPE <type>
GRAPH <projection> NEIGHBORS <element-id>
GRAPH <projection> WALK FROM <element-id> DEPTH <n> [DIRECTION outgoing|incoming|both] [LIMIT n]

Predicates are schema-checked at prepare time: a type or property-family mismatch (for example WHERE age = '42' on an integer key) is rejected before execution, not silently coerced.

Durability and recovery

The engine is crash-safe by construction. Writes go to a CRC-checked log; compact folds committed deltas into a base. On open, a torn final log frame is truncated and the prior committed frame recovered, while corruption inside an already-committed frame or the base fails loudly (LogCorrupt / InvalidStore) rather than being skipped.

Reference

The full public surface — Db, Reader, Writer, the catalog and schema types, traversal, and query results — is documented on docs.rs/oxgraph-db.