diff options
Diffstat (limited to 'app/models/namespaces/traversal/linear_scopes.rb')
-rw-r--r-- | app/models/namespaces/traversal/linear_scopes.rb | 51 |
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) |