obj-core 1.0.2

Storage engine internals for the obj embedded document database (pager, WAL, B-tree, codec, catalog).
Documentation

obj

The embedded document database. Dependable. Portable. Zero-infrastructure.

obj is to document storage what SQLite is to relational storage — a self-contained, serverless, single-file database with a stable file format, full ACID semantics, broad platform support, and a track record of not breaking things. It is written in Rust and designed to last.

Status. v1.0 — stable on-disk format, stable Rust + C ABI, stable Python wheel ABI. From this release forward, the file format (format_major = 1), the public Rust API (obj-db), the C ABI (libobj), and the Python wheel ABI (obj-db on PyPI) are SemVer-strict: backwards-incompatible changes require a 2.0.0 release with an explicit migration tool. Readers also open pre-1.0 (format_major = 0) files for backward compatibility.


Quickstart

# Cargo.toml
[dependencies]
obj-db = "1.0"
serde = { version = "1", features = ["derive"] }
use obj::Db;
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize, obj::Document)]
struct Order {
    customer_id: u64,
    total_cents: u64,
}

fn main() -> obj::Result<()> {
    let dir = tempfile::tempdir()?;
    let db = Db::open(dir.path().join("app.obj"))?;
    let id = db.insert(Order { customer_id: 1, total_cents: 4_200 })?;
    let back: Order = db
        .get::<Order>(id)?
        .ok_or(obj::Error::InvalidArgument("just inserted"))?;
    assert_eq!(back.total_cents, 4_200);
    Ok(())
}

The collection name and schema version default to the type name and 1; override either with #[obj(collection = "...", version = N)]. See the crate docs for the full API (queries, indexes, transactions, migrations).


Cargo features

All features are off by default. Enable individually with cargo add obj-db --features <name> or in Cargo.toml.

Feature Stable in v1.0 What it does
serde yes Derive Serialize/Deserialize on public obj-db types; re-export the two traits from the crate root.
tracing yes Emit structured spans around Db::open, transactions, queries, integrity checks, and pager checkpoints.
compression yes LZ4 per-page compression at the pager layer; new files write format_minor = 2 (the feature is signalled via a per-page flag bit, not the minor).
encryption yes ChaCha20-Poly1305 per-page at-rest encryption; new files write format_minor = 2.
async yes Runtime-agnostic obj::asynchronous mirror of the blocking API, routed through the blocking crate.

See docs.rs/obj-db for per-feature details.


Bindings

CLI (obj binary). A read-only inspector and operator tool: obj dump, obj check, obj stat, obj backup. Built from the obj-cli crate.

C ABI (libobj). A cdylib + staticlib with a cbindgen- generated libobj.h. The C ABI is stable within a major version; an application linking libobj need not be recompiled across obj patch / minor releases. Built from the libobj crate.

Python (obj-py). A PyO3 + abi3-py39 extension wheel. Same typed API exposed as Python classes. Plus an @obj.document decorator for typed Python dataclasses that round-trip byte-identical to Rust #[derive(Document)] records. Built from the obj-py crate.


Performance

The aspirational targets live in design.md § Performance. The reproducible bench harness, gate semantics, and per-platform notes live in docs/performance.md. Current measured numbers — including the markdown table emitted by the perf_table harness — are uploaded as an artifact on each bench workflow run; the perf_table-md artifact carries the latest shared-runner table.


Documentation


Contributing

See CONTRIBUTING.md for the rule set this project enforces — the power-of-ten discipline, the #[allow] justification policy, the multi-agent orchestration workflow, and the release process.


License

obj is dual-licensed under either of

at your option. The .obj file-format specification in docs/format.md is released into the public domain — any implementation may read and write .obj files without restriction.