summaryrefslogtreecommitdiff
path: root/app/models/namespaces/traversal/linear_scopes.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/namespaces/traversal/linear_scopes.rb')
-rw-r--r--app/models/namespaces/traversal/linear_scopes.rb51
1 files changed, 46 insertions, 5 deletions
diff --git a/app/models/namespaces/traversal/linear_scopes.rb b/app/models/namespaces/traversal/linear_scopes.rb
index 90fae8ef35d..2da0e48c2da 100644
--- a/app/models/namespaces/traversal/linear_scopes.rb
+++ b/app/models/namespaces/traversal/linear_scopes.rb
@@ -15,6 +15,28 @@ module Namespaces
select('namespaces.traversal_ids[array_length(namespaces.traversal_ids, 1)] AS id')
end
+ def self_and_ancestors(include_self: true, hierarchy_order: nil)
+ return super unless use_traversal_ids_for_ancestor_scopes?
+
+ records = unscoped
+ .without_sti_condition
+ .where(id: without_sti_condition.select('unnest(traversal_ids)'))
+ .order_by_depth(hierarchy_order)
+ .normal_select
+
+ if include_self
+ records
+ else
+ records.where.not(id: all.as_ids)
+ end
+ end
+
+ def self_and_ancestor_ids(include_self: true)
+ return super unless use_traversal_ids_for_ancestor_scopes?
+
+ self_and_ancestors(include_self: include_self).as_ids
+ end
+
def self_and_descendants(include_self: true)
return super unless use_traversal_ids?
@@ -22,11 +44,7 @@ module Namespaces
distinct = records.select('DISTINCT on(namespaces.id) namespaces.*')
- # Produce a query of the form: SELECT * FROM namespaces;
- #
- # When we have queries that break this SELECT * format we can run in to errors.
- # For example `SELECT DISTINCT on(...)` will fail when we chain a `.count` c
- unscoped.without_sti_condition.from(distinct, :namespaces)
+ distinct.normal_select
end
def self_and_descendant_ids(include_self: true)
@@ -42,12 +60,35 @@ module Namespaces
unscope(where: :type)
end
+ def order_by_depth(hierarchy_order)
+ return all unless hierarchy_order
+
+ depth_order = hierarchy_order == :asc ? :desc : :asc
+
+ all
+ .select(Arel.star, 'array_length(traversal_ids, 1) as depth')
+ .order(depth: depth_order, id: :asc)
+ end
+
+ # Produce a query of the form: SELECT * FROM namespaces;
+ #
+ # When we have queries that break this SELECT * format we can run in to errors.
+ # For example `SELECT DISTINCT on(...)` will fail when we chain a `.count` c
+ def normal_select
+ unscoped.without_sti_condition.from(all, :namespaces)
+ end
+
private
def use_traversal_ids?
Feature.enabled?(:use_traversal_ids, default_enabled: :yaml)
end
+ def use_traversal_ids_for_ancestor_scopes?
+ Feature.enabled?(:use_traversal_ids_for_ancestor_scopes, default_enabled: :yaml) &&
+ use_traversal_ids?
+ end
+
def self_and_descendants_with_duplicates(include_self: true)
base_ids = select(:id)