Use a query builder rather than a PORO to create FDW queries

We were using the PORO to group a bunch of static methods,
and we never instantiate it, so a query builder makes much
more sense in this context.
parent 1b482c5d
......@@ -21,9 +21,10 @@ module Geo
def execute
return Geo::ProjectRegistry.none unless valid_shard?
current_node.project_registries
.merge(Geo::Fdw::ProjectRegistry.registries_pending_verification)
.merge(Geo::Fdw::ProjectRegistry.within_shards(shard_name))
Gitlab::Geo::Fdw::ProjectRegistryQueryBuilder
.new(current_node.project_registries)
.registries_pending_verification
.within_shards(shard_name)
.limit(batch_size)
end
# rubocop:enable CodeReuse/ActiveRecord
......
......@@ -29,7 +29,7 @@ module Geo
private
def registries_for_selected_namespaces
Geo::Fdw::ProjectRegistry
Gitlab::Geo::Fdw::ProjectRegistryQueryBuilder.new
.within_namespaces(selected_namespaces_and_descendants.select(:id))
end
......@@ -57,7 +57,8 @@ module Geo
end
def registries_for_selected_shards
Geo::Fdw::ProjectRegistry.within_shards(selective_sync_shards)
Gitlab::Geo::Fdw::ProjectRegistryQueryBuilder.new
.within_shards(selective_sync_shards)
end
def fdw_namespaces_table
......
......@@ -17,6 +17,14 @@ module Geo
def search(query)
fuzzy_search(query, [:path, :name, :description])
end
def within_namespaces(namespace_ids)
where(arel_table.name => { namespace_id: namespace_ids })
end
def within_shards(shard_names)
where(repository_storage: Array(shard_names))
end
end
end
end
......
# frozen_string_literal: true
module Geo
module Fdw
class ProjectRegistry
class << self
# Builder class to create composable queries using FDW to
# retrieve project registries.
#
# Basic usage:
#
# Gitlab::Geo::Fdw::ProjectRegistryQueryBuilder
# .new(Geo::ProjectRegistry.all)
# .registries_pending_verification
# .within_shards(selective_sync_shards)
#
module Gitlab
module Geo
class Fdw
class ProjectRegistryQueryBuilder < SimpleDelegator
attr_reader :query
def initialize(query = nil)
@query = query || base_query
super(query)
end
# rubocop:disable CodeReuse/ActiveRecord
def registries_pending_verification
Geo::ProjectRegistry
.joins(fdw_inner_join_projects)
.joins(fdw_inner_join_repository_state)
.where(repositories_pending_verification.or(wikis_pending_verification))
reflect(
query
.joins(fdw_inner_join_projects)
.joins(fdw_inner_join_repository_state)
.where(repositories_pending_verification.or(wikis_pending_verification))
)
end
# rubocop:enable CodeReuse/ActiveRecord
# rubocop:disable CodeReuse/ActiveRecord
def within_namespaces(namespace_ids)
Geo::ProjectRegistry
.joins(fdw_inner_join_projects)
.where(fdw_projects_table.name => { namespace_id: namespace_ids })
reflect(
query
.joins(fdw_inner_join_projects)
.merge(projects_within_namespaces(namespace_ids))
)
end
# rubocop:enable CodeReuse/ActiveRecord
# rubocop:disable CodeReuse/ActiveRecord
def within_shards(shard_names)
Geo::ProjectRegistry
.joins(fdw_inner_join_projects)
.where(fdw_projects_table.name => { repository_storage: Array(shard_names) })
reflect(
query
.joins(fdw_inner_join_projects)
.merge(projects_within_shards(shard_names))
)
end
# rubocop:enable CodeReuse/ActiveRecord
private
def base_query
::Geo::ProjectRegistry.select(project_registries_table[Arel.star])
end
def reflect(query)
self.class.new(query)
end
def project_registries_table
Geo::ProjectRegistry.arel_table
::Geo::ProjectRegistry.arel_table
end
def fdw_projects_table
Geo::Fdw::Project.arel_table
::Geo::Fdw::Project.arel_table
end
def fdw_repository_state_table
Geo::Fdw::ProjectRepositoryState.arel_table
::Geo::Fdw::ProjectRepositoryState.arel_table
end
def fdw_inner_join_projects
......@@ -51,13 +88,23 @@ module Geo
.join_sources
end
def projects_within_namespaces(namespace_ids)
::Geo::Fdw::Project.within_namespaces(namespace_ids)
end
def projects_within_shards(shard_names)
::Geo::Fdw::Project.within_shards(shard_names)
end
def repositories_pending_verification
Geo::ProjectRegistry.repositories_pending_verification
::Geo::ProjectRegistry
.repositories_pending_verification
.and(fdw_repository_state_table[:repository_verification_checksum].not_eq(nil))
end
def wikis_pending_verification
Geo::ProjectRegistry.wikis_pending_verification
::Geo::ProjectRegistry
.wikis_pending_verification
.and(fdw_repository_state_table[:wiki_verification_checksum].not_eq(nil))
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment