Expand description
§IC DBMS Canister
The ic-dbms-canister crate provides a database management system (DBMS) canister for the Internet Computer (IC).
You can create a database canister by just defining your data tables using Rust structs and deriving the Table trait.
§Usage
§Add dependencies
[dependencies]
candid = { version = "0.10", features = ["value"] }
ic-cdk = "0.19"
ic-dbms-api = "0.1"
ic-dbms-canister = "0.1"
serde = "1"§Define Tables
use candid::CandidType;
use ic_dbms_api::prelude::{Nullable, Text, Uint32, Uint64};
use ic_dbms_canister::prelude::{DbmsCanister, Table};
use serde::Deserialize;
// define a simple `User` table
#[derive(Debug, Table, CandidType, Deserialize, Clone, PartialEq, Eq)]
#[table = "users"]
pub struct User {
#[primary_key]
id: Uint64,
name: Text,
email: Text,
age: Nullable<Uint32>,
}
// define a table referencing `User`
#[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,
}
// Finally define the schema. This will generate the API for the canister.
#[derive(DbmsCanister)]
#[tables(User = "users", Post = "posts")]
pub struct IcDbmsCanisterGenerator;This will generate the following 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);
}§API Documentation
The API generated by the ic-dbms-canister is the following:
§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. The user must own the transaction to commit it.rollback(transaction_id): Rolls back the transaction with the given ID. The user must own the transaction to roll it back.
§Data Manipulation
For each table defined in the schema, the following methods are generated:
insert_<table_name>(records, transaction_id): Inserts records into the specified table. Optionally within a transaction.select_<table_name>(query, transaction_id): Selects records from the specified table based on the query. Optionally within a transaction.update_<table_name>(updates, transaction_id): Updates records in the specified table. Optionally within a transaction.delete_<table_name>(delete_behavior, filter, transaction_id): Deletes records from the specified table based on the filter and delete behavior. Optionally within a transaction.
§Interacting with the Canister
See the ic-dbms-client crate for a client library to interact with the canister.
§How Internet Computer Memory Works
On the Internet Computer, canisters have access to a stable memory that persists across upgrades. This stable memory is divided into pages, each of which is 64 KiB in size.
When a canister is first created, it starts with a small amount of stable memory, and it can grow this memory as needed by allocating additional pages. The canister can read from and write to this stable memory using specific APIs provided by the Internet Computer SDK.
§Memory Model
---
title: "Memory Model"
---
packet
+32: "Schema Table (65k)"
+32: "ACL Table (65k)"
+16: "Table XX Page Ledger (65k)"
+16: "Table XX Free Segments Ledger (65k)"
+16: "Table YY Page Ledger (65k)"
+16: "Table YY Free Segments Ledger (65k)"
+32: "Table XX Records - Page 1 (65k)"
+32: "Table XX Records - Page 2 (65k)"
+32: "Table YY Records - Page 1 (65k)"
+32: "Table XX Records - Page 3 (65k)"
+32: "Table YY Records - Page 2 (65k)"Modules§
- api
- API generic interface to be used by different DBMS canisters.
- prelude
- Re-exports all the most commonly used items from this crate.
- utils
Macros§
- trap
- A macro for trapping the canister execution.