use async_trait::async_trait;
use chrono::{DateTime, Utc};
use sqlx::Database;
use thiserror::Error;
use torii_core::{Error, error::StorageError};
#[derive(Debug, Error)]
pub enum MigrationError {
#[error("Database error: {0}")]
Sqlx(#[from] sqlx::Error),
}
impl From<MigrationError> for Error {
fn from(value: MigrationError) -> Self {
match value {
MigrationError::Sqlx(e) => Error::Storage(StorageError::Database(e.to_string())),
}
}
}
pub type Result<T> = std::result::Result<T, MigrationError>;
#[async_trait]
pub trait Migration<DB: Database>: Send + Sync {
fn version(&self) -> i64;
fn name(&self) -> &str;
async fn up<'a>(&'a self, conn: &'a mut <DB as Database>::Connection) -> Result<()>;
async fn down<'a>(&'a self, conn: &'a mut <DB as Database>::Connection) -> Result<()>;
}
#[derive(Debug, Clone, sqlx::FromRow)]
pub struct MigrationRecord {
pub version: i64,
pub name: String,
pub applied_at: DateTime<Utc>,
}
#[async_trait]
pub trait MigrationManager<DB: Database>: Send + Sync {
fn get_migration_table_name(&self) -> &str {
"_torii_migrations"
}
async fn initialize(&self) -> Result<()>;
async fn up(&self, migrations: &[Box<dyn Migration<DB>>]) -> Result<()>;
async fn down(&self, migrations: &[Box<dyn Migration<DB>>]) -> Result<()>;
async fn get_applied_migrations(&self) -> Result<Vec<MigrationRecord>>;
async fn is_applied(&self, version: i64) -> Result<bool>;
}