torii_migration/
lib.rs

1//! Migration management for SQL databases in Torii
2//!
3//! This module provides traits and utilities for managing SQL database migrations in Torii.
4//! It defines a common interface for writing migrations that can be used across different
5//! SQL database backends.
6//!
7//! The main traits are:
8//! - [`Migration`]: Defines a single SQL migration with up/down operations
9//! - [`MigrationManager`]: Manages the execution and tracking of migrations
10//!
11//! Migrations are tracked in a database table (default name: `_torii_migrations`) to record
12//! which migrations have been applied and when.
13use async_trait::async_trait;
14use chrono::{DateTime, Utc};
15use sqlx::Database;
16use thiserror::Error;
17use torii_core::{Error, error::StorageError};
18
19#[derive(Debug, Error)]
20pub enum MigrationError {
21    #[error("Database error: {0}")]
22    Sqlx(#[from] sqlx::Error),
23}
24
25impl From<MigrationError> for Error {
26    fn from(value: MigrationError) -> Self {
27        match value {
28            MigrationError::Sqlx(e) => Error::Storage(StorageError::Database(e.to_string())),
29        }
30    }
31}
32
33pub type Result<T> = std::result::Result<T, MigrationError>;
34
35#[async_trait]
36pub trait Migration<DB: Database>: Send + Sync {
37    /// Unique version number for ordering migrations
38    fn version(&self) -> i64;
39
40    /// Human readable name of the migration
41    fn name(&self) -> &str;
42
43    /// Execute the migration
44    async fn up<'a>(&'a self, conn: &'a mut <DB as Database>::Connection) -> Result<()>;
45
46    /// Rollback the migration
47    async fn down<'a>(&'a self, conn: &'a mut <DB as Database>::Connection) -> Result<()>;
48}
49
50#[derive(Debug, Clone, sqlx::FromRow)]
51pub struct MigrationRecord {
52    pub version: i64,
53    pub name: String,
54    pub applied_at: DateTime<Utc>,
55}
56
57#[async_trait]
58pub trait MigrationManager<DB: Database>: Send + Sync {
59    fn get_migration_table_name(&self) -> &str {
60        "_torii_migrations"
61    }
62
63    /// Initialize migration tracking table
64    async fn initialize(&self) -> Result<()>;
65
66    /// Apply pending migrations
67    async fn up(&self, migrations: &[Box<dyn Migration<DB>>]) -> Result<()>;
68
69    /// Rollback migrations
70    async fn down(&self, migrations: &[Box<dyn Migration<DB>>]) -> Result<()>;
71
72    /// Get list of applied migrations
73    async fn get_applied_migrations(&self) -> Result<Vec<MigrationRecord>>;
74
75    /// Check if specific migration was applied
76    async fn is_applied(&self, version: i64) -> Result<bool>;
77}