Не подтверждена Коммит 3466b832 создал по автору Tetiana Chupryna's avatar Tetiana Chupryna
Просмотр файлов

Cleanup the method to reduce AbcSize

владелец bbf692ba
......@@ -10,72 +10,19 @@ def initialize(components:)
@components = components
end
# rubocop: disable Metrics/AbcSize
def fetch
use_replica_if_available do
first_query_search_fields = [
::PackageMetadata::PackageVersion.arel_table[:pm_package_id],
::PackageMetadata::PackageVersion.arel_table[:version]
]
search_fields = [
::PackageMetadata::Package.arel_table[:purl_type],
::PackageMetadata::Package.arel_table[:name],
::PackageMetadata::PackageVersion.arel_table[:version]
]
records_with_licenses = {}
components.each_slice(BATCH_SIZE).each do |_components_batch|
# rubocop: disable CodeReuse/ActiveRecord
component_tuples = components.map do |component|
purl_type_int = ::Enums::Sbom.purl_types[component.purl_type]
[purl_type_int, component.name, component.version]
end
component_values_list = Arel::Nodes::Grouping.new(Arel::Nodes::ValuesList.new(component_tuples))
pm_packages_table = ::PackageMetadata::Package.arel_table
needed_package_versions_table = Arel::Table.new(:needed_package_versions)
component_values = Arel::Nodes::As.new(
Hashie::Mash.new(
name: Arel.sql('needed_package_versions(purl_type, name, version)')), component_values_list
)
query = needed_package_versions_table
.project(pm_packages_table[:id], needed_package_versions_table[:version])
.with(component_values)
.distinct
.join(pm_packages_table)
.on(
pm_packages_table[:purl_type].eq(needed_package_versions_table[:purl_type])
.and(
pm_packages_table[:name].eq(needed_package_versions_table[:name]))
)
query_results = ApplicationRecord.connection.execute(query.to_sql)
query_results = ApplicationRecord.connection.execute(query(components).to_sql)
package_ids_and_versions = query_results.map do |result|
Arel::Nodes::Grouping.new([Arel::Nodes.build_quoted(result["id"]),
Arel::Nodes.build_quoted(result["version"])])
end
records_for_batch = ::PackageMetadata::Package
.joins(package_versions: :licenses)
.where(
Arel::Nodes::In.new(
Arel::Nodes::Grouping.new(first_query_search_fields),
package_ids_and_versions
)
)
.group(search_fields)
.pluck(*search_fields, "ARRAY_AGG(pm_licenses.spdx_identifier)")
# rubocop: enable CodeReuse/ActiveRecord
records_for_batch.each do |purl_type, name, version, licenses|
records_for_batch(package_ids_and_versions).each do |purl_type, name, version, licenses|
records_with_licenses[File.join(name, version, purl_type)] =
Hashie::Mash.new(purl_type: purl_type, name: name, version: version, licenses: licenses)
end
......@@ -85,7 +32,6 @@ def fetch
records_with_licenses.values
end
end
# rubocop: enable Metrics/AbcSize
private
......@@ -102,6 +48,61 @@ def add_records_with_unknown_licenses(records_with_licenses)
end
end
# rubocop: disable CodeReuse/ActiveRecord
def query(components)
component_tuples = components.map do |component|
purl_type_int = ::Enums::Sbom.purl_types[component.purl_type]
[purl_type_int, component.name, component.version]
end
component_values_list = Arel::Nodes::Grouping.new(Arel::Nodes::ValuesList.new(component_tuples))
pm_packages_table = ::PackageMetadata::Package.arel_table
needed_package_versions_table = Arel::Table.new(:needed_package_versions)
component_values = Arel::Nodes::As.new(
Hashie::Mash.new(
name: Arel.sql('needed_package_versions(purl_type, name, version)')), component_values_list
)
needed_package_versions_table
.project(pm_packages_table[:id], needed_package_versions_table[:version])
.with(component_values)
.distinct
.join(pm_packages_table)
.on(
pm_packages_table[:purl_type].eq(needed_package_versions_table[:purl_type])
.and(
pm_packages_table[:name].eq(needed_package_versions_table[:name]))
)
end
def records_for_batch(package_ids_and_versions)
first_query_search_fields = [
::PackageMetadata::PackageVersion.arel_table[:pm_package_id],
::PackageMetadata::PackageVersion.arel_table[:version]
]
search_fields = [
::PackageMetadata::Package.arel_table[:purl_type],
::PackageMetadata::Package.arel_table[:name],
::PackageMetadata::PackageVersion.arel_table[:version]
]
::PackageMetadata::Package
.joins(package_versions: :licenses)
.where(
Arel::Nodes::In.new(
Arel::Nodes::Grouping.new(first_query_search_fields),
package_ids_and_versions
)
)
.group(search_fields)
.pluck(*search_fields, "ARRAY_AGG(pm_licenses.spdx_identifier)")
end
# rubocop: enable CodeReuse/ActiveRecord
def use_replica_if_available(&block)
::Gitlab::Database::LoadBalancing::Session.current.use_replicas_for_read_queries(&block)
end
......
......@@ -67,7 +67,7 @@
it 'fetches in batches of BATCH_SIZE' do
control = ActiveRecord::QueryRecorder.new { fetch }
# when the batch size is 1, we execute 2 queries for each component
# we execute 2 queries for each batch
expect(control.count).to be(components_to_fetch.count * 2)
end
......
Поддерживает Markdown
0% или .
You are about to add 0 people to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Пожалуйста, зарегистрируйтесь или чтобы прокомментировать