IC-DBMS Canister

Documentation
Guides
Step-by-step guides for building database canisters:
- Getting Started - Set up your first ic-dbms canister
- CRUD Operations - Insert, select, update, and delete records
- Querying - Filters, ordering, pagination, and field selection
- Transactions - ACID transactions with commit/rollback
- Relationships - Foreign keys, delete behaviors, and eager loading
- Access Control - Managing the ACL
- Client API - Using the client library
Reference
API and type reference documentation:
- Data Types - All supported column types
- Schema Definition - Table attributes and generated types
- Validation - Built-in and custom validators
- Sanitization - Built-in and custom sanitizers
- JSON - JSON data type and filtering
- Errors - Error types and handling
Technical Documentation
For advanced users and contributors:
- Architecture - Three-layer system overview
- Memory Management - Stable memory internals
- Join Engine - Cross-table join query internals
Quick Example
Define your schema:
use candid::{CandidType, Deserialize};
use ic_dbms_api::prelude::*;
#[derive(Debug, Table, CandidType, Deserialize, 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,
}
Generate the canister:
use ic_dbms_canister::prelude::DbmsCanister;
#[derive(DbmsCanister)]
#[tables(User = "users")]
pub struct MyDbmsCanister;
ic_cdk::export_candid!();
Use the client:
use ic_dbms_client::{IcDbmsCanisterClient, Client as _};
let client = IcDbmsCanisterClient::new(canister_id);
// Insert
let user = UserInsertRequest { id: 1.into(), name: "Alice".into(), email: "alice@example.com".into() };
client.insert::<User>(User::table_name(), user, None).await? ?;
// Query
let query = Query::builder()
.filter(Filter::eq("name", Value::Text("Alice".into())))
.build();
let users = client.select::<User>(User::table_name(), query, None).await? ?;
Features
- Schema-driven: Define tables as Rust structs with derive macros
- CRUD operations: Full insert, select, update, delete support
- ACID transactions: Commit/rollback with isolation
- Foreign keys: Referential integrity with cascade/restrict/break behaviors
- Validation & Sanitization: Built-in validators and sanitizers
- JSON support: Store and query semi-structured data
- Access control: Principal-based ACL
- Type-safe client: Compile-time checked operations