Refactor Geo::SelectiveSync concern

Since GitLab 13.2 we don't rely on FDW query/models
parent bbb9930a
...@@ -45,19 +45,21 @@ module Geo::SelectiveSync ...@@ -45,19 +45,21 @@ module Geo::SelectiveSync
private private
def selected_namespaces_and_descendants def selected_namespaces_and_descendants
relation = selected_namespaces_and_descendants_cte.apply_to(namespaces_model.all) relation = selected_namespaces_and_descendants_cte.apply_to(Namespace.all)
read_only(relation) read_only_relation(relation)
end end
def selected_namespaces_and_descendants_cte def selected_namespaces_and_descendants_cte
namespaces_table = Namespace.arel_table
cte = Gitlab::SQL::RecursiveCTE.new(:base_and_descendants) cte = Gitlab::SQL::RecursiveCTE.new(:base_and_descendants)
cte << geo_node_namespace_links cte << geo_node_namespace_links
.select(geo_node_namespace_links_table[:namespace_id].as('id')) .select(geo_node_namespace_links.arel_table[:namespace_id].as('id'))
.except(:order) .except(:order)
# Recursively get all the descendants of the base set. # Recursively get all the descendants of the base set.
cte << namespaces_model cte << Namespace
.select(namespaces_table[:id]) .select(namespaces_table[:id])
.from([namespaces_table, cte.table]) .from([namespaces_table, cte.table])
.where(namespaces_table[:parent_id].eq(cte.table[:id])) .where(namespaces_table[:parent_id].eq(cte.table[:id]))
...@@ -67,8 +69,8 @@ module Geo::SelectiveSync ...@@ -67,8 +69,8 @@ module Geo::SelectiveSync
end end
def selected_leaf_namespaces_and_ancestors def selected_leaf_namespaces_and_ancestors
relation = selected_leaf_namespaces_and_ancestors_cte.apply_to(namespaces_model.all) relation = selected_leaf_namespaces_and_ancestors_cte.apply_to(Namespace.all)
read_only(relation) read_only_relation(relation)
end end
# Returns a CTE selecting namespace IDs for selected shards # Returns a CTE selecting namespace IDs for selected shards
...@@ -78,14 +80,16 @@ module Geo::SelectiveSync ...@@ -78,14 +80,16 @@ module Geo::SelectiveSync
# namespace of every project in those shards. We must also sync every # namespace of every project in those shards. We must also sync every
# ancestor of those namespaces. # ancestor of those namespaces.
def selected_leaf_namespaces_and_ancestors_cte def selected_leaf_namespaces_and_ancestors_cte
namespaces_table = Namespace.arel_table
cte = Gitlab::SQL::RecursiveCTE.new(:base_and_ancestors) cte = Gitlab::SQL::RecursiveCTE.new(:base_and_ancestors)
cte << namespaces_model cte << Namespace
.select(namespaces_table[:id], namespaces_table[:parent_id]) .select(namespaces_table[:id], namespaces_table[:parent_id])
.where(id: projects.select(:namespace_id)) .where(id: projects.select(:namespace_id))
# Recursively get all the ancestors of the base set. # Recursively get all the ancestors of the base set.
cte << namespaces_model cte << Namespace
.select(namespaces_table[:id], namespaces_table[:parent_id]) .select(namespaces_table[:id], namespaces_table[:parent_id])
.from([namespaces_table, cte.table]) .from([namespaces_table, cte.table])
.where(namespaces_table[:id].eq(cte.table[:parent_id])) .where(namespaces_table[:id].eq(cte.table[:parent_id]))
...@@ -94,36 +98,10 @@ module Geo::SelectiveSync ...@@ -94,36 +98,10 @@ module Geo::SelectiveSync
cte cte
end end
def read_only(relation) def read_only_relation(relation)
# relations using a CTE are not safe to use with update_all as it will # relations using a CTE are not safe to use with update_all as it will
# throw away the CTE, hence we mark them as read-only. # throw away the CTE, hence we mark them as read-only.
relation.extend(Gitlab::Database::ReadOnlyRelation) relation.extend(Gitlab::Database::ReadOnlyRelation)
relation relation
end end
# This concern doesn't define a geo_node_namespace_links relation. That's
# done in ::GeoNode or ::Geo::Fdw::GeoNode respectively. So when we use the
# same code from the two places, they act differently - the first doesn't
# use FDW, the second does.
def geo_node_namespace_links_table
geo_node_namespace_links.arel_table
end
# This concern doesn't define a namespaces relation. That's done in ::GeoNode
# or ::Geo::Fdw::GeoNode respectively. So when we use the same code from the
# two places, they act differently - the first doesn't use FDW, the second does.
def namespaces_model
namespaces.model
end
# This concern doesn't define a namespaces relation. That's done in ::GeoNode
# or ::Geo::Fdw::GeoNode respectively. So when we use the same code from the
# two places, they act differently - the first doesn't use FDW, the second does.
def namespaces_table
namespaces.arel_table
end
def projects_table
Project.arel_table
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