diff --git a/db/post_migrate/20210615234935_fix_batched_migrations_old_format_job_arguments.rb b/db/post_migrate/20210615234935_fix_batched_migrations_old_format_job_arguments.rb new file mode 100644 index 0000000000000000000000000000000000000000..535f74269384cc3cf6fd170f134fbdde7273840d --- /dev/null +++ b/db/post_migrate/20210615234935_fix_batched_migrations_old_format_job_arguments.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +class FixBatchedMigrationsOldFormatJobArguments < ActiveRecord::Migration[6.1] + class BatchedMigration < ActiveRecord::Base + self.table_name = 'batched_background_migrations' + end + + def up + # rubocop:disable Style/WordArray + [ + ['events', 'id', ['id', 'id_convert_to_bigint'], [['id'], ['id_convert_to_bigint']]], + ['push_event_payloads', 'event_id', ['event_id', 'event_id_convert_to_bigint'], [['event_id'], ['event_id_convert_to_bigint']]] + ].each do |table_name, column_name, legacy_job_arguments, current_job_arguments| + base_scope = BatchedMigration + .where(job_class_name: 'CopyColumnUsingBackgroundMigrationJob', table_name: table_name, column_name: column_name) + # rubocop:enable Style/WordArray + + # rubocop:disable Rails/WhereEquals + base_scope + .where('job_arguments = ?', legacy_job_arguments.to_json) + .where('NOT EXISTS (?)', base_scope.select('1').where('job_arguments = ?', current_job_arguments.to_json)) + .update_all(job_arguments: current_job_arguments) + # rubocop:enable Rails/WhereEquals + end + end + + def down + # No-op, there is no way to know were the existing record migrated from + # legacy job arguments, or were using the current format from the start. + # There is no reason to go back anyway. + end +end diff --git a/db/schema_migrations/20210615234935 b/db/schema_migrations/20210615234935 new file mode 100644 index 0000000000000000000000000000000000000000..83e43f74a53b0a49bead9a2e41bd930c43d9fd96 --- /dev/null +++ b/db/schema_migrations/20210615234935 @@ -0,0 +1 @@ +205336e95a6e3c9fa8c56fa67e66ef3023ba8c6cd4e6f3599160b74b3fbfaa3c \ No newline at end of file diff --git a/spec/migrations/fix_batched_migrations_old_format_job_arguments_spec.rb b/spec/migrations/fix_batched_migrations_old_format_job_arguments_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..e15011d0dab284b7d2f16e268e766f21bc0fa31e --- /dev/null +++ b/spec/migrations/fix_batched_migrations_old_format_job_arguments_spec.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +# rubocop:disable Style/WordArray +RSpec.describe FixBatchedMigrationsOldFormatJobArguments do + let(:batched_background_migrations) { table(:batched_background_migrations) } + + context 'when migrations with legacy job arguments exists' do + it 'updates job arguments to current format' do + legacy_events_migration = create_batched_migration('events', 'id', ['id', 'id_convert_to_bigint']) + legacy_push_event_payloads_migration = create_batched_migration('push_event_payloads', 'event_id', ['event_id', 'event_id_convert_to_bigint']) + + migrate! + + expect(legacy_events_migration.reload.job_arguments).to eq([['id'], ['id_convert_to_bigint']]) + expect(legacy_push_event_payloads_migration.reload.job_arguments).to eq([['event_id'], ['event_id_convert_to_bigint']]) + end + end + + context 'when only migrations with current job arguments exists' do + it 'updates nothing' do + events_migration = create_batched_migration('events', 'id', [['id'], ['id_convert_to_bigint']]) + push_event_payloads_migration = create_batched_migration('push_event_payloads', 'event_id', [['event_id'], ['event_id_convert_to_bigint']]) + + migrate! + + expect(events_migration.reload.job_arguments).to eq([['id'], ['id_convert_to_bigint']]) + expect(push_event_payloads_migration.reload.job_arguments).to eq([['event_id'], ['event_id_convert_to_bigint']]) + end + end + + context 'when migrations with both legacy and current job arguments exist' do + it 'updates nothing' do + legacy_events_migration = create_batched_migration('events', 'id', ['id', 'id_convert_to_bigint']) + events_migration = create_batched_migration('events', 'id', [['id'], ['id_convert_to_bigint']]) + legacy_push_event_payloads_migration = create_batched_migration('push_event_payloads', 'event_id', ['event_id', 'event_id_convert_to_bigint']) + push_event_payloads_migration = create_batched_migration('push_event_payloads', 'event_id', [['event_id'], ['event_id_convert_to_bigint']]) + + migrate! + + expect(legacy_events_migration.reload.job_arguments).to eq(['id', 'id_convert_to_bigint']) + expect(events_migration.reload.job_arguments).to eq([['id'], ['id_convert_to_bigint']]) + expect(legacy_push_event_payloads_migration.reload.job_arguments).to eq(['event_id', 'event_id_convert_to_bigint']) + expect(push_event_payloads_migration.reload.job_arguments).to eq([['event_id'], ['event_id_convert_to_bigint']]) + end + end + + def create_batched_migration(table_name, column_name, job_arguments) + batched_background_migrations.create!( + max_value: 10, + batch_size: 10, + sub_batch_size: 10, + interval: 1, + job_class_name: 'CopyColumnUsingBackgroundMigrationJob', + table_name: table_name, + column_name: column_name, + job_arguments: job_arguments + ) + end +end +# rubocop:enable Style/WordArray