Skip to content

veeso/wasm-dbms

Repository files navigation

WASM DBMS

logo

license-mit repo-stars downloads latest-version ko-fi conventional-commits

ci coveralls docs

A Rust framework for building database applications on WASM runtimes, with first-class support for Internet Computer canisters.

Overview

This repository contains two crate families:

  • wasm-dbms - A runtime-agnostic DBMS engine that runs on any WASM runtime (Wasmtime, Wasmer, WasmEdge, IC)
  • ic-dbms - A thin IC-specific adapter that provides Internet Computer canister integration

Crate Architecture

wasm-dbms-macros <── wasm-dbms-api <── wasm-dbms-memory <── wasm-dbms
                                                                 ^
ic-dbms-macros <── ic-dbms-canister ─────────────────────────────┘
                        ^
                   ic-dbms-client
Crate Description
wasm-dbms-api Shared types, traits, validators, sanitizers
wasm-dbms-memory Memory abstraction and page management
wasm-dbms Core DBMS engine with transactions, joins, integrity checks
wasm-dbms-macros Procedural macros: Encode, Table, CustomDataType
ic-dbms-api IC-specific types (re-exports wasm-dbms-api)
ic-dbms-canister IC canister DBMS implementation
ic-dbms-macros IC-specific macro: DbmsCanister
ic-dbms-client Client libraries for canister interaction

Quick Start (Generic)

Define your database schema using Rust structs with derive macros:

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,
}

Wire tables together with the DatabaseSchema macro and use the Database trait:

use wasm_dbms::prelude::*;
use wasm_dbms_api::prelude::*;

#[derive(DatabaseSchema)]
#[tables(User = "users")]
pub struct MySchema;

// Create a database context with any MemoryProvider
let ctx = DbmsContext::new(HeapMemoryProvider::default());
MySchema::register_tables(&ctx)?;

let database = WasmDbmsDatabase::oneshot(&ctx, MySchema);

// Insert
database.insert::<User>(UserInsertRequest {
    id: 1.into(),
    name: "Alice".into(),
    email: "alice@example.com".into(),
})?;

// Query
let users = database.select::<User>(Query::builder().all().build())?;

The MemoryProvider trait abstracts storage — use HeapMemoryProvider for testing, FileMemoryProvider for Wasmtime/WASI, or implement your own for any WASM runtime.

Component Model (WIT)

wasm-dbms can be exposed as a WebAssembly Component via a WIT interface (/wit/dbms.wit), making it accessible from any Component Model host — Go, Python, JavaScript, or any language with Component Model tooling. See the Wasmtime example and the reference implementation in crates/wasm-dbms/example/.

Quick Start (IC Canister)

Define your database schema using Rust structs:

use candid::CandidType;
use ic_dbms_api::prelude::{Text, Uint32};
use ic_dbms_canister::prelude::{DatabaseSchema, DbmsCanister, Table};
use serde::Deserialize;

#[derive(Debug, Table, CandidType, Deserialize, Clone, PartialEq, Eq)]
#[table = "users"]
pub struct User {
    #[primary_key]
    id: Uint64,
    #[sanitizer(ic_dbms_api::prelude::TrimSanitizer)]
    #[validate(ic_dbms_api::prelude::MaxStrlenValidator(20))]
    name: Text,
    #[validate(ic_dbms_api::prelude::EmailValidator)]
    email: Text,
    age: Nullable<Uint32>,
}

Define relationships between tables:

#[derive(Debug, Table, CandidType, Deserialize, Clone, PartialEq, Eq)]
#[table = "posts"]
pub struct Post {
    #[primary_key]
    id: Uint32,
    title: Text,
    content: Text,
    #[foreign_key(entity = "User", table = "users", column = "id")]
    author: Uint32,
}

Note

Deriving CandidType, Deserialize and Clone is required for IC canister tables.

Instantiate the database canister:

#[derive(DatabaseSchema, DbmsCanister)]
#[tables(User = "users", Post = "posts")]
pub struct IcDbmsCanisterGenerator;

This generates a fully functional database canister with all CRUD operations.

Generated Canister API

service : (IcDbmsCanisterArgs) -> {
  acl_add_principal : (principal) -> (Result);
  acl_allowed_principals : () -> (vec principal) query;
  acl_remove_principal : (principal) -> (Result);
  begin_transaction : () -> (nat);
  commit : (nat) -> (Result);
  delete_posts : (DeleteBehavior, opt Filter_1, opt nat) -> (Result_1);
  delete_users : (DeleteBehavior, opt Filter_1, opt nat) -> (Result_1);
  insert_posts : (PostInsertRequest, opt nat) -> (Result);
  insert_users : (UserInsertRequest, opt nat) -> (Result);
  rollback : (nat) -> (Result);
  select_posts : (Query, opt nat) -> (Result_2) query;
  select_users : (Query_1, opt nat) -> (Result_3) query;
  update_posts : (PostUpdateRequest, opt nat) -> (Result_1);
  update_users : (UserUpdateRequest, opt nat) -> (Result_1);
}

ACL Management

  • acl_add_principal(principal): Adds a principal to the ACL.
  • acl_allowed_principals(): Returns the list of principals in the ACL.
  • acl_remove_principal(principal): Removes a principal from the ACL.

Transaction Management

  • begin_transaction(): Starts a new transaction and returns its ID.
  • commit(transaction_id): Commits the transaction with the given ID.
  • rollback(transaction_id): Rolls back the transaction with the given ID.

Data Manipulation

For each table defined in the schema:

  • insert_<table_name>(records, transaction_id): Inserts records into the specified table.
  • select_<table_name>(query, transaction_id): Selects records from the specified table.
  • update_<table_name>(updates, transaction_id): Updates records in the specified table.
  • delete_<table_name>(delete_behavior, filter, transaction_id): Deletes records from the specified table.

Getting Started

See the Getting Started Guide for more information on how to setup and deploy the DBMS canister.

Interacting with the Canister

See the ic-dbms-client for more information on how to interact with the canister.

Features

  • Define tables with common attributes
  • CRUD operations
  • Complex queries with filtering and pagination
  • Relationships between tables with foreign keys
  • Transactions with commit and rollback
  • Access Control Lists (ACL) to restrict access to the database
  • Validation, Sanitizers and constraints on table columns
  • JOIN operations between tables
  • Custom data types
  • Runtime-agnostic core (wasm-dbms) for any WASM runtime
  • Indexes for faster queries
  • Migrations to update the database schema on canister upgrades
  • SQL query support

Documentation

Read the documentation at https://wasm-dbms.cc

License

This project is licensed under the MIT License. See the LICENSE file for details.

About

IC DBMS Canister is an Internet Computer framework which provides an easy way to implement a database canister by just providing the database schema.

Topics

Resources

License

Code of conduct

Stars

Watchers

Forks

Sponsor this project

  •  

Packages

 
 
 

Contributors

Languages