Protect against accidental table renames

This commit is contained in:
Gerhard Schlager
2018-03-21 17:52:05 +01:00
committed by Sam
parent f2c060bdf2
commit 19c5afc69d
3 changed files with 31 additions and 6 deletions

View File

@ -84,26 +84,26 @@ class Migration::SafeMigrate
end end
def self.protect!(sql) def self.protect!(sql)
if sql =~ /^\s*drop\s+table/i if sql =~ /^\s*(?:drop\s+table|alter\s+table.*rename\s+to)\s+/i
$stdout.puts("", <<~STR) $stdout.puts("", <<~STR)
WARNING WARNING
------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------
An attempt was made to drop a table in a migration An attempt was made to drop or rename a table in a migration
SQL used was: '#{sql}' SQL used was: '#{sql}'
Please use the deferred pattrn using Migration::TableDropper in db/seeds to drop Please use the deferred pattern using Migration::TableDropper in db/seeds to drop
the table. or rename the table.
This protection is in place to protect us against dropping tables that are currently This protection is in place to protect us against dropping tables that are currently
in use by live applications. in use by live applications.
STR STR
raise Discourse::InvalidMigration, "Attempt was made to drop a table" raise Discourse::InvalidMigration, "Attempt was made to drop a table"
elsif sql =~ /^\s*alter\s+table.*(rename|drop)/i elsif sql =~ /^\s*alter\s+table.*(?:rename|drop)\s+/i
$stdout.puts("", <<~STR) $stdout.puts("", <<~STR)
WARNING WARNING
------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------
An attempt was made to drop or rename a column in a migration An attempt was made to drop or rename a column in a migration
SQL used was: '#{sql}' SQL used was: '#{sql}'
Please use the deferred pattrn using Migration::ColumnDropper in db/seeds to drop Please use the deferred pattern using Migration::ColumnDropper in db/seeds to drop
or rename columns. or rename columns.
Note, to minimize disruption use self.ignored_columns = ["column name"] on your Note, to minimize disruption use self.ignored_columns = ["column name"] on your

View File

@ -37,6 +37,22 @@ describe Migration::SafeMigrate do
expect(User.first).not_to eq(nil) expect(User.first).not_to eq(nil)
end end
it "bans all table renames" do
Migration::SafeMigrate.enable!
path = File.expand_path "#{Rails.root}/spec/fixtures/migrate/rename_table"
output = capture_stdout do
expect(lambda do
ActiveRecord::Migrator.up([path])
end).to raise_error(StandardError)
end
expect(output).to include("TableDropper")
expect(User.first).not_to eq(nil)
end
it "bans all column removal" do it "bans all column removal" do
Migration::SafeMigrate.enable! Migration::SafeMigrate.enable!

View File

@ -0,0 +1,9 @@
class RenameTable < ActiveRecord::Migration[5.1]
def up
rename_table :users, :persons
end
def down
raise "not tested"
end
end