Remove transaction from abort

All migrations can be aborted idempotently at the moment and hence we
don't need to use a transaction for atomicity.
This commit is contained in:
fabianlindfors 2022-01-12 13:15:26 +01:00
parent b617c8dcda
commit c787111c77
3 changed files with 29 additions and 44 deletions

View File

@ -151,13 +151,10 @@ impl Reshape {
last_migration_index + 1,
last_action_index + 1,
);
self.state.save(&mut self.db)?;
self.abort_migrations(
&remaining_migrations,
last_migration_index + 1,
last_action_index + 1,
)?;
// Abort will only
self.abort()?;
return Err(err);
}
@ -494,31 +491,19 @@ impl Reshape {
continue;
}
// Run each action abort as a separate transaction. We need atomicity
// to ensure the abort changes are run only once for each action.
let mut transaction = self
.db
.transaction()
.context("failed to start transaction")?;
let ctx = MigrationContext::new(migration_index, action_index);
action
.abort(&ctx, &mut transaction)
.abort(&ctx, &mut self.db)
.with_context(|| format!("failed to abort migration {}", migration.name))
.with_context(|| format!("failed to abort action: {}", action.describe()))?;
// Update state with which migrations and actions have been aborted. By running this
// in a transaction, we guarantee that an action is only aborted once.
// We want to use a single transaction for each action to keep the length
// of the transaction as short as possible.
// Update state with which migrations and actions have been aborted.
// We don't need to run this in a transaction as aborts are idempotent.
self.state
.aborting(migrations.to_vec(), migration_index, action_index);
self.state
.save(&mut transaction)
.save(&mut self.db)
.context("failed to save state")?;
transaction
.commit()
.context("failed to commit transaction")?;
}
println!("{}", "done".green());

View File

@ -250,17 +250,6 @@ impl Action for AddColumn {
}
fn abort(&self, ctx: &MigrationContext, db: &mut dyn Conn) -> anyhow::Result<()> {
// Remove triggers and procedures
let query = format!(
"
DROP TRIGGER IF EXISTS {trigger_name} ON {table};
DROP FUNCTION IF EXISTS {trigger_name};
",
table = self.table,
trigger_name = self.trigger_name(ctx),
);
db.run(&query).context("failed to drop up trigger")?;
// Remove column
let query = format!(
"
@ -272,6 +261,17 @@ impl Action for AddColumn {
);
db.run(&query).context("failed to drop column")?;
// Remove triggers and procedures
let query = format!(
"
DROP TRIGGER IF EXISTS {trigger_name} ON {table};
DROP FUNCTION IF EXISTS {trigger_name};
",
table = self.table,
trigger_name = self.trigger_name(ctx),
);
db.run(&query).context("failed to drop up trigger")?;
Ok(())
}
}

View File

@ -311,6 +311,17 @@ impl Action for AlterColumn {
}
fn abort(&self, ctx: &MigrationContext, db: &mut dyn Conn) -> anyhow::Result<()> {
// Drop temporary column
let query = format!(
"
ALTER TABLE {table}
DROP COLUMN IF EXISTS {temp_column};
",
table = self.table,
temp_column = self.temporary_column_name(ctx),
);
db.run(&query).context("failed to drop temporary column")?;
// Remove triggers and procedures
let query = format!(
"
@ -327,17 +338,6 @@ impl Action for AlterColumn {
db.run(&query)
.context("failed to drop up and down triggers")?;
// Drop temporary column
let query = format!(
"
ALTER TABLE {table}
DROP COLUMN IF EXISTS {temp_column};
",
table = self.table,
temp_column = self.temporary_column_name(ctx),
);
db.run(&query).context("failed to drop temporary column")?;
Ok(())
}
}