mirror of
https://github.com/fabianlindfors/reshape.git
synced 2024-11-26 04:07:06 +03:00
Add context to errors
This commit is contained in:
parent
6e005144f4
commit
0bac1245cd
@ -2,7 +2,7 @@ use anyhow::Context;
|
||||
|
||||
use crate::db::Conn;
|
||||
|
||||
pub fn setup_helpers(db: &mut dyn Conn, current_migration: &Option<String>) -> anyhow::Result<()> {
|
||||
pub fn set_up_helpers(db: &mut dyn Conn, current_migration: &Option<String>) -> anyhow::Result<()> {
|
||||
let predicate = if let Some(current_migration) = current_migration {
|
||||
format!(
|
||||
"current_setting('search_path') = 'migration_{}' OR setting_bool",
|
||||
@ -32,7 +32,7 @@ pub fn setup_helpers(db: &mut dyn Conn, current_migration: &Option<String>) -> a
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn teardown_helpers(db: &mut dyn Conn) -> anyhow::Result<()> {
|
||||
pub fn tear_down_helpers(db: &mut dyn Conn) -> anyhow::Result<()> {
|
||||
db.query("DROP FUNCTION reshape.is_old_schema;")?;
|
||||
Ok(())
|
||||
}
|
||||
|
103
src/lib.rs
103
src/lib.rs
@ -3,7 +3,7 @@ use crate::{
|
||||
schema::Schema,
|
||||
};
|
||||
|
||||
use anyhow::anyhow;
|
||||
use anyhow::{anyhow, Context};
|
||||
use colored::*;
|
||||
use db::{Conn, DbConn};
|
||||
use postgres::Config;
|
||||
@ -96,7 +96,8 @@ impl Reshape {
|
||||
|
||||
println!(" Applying {} migrations\n", remaining_migrations.len());
|
||||
|
||||
helpers::setup_helpers(&mut self.db, current_migration)?;
|
||||
helpers::set_up_helpers(&mut self.db, current_migration)
|
||||
.context("failed to set up helpers")?;
|
||||
|
||||
let mut new_schema = Schema::new();
|
||||
let mut processed_migrations: &[Migration] = &[];
|
||||
@ -107,10 +108,13 @@ impl Reshape {
|
||||
processed_migrations = &remaining_migrations[..migration_index + 1];
|
||||
|
||||
for (action_index, action) in migration.actions.iter().enumerate() {
|
||||
print!(" + {} ", action.describe());
|
||||
let description = action.describe();
|
||||
print!(" + {} ", description);
|
||||
|
||||
let ctx = MigrationContext::new(migration_index, action_index);
|
||||
result = action.run(&ctx, &mut self.db, &new_schema);
|
||||
result = action
|
||||
.run(&ctx, &mut self.db, &new_schema)
|
||||
.with_context(|| format!("failed to {}", description));
|
||||
|
||||
if result.is_ok() {
|
||||
action.update_schema(&ctx, &mut new_schema);
|
||||
@ -133,16 +137,22 @@ impl Reshape {
|
||||
|
||||
// Create schema and views for migration
|
||||
let target_migration = remaining_migrations.last().unwrap().name.to_string();
|
||||
self.create_schema_for_migration(&target_migration, &new_schema)?;
|
||||
self.create_schema_for_migration(&target_migration, &new_schema)
|
||||
.with_context(|| {
|
||||
format!("failed to create schema for migration {}", target_migration)
|
||||
})?;
|
||||
|
||||
// Update state once migrations have been performed
|
||||
self.state.in_progress(remaining_migrations);
|
||||
self.state.save(&mut self.db)?;
|
||||
self.state
|
||||
.save(&mut self.db)
|
||||
.context("failed to save in-progress state")?;
|
||||
|
||||
// If we started from a blank slate, we can finish the migration immediately
|
||||
if current_migration.is_none() {
|
||||
println!("Automatically completing migrations\n");
|
||||
self.complete_migration()?;
|
||||
self.complete_migration()
|
||||
.context("failed to automatically complete migrations")?;
|
||||
|
||||
println!("Migrations complete:");
|
||||
println!(
|
||||
@ -176,41 +186,61 @@ impl Reshape {
|
||||
}
|
||||
};
|
||||
|
||||
helpers::teardown_helpers(&mut self.db)?;
|
||||
helpers::tear_down_helpers(&mut self.db).context("failed to tear down helpers")?;
|
||||
|
||||
let mut temp_schema = Schema::new();
|
||||
|
||||
// Run all the completion changes as a transaction to avoid incomplete updates
|
||||
let mut transaction = self.db.transaction()?;
|
||||
let mut transaction = self
|
||||
.db
|
||||
.transaction()
|
||||
.context("failed to start transaction")?;
|
||||
|
||||
// Remove previous migration's schema
|
||||
if let Some(current_migration) = &self.state.current_migration {
|
||||
transaction.run(&format!(
|
||||
transaction
|
||||
.run(&format!(
|
||||
"DROP SCHEMA IF EXISTS {} CASCADE",
|
||||
schema_name_for_migration(current_migration)
|
||||
))?;
|
||||
))
|
||||
.context("failed to remove previous migration's schema")?;
|
||||
}
|
||||
|
||||
for (migration_index, migration) in remaining_migrations.iter().enumerate() {
|
||||
println!("Completing '{}':", migration.name);
|
||||
|
||||
for (action_index, action) in migration.actions.iter().enumerate() {
|
||||
print!(" + {} ", action.describe());
|
||||
let description = action.describe();
|
||||
print!(" + {} ", description);
|
||||
|
||||
let ctx = MigrationContext::new(migration_index, action_index);
|
||||
action.complete(&ctx, &mut transaction, &temp_schema)?;
|
||||
action.update_schema(&ctx, &mut temp_schema);
|
||||
let result = action
|
||||
.complete(&ctx, &mut transaction, &temp_schema)
|
||||
.with_context(|| format!("failed to complete migration {}", migration.name))
|
||||
.with_context(|| format!("failed to complete action: {}", description));
|
||||
|
||||
if result.is_ok() {
|
||||
action.update_schema(&ctx, &mut temp_schema);
|
||||
println!("{}", "done".green());
|
||||
} else {
|
||||
println!("{}", "failed".green());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
println!("");
|
||||
}
|
||||
|
||||
self.state.complete()?;
|
||||
self.state.save(&mut transaction)?;
|
||||
self.state
|
||||
.complete()
|
||||
.context("failed to update state as completed")?;
|
||||
self.state
|
||||
.save(&mut transaction)
|
||||
.context("failed to save state after setting as completed")?;
|
||||
|
||||
transaction.commit()?;
|
||||
transaction
|
||||
.commit()
|
||||
.context("failed to apply transaction")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -223,7 +253,13 @@ impl Reshape {
|
||||
// Create schema for migration
|
||||
let schema_name = schema_name_for_migration(migration_name);
|
||||
self.db
|
||||
.run(&format!("CREATE SCHEMA IF NOT EXISTS {}", schema_name))?;
|
||||
.run(&format!("CREATE SCHEMA IF NOT EXISTS {}", schema_name))
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"failed to create schema {} for migration {}",
|
||||
schema_name, migration_name
|
||||
)
|
||||
})?;
|
||||
|
||||
// Create views inside schema
|
||||
for table in schema.get_tables(&mut self.db)? {
|
||||
@ -252,7 +288,8 @@ impl Reshape {
|
||||
table_name = table.real_name,
|
||||
view_name = table.name,
|
||||
columns = select_columns.join(","),
|
||||
))?;
|
||||
))
|
||||
.with_context(|| format!("failed to create view for table {}", table.name))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -300,16 +337,19 @@ impl Reshape {
|
||||
};
|
||||
let target_migration = remaining_migrations.last().unwrap().name.to_string();
|
||||
|
||||
helpers::teardown_helpers(&mut self.db)?;
|
||||
helpers::tear_down_helpers(&mut self.db).context("failed to tear down helpers")?;
|
||||
|
||||
// Run all the abort changes as a transaction to avoid incomplete changes
|
||||
let mut transaction = self.db.transaction()?;
|
||||
let mut transaction = self
|
||||
.db
|
||||
.transaction()
|
||||
.context("failed to start transaction")?;
|
||||
|
||||
// Remove new migration's schema
|
||||
transaction.run(&format!(
|
||||
"DROP SCHEMA IF EXISTS {} CASCADE",
|
||||
schema_name_for_migration(&target_migration)
|
||||
))?;
|
||||
let schema_name = schema_name_for_migration(&target_migration);
|
||||
transaction
|
||||
.run(&format!("DROP SCHEMA IF EXISTS {} CASCADE", schema_name,))
|
||||
.with_context(|| format!("failed to drop schema {}", schema_name))?;
|
||||
|
||||
// Abort all pending migrations
|
||||
abort_migrations(&mut transaction, &remaining_migrations)?;
|
||||
@ -317,9 +357,13 @@ impl Reshape {
|
||||
let keep_count = self.state.migrations.len() - remaining_migrations.len();
|
||||
self.state.migrations.truncate(keep_count);
|
||||
self.state.status = state::Status::Idle;
|
||||
self.state.save(&mut transaction)?;
|
||||
self.state
|
||||
.save(&mut transaction)
|
||||
.context("failed to save state")?;
|
||||
|
||||
transaction.commit()?;
|
||||
transaction
|
||||
.commit()
|
||||
.context("failed to commit transaction")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -331,7 +375,10 @@ fn abort_migrations(db: &mut dyn Conn, migrations: &[Migration]) -> anyhow::Resu
|
||||
print!("Aborting '{}' ", migration.name);
|
||||
for (action_index, action) in migration.actions.iter().rev().enumerate() {
|
||||
let ctx = MigrationContext::new(migration_index, action_index);
|
||||
action.abort(&ctx, db)?;
|
||||
action
|
||||
.abort(&ctx, db)
|
||||
.with_context(|| format!("failed to abort migration {}", migration.name))
|
||||
.with_context(|| format!("failed to abort action: {}", action.describe()))?;
|
||||
}
|
||||
println!("{}", "done".green());
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
use super::{common, Action, Column, MigrationContext};
|
||||
use crate::{db::Conn, schema::Schema};
|
||||
use anyhow::Context;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
@ -80,7 +81,7 @@ impl Action for AddColumn {
|
||||
table = self.table,
|
||||
definition = definition_parts.join(" "),
|
||||
);
|
||||
db.run(&query)?;
|
||||
db.run(&query).context("failed to add column")?;
|
||||
|
||||
if let Some(up) = &self.up {
|
||||
let table = schema.get_table(db, &self.table)?;
|
||||
@ -124,12 +125,13 @@ impl Action for AddColumn {
|
||||
table = self.table,
|
||||
declarations = declarations.join("\n"),
|
||||
);
|
||||
db.run(&query)?;
|
||||
db.run(&query).context("failed to create up trigger")?;
|
||||
}
|
||||
|
||||
// Backfill values in batches
|
||||
if self.up.is_some() {
|
||||
common::batch_touch_rows(db, &table.real_name, &temp_column_name)?;
|
||||
common::batch_touch_rows(db, &table.real_name, &temp_column_name)
|
||||
.context("failed to batch update existing rows")?;
|
||||
}
|
||||
|
||||
// Add a temporary NOT NULL constraint if the column shouldn't be nullable.
|
||||
@ -147,7 +149,8 @@ impl Action for AddColumn {
|
||||
constraint_name = self.not_null_constraint_name(&ctx),
|
||||
column = temp_column_name,
|
||||
);
|
||||
db.run(&query)?;
|
||||
db.run(&query)
|
||||
.context("failed to add NOT NULL constraint")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -170,7 +173,7 @@ impl Action for AddColumn {
|
||||
table = self.table,
|
||||
trigger_name = self.trigger_name(ctx),
|
||||
);
|
||||
db.run(&query)?;
|
||||
db.run(&query).context("failed to drop up trigger")?;
|
||||
|
||||
// Update column to be NOT NULL if necessary
|
||||
if !self.column.nullable {
|
||||
@ -184,7 +187,8 @@ impl Action for AddColumn {
|
||||
table = self.table,
|
||||
constraint_name = self.not_null_constraint_name(ctx),
|
||||
);
|
||||
db.run(&query)?;
|
||||
db.run(&query)
|
||||
.context("failed to validate NOT NULL constraint")?;
|
||||
|
||||
// Update the column to be NOT NULL.
|
||||
// This requires an exclusive lock but since PG 12 it can check
|
||||
@ -198,7 +202,7 @@ impl Action for AddColumn {
|
||||
table = self.table,
|
||||
column = self.temp_column_name(ctx),
|
||||
);
|
||||
db.run(&query)?;
|
||||
db.run(&query).context("failed to set column as NOT NULL")?;
|
||||
|
||||
// Drop the temporary constraint
|
||||
let query = format!(
|
||||
@ -209,7 +213,8 @@ impl Action for AddColumn {
|
||||
table = self.table,
|
||||
constraint_name = self.not_null_constraint_name(ctx),
|
||||
);
|
||||
db.run(&query)?;
|
||||
db.run(&query)
|
||||
.context("failed to drop NOT NULL constraint")?;
|
||||
}
|
||||
|
||||
// Rename the temporary column to its real name
|
||||
@ -221,7 +226,8 @@ impl Action for AddColumn {
|
||||
table = table.real_name,
|
||||
temp_column_name = self.temp_column_name(ctx),
|
||||
column_name = self.column.name,
|
||||
))?;
|
||||
))
|
||||
.context("failed to rename column to final name")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -244,7 +250,7 @@ impl Action for AddColumn {
|
||||
table = self.table,
|
||||
trigger_name = self.trigger_name(ctx),
|
||||
);
|
||||
db.run(&query)?;
|
||||
db.run(&query).context("failed to drop up trigger")?;
|
||||
|
||||
// Remove column
|
||||
let query = format!(
|
||||
@ -255,7 +261,7 @@ impl Action for AddColumn {
|
||||
table = self.table,
|
||||
column = self.temp_column_name(ctx),
|
||||
);
|
||||
db.run(&query)?;
|
||||
db.run(&query).context("failed to drop column")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
use super::{Action, MigrationContext};
|
||||
use crate::{db::Conn, schema::Schema};
|
||||
use anyhow::Context;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
@ -37,7 +38,8 @@ impl Action for AddIndex {
|
||||
name = self.name,
|
||||
table = self.table,
|
||||
columns = column_real_names.join(", "),
|
||||
))?;
|
||||
))
|
||||
.context("failed to create index")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -59,7 +61,8 @@ impl Action for AddIndex {
|
||||
",
|
||||
name = self.name,
|
||||
table = self.table,
|
||||
))?;
|
||||
))
|
||||
.context("failed to drop index")?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use super::{Action, MigrationContext};
|
||||
use crate::{db::Conn, migrations::common, schema::Schema};
|
||||
use anyhow::anyhow;
|
||||
use anyhow::{anyhow, Context};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
@ -90,7 +90,7 @@ impl Action for AlterColumn {
|
||||
.columns
|
||||
.iter()
|
||||
.find(|column| column.name == self.column)
|
||||
.ok_or_else(|| anyhow!("no such column exists"))?;
|
||||
.ok_or_else(|| anyhow!("no such column {} exists", self.column))?;
|
||||
|
||||
let temporary_column_type = self
|
||||
.changes
|
||||
@ -108,7 +108,7 @@ impl Action for AlterColumn {
|
||||
temp_column = self.temporary_column_name(ctx),
|
||||
temp_column_type = temporary_column_type,
|
||||
);
|
||||
db.run(&query)?;
|
||||
db.run(&query).context("failed to add temporary column")?;
|
||||
|
||||
let declarations: Vec<String> = table
|
||||
.columns
|
||||
@ -173,10 +173,12 @@ impl Action for AlterColumn {
|
||||
down_trigger = self.down_trigger_name(ctx),
|
||||
declarations = declarations.join("\n"),
|
||||
);
|
||||
db.run(&query)?;
|
||||
db.run(&query)
|
||||
.context("failed to create up and down triggers")?;
|
||||
|
||||
// Backfill values in batches by touching the previous column
|
||||
common::batch_touch_rows(db, &table.real_name, &column.real_name)?;
|
||||
common::batch_touch_rows(db, &table.real_name, &column.real_name)
|
||||
.context("failed to batch update existing rows")?;
|
||||
|
||||
// Add a temporary NOT NULL constraint if the column shouldn't be nullable.
|
||||
// This constraint is set as NOT VALID so it doesn't apply to existing rows and
|
||||
@ -193,7 +195,8 @@ impl Action for AlterColumn {
|
||||
constraint_name = self.not_null_constraint_name(ctx),
|
||||
column = self.temporary_column_name(ctx),
|
||||
);
|
||||
db.run(&query)?;
|
||||
db.run(&query)
|
||||
.context("failed to add NOT NULL constraint")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -216,7 +219,7 @@ impl Action for AlterColumn {
|
||||
existing_name = self.column,
|
||||
new_name = new_name,
|
||||
);
|
||||
db.run(&query)?;
|
||||
db.run(&query).context("failed to rename column")?;
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
@ -237,7 +240,7 @@ impl Action for AlterColumn {
|
||||
",
|
||||
self.table, column.real_name
|
||||
);
|
||||
db.run(&query)?;
|
||||
db.run(&query).context("failed to drop old column")?;
|
||||
|
||||
// Rename temporary column
|
||||
let query = format!(
|
||||
@ -248,7 +251,8 @@ impl Action for AlterColumn {
|
||||
temp_column = self.temporary_column_name(ctx),
|
||||
name = column_name,
|
||||
);
|
||||
db.run(&query)?;
|
||||
db.run(&query)
|
||||
.context("failed to rename temporary column")?;
|
||||
|
||||
// Remove triggers and procedures
|
||||
let query = format!(
|
||||
@ -263,7 +267,8 @@ impl Action for AlterColumn {
|
||||
up_trigger = self.up_trigger_name(ctx),
|
||||
down_trigger = self.down_trigger_name(ctx),
|
||||
);
|
||||
db.run(&query)?;
|
||||
db.run(&query)
|
||||
.context("failed to drop up and down triggers")?;
|
||||
|
||||
// Update column to be NOT NULL if necessary
|
||||
if !column.nullable {
|
||||
@ -277,7 +282,8 @@ impl Action for AlterColumn {
|
||||
table = self.table,
|
||||
constraint_name = self.not_null_constraint_name(ctx),
|
||||
);
|
||||
db.run(&query)?;
|
||||
db.run(&query)
|
||||
.context("failed to validate NOT NULL constraint")?;
|
||||
|
||||
// Update the column to be NOT NULL.
|
||||
// This requires an exclusive lock but since PG 12 it can check
|
||||
@ -291,7 +297,7 @@ impl Action for AlterColumn {
|
||||
table = self.table,
|
||||
column = column_name,
|
||||
);
|
||||
db.run(&query)?;
|
||||
db.run(&query).context("failed to set column as NOT NULL")?;
|
||||
|
||||
// Drop the temporary constraint
|
||||
let query = format!(
|
||||
@ -302,7 +308,8 @@ impl Action for AlterColumn {
|
||||
table = self.table,
|
||||
constraint_name = self.not_null_constraint_name(ctx),
|
||||
);
|
||||
db.run(&query)?;
|
||||
db.run(&query)
|
||||
.context("failed to drop NOT NULL constraint")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -344,7 +351,8 @@ impl Action for AlterColumn {
|
||||
up_trigger = self.up_trigger_name(ctx),
|
||||
down_trigger = self.down_trigger_name(ctx),
|
||||
);
|
||||
db.run(&query)?;
|
||||
db.run(&query)
|
||||
.context("failed to drop up and down triggers")?;
|
||||
|
||||
// Drop temporary column
|
||||
let query = format!(
|
||||
@ -355,7 +363,7 @@ impl Action for AlterColumn {
|
||||
table = self.table,
|
||||
temp_column = self.temporary_column_name(ctx),
|
||||
);
|
||||
db.run(&query)?;
|
||||
db.run(&query).context("failed to drop temporary column")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
use super::{Action, Column, MigrationContext};
|
||||
use crate::{db::Conn, schema::Schema};
|
||||
use anyhow::Context;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
@ -71,7 +72,8 @@ impl Action for CreateTable {
|
||||
)",
|
||||
self.name,
|
||||
definition_rows.join(",\n"),
|
||||
))?;
|
||||
))
|
||||
.context("failed to create table")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -88,8 +90,8 @@ impl Action for CreateTable {
|
||||
fn update_schema(&self, _ctx: &MigrationContext, _schema: &mut Schema) {}
|
||||
|
||||
fn abort(&self, _ctx: &MigrationContext, db: &mut dyn Conn) -> anyhow::Result<()> {
|
||||
let query = format!("DROP TABLE IF EXISTS {table}", table = self.name,);
|
||||
db.run(&query)?;
|
||||
db.run(&format!("DROP TABLE IF EXISTS {}", self.name,))
|
||||
.context("failed to drop table")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
use super::{Action, MigrationContext};
|
||||
use crate::{db::Conn, schema::Schema};
|
||||
use anyhow::Context;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
@ -77,7 +78,7 @@ impl Action for RemoveColumn {
|
||||
table = self.table,
|
||||
declarations = declarations.join("\n"),
|
||||
);
|
||||
db.run(&query)?;
|
||||
db.run(&query).context("failed to create down trigger")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -102,7 +103,8 @@ impl Action for RemoveColumn {
|
||||
column = self.column,
|
||||
trigger_name = self.trigger_name(&ctx),
|
||||
);
|
||||
db.run(&query)?;
|
||||
db.run(&query)
|
||||
.context("failed to drop column and down trigger")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -124,7 +126,8 @@ impl Action for RemoveColumn {
|
||||
",
|
||||
table = self.table,
|
||||
trigger_name = self.trigger_name(&ctx),
|
||||
))?;
|
||||
))
|
||||
.context("failed to drop down trigger")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
use super::{Action, MigrationContext};
|
||||
use crate::{db::Conn, schema::Schema};
|
||||
use anyhow::Context;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
@ -35,7 +36,7 @@ impl Action for RemoveTable {
|
||||
",
|
||||
table = self.table,
|
||||
);
|
||||
db.run(&query)?;
|
||||
db.run(&query).context("failed to drop table")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
use super::{Action, MigrationContext};
|
||||
use crate::{db::Conn, schema::Schema};
|
||||
use anyhow::Context;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
@ -38,7 +39,7 @@ impl Action for RenameTable {
|
||||
table = self.table,
|
||||
new_name = self.new_name,
|
||||
);
|
||||
db.run(&query)?;
|
||||
db.run(&query).context("failed to rename table")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user