Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'db/post_migrate/20210813151908_replace_external_wiki_triggers.rb')
-rw-r--r--db/post_migrate/20210813151908_replace_external_wiki_triggers.rb66
1 files changed, 66 insertions, 0 deletions
diff --git a/db/post_migrate/20210813151908_replace_external_wiki_triggers.rb b/db/post_migrate/20210813151908_replace_external_wiki_triggers.rb
new file mode 100644
index 00000000000..d11baae42e2
--- /dev/null
+++ b/db/post_migrate/20210813151908_replace_external_wiki_triggers.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+class ReplaceExternalWikiTriggers < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::SchemaHelpers
+
+ def up
+ replace_triggers('type_new', 'Integrations::ExternalWiki')
+
+ # we need an extra trigger to handle when type_new is updated by the
+ # `integrations_set_type_new` trigger.
+ # This can be removed when this trigger has been removed.
+ execute(<<~SQL.squish)
+ CREATE TRIGGER #{trigger_name(:type_new_updated)}
+ AFTER UPDATE OF type_new ON integrations FOR EACH ROW
+ WHEN ((new.type_new)::text = 'Integrations::ExternalWiki'::text AND new.project_id IS NOT NULL)
+ EXECUTE FUNCTION set_has_external_wiki();
+ SQL
+ end
+
+ def down
+ execute("DROP TRIGGER IF EXISTS #{trigger_name(:type_new_updated)} ON integrations;")
+ replace_triggers('type', 'ExternalWikiService')
+ end
+
+ private
+
+ def replace_triggers(column_name, value)
+ triggers(column_name, value).each do |event, condition|
+ trigger = trigger_name(event)
+
+ # create duplicate trigger, using the defined condition
+ execute(<<~SQL.squish)
+ CREATE TRIGGER #{trigger}_new AFTER #{event.upcase} ON integrations FOR EACH ROW
+ WHEN (#{condition})
+ EXECUTE FUNCTION set_has_external_wiki();
+ SQL
+
+ # Swap the triggers in place, so that the new trigger has the canonical name
+ execute("ALTER TRIGGER #{trigger} ON integrations RENAME TO #{trigger}_old;")
+ execute("ALTER TRIGGER #{trigger}_new ON integrations RENAME TO #{trigger};")
+
+ # remove the old, now redundant trigger
+ execute("DROP TRIGGER IF EXISTS #{trigger}_old ON integrations;")
+ end
+ end
+
+ def trigger_name(event)
+ "trigger_has_external_wiki_on_#{event}"
+ end
+
+ def triggers(column_name, value)
+ {
+ delete: "#{matches_value('old', column_name, value)} AND #{project_not_null('old')}",
+ insert: "(new.active = true) AND #{matches_value('new', column_name, value)} AND #{project_not_null('new')}",
+ update: "#{matches_value('new', column_name, value)} AND (old.active <> new.active) AND #{project_not_null('new')}"
+ }
+ end
+
+ def project_not_null(row)
+ "(#{row}.project_id IS NOT NULL)"
+ end
+
+ def matches_value(row, column_name, value)
+ "((#{row}.#{column_name})::text = '#{value}'::text)"
+ end
+end