2018-03-20 03:20:50 -04:00
|
|
|
require_dependency 'migration/base_dropper'
|
|
|
|
|
|
|
|
module Migration
|
|
|
|
class ColumnDropper < BaseDropper
|
2018-07-09 04:54:18 -04:00
|
|
|
def self.drop(table:, after_migration:, columns:, delay: nil, on_drop: nil, after_drop: nil)
|
2018-03-20 03:20:50 -04:00
|
|
|
validate_table_name(table)
|
|
|
|
columns.each { |column| validate_column_name(column) }
|
|
|
|
|
2018-07-09 04:54:18 -04:00
|
|
|
ColumnDropper.new(
|
|
|
|
table, columns, after_migration, delay, on_drop, after_drop
|
|
|
|
).delayed_drop
|
2018-03-20 03:20:50 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.mark_readonly(table_name, column_name)
|
|
|
|
create_readonly_function(table_name, column_name)
|
|
|
|
|
2018-06-19 02:13:14 -04:00
|
|
|
DB.exec <<~SQL
|
2018-03-20 03:20:50 -04:00
|
|
|
CREATE TRIGGER #{readonly_trigger_name(table_name, column_name)}
|
|
|
|
BEFORE INSERT OR UPDATE OF #{column_name}
|
|
|
|
ON #{table_name}
|
|
|
|
FOR EACH ROW
|
|
|
|
WHEN (NEW.#{column_name} IS NOT NULL)
|
|
|
|
EXECUTE PROCEDURE #{readonly_function_name(table_name, column_name)};
|
|
|
|
SQL
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
2018-07-09 04:54:18 -04:00
|
|
|
def initialize(table, columns, after_migration, delay, on_drop, after_drop)
|
|
|
|
super(after_migration, delay, on_drop, after_drop)
|
2018-03-20 03:20:50 -04:00
|
|
|
|
|
|
|
@table = table
|
|
|
|
@columns = columns
|
|
|
|
end
|
|
|
|
|
|
|
|
def droppable?
|
2018-06-20 03:48:02 -04:00
|
|
|
builder = DB.build(<<~SQL)
|
2018-03-20 03:20:50 -04:00
|
|
|
SELECT 1
|
|
|
|
FROM INFORMATION_SCHEMA.COLUMNS
|
|
|
|
/*where*/
|
|
|
|
LIMIT 1
|
|
|
|
SQL
|
|
|
|
|
2018-06-20 03:48:02 -04:00
|
|
|
builder
|
|
|
|
.where("table_schema = 'public'")
|
2018-03-20 03:20:50 -04:00
|
|
|
.where("table_name = :table")
|
|
|
|
.where("column_name IN (:columns)")
|
|
|
|
.where(previous_migration_done)
|
|
|
|
.exec(table: @table,
|
|
|
|
columns: @columns,
|
|
|
|
delay: "#{@delay} seconds",
|
2018-06-20 03:48:02 -04:00
|
|
|
after_migration: @after_migration) > 0
|
2018-03-20 03:20:50 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def execute_drop!
|
|
|
|
@columns.each do |column|
|
2018-06-19 02:13:14 -04:00
|
|
|
DB.exec <<~SQL
|
2018-03-20 03:20:50 -04:00
|
|
|
DROP TRIGGER IF EXISTS #{BaseDropper.readonly_trigger_name(@table, column)} ON #{@table};
|
|
|
|
DROP FUNCTION IF EXISTS #{BaseDropper.readonly_function_name(@table, column)} CASCADE;
|
|
|
|
SQL
|
|
|
|
|
|
|
|
# safe cause it is protected on method entry, can not be passed in params
|
2018-06-19 02:13:14 -04:00
|
|
|
DB.exec("ALTER TABLE #{@table} DROP COLUMN IF EXISTS #{column}")
|
2018-03-20 03:20:50 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|