1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
// Rust guideline compliant 2026-04-28
// X-WHERE-CLAUSE, M-CANONICAL-DOCS
//! # 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.
extern crate self as wasm_dbms;
pub use DbmsContext;
pub use 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::*;
/// ```