mirror of
https://github.com/discourse/discourse.git
synced 2024-11-30 14:46:18 +08:00
7cb51d0e40
Temporarily recreate already dropped functions in the discourse_functions schema in order to allow restoring of backups which still reference dropped functions.
71 lines
2.0 KiB
Ruby
71 lines
2.0 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Migration
|
|
class BaseDropper
|
|
FUNCTION_SCHEMA_NAME ||= "discourse_functions".freeze
|
|
|
|
def self.create_readonly_function(table_name, column_name = nil)
|
|
DB.exec <<~SQL
|
|
CREATE SCHEMA IF NOT EXISTS #{FUNCTION_SCHEMA_NAME};
|
|
SQL
|
|
|
|
message = column_name ?
|
|
"Discourse: #{column_name} in #{table_name} is readonly" :
|
|
"Discourse: #{table_name} is read only"
|
|
|
|
DB.exec <<~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
|
|
|
|
def self.drop_readonly_function(table_name, column_name = nil)
|
|
DB.exec("DROP FUNCTION IF EXISTS #{readonly_function_name(table_name, column_name)} CASCADE")
|
|
end
|
|
|
|
def self.readonly_function_name(table_name, column_name = nil, with_schema: true)
|
|
function_name = [
|
|
"raise",
|
|
table_name,
|
|
column_name,
|
|
"readonly()"
|
|
].compact.join("_")
|
|
|
|
if with_schema && function_schema_exists?
|
|
"#{FUNCTION_SCHEMA_NAME}.#{function_name}"
|
|
else
|
|
function_name
|
|
end
|
|
end
|
|
|
|
def self.old_readonly_function_name(table_name, column_name = nil)
|
|
readonly_function_name(table_name, column_name).sub(
|
|
"#{FUNCTION_SCHEMA_NAME}.", ''
|
|
)
|
|
end
|
|
|
|
def self.readonly_trigger_name(table_name, column_name = nil)
|
|
[table_name, column_name, "readonly"].compact.join("_")
|
|
end
|
|
|
|
def self.function_schema_exists?
|
|
DB.exec(<<~SQL).to_s == '1'
|
|
SELECT schema_name
|
|
FROM information_schema.schemata
|
|
WHERE schema_name = '#{FUNCTION_SCHEMA_NAME}'
|
|
SQL
|
|
end
|
|
|
|
def self.existing_discourse_function_names
|
|
DB.query_single(<<~SQL)
|
|
SELECT routine_name
|
|
FROM information_schema.routines
|
|
WHERE routine_type = 'FUNCTION' AND specific_schema = '#{FUNCTION_SCHEMA_NAME}'
|
|
SQL
|
|
end
|
|
end
|
|
end
|