wasm-dbms 0.9.0

Runtime-agnostic DBMS engine for WASM environments
Documentation
// Rust guideline compliant 2026-04-28
// X-WHERE-CLAUSE, M-CANONICAL-DOCS

#![crate_name = "wasm_dbms"]
#![crate_type = "lib"]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![deny(clippy::print_stdout)]
#![deny(clippy::print_stderr)]

//! # wasm-dbms
//!
//! Runtime-agnostic DBMS engine for WASM environments.
//!
//! `wasm-dbms` is the core engine of the [wasm-dbms framework]. It turns a
//! schema described with Rust structs into a fully featured embedded
//! relational database that can be hosted on any WASM runtime
//! (Wasmtime, Wasmer, WasmEdge, Internet Computer, ...).
//!
//! Schemas are declared with the `Table` and `DatabaseSchema` derive
//! macros from [`wasm-dbms-macros`] and consumed through this crate via
//! the [`DbmsContext`] / [`WasmDbmsDatabase`] pair.
//!
//! [`wasm-dbms-macros`]: https://crates.io/crates/wasm-dbms-macros
//!
//! [wasm-dbms framework]: https://wasm-dbms.cc
//!
//! ## Crate architecture
//!
//! ```text
//! wasm-dbms-macros <── wasm-dbms-api <── wasm-dbms-memory <── wasm-dbms
//! ```
//!
//! | Crate              | Role                                                                    |
//! |--------------------|-------------------------------------------------------------------------|
//! | `wasm-dbms-api`    | Shared types, traits, validators, sanitizers, error variants            |
//! | `wasm-dbms-memory` | `MemoryProvider` abstraction, page management, schema/ACL/table storage |
//! | `wasm-dbms-macros` | `Encode`, `Table`, `CustomDataType`, `DatabaseSchema` derive macros     |
//! | `wasm-dbms`        | DBMS engine: CRUD, joins, aggregations, integrity, transactions         |
//!
//! Use this crate together with `wasm-dbms-api` (types) and
//! `wasm-dbms-macros` (derives). For IC canisters, prefer the
//! `ic-dbms-canister` adapter, which is built on top of this crate.
//!
//! ## Layout
//!
//! Each engine concern lives in its own module:
//!
//! - [`DbmsContext`] — owns all database state (schema registry, ACL,
//!   memory manager, active transactions). Wraps mutable state in
//!   `RefCell` so a single shared reference is enough to drive
//!   operations.
//! - [`WasmDbmsDatabase`] — short-lived session bound to a
//!   [`DbmsContext`]. Provides the typed CRUD surface
//!   (`insert`, `select`, `update`, `delete`, `aggregate`) and the
//!   transaction lifecycle (`commit` / `rollback`).
//! - [`schema::DatabaseSchema`] — dispatch trait generated by the
//!   `#[derive(DatabaseSchema)]` macro; routes name-based operations
//!   ("users", "posts", ...) to the matching typed table.
//! - [`join::JoinEngine`] — nested-loop cross-table join executor used
//!   by `Query::join`.
//! - [`integrity`] — insert and update validators (primary key,
//!   uniqueness, foreign key, nullability, custom validators).
//! - [`transaction`] — overlay-based MVCC-like read-your-writes layer
//!   plus journaling for commit/rollback.
//! - [`referenced_tables`] — foreign-key reverse lookups used during
//!   `delete` to honour `Restrict` / `Cascade` semantics.
//!
//! ## Quick start
//!
//! Add the crate to `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! wasm-dbms = "0.9"
//! wasm-dbms-api = "0.9"
//! ```
//!
//! ### Define tables
//!
//! ```rust,ignore
//! use wasm_dbms_api::prelude::*;
//!
//! #[derive(Debug, Table, Clone, PartialEq, Eq)]
//! #[table = "users"]
//! pub struct User {
//!     #[primary_key]
//!     pub id: Uint32,
//!     #[sanitizer(TrimSanitizer)]
//!     #[validate(MaxStrlenValidator(100))]
//!     pub name: Text,
//!     #[validate(EmailValidator)]
//!     pub email: Text,
//! }
//!
//! #[derive(Debug, Table, Clone, PartialEq, Eq)]
//! #[table = "posts"]
//! pub struct Post {
//!     #[primary_key]
//!     pub id: Uint32,
//!     pub title: Text,
//!     pub content: Text,
//!     #[foreign_key(entity = "User", table = "users", column = "id")]
//!     pub author_id: Uint32,
//! }
//! ```
//!
//! ### Wire the schema
//!
//! ```rust,ignore
//! use wasm_dbms::prelude::*;
//!
//! #[derive(DatabaseSchema)]
//! #[tables(User = "users", Post = "posts")]
//! pub struct MySchema;
//! ```
//!
//! ### Open a database session
//!
//! ```rust,ignore
//! use wasm_dbms::prelude::*;
//! use wasm_dbms_api::prelude::*;
//! use wasm_dbms_memory::HeapMemoryProvider;
//!
//! let ctx = DbmsContext::new(HeapMemoryProvider::default());
//! MySchema::register_tables(&ctx)?;
//!
//! let db = WasmDbmsDatabase::oneshot(&ctx, MySchema);
//!
//! db.insert::<User>(UserInsertRequest {
//!     id: 1.into(),
//!     name: "Alice".into(),
//!     email: "alice@example.com".into(),
//! })?;
//!
//! let query = Query::builder()
//!     .filter(Filter::eq("name", Value::Text("Alice".into())))
//!     .build();
//! let users = db.select::<User>(query)?;
//! ```
//!
//! ### Transactions
//!
//! ```rust,ignore
//! let tx_id = ctx.begin_transaction(caller_id);
//! let mut db = WasmDbmsDatabase::from_transaction(&ctx, MySchema, tx_id);
//!
//! db.insert::<User>(insert_req)?;
//! db.update::<User>(update_req)?;
//!
//! db.commit()?;        // or db.rollback()?;
//! ```
//!
//! Transactions are per-caller. The overlay records uncommitted writes
//! so reads inside the session observe read-your-writes semantics
//! without leaking changes to other sessions until `commit`.
//!
//! ## Memory backends
//!
//! `wasm-dbms` is parametric on the [`MemoryProvider`] from
//! [`wasm_dbms_memory`]. The framework ships:
//!
//! - `HeapMemoryProvider` — in-memory backend for tests and embedded
//!   use cases.
//! - `WasiMemoryProvider` (via `wasi-dbms-memory`) — file-backed
//!   provider for WASI runtimes.
//! - IC stable memory provider (via `ic-dbms-canister`) — production
//!   backend for Internet Computer canisters.
//!
//! Custom backends just need to implement `MemoryProvider`.
//!
//! ## Access control
//!
//! [`DbmsContext`] is generic over an [`AccessControl`] provider.
//! Use [`AccessControlList`] for identity-based per-table permissions
//! or [`NoAccessControl`] for runtimes that do not need it. The IC
//! adapter wires `AccessControlList` to canister principals.
//!
//! [`MemoryProvider`]: wasm_dbms_memory::MemoryProvider
//! [`AccessControl`]: wasm_dbms_memory::AccessControl
//! [`AccessControlList`]: wasm_dbms_memory::AccessControlList
//! [`NoAccessControl`]: wasm_dbms_memory::NoAccessControl
//!
//! ## Threading
//!
//! [`DbmsContext`] is `!Send` and `!Sync`. WASM runtimes are
//! single-threaded, so the engine relies on `RefCell` rather than
//! synchronization primitives. Embedders that need multi-threaded
//! access must wrap the context in their own synchronization layer.

#![doc(html_playground_url = "https://play.rust-lang.org")]
#![doc(
    html_favicon_url = "https://raw.githubusercontent.com/veeso/wasm-dbms/main/assets/images/cargo/logo-128.png"
)]
#![doc(
    html_logo_url = "https://raw.githubusercontent.com/veeso/wasm-dbms/main/assets/images/cargo/logo-512.png"
)]

extern crate self as wasm_dbms;

mod context;
mod database;
pub mod integrity;
pub mod join;
pub mod referenced_tables;
pub mod schema;
pub mod transaction;

pub use self::context::DbmsContext;
pub use self::database::WasmDbmsDatabase;

/// Prelude re-exports for convenient use.
///
/// Bring the most common engine items into scope with a single import:
///
/// ```rust,ignore
/// use wasm_dbms::prelude::*;
/// ```
pub mod prelude {
    pub use super::context::DbmsContext;
    pub use super::database::WasmDbmsDatabase;
    pub use super::integrity::{InsertIntegrityValidator, UpdateIntegrityValidator};
    pub use super::join::JoinEngine;
    pub use super::referenced_tables::get_referenced_tables;
    pub use super::schema::DatabaseSchema;
    pub use super::transaction::DatabaseOverlay;
    pub use super::transaction::session::TransactionSession;
}