Crate ic_sql_migrate

Crate ic_sql_migrate 

Source
Expand description

A lightweight database migration library for Internet Computer (ICP) canisters.

This library provides automatic database schema management and version control for SQLite (via ic-rusqlite) and Turso databases in ICP canisters. Migrations are embedded at compile time and executed during canister initialization and upgrades.

§Features

IMPORTANT: You must enable exactly one database feature for this library to work:

  • SQLite support via ic-rusqlite (feature: sqlite)
  • Turso support for distributed SQLite (feature: turso)

Additional capabilities:

  • Automatic migration execution on canister init and post_upgrade
  • Compile-time migration embedding via include!() macro
  • Transaction-based execution for atomicity

The library has no default features. Attempting to use it without enabling either sqlite or turso will result in compilation errors when trying to access the database modules.

§Quick Start for ICP Canisters

§1. Prerequisites

In addition to having the Rust toolchain setup and dfx, you need to install the wasi2ic tool that replaces WebAssembly System Interface (WASI) specific function calls with their corresponding polyfill implementations. This allows you to run Wasm binaries compiled for wasm32-wasi on the Internet Computer.

cargo install wasi2ic

§Configure dfx.json

You also need to configure your dfx.json to compile for the wasm32-wasip1 target and use wasi2ic to process the binary:

{
  "canisters": {
    "your_canister": {
      "candid": "your_canister.did",
      "package": "your_canister",
      "type": "custom",
      "build": [
        "cargo build --target wasm32-wasip1 --release",
        "wasi2ic target/wasm32-wasip1/release/your_canister.wasm target/wasm32-wasip1/release/your_canister-wasi2ic.wasm"
      ],
      "wasm": "target/wasm32-wasip1/release/your_canister-wasi2ic.wasm"
    }
  }
}

§For Turso

No additional toolchain setup required beyond Rust and DFX.

§2. Add to Cargo.toml

[dependencies]
ic-sql-migrate = { version = "0.0.4", features = ["sqlite"] } # or feature "turso"
ic-rusqlite = { version = "0.4.2", features = ["precompiled"], default-features = false }
# or turso = "0.1.4" for Turso
ic-cdk = "0.18.7"

[build-dependencies]
ic-sql-migrate = "0.0.4"

§3. Create build.rs

fn main() {
    ic_sql_migrate::list(Some("migrations")).unwrap();
}

§4. Use in canister

use ic_cdk::{init, post_upgrade, pre_upgrade};
use ic_rusqlite::{close_connection, with_connection, Connection};

static MIGRATIONS: &[ic_sql_migrate::Migration] = ic_sql_migrate::include!();

fn run_migrations() {
    with_connection(|mut conn| {
        let conn: &mut Connection = &mut conn;
        ic_sql_migrate::sqlite::up(conn, MIGRATIONS).unwrap();
    });
}

#[init]
fn init() {
    run_migrations();
}

#[pre_upgrade]
fn pre_upgrade() {
    close_connection();
}

#[post_upgrade]
fn post_upgrade() {
    run_migrations();
}

Macros§

include
Includes all migration files discovered by the list function at compile time.

Structs§

Migration
Represents a single database migration with its unique identifier and SQL content.

Enums§

Error
Custom error type for migration operations.

Functions§

list
Discovers and lists all SQL migration files for inclusion at compile time.

Type Aliases§

MigrateResult
Type alias for Result<T, Error> used throughout the library.