58 lines
1.8 KiB
Ruby
58 lines
1.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Gitlab
|
|
module BackgroundMigration
|
|
# This background migration creates records on user_highest_roles according to
|
|
# the given user IDs range. IDs will load users with a left outer joins to
|
|
# have a record for users without a Group or Project. One INSERT per ID is
|
|
# issued.
|
|
class PopulateUserHighestRolesTable
|
|
BATCH_SIZE = 100
|
|
|
|
# rubocop:disable Style/Documentation
|
|
class User < ActiveRecord::Base
|
|
self.table_name = 'users'
|
|
|
|
scope :active, -> {
|
|
where(state: 'active', user_type: nil, bot_type: nil)
|
|
.where('ghost IS NOT TRUE')
|
|
}
|
|
end
|
|
|
|
def perform(from_id, to_id)
|
|
return unless User.column_names.include?('bot_type')
|
|
|
|
(from_id..to_id).each_slice(BATCH_SIZE) do |ids|
|
|
execute(
|
|
<<-EOF
|
|
INSERT INTO user_highest_roles (updated_at, user_id, highest_access_level)
|
|
#{select_sql(from_id, to_id)}
|
|
ON CONFLICT (user_id) DO
|
|
UPDATE SET highest_access_level = EXCLUDED.highest_access_level
|
|
EOF
|
|
)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def select_sql(from_id, to_id)
|
|
User
|
|
.select('NOW() as updated_at, users.id, MAX(access_level) AS highest_access_level')
|
|
.joins('LEFT OUTER JOIN members ON members.user_id = users.id AND members.requested_at IS NULL')
|
|
.where(users: { id: active_user_ids(from_id, to_id) })
|
|
.group('users.id')
|
|
.to_sql
|
|
end
|
|
|
|
def active_user_ids(from_id, to_id)
|
|
User.active.where(users: { id: from_id..to_id }).pluck(:id)
|
|
end
|
|
|
|
def execute(sql)
|
|
@connection ||= ActiveRecord::Base.connection
|
|
@connection.execute(sql)
|
|
end
|
|
end
|
|
end
|
|
end
|