diff options
Diffstat (limited to 'app/models/namespaces')
-rw-r--r-- | app/models/namespaces/traversal/linear.rb | 51 | ||||
-rw-r--r-- | app/models/namespaces/traversal/recursive.rb | 20 |
2 files changed, 56 insertions, 15 deletions
diff --git a/app/models/namespaces/traversal/linear.rb b/app/models/namespaces/traversal/linear.rb index d0281f4d974..3d78f384634 100644 --- a/app/models/namespaces/traversal/linear.rb +++ b/app/models/namespaces/traversal/linear.rb @@ -64,15 +64,28 @@ module Namespaces traversal_ids.present? end - def root_ancestor - return super if parent.nil? - return super unless persisted? + def use_traversal_ids_for_ancestors? + return false unless use_traversal_ids? + return false unless Feature.enabled?(:use_traversal_ids_for_ancestors, root_ancestor, default_enabled: :yaml) + + traversal_ids.present? + end + + def use_traversal_ids_for_root_ancestor? + return false unless Feature.enabled?(:use_traversal_ids_for_root_ancestor, default_enabled: :yaml) - return super if traversal_ids.blank? - return super unless Feature.enabled?(:use_traversal_ids_for_root_ancestor, default_enabled: :yaml) + traversal_ids.present? + end + + def root_ancestor + return super unless use_traversal_ids_for_root_ancestor? strong_memoize(:root_ancestor) do - Namespace.find_by(id: traversal_ids.first) + if parent.nil? + self + else + Namespace.find_by(id: traversal_ids.first) + end end end @@ -95,14 +108,33 @@ module Namespaces end def ancestors(hierarchy_order: nil) - return super() unless use_traversal_ids? - return super() unless Feature.enabled?(:use_traversal_ids_for_ancestors, root_ancestor, default_enabled: :yaml) + return super unless use_traversal_ids_for_ancestors? return self.class.none if parent_id.blank? lineage(bottom: parent, hierarchy_order: hierarchy_order) end + def ancestor_ids(hierarchy_order: nil) + return super unless use_traversal_ids_for_ancestors? + + hierarchy_order == :desc ? traversal_ids[0..-2] : traversal_ids[0..-2].reverse + end + + def self_and_ancestors(hierarchy_order: nil) + return super unless use_traversal_ids_for_ancestors? + + return self.class.where(id: id) if parent_id.blank? + + lineage(bottom: self, hierarchy_order: hierarchy_order) + end + + def self_and_ancestor_ids(hierarchy_order: nil) + return super unless use_traversal_ids_for_ancestors? + + hierarchy_order == :desc ? traversal_ids : traversal_ids.reverse + end + private # Update the traversal_ids for the full hierarchy. @@ -112,8 +144,7 @@ module Namespaces # Clear any previously memoized root_ancestor as our ancestors have changed. clear_memoization(:root_ancestor) - # We cannot rely on Namespaces::Traversal::Linear#root_ancestor because it might be stale - Namespace::TraversalHierarchy.for_namespace(recursive_root_ancestor).sync_traversal_ids! + Namespace::TraversalHierarchy.for_namespace(self).sync_traversal_ids! end # Lock the root of the hierarchy we just left, and lock the root of the hierarchy diff --git a/app/models/namespaces/traversal/recursive.rb b/app/models/namespaces/traversal/recursive.rb index 5a1a9d24117..d9e8743aa50 100644 --- a/app/models/namespaces/traversal/recursive.rb +++ b/app/models/namespaces/traversal/recursive.rb @@ -10,7 +10,7 @@ module Namespaces if persisted? strong_memoize(:root_ancestor) do - self_and_ancestors.reorder(nil).find_by(parent_id: nil) + recursive_self_and_ancestors.reorder(nil).find_by(parent_id: nil) end else parent.root_ancestor @@ -26,14 +26,19 @@ module Namespaces alias_method :recursive_self_and_hierarchy, :self_and_hierarchy # Returns all the ancestors of the current namespaces. - def ancestors + def ancestors(hierarchy_order: nil) return self.class.none unless parent_id object_hierarchy(self.class.where(id: parent_id)) - .base_and_ancestors + .base_and_ancestors(hierarchy_order: hierarchy_order) end alias_method :recursive_ancestors, :ancestors + def ancestor_ids(hierarchy_order: nil) + recursive_ancestors(hierarchy_order: hierarchy_order).pluck(:id) + end + alias_method :recursive_ancestor_ids, :ancestor_ids + # returns all ancestors upto but excluding the given namespace # when no namespace is given, all ancestors upto the top are returned def ancestors_upto(top = nil, hierarchy_order: nil) @@ -49,6 +54,11 @@ module Namespaces end alias_method :recursive_self_and_ancestors, :self_and_ancestors + def self_and_ancestor_ids(hierarchy_order: nil) + recursive_self_and_ancestors(hierarchy_order: hierarchy_order).pluck(:id) + end + alias_method :recursive_self_and_ancestor_ids, :self_and_ancestor_ids + # Returns all the descendants of the current namespace. def descendants object_hierarchy(self.class.where(parent_id: id)) @@ -63,12 +73,12 @@ module Namespaces alias_method :recursive_self_and_descendants, :self_and_descendants def self_and_descendant_ids - self_and_descendants.select(:id) + recursive_self_and_descendants.select(:id) end alias_method :recursive_self_and_descendant_ids, :self_and_descendant_ids def object_hierarchy(ancestors_base) - Gitlab::ObjectHierarchy.new(ancestors_base, options: { use_distinct: Feature.enabled?(:use_distinct_in_object_hierarchy, self) }) + Gitlab::ObjectHierarchy.new(ancestors_base) end end end |