diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-03 00:07:46 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-03 00:07:46 +0300 |
commit | 9579eee8954e0405c2dadb19c2a73c9597ce37ea (patch) | |
tree | d90223b7e449d8d25eef60ad16084ce0d2ca2b1b /app/models | |
parent | 0a9b6b99a9bdcacea434501320f1a8d131a33827 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/models')
-rw-r--r-- | app/models/concerns/issue_parent.rb | 11 | ||||
-rw-r--r-- | app/models/group.rb | 1 | ||||
-rw-r--r-- | app/models/namespaces/traversal/linear.rb | 53 | ||||
-rw-r--r-- | app/models/project.rb | 1 | ||||
-rw-r--r-- | app/models/work_item.rb | 4 | ||||
-rw-r--r-- | app/models/work_items/type.rb | 4 |
6 files changed, 69 insertions, 5 deletions
diff --git a/app/models/concerns/issue_parent.rb b/app/models/concerns/issue_parent.rb new file mode 100644 index 00000000000..c1fcbdcfc12 --- /dev/null +++ b/app/models/concerns/issue_parent.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +# == IssuParent +# +# Used as a common ancestor for Group and Project so we can allow a polymorphic +# Types::GlobalIDType[::IssueParent] in the GraphQL API +# +# Used by Project, Group +# +module IssueParent +end diff --git a/app/models/group.rb b/app/models/group.rb index a2d984973bd..67800306606 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -21,6 +21,7 @@ class Group < Namespace include ChronicDurationAttribute include RunnerTokenExpirationInterval include Todoable + include IssueParent extend ::Gitlab::Utils::Override diff --git a/app/models/namespaces/traversal/linear.rb b/app/models/namespaces/traversal/linear.rb index 16a9c20dfdc..0e9760832af 100644 --- a/app/models/namespaces/traversal/linear.rb +++ b/app/models/namespaces/traversal/linear.rb @@ -47,6 +47,9 @@ module Namespaces # This uses rails internal before_commit API to sync traversal_ids on namespace create, right before transaction is committed. # This helps reduce the time during which the root namespace record is locked to ensure updated traversal_ids are valid before_commit :sync_traversal_ids, on: [:create] + after_commit :set_traversal_ids, + if: -> { traversal_ids.empty? || saved_change_to_parent_id? }, + on: [:create, :update] define_model_callbacks :sync_traversal_ids end @@ -78,6 +81,15 @@ module Namespaces end end + def traversal_ids=(ids) + super(ids) + self.transient_traversal_ids = nil + end + + def traversal_ids + read_attribute(:traversal_ids).presence || transient_traversal_ids || [] + end + def use_traversal_ids? return false unless Feature.enabled?(:use_traversal_ids) @@ -174,12 +186,11 @@ module Namespaces # we need to preserve those specific parameters for super. hierarchy_order ||= :desc - # Get all ancestor IDs inclusively between top and our parent. - top_index = top ? traversal_ids.find_index(top.id) : 0 - ids = traversal_ids[top_index...-1] - ids_string = ids.map { |id| Integer(id) }.join(',') + top_index = ancestors_upto_top_index(top) + ids = traversal_ids[top_index...-1].reverse # WITH ORDINALITY lets us order the result to match traversal_ids order. + ids_string = ids.map { |id| Integer(id) }.join(',') from_sql = <<~SQL unnest(ARRAY[#{ids_string}]::bigint[]) WITH ORDINALITY AS ancestors(id, ord) INNER JOIN namespaces ON namespaces.id = ancestors.id @@ -206,6 +217,8 @@ module Namespaces private + attr_accessor :transient_traversal_ids + # Update the traversal_ids for the full hierarchy. # # NOTE: self.traversal_ids will be stale. Reload for a fresh record. @@ -218,6 +231,27 @@ module Namespaces end end + def set_traversal_ids + # This is a temporary guard and will be removed. + return if is_a?(Namespaces::ProjectNamespace) + + return unless Feature.enabled?(:set_traversal_ids_on_save, root_ancestor) + + self.transient_traversal_ids = if parent_id + parent.traversal_ids + [id] + else + [id] + end + + # Clear root_ancestor memo if changed. + if read_attribute(traversal_ids)&.first != transient_traversal_ids.first + clear_memoization(:root_ancestor) + end + + # Update traversal_ids for any associated child objects. + children.each(&:reload) if children.loaded? + end + # Lock the root of the hierarchy we just left, and lock the root of the hierarchy # we just joined. In most cases the two hierarchies will be the same. def lock_both_roots @@ -266,6 +300,17 @@ module Namespaces skope end + + def ancestors_upto_top_index(top) + return 0 if top.nil? + + index = traversal_ids.find_index(top.id) + if index.nil? + 0 + else + index + 1 + end + end end end end diff --git a/app/models/project.rb b/app/models/project.rb index a4fa20b227e..1941397b846 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -40,6 +40,7 @@ class Project < ApplicationRecord include RunnerTokenExpirationInterval include BlocksUnsafeSerialization include Subquery + include IssueParent extend Gitlab::Cache::RequestCache extend Gitlab::Utils::Override diff --git a/app/models/work_item.rb b/app/models/work_item.rb index be090b09425..ec2071b663f 100644 --- a/app/models/work_item.rb +++ b/app/models/work_item.rb @@ -22,6 +22,8 @@ class WorkItem < Issue scope :inc_relations_for_permission_check, -> { includes(:author, project: :project_feature) } + delegate :supports_assignee?, to: :work_item_type + class << self def assignee_association_name 'issue' @@ -57,7 +59,7 @@ class WorkItem < Issue end def supported_quick_action_commands - commands_for_widgets = widgets.map(&:class).flat_map(&:quick_action_commands).uniq + commands_for_widgets = work_item_type.widgets.flat_map(&:quick_action_commands).uniq COMMON_QUICK_ACTIONS_COMMANDS + commands_for_widgets end diff --git a/app/models/work_items/type.rb b/app/models/work_items/type.rb index e1f6a13f7a7..9b434ef946c 100644 --- a/app/models/work_items/type.rb +++ b/app/models/work_items/type.rb @@ -141,6 +141,10 @@ module WorkItems WIDGETS_FOR_TYPE[base_type.to_sym] end + def supports_assignee? + widgets.include? ::WorkItems::Widgets::Assignees + end + private def strip_whitespace |