Commit b4c7e08d authored by Krasimir Angelov's avatar Krasimir Angelov

Extract swapping of column names in a migration helper

to be used for `integer` to `bigint` conversion.

https://gitlab.com/gitlab-org/gitlab/-/issues/288005.
parent b4def6d4
......@@ -32,10 +32,7 @@ class FinalizePushEventPayloadsBigintConversion < ActiveRecord::Migration[6.1]
add_concurrent_foreign_key TABLE_NAME, :events, column: :event_id_convert_to_bigint, on_delete: :cascade
with_lock_retries(safe: true) do
# Swap column names
rename_column TABLE_NAME, :event_id, :event_id_convert_to_bigint_tmp
rename_column TABLE_NAME, :event_id_convert_to_bigint, :event_id
rename_column TABLE_NAME, :event_id_convert_to_bigint_tmp, :event_id_convert_to_bigint
swap_column_names TABLE_NAME, :event_id, :event_id_convert_to_bigint # rubocop:disable Migration/WithLockRetriesDisallowedMethod
# Swap defaults
change_column_default TABLE_NAME, :event_id, nil
......
......@@ -1616,6 +1616,17 @@ into similar problems in the future (e.g. when new tables are created).
raise
end
def swap_column_names(table_name, column_1, column_2)
unless transaction_open?
raise 'Cannot call swap_column_names without a transaction open or outside of a transaction block.'
end
temp_name = "#{column_1}_tmp"
rename_column(table_name, column_1, temp_name)
rename_column(table_name, column_2, column_1)
rename_column(table_name, temp_name, column_2)
end
private
def validate_check_constraint_name!(constraint_name)
......
......@@ -2980,4 +2980,42 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
end
end
end
describe '#swap_column_names' do
let(:table) { :_test_table }
let(:ar_model) do
Class.new(ActiveRecord::Base) do
self.table_name = :_test_table
end
end
before do
model.drop_table table, if_exists: true
model.create_table table, id: false do |t|
t.integer :column_1
t.bigint :column_2
end
end
after do
model.drop_table table, if_exists: true
end
it 'swaps column names as requested' do
model.swap_column_names(table, :column_1, :column_2)
column_1 = ar_model.column_for_attribute(:column_1)
column_2 = ar_model.column_for_attribute(:column_2)
expect(column_1.sql_type).to eq('bigint')
expect(column_2.sql_type).to eq('integer')
end
it 'raises an error when not in transaction' do
expect(model).to receive(:transaction_open?).and_return(false)
expect { model.swap_column_names(table, :column_1, :column_2) }
.to raise_error 'Cannot call swap_column_names without a transaction open or outside of a transaction block.'
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment