2018-03-20 03:20:50 -04:00
|
|
|
require_dependency 'migration/base_dropper'
|
|
|
|
|
|
|
|
module Migration
|
|
|
|
class Migration::TableDropper < BaseDropper
|
2018-07-09 04:54:18 -04:00
|
|
|
def self.delayed_drop(table_name:, after_migration:, delay: nil, on_drop: nil, after_drop: nil)
|
2018-03-21 06:31:05 -04:00
|
|
|
validate_table_name(table_name)
|
|
|
|
|
2018-07-09 04:54:18 -04:00
|
|
|
TableDropper.new(
|
|
|
|
table_name, nil, after_migration, delay, on_drop, after_drop
|
|
|
|
).delayed_drop
|
2018-03-21 06:31:05 -04:00
|
|
|
end
|
|
|
|
|
2018-07-09 04:54:18 -04:00
|
|
|
def self.delayed_rename(old_name:, new_name:, after_migration:, delay: nil, on_drop: nil, after_drop: nil)
|
2018-03-20 03:20:50 -04:00
|
|
|
validate_table_name(old_name)
|
|
|
|
validate_table_name(new_name)
|
|
|
|
|
2018-07-09 04:54:18 -04:00
|
|
|
TableDropper.new(
|
|
|
|
old_name, new_name, after_migration, delay, on_drop, after_drop
|
|
|
|
).delayed_drop
|
2018-03-20 03:20:50 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.read_only_table(table_name)
|
|
|
|
create_readonly_function(table_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)}
|
|
|
|
BEFORE INSERT OR UPDATE OR DELETE OR TRUNCATE
|
|
|
|
ON #{table_name}
|
|
|
|
FOR EACH STATEMENT
|
|
|
|
EXECUTE PROCEDURE #{readonly_function_name(table_name)};
|
|
|
|
SQL
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
2018-07-09 04:54:18 -04:00
|
|
|
def initialize(old_name, new_name, after_migration, delay, on_drop, after_drop)
|
|
|
|
super(after_migration, delay, on_drop, after_drop)
|
2018-03-20 03:20:50 -04:00
|
|
|
|
|
|
|
@old_name = old_name
|
|
|
|
@new_name = new_name
|
|
|
|
end
|
|
|
|
|
|
|
|
def droppable?
|
2018-06-19 02:13:14 -04:00
|
|
|
builder = DB.build(<<~SQL)
|
2018-03-20 03:20:50 -04:00
|
|
|
SELECT 1
|
|
|
|
FROM INFORMATION_SCHEMA.TABLES
|
|
|
|
/*where*/
|
|
|
|
LIMIT 1
|
|
|
|
SQL
|
|
|
|
|
2018-03-26 11:05:18 -04:00
|
|
|
builder.where(table_exists(":new_name")) if @new_name.present?
|
2018-03-21 06:31:05 -04:00
|
|
|
|
2018-03-20 03:20:50 -04:00
|
|
|
builder.where("table_schema = 'public'")
|
2018-03-26 11:05:18 -04:00
|
|
|
.where(table_exists(":old_name"))
|
2018-03-20 03:20:50 -04:00
|
|
|
.where(previous_migration_done)
|
|
|
|
.exec(old_name: @old_name,
|
|
|
|
new_name: @new_name,
|
|
|
|
delay: "#{@delay} seconds",
|
2018-06-19 02:13:14 -04:00
|
|
|
after_migration: @after_migration) > 0
|
2018-03-20 03:20:50 -04:00
|
|
|
end
|
|
|
|
|
2018-03-26 11:05:18 -04:00
|
|
|
def table_exists(table_name_placeholder)
|
2018-03-20 03:20:50 -04:00
|
|
|
<<~SQL
|
|
|
|
EXISTS(
|
|
|
|
SELECT 1
|
|
|
|
FROM INFORMATION_SCHEMA.TABLES
|
|
|
|
WHERE table_schema = 'public' AND
|
2018-03-26 11:05:18 -04:00
|
|
|
table_name = #{table_name_placeholder}
|
2018-03-20 03:20:50 -04:00
|
|
|
)
|
|
|
|
SQL
|
|
|
|
end
|
|
|
|
|
|
|
|
def execute_drop!
|
2018-06-19 02:13:14 -04:00
|
|
|
DB.exec("DROP TABLE IF EXISTS #{@old_name}")
|
2018-03-20 03:20:50 -04:00
|
|
|
|
2018-06-19 02:13:14 -04:00
|
|
|
DB.exec <<~SQL
|
2018-03-20 03:20:50 -04:00
|
|
|
DROP FUNCTION IF EXISTS #{BaseDropper.readonly_function_name(@old_name)} CASCADE;
|
|
|
|
SQL
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|