summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuben Davila <rdavila84@gmail.com>2017-02-07 09:30:14 -0500
committerRuben Davila <rdavila84@gmail.com>2017-02-07 10:42:42 -0500
commit85a98fd40fbfbc4657ca910e8885015e50ca105d (patch)
tree29d8b884fbe509f19bdcecd3b03a3ee842157d5a
parentbdc932245088b3a7ae5d633e81175352d5599083 (diff)
downloadgitlab-ce-26908-add-foreign-keys-to-timelogs.tar.gz
Refactor migration to not require downtime26908-add-foreign-keys-to-timelogs
-rw-r--r--db/migrate/20170124174637_add_foreign_keys_to_timelogs.rb27
-rw-r--r--db/post_migrate/20170206101007_remove_trackable_columns_from_timelogs.rb23
-rw-r--r--db/post_migrate/20170206101030_validate_foreign_keys_on_timelogs.rb32
-rw-r--r--db/schema.rb6
4 files changed, 76 insertions, 12 deletions
diff --git a/db/migrate/20170124174637_add_foreign_keys_to_timelogs.rb b/db/migrate/20170124174637_add_foreign_keys_to_timelogs.rb
index 7956463e12c..69bfa2d3fc4 100644
--- a/db/migrate/20170124174637_add_foreign_keys_to_timelogs.rb
+++ b/db/migrate/20170124174637_add_foreign_keys_to_timelogs.rb
@@ -5,11 +5,11 @@ class AddForeignKeysToTimelogs < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
# Set this constant to true if this migration requires downtime.
- DOWNTIME = true
+ 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 = 'Adding foreign keys'
+ DOWNTIME_REASON = ''
# When using the methods "add_concurrent_index" or "add_column_with_default"
# you must disable the use of transactions as these methods can not run in an
@@ -20,23 +20,32 @@ class AddForeignKeysToTimelogs < ActiveRecord::Migration
#
# To disable transactions uncomment the following line and remove these
# comments:
- # disable_ddl_transaction!
+ disable_ddl_transaction!
def up
change_table :timelogs do |t|
- t.references :issue, index: true, foreign_key: { on_delete: :cascade }
- t.references :merge_request, index: true, foreign_key: { on_delete: :cascade }
+ t.column :issue_id, :integer
+ t.column :merge_request_id, :integer
+ end
+
+ add_concurrent_index :timelogs, :issue_id
+ add_concurrent_index :timelogs, :merge_request_id
+
+ if Gitlab::Database.postgresql?
+ execute <<-EOF
+ ALTER TABLE timelogs ADD CONSTRAINT "fk_timelogs_issues_issue_id" FOREIGN KEY (issue_id) REFERENCES "issues" (id) ON DELETE CASCADE NOT VALID;
+ ALTER TABLE timelogs ADD CONSTRAINT "fk_timelogs_merge_requests_merge_request_id" FOREIGN KEY (merge_request_id) REFERENCES "merge_requests" (id) ON DELETE CASCADE NOT VALID;
+ EOF
+ else
+ execute "ALTER TABLE timelogs ADD CONSTRAINT fk_timelogs_issues_issue_id FOREIGN KEY (issue_id) REFERENCES issues(id) ON DELETE CASCADE;"
+ execute "ALTER TABLE timelogs ADD CONSTRAINT fk_timelogs_merge_requests_merge_request_id FOREIGN KEY (merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;"
end
Timelog.where(trackable_type: 'Issue').update_all("issue_id = trackable_id")
Timelog.where(trackable_type: 'MergeRequest').update_all("merge_request_id = trackable_id")
-
- remove_columns :timelogs, :trackable_id, :trackable_type
end
def down
- add_reference :timelogs, :trackable, polymorphic: true, index: true
-
Timelog.where('issue_id IS NOT NULL').update_all("trackable_id = issue_id, trackable_type = 'Issue'")
Timelog.where('merge_request_id IS NOT NULL').update_all("trackable_id = merge_request_id, trackable_type = 'MergeRequest'")
diff --git a/db/post_migrate/20170206101007_remove_trackable_columns_from_timelogs.rb b/db/post_migrate/20170206101007_remove_trackable_columns_from_timelogs.rb
new file mode 100644
index 00000000000..89aa753646c
--- /dev/null
+++ b/db/post_migrate/20170206101007_remove_trackable_columns_from_timelogs.rb
@@ -0,0 +1,23 @@
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class RemoveTrackableColumnsFromTimelogs < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ # When using the methods "add_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" make sure that this
+ # method 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 fails and can be retried or reverted easily.
+ #
+ # To disable transactions uncomment the following line and remove these
+ # comments:
+ # disable_ddl_transaction!
+
+ def change
+ remove_columns :timelogs, :trackable_id, :trackable_type
+ end
+end
diff --git a/db/post_migrate/20170206101030_validate_foreign_keys_on_timelogs.rb b/db/post_migrate/20170206101030_validate_foreign_keys_on_timelogs.rb
new file mode 100644
index 00000000000..f397ef919cc
--- /dev/null
+++ b/db/post_migrate/20170206101030_validate_foreign_keys_on_timelogs.rb
@@ -0,0 +1,32 @@
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class ValidateForeignKeysOnTimelogs < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ # When using the methods "add_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" make sure that this
+ # method 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 fails and can be retried or reverted easily.
+ #
+ # To disable transactions uncomment the following line and remove these
+ # comments:
+ disable_ddl_transaction!
+
+ def up
+ if Gitlab::Database.postgresql?
+ execute <<-EOF
+ ALTER TABLE timelogs VALIDATE CONSTRAINT "fk_timelogs_issues_issue_id";
+ ALTER TABLE timelogs VALIDATE CONSTRAINT "fk_timelogs_merge_requests_merge_request_id";
+ EOF
+ end
+ end
+
+ def down
+ # noop
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index cef887f65f1..850772ba356 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: 20170206071414) do
+ActiveRecord::Schema.define(version: 20170206101030) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -1341,8 +1341,8 @@ ActiveRecord::Schema.define(version: 20170206071414) do
add_foreign_key "protected_branch_merge_access_levels", "protected_branches"
add_foreign_key "protected_branch_push_access_levels", "protected_branches"
add_foreign_key "subscriptions", "projects", on_delete: :cascade
- add_foreign_key "timelogs", "issues", on_delete: :cascade
- add_foreign_key "timelogs", "merge_requests", on_delete: :cascade
+ add_foreign_key "timelogs", "issues", name: "fk_timelogs_issues_issue_id", on_delete: :cascade
+ add_foreign_key "timelogs", "merge_requests", name: "fk_timelogs_merge_requests_merge_request_id", on_delete: :cascade
add_foreign_key "trending_projects", "projects", on_delete: :cascade
add_foreign_key "u2f_registrations", "users"
end