//! SQL migration runner. //! //! Reads migration files from the `migrate/` directory and applies them //! in lexicographic order using sqlx's built-in migration infrastructure. use sqlx::PgPool; use sqlx::migrate::Migrator; use std::path::Path; use crate::{ImksError, ImksResult}; /// Run all pending SQL migrations from the `migrate/` directory. /// /// Migrations are applied in filename order (e.g. `001_…sql` before `002_…sql`). /// sqlx tracks applied migrations in a `_sqlx_migrations` table so that /// only new migrations are executed on subsequent runs. pub async fn run_migrations(pool: &PgPool) -> ImksResult<()> { let migrations_dir = Path::new("migrate"); if !migrations_dir.exists() { tracing::warn!("No migrate/ directory found — skipping migrations"); return Ok(()); } let migrator = Migrator::new(migrations_dir) .await .map_err(|e| ImksError::Internal(format!("Failed to load migrations: {e}")))?; migrator .run(pool) .await .map_err(|e| ImksError::Internal(format!("Migration failed: {e}")))?; tracing::info!("Database migrations completed"); Ok(()) }