| Crates.io | spin-migrate |
| lib.rs | spin-migrate |
| version | 0.0.1 |
| created_at | 2026-01-10 02:00:54.821901+00 |
| updated_at | 2026-01-10 02:00:54.821901+00 |
| description | Database migration library for Spin WASM applications |
| homepage | |
| repository | https://github.com/halzy/spin-migrate |
| max_upload_size | |
| id | 2033305 |
| size | 73,007 |
A lightweight database migration library for Spin WASM applications.
[dependencies]
spin-migrate = "0.0.1"
use spin_migrate::{migrations, run_migrations};
use spin_sdk::sqlite::Connection;
const MIGRATIONS: &[spin_migrate::Migration] = migrations! {
"001_create_users" => "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT NOT NULL)",
"002_create_posts" => "CREATE TABLE posts (id INTEGER PRIMARY KEY, user_id INTEGER)",
"003_add_index" => "CREATE INDEX idx_posts_user ON posts(user_id)",
};
fn setup_database() -> Result<(), spin_migrate::MigrationError> {
let conn = Connection::open_default()?;
let applied = run_migrations(&conn, MIGRATIONS)?;
println!("Applied {applied} migrations");
Ok(())
}
Due to limitations in Spin's SQLite API (single-statement execution only), each migration must contain exactly one SQL statement. Create separate migrations for multiple statements:
// Correct: separate migrations
migrations! {
"001_create_users" => "CREATE TABLE users (id INTEGER PRIMARY KEY)",
"002_create_posts" => "CREATE TABLE posts (id INTEGER PRIMARY KEY)",
}
// Wrong: multiple statements in one migration
migrations! {
"001_create_tables" => "CREATE TABLE users (...); CREATE TABLE posts (...)",
}
| Function | Description |
|---|---|
run_migrations(conn, migrations) |
Run all pending migrations, returns count applied |
all_migrations_applied(conn, migrations) |
Check if all migrations have been applied |
get_applied_migrations(conn) |
List all applied migration names |
get_pending_migrations(conn, migrations) |
Get migrations that haven't been applied yet |
validate_migration_order(migrations) |
Verify migrations are in lexicographic order |
The crate supports rusqlite for testing outside of Spin:
[dev-dependencies]
spin-migrate = { version = "0.0.1", features = ["rusqlite"] }
rusqlite = "0.37"
#[test]
fn test_migrations() {
let conn = rusqlite::Connection::open_in_memory().unwrap();
run_migrations(&conn, MIGRATIONS).unwrap();
assert!(all_migrations_applied(&conn, MIGRATIONS).unwrap());
}
Licensed under either of Apache License, Version 2.0 or MIT license at your option.