durable-migrations-rs banner

durable-migrations-rs

This lib was inspired by durable-utils, it follows a similar idea but for Rust, the main change is that this lib uses the sync SQL API, this allows you to invoke and run all migrations before you durable object’s request get processed without the need to use blockConcurrencyWhile.

./info

This lib adds the cost of at minimum 2 read operations per request, and 1+n write operation if it is the first time that durable object is being executed. Migrations will only run if the `id` is greater than the one persisted in the durable object storage.

Getting started

[dependencies]
durable_migrations = "1.0"
use durable_migrations::{Migration, migrate};

//...
#[durable_object]
struct MyDurableObject {}

impl DurableObject for MyDurableObject {
    fn new(state: State, env: Env) -> Self {
        if let Err(e) = migrate(
            &[
                Migration {
                    id: 1,
                    sql: r#"CREATE TABLE IF NOT EXISTS my_inventory (
                                "id" INTEGER PRIMARY KEY AUTOINCREMENT,
                                "metadata" TEXT,
                                "kind" TEXT,
                                "created_at" INTEGER NOT NULL DEFAULT ( unixepoch('subsec') * 1000 ),
                                "updated_at" INTEGER NOT NULL DEFAULT ( unixepoch('subsec') * 1000 ),
                                CONSTRAINT valid_json CHECK(json_valid(metadata))
                            )"#,
                },
                Migration {
                    id: 2,
                    sql: r#"CREATE TABLE IF NOT EXISTS my_missions (
                                "id" INTEGER PRIMARY KEY AUTOINCREMENT,
                                "name" TEXT NOT NULL,
                                "description" TEXT NOT NULL,
                                "reward" TEXT NOT NULL,
                                "evt" TEXT NOT NULL,
                                "kind" TEXT,
                                "cooldown_in_min" INTEGER,
                                "cooldown_ends_at" INTEGER,
                                "done" INTEGER NOT NULL DEFAULT 0,
                                "created_at" INTEGER NOT NULL DEFAULT ( unixepoch('subsec') * 1000 ),
                                "updated_at" INTEGER NOT NULL DEFAULT ( unixepoch('subsec') * 1000 )
                            )"#,
                },
            ],
            state.storage(),
        ) {
            console_error!("error running migrations {e:?}");
        }

        Self {}
    }
}
//...