mirror of
https://github.com/discourse/discourse.git
synced 2024-11-23 23:54:16 +08:00
73 lines
2.0 KiB
Ruby
73 lines
2.0 KiB
Ruby
|
module Migration
|
||
|
class BaseDropper
|
||
|
def initialize(after_migration, delay, on_drop)
|
||
|
@after_migration = after_migration
|
||
|
@on_drop = on_drop
|
||
|
|
||
|
# in production we need some extra delay to allow for slow migrations
|
||
|
@delay = delay || (Rails.env.production? ? 3600 : 0)
|
||
|
end
|
||
|
|
||
|
def delayed_drop
|
||
|
if droppable?
|
||
|
@on_drop&.call
|
||
|
execute_drop!
|
||
|
|
||
|
Discourse.reset_active_record_cache
|
||
|
end
|
||
|
end
|
||
|
|
||
|
private
|
||
|
|
||
|
def droppable?
|
||
|
raise NotImplementedError
|
||
|
end
|
||
|
|
||
|
def execute_drop!
|
||
|
raise NotImplementedError
|
||
|
end
|
||
|
|
||
|
def previous_migration_done
|
||
|
<<~SQL
|
||
|
EXISTS(
|
||
|
SELECT 1
|
||
|
FROM schema_migration_details
|
||
|
WHERE name = :after_migration AND
|
||
|
created_at <= (current_timestamp AT TIME ZONE 'UTC' - INTERVAL :delay)
|
||
|
)
|
||
|
SQL
|
||
|
end
|
||
|
|
||
|
def self.create_readonly_function(table_name, column_name = nil)
|
||
|
message = column_name ?
|
||
|
"Discourse: #{column_name} in #{table_name} is readonly" :
|
||
|
"Discourse: #{table_name} is read only"
|
||
|
|
||
|
ActiveRecord::Base.exec_sql <<~SQL
|
||
|
CREATE OR REPLACE FUNCTION #{readonly_function_name(table_name, column_name)} RETURNS trigger AS $rcr$
|
||
|
BEGIN
|
||
|
RAISE EXCEPTION '#{message}';
|
||
|
END
|
||
|
$rcr$ LANGUAGE plpgsql;
|
||
|
SQL
|
||
|
end
|
||
|
private_class_method :create_readonly_function
|
||
|
|
||
|
def self.validate_table_name(table_name)
|
||
|
raise ArgumentError.new("Invalid table name passed: #{table_name}") if table_name =~ /[^a-z0-9_]/i
|
||
|
end
|
||
|
|
||
|
def self.validate_column_name(column_name)
|
||
|
raise ArgumentError.new("Invalid column name passed to drop #{column_name}") if column_name =~ /[^a-z0-9_]/i
|
||
|
end
|
||
|
|
||
|
def self.readonly_function_name(table_name, column_name = nil)
|
||
|
["raise", table_name, column_name, "readonly()"].compact.join("_")
|
||
|
end
|
||
|
|
||
|
def self.readonly_trigger_name(table_name, column_name = nil)
|
||
|
[table_name, column_name, "readonly"].compact.join("_")
|
||
|
end
|
||
|
end
|
||
|
end
|