1use 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 fn version(&self) -> i64;
39
40 fn name(&self) -> &str;
42
43 async fn up<'a>(&'a self, conn: &'a mut <DB as Database>::Connection) -> Result<()>;
45
46 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 async fn initialize(&self) -> Result<()>;
65
66 async fn up(&self, migrations: &[Box<dyn Migration<DB>>]) -> Result<()>;
68
69 async fn down(&self, migrations: &[Box<dyn Migration<DB>>]) -> Result<()>;
71
72 async fn get_applied_migrations(&self) -> Result<Vec<MigrationRecord>>;
74
75 async fn is_applied(&self, version: i64) -> Result<bool>;
77}