1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
# frozen_string_literal: true
databases = ActiveRecord::Tasks::DatabaseTasks.setup_initial_database_yaml
namespace :gitlab do
namespace :background_migrations do
desc 'Synchronously finish executing a batched background migration'
task :finalize, [:job_class_name, :table_name, :column_name, :job_arguments] => :environment do |_, args|
if Gitlab::Database.db_config_names.size > 1
puts "Please specify the database".color(:red)
exit 1
end
validate_finalization_arguments!(args)
main_model = Gitlab::Database.database_base_models[:main]
finalize_migration(
args[:job_class_name],
args[:table_name],
args[:column_name],
args[:job_arguments],
connection: main_model.connection
)
end
namespace :finalize do
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
next if name.to_s == 'geo'
desc "Gitlab | DB | Synchronously finish executing a batched background migration on #{name} database"
task name, [:job_class_name, :table_name, :column_name, :job_arguments] => :environment do |_, args|
validate_finalization_arguments!(args)
model = Gitlab::Database.database_base_models[name]
finalize_migration(
args[:job_class_name],
args[:table_name],
args[:column_name],
args[:job_arguments],
connection: model.connection
)
end
end
end
desc 'Display the status of batched background migrations'
task status: :environment do |_, args|
Gitlab::Database.database_base_models.each do |name, model|
display_migration_status(name, model.connection)
end
end
namespace :status do
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
next if name.to_s == 'geo'
desc "Gitlab | DB | Display the status of batched background migrations on #{name} database"
task name => :environment do |_, args|
model = Gitlab::Database.database_base_models[name]
display_migration_status(name, model.connection)
end
end
end
private
def finalize_migration(class_name, table_name, column_name, job_arguments, connection:)
Gitlab::Database::BackgroundMigration::BatchedMigrationRunner.finalize(
class_name,
table_name,
column_name,
Gitlab::Json.parse(job_arguments),
connection: connection
)
puts "Done.".color(:green)
end
def display_migration_status(database_name, connection)
Gitlab::Database::SharedModel.using_connection(connection) do
statuses = Gitlab::Database::BackgroundMigration::BatchedMigration.statuses
max_status_length = statuses.keys.map(&:length).max
format_string = "%-#{max_status_length}s | %s\n"
puts "Database: #{database_name}\n"
Gitlab::Database::BackgroundMigration::BatchedMigration.find_each(batch_size: 100) do |migration|
identification_fields = [
migration.job_class_name,
migration.table_name,
migration.column_name,
migration.job_arguments.to_json
].join(',')
printf(format_string, migration.status, identification_fields)
end
end
end
def validate_finalization_arguments!(args)
[:job_class_name, :table_name, :column_name, :job_arguments].each do |argument|
unless args[argument]
puts "Must specify #{argument} as an argument".color(:red)
exit 1
end
end
end
end
end
|