79 lines
2.6 KiB
Ruby
79 lines
2.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Gitlab
|
|
module BackgroundMigration
|
|
# The migration is used to cleanup orphaned lfs_objects_projects in order to
|
|
# introduce valid foreign keys to this table
|
|
class CleanupOrphanedLfsObjectsProjects
|
|
# A model to access lfs_objects_projects table in migrations
|
|
class LfsObjectsProject < ActiveRecord::Base
|
|
self.table_name = 'lfs_objects_projects'
|
|
|
|
include ::EachBatch
|
|
|
|
belongs_to :lfs_object
|
|
belongs_to :project
|
|
end
|
|
|
|
# A model to access lfs_objects table in migrations
|
|
class LfsObject < ActiveRecord::Base
|
|
self.table_name = 'lfs_objects'
|
|
end
|
|
|
|
# A model to access projects table in migrations
|
|
class Project < ActiveRecord::Base
|
|
self.table_name = 'projects'
|
|
end
|
|
|
|
SUB_BATCH_SIZE = 5000
|
|
CLEAR_CACHE_DELAY = 1.minute
|
|
|
|
def perform(start_id, end_id)
|
|
cleanup_lfs_objects_projects_without_lfs_object(start_id, end_id)
|
|
cleanup_lfs_objects_projects_without_project(start_id, end_id)
|
|
end
|
|
|
|
private
|
|
|
|
def cleanup_lfs_objects_projects_without_lfs_object(start_id, end_id)
|
|
each_record_without_association(start_id, end_id, :lfs_object, :lfs_objects) do |lfs_objects_projects_without_lfs_objects|
|
|
projects = Project.where(id: lfs_objects_projects_without_lfs_objects.select(:project_id))
|
|
|
|
if projects.present?
|
|
ProjectCacheWorker.bulk_perform_in_with_contexts(
|
|
CLEAR_CACHE_DELAY,
|
|
projects,
|
|
arguments_proc: ->(project) { [project.id, [], [:lfs_objects_size]] },
|
|
context_proc: ->(project) { { project: project } }
|
|
)
|
|
end
|
|
|
|
lfs_objects_projects_without_lfs_objects.delete_all
|
|
end
|
|
end
|
|
|
|
def cleanup_lfs_objects_projects_without_project(start_id, end_id)
|
|
each_record_without_association(start_id, end_id, :project, :projects) do |lfs_objects_projects_without_projects|
|
|
lfs_objects_projects_without_projects.delete_all
|
|
end
|
|
end
|
|
|
|
def each_record_without_association(start_id, end_id, association, table_name)
|
|
batch = LfsObjectsProject.where(id: start_id..end_id)
|
|
|
|
batch.each_batch(of: SUB_BATCH_SIZE) do |sub_batch|
|
|
first, last = sub_batch.pick(Arel.sql('min(lfs_objects_projects.id), max(lfs_objects_projects.id)'))
|
|
|
|
lfs_objects_without_association =
|
|
LfsObjectsProject
|
|
.unscoped
|
|
.left_outer_joins(association)
|
|
.where(id: (first..last), table_name => { id: nil })
|
|
|
|
yield lfs_objects_without_association
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|