Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/object_hierarchy.rb')
-rw-r--r--lib/gitlab/object_hierarchy.rb28
1 files changed, 28 insertions, 0 deletions
diff --git a/lib/gitlab/object_hierarchy.rb b/lib/gitlab/object_hierarchy.rb
index 693f1470d9d..9a850246221 100644
--- a/lib/gitlab/object_hierarchy.rb
+++ b/lib/gitlab/object_hierarchy.rb
@@ -92,6 +92,14 @@ module Gitlab
end
# rubocop: enable CodeReuse/ActiveRecord
+ # Returns a relation that includes ID of the descendants_base set of objects
+ # and all their descendants IDs (recursively).
+ # rubocop: disable CodeReuse/ActiveRecord
+ def base_and_descendant_ids
+ read_only(base_and_descendant_ids_cte.apply_to(unscoped_model.select(objects_table[:id])))
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
# Returns a relation that includes the base objects, their ancestors,
# and the descendants of the base objects.
#
@@ -214,6 +222,26 @@ module Gitlab
end
# rubocop: enable CodeReuse/ActiveRecord
+ # rubocop: disable CodeReuse/ActiveRecord
+ def base_and_descendant_ids_cte
+ cte = SQL::RecursiveCTE.new(:base_and_descendants)
+
+ base_query = descendants_base.except(:order).select(objects_table[:id])
+
+ cte << base_query
+
+ # Recursively get all the descendants of the base set.
+ descendants_query = unscoped_model
+ .select(objects_table[:id])
+ .from(from_tables(cte))
+ .where(descendant_conditions(cte))
+ .except(:order)
+
+ cte << descendants_query
+ cte
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
def objects_table
model.arel_table
end