69 lines
2.0 KiB
Ruby
69 lines
2.0 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Migration
|
|
class BaseDropper
|
|
FUNCTION_SCHEMA_NAME = "discourse_functions"
|
|
|
|
def self.create_readonly_function(table_name, column_name = nil)
|
|
DB.exec <<~SQL
|
|
CREATE SCHEMA IF NOT EXISTS #{FUNCTION_SCHEMA_NAME};
|
|
SQL
|
|
|
|
message =
|
|
(
|
|
if column_name
|
|
"Discourse: #{column_name} in #{table_name} is readonly"
|
|
else
|
|
"Discourse: #{table_name} is read only"
|
|
end
|
|
)
|
|
|
|
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::text
|
|
FROM information_schema.routines
|
|
WHERE routine_type = 'FUNCTION' AND specific_schema = '#{FUNCTION_SCHEMA_NAME}'
|
|
SQL
|
|
end
|
|
end
|
|
end
|