use std::collections::HashSet;
use async_trait::async_trait;
use crate::OxiSqlError;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum MigrationStatus {
Applied,
Pending,
Unknown,
}
#[derive(Debug, Clone)]
pub struct MigrationInfo {
pub version: u64,
pub name: String,
pub status: MigrationStatus,
pub applied_at: Option<String>,
pub checksum: Option<String>,
}
#[async_trait]
pub trait Migrator: Send + Sync {
async fn apply(&mut self, version: u64, sql: &str) -> Result<(), OxiSqlError>;
async fn rollback(&mut self, version: u64, down_sql: &str) -> Result<(), OxiSqlError>;
async fn status(&self) -> Result<Vec<MigrationInfo>, OxiSqlError>;
async fn pending(&self, all_versions: &[u64]) -> Result<Vec<u64>, OxiSqlError> {
let applied: HashSet<u64> = self
.status()
.await?
.into_iter()
.filter(|m| m.status == MigrationStatus::Applied)
.map(|m| m.version)
.collect();
Ok(all_versions
.iter()
.filter(|v| !applied.contains(v))
.copied()
.collect())
}
}