use miette::Diagnostic; use thiserror::Error; pub struct Migration { pub filename: String, pub directory: String, pub script_contents: String, } const DB_MIGRATION_DIR: &str = "./src/db/"; /// To prevent accidental error coersion in other modules, std::io::Error gets cast as Migration Error here #[derive(Debug, Diagnostic, Error)] pub enum MigrationError { #[error("IO error")] IOMigrationError(#[from] std::io::Error), } type Result = std::result::Result; /// Reads the filesystem for sql files in the DB migration directory fn get_script_filenames() -> Result> { let results = std::fs::read_dir(DB_MIGRATION_DIR)?; Ok(results .flat_map(|entry| entry.unwrap().file_name().into_string()) .filter(|s| s.ends_with(".sql")) .collect()) } /// Gets SQL files from the DB migration directory to provide instructions for setting up the database pub fn get_migration_scripts() -> Result> { let files = get_script_filenames()?; let mut migrations = vec![]; for file in files { let filename = String::from(DB_MIGRATION_DIR) + &file; tracing::event!( tracing::Level::TRACE, filename = filename, "Found migration script." ); let contents = std::fs::read_to_string(filename)?; migrations.push(Migration { filename: file, directory: DB_MIGRATION_DIR.into(), script_contents: contents, }); } Ok(migrations) }