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 ...@@ -21,9 +21,10 @@ module Geo
def execute def execute
return Geo::ProjectRegistry.none unless valid_shard? return Geo::ProjectRegistry.none unless valid_shard?
current_node.project_registries Gitlab::Geo::Fdw::ProjectRegistryQueryBuilder
.merge(Geo::Fdw::ProjectRegistry.registries_pending_verification) .new(current_node.project_registries)
.merge(Geo::Fdw::ProjectRegistry.within_shards(shard_name)) .registries_pending_verification
.within_shards(shard_name)
.limit(batch_size) .limit(batch_size)
end end
# rubocop:enable CodeReuse/ActiveRecord # rubocop:enable CodeReuse/ActiveRecord
......
...@@ -29,7 +29,7 @@ module Geo ...@@ -29,7 +29,7 @@ module Geo
private private
def registries_for_selected_namespaces def registries_for_selected_namespaces
Geo::Fdw::ProjectRegistry Gitlab::Geo::Fdw::ProjectRegistryQueryBuilder.new
.within_namespaces(selected_namespaces_and_descendants.select(:id)) .within_namespaces(selected_namespaces_and_descendants.select(:id))
end end
...@@ -57,7 +57,8 @@ module Geo ...@@ -57,7 +57,8 @@ module Geo
end end
def registries_for_selected_shards def registries_for_selected_shards
Geo::Fdw::ProjectRegistry.within_shards(selective_sync_shards) Gitlab::Geo::Fdw::ProjectRegistryQueryBuilder.new
.within_shards(selective_sync_shards)
end end
def fdw_namespaces_table def fdw_namespaces_table
......
...@@ -17,6 +17,14 @@ module Geo ...@@ -17,6 +17,14 @@ module Geo
def search(query) def search(query)
fuzzy_search(query, [:path, :name, :description]) fuzzy_search(query, [:path, :name, :description])
end 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 end
end end
......
# frozen_string_literal: true # frozen_string_literal: true
module Geo # Builder class to create composable queries using FDW to
module Fdw # retrieve project registries.
class ProjectRegistry #
class << self # 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 def registries_pending_verification
Geo::ProjectRegistry reflect(
.joins(fdw_inner_join_projects) query
.joins(fdw_inner_join_repository_state) .joins(fdw_inner_join_projects)
.where(repositories_pending_verification.or(wikis_pending_verification)) .joins(fdw_inner_join_repository_state)
.where(repositories_pending_verification.or(wikis_pending_verification))
)
end end
# rubocop:enable CodeReuse/ActiveRecord
# rubocop:disable CodeReuse/ActiveRecord
def within_namespaces(namespace_ids) def within_namespaces(namespace_ids)
Geo::ProjectRegistry reflect(
.joins(fdw_inner_join_projects) query
.where(fdw_projects_table.name => { namespace_id: namespace_ids }) .joins(fdw_inner_join_projects)
.merge(projects_within_namespaces(namespace_ids))
)
end end
# rubocop:enable CodeReuse/ActiveRecord
# rubocop:disable CodeReuse/ActiveRecord
def within_shards(shard_names) def within_shards(shard_names)
Geo::ProjectRegistry reflect(
.joins(fdw_inner_join_projects) query
.where(fdw_projects_table.name => { repository_storage: Array(shard_names) }) .joins(fdw_inner_join_projects)
.merge(projects_within_shards(shard_names))
)
end end
# rubocop:enable CodeReuse/ActiveRecord
private 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 def project_registries_table
Geo::ProjectRegistry.arel_table ::Geo::ProjectRegistry.arel_table
end end
def fdw_projects_table def fdw_projects_table
Geo::Fdw::Project.arel_table ::Geo::Fdw::Project.arel_table
end end
def fdw_repository_state_table def fdw_repository_state_table
Geo::Fdw::ProjectRepositoryState.arel_table ::Geo::Fdw::ProjectRepositoryState.arel_table
end end
def fdw_inner_join_projects def fdw_inner_join_projects
...@@ -51,13 +88,23 @@ module Geo ...@@ -51,13 +88,23 @@ module Geo
.join_sources .join_sources
end 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 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)) .and(fdw_repository_state_table[:repository_verification_checksum].not_eq(nil))
end end
def wikis_pending_verification 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)) .and(fdw_repository_state_table[:wiki_verification_checksum].not_eq(nil))
end end
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