use super::publish;
use crate::database::migrations::CustomMigrationError;
use crate::database::versions::{exec, history, naming, query, record};
use crate::database::DatabaseConnection;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Started {
pub version: String,
pub schema: String,
}
pub async fn start(
connection: &DatabaseConnection,
schema: &str,
version: &str,
sql: &[String],
) -> Result<Started, CustomMigrationError> {
history::ensure_table(connection).await?;
if let Some(active) = query::active(connection).await? {
return Err(super::conflict(format!(
"migration '{active}' is already in progress; complete or roll it back first"
)));
}
record::start(connection, version).await?;
apply(connection, schema, version, sql).await?;
Ok(Started {
version: version.to_string(),
schema: naming::versioned_schema(schema, version),
})
}
async fn apply(
connection: &DatabaseConnection,
schema: &str,
version: &str,
sql: &[String],
) -> Result<(), CustomMigrationError> {
for statement in sql {
if let Err(error) = exec::run(connection, statement, &[]).await {
record::discard(connection, version).await?;
return Err(error);
}
}
if let Err(error) = publish::publish(connection, schema, version).await {
record::discard(connection, version).await?;
return Err(error);
}
Ok(())
}