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/search_results.rb')
-rw-r--r--lib/gitlab/search_results.rb106
1 files changed, 68 insertions, 38 deletions
diff --git a/lib/gitlab/search_results.rb b/lib/gitlab/search_results.rb
index efe8095beea..1e45d074e0a 100644
--- a/lib/gitlab/search_results.rb
+++ b/lib/gitlab/search_results.rb
@@ -1,15 +1,19 @@
module Gitlab
class SearchResults
class FoundBlob
- attr_reader :id, :filename, :basename, :ref, :startline, :data
+ include EncodingHelper
+
+ attr_reader :id, :filename, :basename, :ref, :startline, :data, :project_id
def initialize(opts = {})
@id = opts.fetch(:id, nil)
- @filename = opts.fetch(:filename, nil)
- @basename = opts.fetch(:basename, nil)
+ @filename = encode_utf8(opts.fetch(:filename, nil))
+ @basename = encode_utf8(opts.fetch(:basename, nil))
@ref = opts.fetch(:ref, nil)
@startline = opts.fetch(:startline, nil)
- @data = opts.fetch(:data, nil)
+ @data = encode_utf8(opts.fetch(:data, nil))
+ @per_page = opts.fetch(:per_page, 20)
+ @project_id = opts.fetch(:project_id, nil)
end
def path
@@ -21,61 +25,86 @@ module Gitlab
end
end
- attr_reader :current_user, :query
+ attr_reader :current_user, :query, :per_page
# Limit search results by passed projects
# It allows us to search only for projects user has access to
attr_reader :limit_projects
- def initialize(current_user, limit_projects, query)
+ # Whether a custom filter is used to restrict scope of projects.
+ # If the default filter (which lists all projects user has access to)
+ # is used, we can skip it when filtering merge requests and optimize the
+ # query
+ attr_reader :default_project_filter
+
+ def initialize(current_user, limit_projects, query, default_project_filter: false, per_page: 20)
@current_user = current_user
@limit_projects = limit_projects || Project.all
- @query = Shellwords.shellescape(query) if query.present?
+ @query = query
+ @default_project_filter = default_project_filter
+ @per_page = per_page
end
- def objects(scope, page = nil)
- case scope
- when 'projects'
- projects.page(page).per(per_page)
- when 'issues'
- issues.page(page).per(per_page)
- when 'merge_requests'
- merge_requests.page(page).per(per_page)
- when 'milestones'
- milestones.page(page).per(per_page)
- else
- Kaminari.paginate_array([]).page(page).per(per_page)
- end
+ def objects(scope, page = nil, without_count = true)
+ collection = case scope
+ when 'projects'
+ projects.page(page).per(per_page)
+ when 'issues'
+ issues.page(page).per(per_page)
+ when 'merge_requests'
+ merge_requests.page(page).per(per_page)
+ when 'milestones'
+ milestones.page(page).per(per_page)
+ else
+ Kaminari.paginate_array([]).page(page).per(per_page)
+ end
+
+ without_count ? collection.without_count : collection
end
- def projects_count
- @projects_count ||= projects.count
+ def limited_projects_count
+ @limited_projects_count ||= projects.limit(count_limit).count
end
- def issues_count
- @issues_count ||= issues.count
+ def limited_issues_count
+ return @limited_issues_count if @limited_issues_count
+
+ # By default getting limited count (e.g. 1000+) is fast on issuable
+ # collections except for issues, where filtering both not confidential
+ # and confidential issues user has access to, is too complex.
+ # It's faster to try to fetch all public issues first, then only
+ # if necessary try to fetch all issues.
+ sum = issues(public_only: true).limit(count_limit).count
+ @limited_issues_count = sum < count_limit ? issues.limit(count_limit).count : sum
end
- def merge_requests_count
- @merge_requests_count ||= merge_requests.count
+ def limited_merge_requests_count
+ @limited_merge_requests_count ||= merge_requests.limit(count_limit).count
end
- def milestones_count
- @milestones_count ||= milestones.count
+ def limited_milestones_count
+ @limited_milestones_count ||= milestones.limit(count_limit).count
end
def single_commit_result?
false
end
+ def count_limit
+ 1001
+ end
+
private
def projects
limit_projects.search(query)
end
- def issues
- issues = IssuesFinder.new(current_user).execute.where(project_id: project_ids_relation)
+ def issues(finder_params = {})
+ issues = IssuesFinder.new(current_user, finder_params).execute
+ unless default_project_filter
+ issues = issues.where(project_id: project_ids_relation)
+ end
issues =
if query =~ /#(\d+)\z/
@@ -84,34 +113,35 @@ module Gitlab
issues.full_search(query)
end
- issues.order('updated_at DESC')
+ issues.reorder('updated_at DESC')
end
def milestones
milestones = Milestone.where(project_id: project_ids_relation)
milestones = milestones.search(query)
- milestones.order('updated_at DESC')
+ milestones.reorder('updated_at DESC')
end
def merge_requests
- merge_requests = MergeRequestsFinder.new(current_user).execute.in_projects(project_ids_relation)
+ merge_requests = MergeRequestsFinder.new(current_user).execute
+ unless default_project_filter
+ merge_requests = merge_requests.in_projects(project_ids_relation)
+ end
+
merge_requests =
if query =~ /[#!](\d+)\z/
merge_requests.where(iid: $1)
else
merge_requests.full_search(query)
end
- merge_requests.order('updated_at DESC')
+
+ merge_requests.reorder('updated_at DESC')
end
def default_scope
'projects'
end
- def per_page
- 20
- end
-
def project_ids_relation
limit_projects.select(:id).reorder(nil)
end