gitlab-org--gitlab-foss/lib/gitlab/background_migration/populate_vulnerability_read...

85 lines
2.6 KiB
Ruby

# frozen_string_literal: true
module Gitlab
module BackgroundMigration
# rubocop:disable Style/Documentation
class PopulateVulnerabilityReads
include Gitlab::Database::DynamicModelHelpers
PAUSE_SECONDS = 0.1
def perform(start_id, end_id, sub_batch_size)
vulnerability_model.where(id: start_id..end_id).each_batch(of: sub_batch_size) do |sub_batch|
first, last = sub_batch.pluck(Arel.sql('min(id), max(id)')).first
connection.execute(insert_query(first, last))
sleep PAUSE_SECONDS
end
mark_job_as_succeeded(start_id, end_id, sub_batch_size)
end
private
def vulnerability_model
define_batchable_model('vulnerabilities', connection: connection)
end
def connection
ApplicationRecord.connection
end
def insert_query(start_id, end_id)
<<~SQL
INSERT INTO vulnerability_reads (
vulnerability_id,
project_id,
scanner_id,
report_type,
severity,
state,
has_issues,
resolved_on_default_branch,
uuid,
location_image
)
SELECT
vulnerabilities.id,
vulnerabilities.project_id,
vulnerability_scanners.id,
vulnerabilities.report_type,
vulnerabilities.severity,
vulnerabilities.state,
CASE
WHEN
vulnerability_issue_links.vulnerability_id IS NOT NULL
THEN
true
ELSE
false
END
has_issues,
vulnerabilities.resolved_on_default_branch,
vulnerability_occurrences.uuid::uuid,
vulnerability_occurrences.location ->> 'image'
FROM
vulnerabilities
INNER JOIN vulnerability_occurrences ON vulnerability_occurrences.vulnerability_id = vulnerabilities.id
INNER JOIN vulnerability_scanners ON vulnerability_scanners.id = vulnerability_occurrences.scanner_id
LEFT JOIN vulnerability_issue_links ON vulnerability_issue_links.vulnerability_id = vulnerabilities.id
WHERE vulnerabilities.id BETWEEN #{start_id} AND #{end_id}
ON CONFLICT(vulnerability_id) DO NOTHING;
SQL
end
def mark_job_as_succeeded(*arguments)
Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded(
self.class.name.demodulize,
arguments
)
end
end
# rubocop:enable Style/Documentation
end
end