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:
authorHeinrich Lee Yu <heinrich@gitlab.com>2019-02-26 20:59:26 +0300
committerHeinrich Lee Yu <heinrich@gitlab.com>2019-02-26 20:59:26 +0300
commitf4be2d4e1bd4ac456610c72862f20ff29b3820a8 (patch)
tree3c581fe26b071b2b3084daed9ae46597b01ac701 /lib/api/entities.rb
parentf5201a816f2eff9393e16f362403451e5d86ee6c (diff)
Revert "Merge branch '56726-fix-n+1-in-issues-and-merge-requests-api' into 'master'"
This reverts merge request !25042
Diffstat (limited to 'lib/api/entities.rb')
-rw-r--r--lib/api/entities.rb72
1 files changed, 50 insertions, 22 deletions
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 237705a63d0..7c035990fb0 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -468,17 +468,11 @@ module API
end
end
- class IssueableEntity < Grape::Entity
+ class ProjectEntity < Grape::Entity
expose :id, :iid
expose(:project_id) { |entity| entity&.project.try(:id) }
expose :title, :description
expose :state, :created_at, :updated_at
-
- # Avoids an N+1 query when metadata is included
- def issuable_metadata(subject, options, method)
- cached_subject = options.dig(:issuable_metadata, subject.id)
- (cached_subject || subject).public_send(method) # rubocop: disable GitlabSecurity/PublicSend
- end
end
class Diff < Grape::Entity
@@ -521,35 +515,57 @@ module API
end
end
- class IssueBasic < IssueableEntity
+ class IssueBasic < ProjectEntity
expose :closed_at
expose :closed_by, using: Entities::UserBasic
- expose :labels do |issue|
+ expose :labels do |issue, options|
# Avoids an N+1 query since labels are preloaded
issue.labels.map(&:title).sort
end
expose :milestone, using: Entities::Milestone
expose :assignees, :author, using: Entities::UserBasic
- expose :assignee, using: ::API::Entities::UserBasic do |issue|
+ expose :assignee, using: ::API::Entities::UserBasic do |issue, options|
issue.assignees.first
end
- expose(:user_notes_count) { |issue, options| issuable_metadata(issue, options, :user_notes_count) }
- expose(:merge_requests_count) { |issue, options| issuable_metadata(issue, options, :merge_requests_count) }
- expose(:upvotes) { |issue, options| issuable_metadata(issue, options, :upvotes) }
- expose(:downvotes) { |issue, options| issuable_metadata(issue, options, :downvotes) }
+ expose :user_notes_count
+ expose :upvotes do |issue, options|
+ if options[:issuable_metadata]
+ # Avoids an N+1 query when metadata is included
+ options[:issuable_metadata][issue.id].upvotes
+ else
+ issue.upvotes
+ end
+ end
+ expose :downvotes do |issue, options|
+ if options[:issuable_metadata]
+ # Avoids an N+1 query when metadata is included
+ options[:issuable_metadata][issue.id].downvotes
+ else
+ issue.downvotes
+ end
+ end
expose :due_date
expose :confidential
expose :discussion_locked
- expose :web_url do |issue|
+ expose :web_url do |issue, options|
Gitlab::UrlBuilder.build(issue)
end
expose :time_stats, using: 'API::Entities::IssuableTimeStats' do |issue|
issue
end
+
+ expose :merge_requests_count do |issue, options|
+ if options[:issuable_metadata]
+ # Avoids an N+1 query when metadata is included
+ options[:issuable_metadata][issue.id].merge_requests_count
+ else
+ issue.merge_requests_closing_issues.count
+ end
+ end
end
class Issue < IssueBasic
@@ -612,14 +628,14 @@ module API
end
end
- class MergeRequestSimple < IssueableEntity
+ class MergeRequestSimple < ProjectEntity
expose :title
expose :web_url do |merge_request, options|
Gitlab::UrlBuilder.build(merge_request)
end
end
- class MergeRequestBasic < IssueableEntity
+ class MergeRequestBasic < ProjectEntity
expose :merged_by, using: Entities::UserBasic do |merge_request, _options|
merge_request.metrics&.merged_by
end
@@ -643,12 +659,23 @@ module API
MarkupHelper.markdown_field(entity, :description)
end
expose :target_branch, :source_branch
- expose(:user_notes_count) { |merge_request, options| issuable_metadata(merge_request, options, :user_notes_count) }
- expose(:upvotes) { |merge_request, options| issuable_metadata(merge_request, options, :upvotes) }
- expose(:downvotes) { |merge_request, options| issuable_metadata(merge_request, options, :downvotes) }
+ expose :upvotes do |merge_request, options|
+ if options[:issuable_metadata]
+ options[:issuable_metadata][merge_request.id].upvotes
+ else
+ merge_request.upvotes
+ end
+ end
+ expose :downvotes do |merge_request, options|
+ if options[:issuable_metadata]
+ options[:issuable_metadata][merge_request.id].downvotes
+ else
+ merge_request.downvotes
+ end
+ end
expose :author, :assignee, using: Entities::UserBasic
expose :source_project_id, :target_project_id
- expose :labels do |merge_request|
+ expose :labels do |merge_request, options|
# Avoids an N+1 query since labels are preloaded
merge_request.labels.map(&:title).sort
end
@@ -666,6 +693,7 @@ module API
end
expose :diff_head_sha, as: :sha
expose :merge_commit_sha
+ expose :user_notes_count
expose :discussion_locked
expose :should_remove_source_branch?, as: :should_remove_source_branch
expose :force_remove_source_branch?, as: :force_remove_source_branch
@@ -673,7 +701,7 @@ module API
# Deprecated
expose :allow_collaboration, as: :allow_maintainer_to_push, if: -> (merge_request, _) { merge_request.for_fork? }
- expose :web_url do |merge_request|
+ expose :web_url do |merge_request, options|
Gitlab::UrlBuilder.build(merge_request)
end