83 lines
2.8 KiB
Ruby
83 lines
2.8 KiB
Ruby
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
|
|
# for more information on how to write migrations for GitLab.
|
|
|
|
class MigrateAssigneeToSeparateTable < ActiveRecord::Migration
|
|
include Gitlab::Database::MigrationHelpers
|
|
|
|
# Set this constant to true if this migration requires downtime.
|
|
DOWNTIME = false
|
|
|
|
# When a migration requires downtime you **must** uncomment the following
|
|
# constant and define a short and easy to understand explanation as to why the
|
|
# migration requires downtime.
|
|
# DOWNTIME_REASON = ''
|
|
|
|
# When using the methods "add_concurrent_index", "remove_concurrent_index" or
|
|
# "add_column_with_default" you must disable the use of transactions
|
|
# as these methods can not run in an existing transaction.
|
|
# When using "add_concurrent_index" or "remove_concurrent_index" methods make sure
|
|
# that either of them is the _only_ method called in the migration,
|
|
# any other changes should go in a separate migration.
|
|
# This ensures that upon failure _only_ the index creation or removing fails
|
|
# and can be retried or reverted easily.
|
|
#
|
|
# To disable transactions uncomment the following line and remove these
|
|
# comments:
|
|
# disable_ddl_transaction!
|
|
|
|
def up
|
|
drop_table(:issue_assignees) if table_exists?(:issue_assignees)
|
|
|
|
if Gitlab::Database.mysql?
|
|
execute <<-EOF
|
|
CREATE TABLE issue_assignees AS
|
|
SELECT assignee_id AS user_id, id AS issue_id FROM issues WHERE assignee_id IS NOT NULL
|
|
EOF
|
|
else
|
|
ActiveRecord::Base.transaction do
|
|
execute('LOCK TABLE issues IN EXCLUSIVE MODE')
|
|
|
|
execute <<-EOF
|
|
CREATE TABLE issue_assignees AS
|
|
SELECT assignee_id AS user_id, id AS issue_id FROM issues WHERE assignee_id IS NOT NULL
|
|
EOF
|
|
|
|
execute <<-EOF
|
|
CREATE OR REPLACE FUNCTION replicate_assignee_id()
|
|
RETURNS trigger AS
|
|
$BODY$
|
|
BEGIN
|
|
if OLD.assignee_id IS NOT NULL THEN
|
|
DELETE FROM issue_assignees WHERE issue_id = OLD.id;
|
|
END IF;
|
|
|
|
if NEW.assignee_id IS NOT NULL THEN
|
|
INSERT INTO issue_assignees (user_id, issue_id) VALUES (NEW.assignee_id, NEW.id);
|
|
END IF;
|
|
|
|
RETURN NEW;
|
|
END;
|
|
$BODY$
|
|
LANGUAGE 'plpgsql'
|
|
VOLATILE;
|
|
|
|
CREATE TRIGGER replicate_assignee_id
|
|
BEFORE INSERT OR UPDATE OF assignee_id
|
|
ON issues
|
|
FOR EACH ROW EXECUTE PROCEDURE replicate_assignee_id();
|
|
EOF
|
|
end
|
|
end
|
|
end
|
|
|
|
def down
|
|
drop_table(:issue_assignees) if table_exists?(:issue_assignees)
|
|
|
|
if Gitlab::Database.postgresql?
|
|
execute <<-EOF
|
|
DROP TRIGGER IF EXISTS replicate_assignee_id ON issues;
|
|
DROP FUNCTION IF EXISTS replicate_assignee_id();
|
|
EOF
|
|
end
|
|
end
|
|
end
|