Efficiently load multiple references of one type.

This commit is contained in:
Douwe Maan 2015-10-13 18:23:49 +02:00
parent 5dd77358f6
commit 251e13666d
7 changed files with 33 additions and 23 deletions

View file

@ -28,10 +28,7 @@ module Gitlab
end
def self.referenced_by(node)
issue = Issue.find(node.attr("data-issue")) rescue nil
return unless issue
{ issue: issue }
{ issue: LazyReference.new(Issue, node.attr("data-issue")) }
end
def call

View file

@ -23,10 +23,7 @@ module Gitlab
end
def self.referenced_by(node)
label = Label.find(node.attr("data-label")) rescue nil
return unless label
{ label: label }
{ label: LazyReference.new(Label, node.attr("data-label")) }
end
def call

View file

@ -28,10 +28,7 @@ module Gitlab
end
def self.referenced_by(node)
merge_request = MergeRequest.find(node.attr("data-merge-request")) rescue nil
return unless merge_request
{ merge_request: merge_request }
{ merge_request: LazyReference.new(MergeRequest, node.attr("data-merge-request")) }
end
def call

View file

@ -12,6 +12,8 @@ module Gitlab
# :project (required) - Current project, ignored if reference is cross-project.
# :only_path - Generate path-only links.
class ReferenceFilter < HTML::Pipeline::Filter
LazyReference = Struct.new(:klass, :ids)
def self.user_can_reference?(user, node, context)
if node.has_attribute?('data-project')
project_id = node.attr('data-project').to_i

View file

@ -12,7 +12,8 @@ module Gitlab
def initialize(*)
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
def call
@ -20,6 +21,8 @@ module Gitlab
gather_references(node)
end
load_lazy_references
doc
end
@ -37,7 +40,27 @@ module Gitlab
return unless references
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

View file

@ -28,10 +28,7 @@ module Gitlab
end
def self.referenced_by(node)
snippet = Snippet.find(node.attr("data-snippet")) rescue nil
return unless snippet
{ snippet: snippet }
{ snippet: LazyReference.new(Snippet, node.attr("data-snippet")) }
end
def call

View file

@ -30,10 +30,7 @@ module Gitlab
{ user: group.users }
elsif node.has_attribute?('data-user')
user = User.find(node.attr('data-user')) rescue nil
return unless user
{ user: user }
{ user: LazyReference.new(User, node.attr('data-user')) }
elsif node.has_attribute?('data-project')
project = Project.find(node.attr('data-project')) rescue nil
return unless project