torii-migration

Crates.iotorii-migration
lib.rstorii-migration
version0.5.1
created_at2025-02-27 04:16:35.578957+00
updated_at2025-07-23 00:20:42.94+00
descriptionMigration utilities for the torii authentication ecosystem
homepage
repositoryhttps://github.com/cmackenzie1/torii-rs
max_upload_size
id1571230
size66,860
Cole Mackenzie (cmackenzie1)

documentation

README

torii-migration

Database migration management for the Torii authentication framework.

This crate provides traits and utilities for managing SQL database migrations in Torii. It defines a common interface for writing migrations that can be used across different SQL database backends like SQLite, PostgreSQL, and MySQL.

Features

  • Generic Migration Interface: Common traits for all database backends
  • Migration Tracking: Automatic tracking of applied migrations
  • Async/Await Support: Fully async migration operations
  • Database Agnostic: Works with any sqlx-supported database
  • Rollback Support: Bidirectional migrations with up/down operations
  • Timestamp Tracking: Records when migrations were applied

Usage

This crate is primarily used internally by Torii storage backends, but can be used directly if you need custom migration management.

Add this to your Cargo.toml:

[dependencies]
torii-migration = "0.4.0"

Basic Migration

use torii_migration::{Migration, MigrationManager};
use async_trait::async_trait;
use sqlx::Sqlite;

struct CreateUsersTable;

#[async_trait]
impl Migration<Sqlite> for CreateUsersTable {
    fn version(&self) -> i64 {
        20250101_000001
    }

    fn name(&self) -> &str {
        "create_users_table"
    }

    async fn up<'a>(&'a self, conn: &'a mut sqlx::SqliteConnection) -> torii_migration::Result<()> {
        sqlx::query(
            r#"
            CREATE TABLE users (
                id TEXT PRIMARY KEY,
                email TEXT UNIQUE NOT NULL,
                name TEXT,
                email_verified_at INTEGER,
                created_at INTEGER NOT NULL,
                updated_at INTEGER NOT NULL
            )
            "#,
        )
        .execute(conn)
        .await?;
        Ok(())
    }

    async fn down<'a>(&'a self, conn: &'a mut sqlx::SqliteConnection) -> torii_migration::Result<()> {
        sqlx::query("DROP TABLE users").execute(conn).await?;
        Ok(())
    }
}

Migration Manager

use torii_migration::{Migration, MigrationManager};
use sqlx::SqlitePool;

// Implement MigrationManager for your specific database
struct SqliteMigrationManager {
    pool: SqlitePool,
}

impl SqliteMigrationManager {
    pub fn new(pool: SqlitePool) -> Self {
        Self { pool }
    }
}

#[async_trait]
impl MigrationManager<sqlx::Sqlite> for SqliteMigrationManager {
    // Implementation details...
}

Core Traits

Migration

The Migration trait defines a single database migration:

#[async_trait]
pub trait Migration<DB: Database>: Send + Sync {
    /// Unique version number for ordering migrations
    fn version(&self) -> i64;

    /// Human readable name of the migration
    fn name(&self) -> &str;

    /// Execute the migration
    async fn up<'a>(&'a self, conn: &'a mut <DB as Database>::Connection) -> Result<()>;

    /// Rollback the migration
    async fn down<'a>(&'a self, conn: &'a mut <DB as Database>::Connection) -> Result<()>;
}

MigrationManager

The MigrationManager trait manages the execution and tracking of migrations:

#[async_trait]
pub trait MigrationManager<DB: Database>: Send + Sync {
    /// Initialize migration tracking table
    async fn initialize(&self) -> Result<()>;

    /// Apply pending migrations
    async fn up(&self, migrations: &[Box<dyn Migration<DB>>]) -> Result<()>;

    /// Rollback migrations
    async fn down(&self, migrations: &[Box<dyn Migration<DB>>]) -> Result<()>;

    /// Get list of applied migrations
    async fn get_applied_migrations(&self) -> Result<Vec<MigrationRecord>>;

    /// Check if specific migration was applied
    async fn is_applied(&self, version: i64) -> Result<bool>;
}

Migration Tracking

Migrations are tracked in a database table (default name: _torii_migrations) that records:

  • version: The migration version number
  • name: Human-readable migration name
  • applied_at: Timestamp when the migration was applied

Version Numbering

It's recommended to use timestamp-based version numbers for migrations:

// Format: YYYYMMDD_HHMMSS
20250101_000001  // 2025-01-01 00:00:01
20250101_120000  // 2025-01-01 12:00:00

This ensures migrations are applied in the correct order and prevents conflicts.

Database Support

This crate works with any database supported by sqlx:

  • SQLite: Great for development and smaller deployments
  • PostgreSQL: Production-ready with full feature support
  • MySQL: Production-ready with full feature support

Error Handling

The crate provides comprehensive error handling with the MigrationError type that integrates with Torii's error system:

#[derive(Debug, Error)]
pub enum MigrationError {
    #[error("Database error: {0}")]
    Sqlx(#[from] sqlx::Error),
}

Integration with Storage Backends

Storage backends like torii-storage-sqlite and torii-storage-postgres use this crate to provide automatic schema management. Users typically don't need to interact with this crate directly unless they're implementing custom storage backends.

Commit count: 149

cargo fmt