ic_dbms_canister/lib.rs
1#![crate_name = "ic_dbms_canister"]
2#![crate_type = "lib"]
3#![cfg_attr(docsrs, feature(doc_cfg))]
4
5//! # IC DBMS Canister
6//!
7//! The `ic-dbms-canister` crate provides a database management system (DBMS) canister for the Internet Computer (IC).
8//!
9//! You can create a database canister by just defining your data tables using Rust structs and deriving the `Table` trait.
10//!
11//! ## Usage
12//!
13//! ### Add dependencies
14//!
15//! ```toml
16//! [dependencies]
17//! candid = { version = "0.10", features = ["value"] }
18//! ic-cdk = "0.19"
19//! ic-dbms-api = "0.1"
20//! ic-dbms-canister = "0.1"
21//! serde = "1"
22//! ```
23//!
24//! ### Define Tables
25//!
26//! ```rust
27//! use candid::CandidType;
28//! use ic_dbms_api::prelude::{Nullable, Text, Uint32, Uint64};
29//! use ic_dbms_canister::prelude::{DbmsCanister, Table};
30//! use serde::Deserialize;
31//!
32//! // define a simple `User` table
33//!
34//! #[derive(Debug, Table, CandidType, Deserialize, Clone, PartialEq, Eq)]
35//! #[table = "users"]
36//! pub struct User {
37//! #[primary_key]
38//! id: Uint64,
39//! name: Text,
40//! email: Text,
41//! age: Nullable<Uint32>,
42//! }
43//!
44//! // define a table referencing `User`
45//!
46//! #[derive(Debug, Table, CandidType, Deserialize, Clone, PartialEq, Eq)]
47//! #[table = "posts"]
48//! pub struct Post {
49//! #[primary_key]
50//! id: Uint32,
51//! title: Text,
52//! content: Text,
53//! #[foreign_key(entity = "User", table = "users", column = "id")]
54//! author: Uint32,
55//! }
56//!
57//! // Finally define the schema. This will generate the API for the canister.
58//!
59//! #[derive(DbmsCanister)]
60//! #[tables(User = "users", Post = "posts")]
61//! pub struct IcDbmsCanisterGenerator;
62//! ```
63//!
64//! This will generate the following API:
65//!
66//! ```txt
67//! service : (IcDbmsCanisterArgs) -> {
68//! acl_add_principal : (principal) -> (Result);
69//! acl_allowed_principals : () -> (vec principal) query;
70//! acl_remove_principal : (principal) -> (Result);
71//! begin_transaction : () -> (nat);
72//! commit : (nat) -> (Result);
73//! delete_posts : (DeleteBehavior, opt Filter_1, opt nat) -> (Result_1);
74//! delete_users : (DeleteBehavior, opt Filter_1, opt nat) -> (Result_1);
75//! insert_posts : (PostInsertRequest, opt nat) -> (Result);
76//! insert_users : (UserInsertRequest, opt nat) -> (Result);
77//! rollback : (nat) -> (Result);
78//! select_posts : (Query, opt nat) -> (Result_2) query;
79//! select_users : (Query_1, opt nat) -> (Result_3) query;
80//! update_posts : (PostUpdateRequest, opt nat) -> (Result_1);
81//! update_users : (UserUpdateRequest, opt nat) -> (Result_1);
82//! }
83//! ```
84//!
85//! ## API Documentation
86//!
87//! The API generated by the `ic-dbms-canister` is the following:
88//!
89//! ### ACL Management
90//!
91//! - `acl_add_principal(principal)`: Adds a principal to the ACL.
92//! - `acl_allowed_principals()`: Returns the list of principals in the ACL.
93//! - `acl_remove_principal(principal)`: Removes a principal from the ACL.
94//!
95//! ### Transaction Management
96//!
97//! - `begin_transaction()`: Starts a new transaction and returns its ID.
98//! - `commit(transaction_id)`: Commits the transaction with the given ID. The user must own the transaction to commit it.
99//! - `rollback(transaction_id)`: Rolls back the transaction with the given ID. The user must own the transaction to roll it back.
100//!
101//! ### Data Manipulation
102//!
103//! For each table defined in the schema, the following methods are generated:
104//!
105//! - `insert_<table_name>(records, transaction_id)`: Inserts records into the specified table. Optionally within a transaction.
106//! - `select_<table_name>(query, transaction_id)`: Selects records from the specified table based on the query. Optionally within a transaction.
107//! - `update_<table_name>(updates, transaction_id)`: Updates records in the specified table. Optionally within a transaction.
108//! - `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.
109//!
110//! ## Interacting with the Canister
111//!
112//! See the [ic-dbms-client](https://crates.io/crates/ic-dbms-client) crate for a client library to interact with the canister.
113//!
114//! ## How Internet Computer Memory Works
115//!
116//! On the Internet Computer, canisters have access to a stable memory that persists across upgrades.
117//! This stable memory is divided into pages, each of which is 64 KiB in size.
118//!
119//! When a canister is first created, it starts with a small amount of stable memory,
120//! and it can grow this memory as needed by allocating additional pages.
121//! The canister can read from and write to this stable memory using specific APIs provided by the Internet Computer SDK.
122//!
123//! ## Memory Model
124//!
125//! ```mermaid
126//! ---
127//! title: "Memory Model"
128//! ---
129//! packet
130//! +32: "Schema Table (65k)"
131//! +32: "ACL Table (65k)"
132//! +16: "Table XX Page Ledger (65k)"
133//! +16: "Table XX Free Segments Ledger (65k)"
134//! +16: "Table YY Page Ledger (65k)"
135//! +16: "Table YY Free Segments Ledger (65k)"
136//! +32: "Table XX Records - Page 1 (65k)"
137//! +32: "Table XX Records - Page 2 (65k)"
138//! +32: "Table YY Records - Page 1 (65k)"
139//! +32: "Table XX Records - Page 3 (65k)"
140//! +32: "Table YY Records - Page 2 (65k)"
141//! ```
142
143#![doc(html_playground_url = "https://play.rust-lang.org")]
144#![doc(
145 html_favicon_url = "https://raw.githubusercontent.com/veeso/ic-dbms/main/assets/images/cargo/logo-128.png"
146)]
147#![doc(
148 html_logo_url = "https://raw.githubusercontent.com/veeso/ic-dbms/main/assets/images/cargo/logo-512.png"
149)]
150
151// makes the crate accessible as `ic_dbms_canister` in macros
152extern crate self as ic_dbms_canister;
153
154pub mod api;
155mod dbms;
156mod memory;
157pub mod prelude;
158#[cfg(test)]
159mod tests;
160pub mod utils;