Add a method to retrieve projects when selective sync is enabled

This method allow us to enable selective sync support for the
FDW queries.
parent feed78d6
......@@ -14,6 +14,18 @@ module Geo
has_many :geo_node_namespace_links, class_name: 'Geo::Fdw::GeoNodeNamespaceLink'
has_many :namespaces, class_name: 'Geo::Fdw::Namespace', through: :geo_node_namespace_links
def projects
return Geo::Fdw::Project.all unless selective_sync?
if selective_sync_by_namespaces?
projects_for_selected_namespaces
elsif selective_sync_by_shards?
projects_for_selected_shards
else
Geo::Fdw::Project.none
end
end
def project_registries
return Geo::ProjectRegistry.all unless selective_sync?
......@@ -28,11 +40,25 @@ module Geo
private
def projects_for_selected_namespaces
Geo::Fdw::Project
.within_namespaces(selected_namespaces_and_descendants.select(:id))
end
def projects_for_selected_shards
Geo::Fdw::Project.within_shards(selective_sync_shards)
end
def registries_for_selected_namespaces
Gitlab::Geo::Fdw::ProjectRegistryQueryBuilder.new
.within_namespaces(selected_namespaces_and_descendants.select(:id))
end
def registries_for_selected_shards
Gitlab::Geo::Fdw::ProjectRegistryQueryBuilder.new
.within_shards(selective_sync_shards)
end
def selected_namespaces_and_descendants
relation = selected_namespaces_and_descendants_cte.apply_to(Geo::Fdw::Namespace.all)
relation.extend(Gitlab::Database::ReadOnlyRelation)
......@@ -56,11 +82,6 @@ module Geo
cte
end
def registries_for_selected_shards
Gitlab::Geo::Fdw::ProjectRegistryQueryBuilder.new
.within_shards(selective_sync_shards)
end
def fdw_namespaces_table
Geo::Fdw::Namespace.arel_table
end
......
......@@ -8,6 +8,46 @@ RSpec.describe Geo::Fdw::GeoNode, :geo, type: :model do
it { is_expected.to have_many(:namespaces).class_name('Geo::Fdw::Namespace').through(:geo_node_namespace_links) }
end
# Disable transactions via :delete method because a foreign table
# can't see changes inside a transaction of a different connection.
describe '#projects', :delete do
before do
skip('FDW is not configured') unless Gitlab::Geo::Fdw.enabled?
end
let(:node) { create(:geo_node) }
let(:group_1) { create(:group) }
let(:group_2) { create(:group) }
let(:nested_group_1) { create(:group, parent: group_1) }
let(:project_1) { create(:project, group: group_1) }
let(:project_2) { create(:project, group: nested_group_1) }
let(:project_3) { create(:project, :broken_storage, group: group_2) }
subject { described_class.find(node.id) }
it 'returns all registries without selective sync' do
expect(subject.projects).to match_ids(project_1, project_2, project_3)
end
it 'returns projects that belong to the namespaces with selective sync by namespace' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.projects).to match_ids(project_1, project_2)
end
it 'returns projects that belong to the shards with selective sync by shard' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: %w[broken])
expect(subject.projects).to match_ids(project_3)
end
it 'returns nothing if an unrecognised selective sync type is used' do
node.update_attribute(:selective_sync_type, 'unknown')
expect(subject.projects).to be_empty
end
end
# Disable transactions via :delete method because a foreign table
# can't see changes inside a transaction of a different connection.
describe '#project_registries', :delete do
......@@ -33,15 +73,15 @@ RSpec.describe Geo::Fdw::GeoNode, :geo, type: :model do
end
it 'returns registries where projects belong to the namespaces with selective sync by namespace' do
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1, nested_group_1])
node.update!(selective_sync_type: 'namespaces', namespaces: [group_1])
expect(subject.project_registries).to match_array([registry_1, registry_2])
end
it 'returns registries where projects belong to the shards with selective sync by shard' do
node.update!(selective_sync_type: 'shards', selective_sync_shards: %w[default bar])
node.update!(selective_sync_type: 'shards', selective_sync_shards: %w[broken])
expect(subject.project_registries).to match_array([registry_1, registry_2])
expect(subject.project_registries).to match_array([registry_3])
end
it 'returns nothing if an unrecognised selective sync type is used' do
......
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