From b0e30189a0cb82a03d6b6b25c04fa1498da85b0b Mon Sep 17 00:00:00 2001 From: Jarka Kadlecova Date: Fri, 25 Aug 2017 13:37:21 +0200 Subject: [PATCH] Migrate issues authored by deleted user to the Ghost user --- .../36860-migrate-issues-author.yml | 5 ++ ...0825104051_migrate_issues_to_ghost_user.rb | 36 +++++++++++++ ...1071411_add_foreign_key_to_issue_author.rb | 14 +++++ db/schema.rb | 3 +- .../migrate_issues_to_ghost_user_spec.rb | 51 +++++++++++++++++++ 5 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/36860-migrate-issues-author.yml create mode 100644 db/migrate/20170825104051_migrate_issues_to_ghost_user.rb create mode 100644 db/migrate/20170901071411_add_foreign_key_to_issue_author.rb create mode 100644 spec/migrations/migrate_issues_to_ghost_user_spec.rb diff --git a/changelogs/unreleased/36860-migrate-issues-author.yml b/changelogs/unreleased/36860-migrate-issues-author.yml new file mode 100644 index 00000000000..3e9fcc55836 --- /dev/null +++ b/changelogs/unreleased/36860-migrate-issues-author.yml @@ -0,0 +1,5 @@ +--- +title: Migrate issues authored by deleted user to the Ghost user +merge_request: +author: +type: fixed diff --git a/db/migrate/20170825104051_migrate_issues_to_ghost_user.rb b/db/migrate/20170825104051_migrate_issues_to_ghost_user.rb new file mode 100644 index 00000000000..294141e4fdb --- /dev/null +++ b/db/migrate/20170825104051_migrate_issues_to_ghost_user.rb @@ -0,0 +1,36 @@ +class MigrateIssuesToGhostUser < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + DOWNTIME = false + + disable_ddl_transaction! + + class User < ActiveRecord::Base + self.table_name = 'users' + end + + class Issue < ActiveRecord::Base + self.table_name = 'issues' + + include ::EachBatch + end + + def reset_column_in_migration_models + ActiveRecord::Base.clear_cache! + + ::User.reset_column_information + end + + def up + reset_column_in_migration_models + + # we use the model method because rewriting it is too complicated and would require copying multiple methods + ghost_id = ::User.ghost.id + + Issue.where('NOT EXISTS (?)', User.unscoped.select(1).where('issues.author_id = users.id')).each_batch do |relation| + relation.update_all(author_id: ghost_id) + end + end + + def down + end +end diff --git a/db/migrate/20170901071411_add_foreign_key_to_issue_author.rb b/db/migrate/20170901071411_add_foreign_key_to_issue_author.rb new file mode 100644 index 00000000000..ab6e9fb565a --- /dev/null +++ b/db/migrate/20170901071411_add_foreign_key_to_issue_author.rb @@ -0,0 +1,14 @@ +class AddForeignKeyToIssueAuthor < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + disable_ddl_transaction! + + def up + add_concurrent_foreign_key(:issues, :users, column: :author_id, on_delete: :nullify) + end + + def down + remove_foreign_key(:issues, column: :author_id) + end +end diff --git a/db/schema.rb b/db/schema.rb index a5f867df9ae..9b45861cde7 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170824162758) do +ActiveRecord::Schema.define(version: 20170901071411) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -1707,6 +1707,7 @@ ActiveRecord::Schema.define(version: 20170824162758) do add_foreign_key "issue_assignees", "users", name: "fk_5e0c8d9154", on_delete: :cascade add_foreign_key "issue_metrics", "issues", on_delete: :cascade add_foreign_key "issues", "projects", name: "fk_899c8f3231", on_delete: :cascade + add_foreign_key "issues", "users", column: "author_id", name: "fk_05f1e72feb", on_delete: :cascade add_foreign_key "label_priorities", "labels", on_delete: :cascade add_foreign_key "label_priorities", "projects", on_delete: :cascade add_foreign_key "labels", "namespaces", column: "group_id", on_delete: :cascade diff --git a/spec/migrations/migrate_issues_to_ghost_user_spec.rb b/spec/migrations/migrate_issues_to_ghost_user_spec.rb new file mode 100644 index 00000000000..cfd4021fbac --- /dev/null +++ b/spec/migrations/migrate_issues_to_ghost_user_spec.rb @@ -0,0 +1,51 @@ +require 'spec_helper' +require Rails.root.join('db', 'migrate', '20170825104051_migrate_issues_to_ghost_user.rb') + +describe MigrateIssuesToGhostUser, :migration do + describe '#up' do + let(:projects) { table(:projects) } + let(:issues) { table(:issues) } + let(:users) { table(:users) } + + before do + projects.create!(name: 'gitlab') + user = users.create(email: 'test@example.com') + issues.create(title: 'Issue 1', author_id: nil, project_id: 1) + issues.create(title: 'Issue 2', author_id: user.id, project_id: 1) + end + + context 'when ghost user exists' do + let!(:ghost) { users.create(ghost: true, email: 'ghost@example.com') } + + it 'does not create a new user' do + expect { schema_migrate_up! }.not_to change { User.count } + end + + it 'migrates issues where author = nil to the ghost user' do + schema_migrate_up! + + expect(issues.first.reload.author_id).to eq(ghost.id) + end + + it 'does not change issues authored by an existing user' do + expect { schema_migrate_up! }.not_to change { issues.second.reload.author_id} + end + end + + context 'when ghost user does not exist' do + it 'creates a new user' do + expect { schema_migrate_up! }.to change { User.count }.by(1) + end + + it 'migrates issues where author = nil to the ghost user' do + schema_migrate_up! + + expect(issues.first.reload.author_id).to eq(User.ghost.id) + end + + it 'does not change issues authored by an existing user' do + expect { schema_migrate_up! }.not_to change { issues.second.reload.author_id} + end + end + end +end -- GitLab