use diesel::{RunQueryDsl, SqliteConnection};
use crate::infrastructure::repositories::sqlite::error::SqliteRepositoryError;
use diesel::sqlite::Sqlite;
use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};
use tracing::{debug, info, instrument};
pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!("./migrations");
#[allow(unused)]
pub fn init_db(
connection: &mut impl MigrationHarness<Sqlite>,
) -> Result<(), SqliteRepositoryError> {
debug!("{:?}", "--> initdb <--");
connection.revert_all_migrations(MIGRATIONS).map_err(|e| {
SqliteRepositoryError::MigrationError(format!("Failed to revert migrations: {}", e))
})?;
let pending = connection.pending_migrations(MIGRATIONS).map_err(|e| {
SqliteRepositoryError::MigrationError(format!("Failed to get pending migrations: {}", e))
})?;
pending.iter().for_each(|m| {
info!("Pending migration: {}", m.name());
});
connection.run_pending_migrations(MIGRATIONS).map_err(|e| {
SqliteRepositoryError::MigrationError(format!("Failed to run pending migrations: {}", e))
})?;
info!("All migrations applied successfully");
Ok(())
}
#[instrument(skip(conn), level = "debug")]
pub fn check_schema_migrations_exists(
conn: &mut SqliteConnection,
) -> Result<bool, SqliteRepositoryError> {
use diesel::sql_query;
use diesel::sql_types::Integer;
use diesel::QueryableByName;
#[derive(QueryableByName, Debug)]
struct TableCheckResult {
#[diesel(sql_type = Integer)]
pub table_exists: i32,
}
let query = "
SELECT COUNT(*) as table_exists
FROM sqlite_master
WHERE type='table' AND name='__diesel_schema_migrations'
";
let result: TableCheckResult = sql_query(query)
.get_result(conn)
.map_err(SqliteRepositoryError::DatabaseError)?;
Ok(result.table_exists > 0)
}