Commit 251e1366 authored by Douwe Maan's avatar Douwe Maan

Efficiently load multiple references of one type.

parent 5dd77358
...@@ -28,10 +28,7 @@ module Gitlab ...@@ -28,10 +28,7 @@ module Gitlab
end end
def self.referenced_by(node) def self.referenced_by(node)
issue = Issue.find(node.attr("data-issue")) rescue nil { issue: LazyReference.new(Issue, node.attr("data-issue")) }
return unless issue
{ issue: issue }
end end
def call def call
......
...@@ -23,10 +23,7 @@ module Gitlab ...@@ -23,10 +23,7 @@ module Gitlab
end end
def self.referenced_by(node) def self.referenced_by(node)
label = Label.find(node.attr("data-label")) rescue nil { label: LazyReference.new(Label, node.attr("data-label")) }
return unless label
{ label: label }
end end
def call def call
......
...@@ -28,10 +28,7 @@ module Gitlab ...@@ -28,10 +28,7 @@ module Gitlab
end end
def self.referenced_by(node) def self.referenced_by(node)
merge_request = MergeRequest.find(node.attr("data-merge-request")) rescue nil { merge_request: LazyReference.new(MergeRequest, node.attr("data-merge-request")) }
return unless merge_request
{ merge_request: merge_request }
end end
def call def call
......
...@@ -12,6 +12,8 @@ module Gitlab ...@@ -12,6 +12,8 @@ module Gitlab
# :project (required) - Current project, ignored if reference is cross-project. # :project (required) - Current project, ignored if reference is cross-project.
# :only_path - Generate path-only links. # :only_path - Generate path-only links.
class ReferenceFilter < HTML::Pipeline::Filter class ReferenceFilter < HTML::Pipeline::Filter
LazyReference = Struct.new(:klass, :ids)
def self.user_can_reference?(user, node, context) def self.user_can_reference?(user, node, context)
if node.has_attribute?('data-project') if node.has_attribute?('data-project')
project_id = node.attr('data-project').to_i project_id = node.attr('data-project').to_i
......
...@@ -12,7 +12,8 @@ module Gitlab ...@@ -12,7 +12,8 @@ module Gitlab
def initialize(*) def initialize(*)
super super
result[:references] ||= Hash.new { |hash, type| hash[type] = [] } result[:lazy_references] ||= Hash.new { |hash, type| hash[type] = [] }
result[:references] ||= Hash.new { |hash, type| hash[type] = [] }
end end
def call def call
...@@ -20,6 +21,8 @@ module Gitlab ...@@ -20,6 +21,8 @@ module Gitlab
gather_references(node) gather_references(node)
end end
load_lazy_references
doc doc
end end
...@@ -35,9 +38,29 @@ module Gitlab ...@@ -35,9 +38,29 @@ module Gitlab
references = reference_filter.referenced_by(node) references = reference_filter.referenced_by(node)
return unless references return unless references
references.each do |type, values| references.each do |type, values|
result[:references][type].push(*values) Array.wrap(values).each do |value|
refs =
if value.is_a?(ReferenceFilter::LazyReference)
result[:lazy_references]
else
result[:references]
end
refs[type] << value
end
end
end
# Will load all references of one type using one query.
def load_lazy_references
result[:lazy_references].each do |type, refs|
refs.group_by(&:klass).each do |klass, refs|
ids = refs.map(&:ids).flatten
values = klass.find(ids)
result[:references][type].push(*values)
end
end end
end end
......
...@@ -28,10 +28,7 @@ module Gitlab ...@@ -28,10 +28,7 @@ module Gitlab
end end
def self.referenced_by(node) def self.referenced_by(node)
snippet = Snippet.find(node.attr("data-snippet")) rescue nil { snippet: LazyReference.new(Snippet, node.attr("data-snippet")) }
return unless snippet
{ snippet: snippet }
end end
def call def call
......
...@@ -30,10 +30,7 @@ module Gitlab ...@@ -30,10 +30,7 @@ module Gitlab
{ user: group.users } { user: group.users }
elsif node.has_attribute?('data-user') elsif node.has_attribute?('data-user')
user = User.find(node.attr('data-user')) rescue nil { user: LazyReference.new(User, node.attr('data-user')) }
return unless user
{ user: user }
elsif node.has_attribute?('data-project') elsif node.has_attribute?('data-project')
project = Project.find(node.attr('data-project')) rescue nil project = Project.find(node.attr('data-project')) rescue nil
return unless project return unless project
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment