2018-10-22 03:00:50 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2014-08-26 16:32:41 -04:00
|
|
|
module Gitlab
|
|
|
|
class ProjectSearchResults < SearchResults
|
2020-05-07 17:09:26 -04:00
|
|
|
attr_reader :project, :repository_ref
|
2014-08-26 16:32:41 -04:00
|
|
|
|
2020-05-07 17:09:26 -04:00
|
|
|
def initialize(current_user, project, query, repository_ref = nil)
|
2016-03-17 16:48:19 -04:00
|
|
|
@current_user = current_user
|
2016-03-01 12:04:37 -05:00
|
|
|
@project = project
|
2018-07-20 09:49:30 -04:00
|
|
|
@repository_ref = repository_ref.presence
|
2015-10-14 19:14:24 -04:00
|
|
|
@query = query
|
2014-08-26 16:32:41 -04:00
|
|
|
end
|
|
|
|
|
2020-05-20 02:08:06 -04:00
|
|
|
def objects(scope, page: nil, per_page: DEFAULT_PER_PAGE, preload_method: nil)
|
2014-08-26 16:32:41 -04:00
|
|
|
case scope
|
|
|
|
when 'notes'
|
|
|
|
notes.page(page).per(per_page)
|
|
|
|
when 'blobs'
|
2020-05-07 17:09:26 -04:00
|
|
|
paginated_blobs(blobs(limit: limit_up_to_page(page, per_page)), page, per_page)
|
2014-09-05 06:33:05 -04:00
|
|
|
when 'wiki_blobs'
|
2020-05-08 11:09:28 -04:00
|
|
|
paginated_wiki_blobs(wiki_blobs(limit: limit_up_to_page(page, per_page)), page, per_page)
|
2015-06-14 18:04:20 -04:00
|
|
|
when 'commits'
|
2020-05-24 23:08:11 -04:00
|
|
|
paginated_commits(page, per_page)
|
2018-08-15 07:53:23 -04:00
|
|
|
when 'users'
|
|
|
|
users.page(page).per(per_page)
|
2014-08-26 16:32:41 -04:00
|
|
|
else
|
2020-05-07 17:09:26 -04:00
|
|
|
super(scope, page: page, per_page: per_page, without_count: false)
|
2014-08-26 16:32:41 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-07-15 13:59:57 -04:00
|
|
|
def formatted_count(scope)
|
|
|
|
case scope
|
|
|
|
when 'blobs'
|
2020-02-16 16:08:53 -05:00
|
|
|
formatted_limited_count(limited_blobs_count)
|
2019-07-15 13:59:57 -04:00
|
|
|
when 'notes'
|
|
|
|
formatted_limited_count(limited_notes_count)
|
|
|
|
when 'wiki_blobs'
|
|
|
|
wiki_blobs_count.to_s
|
|
|
|
when 'commits'
|
2020-05-24 23:08:11 -04:00
|
|
|
formatted_limited_count(commits_count)
|
2019-07-15 13:59:57 -04:00
|
|
|
else
|
|
|
|
super
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-08-15 07:53:23 -04:00
|
|
|
def users
|
2018-12-11 07:25:52 -05:00
|
|
|
super.where(id: @project.team.members) # rubocop:disable CodeReuse/ActiveRecord
|
2018-08-15 07:53:23 -04:00
|
|
|
end
|
|
|
|
|
2020-02-16 16:08:53 -05:00
|
|
|
def limited_blobs_count
|
2020-05-07 17:09:26 -04:00
|
|
|
@limited_blobs_count ||= blobs(limit: count_limit).count
|
2014-08-26 16:32:41 -04:00
|
|
|
end
|
|
|
|
|
2018-08-27 11:31:01 -04:00
|
|
|
# rubocop: disable CodeReuse/ActiveRecord
|
2018-03-05 08:25:56 -05:00
|
|
|
def limited_notes_count
|
|
|
|
return @limited_notes_count if defined?(@limited_notes_count)
|
|
|
|
|
|
|
|
types = %w(issue merge_request commit snippet)
|
|
|
|
@limited_notes_count = 0
|
|
|
|
|
|
|
|
types.each do |type|
|
|
|
|
@limited_notes_count += notes_finder(type).limit(count_limit).count
|
|
|
|
break if @limited_notes_count >= count_limit
|
|
|
|
end
|
|
|
|
|
|
|
|
@limited_notes_count
|
2014-08-26 16:32:41 -04:00
|
|
|
end
|
2018-08-27 11:31:01 -04:00
|
|
|
# rubocop: enable CodeReuse/ActiveRecord
|
2014-08-26 16:32:41 -04:00
|
|
|
|
2014-09-05 06:33:05 -04:00
|
|
|
def wiki_blobs_count
|
2020-05-07 17:09:26 -04:00
|
|
|
@wiki_blobs_count ||= wiki_blobs(limit: count_limit).count
|
2014-09-05 06:33:05 -04:00
|
|
|
end
|
|
|
|
|
2015-06-14 18:04:20 -04:00
|
|
|
def commits_count
|
2020-05-24 23:08:11 -04:00
|
|
|
@commits_count ||= commits(limit: count_limit).count
|
2015-06-14 18:04:20 -04:00
|
|
|
end
|
|
|
|
|
2017-01-10 23:20:32 -05:00
|
|
|
def single_commit_result?
|
2018-03-05 08:25:56 -05:00
|
|
|
return false if commits_count != 1
|
2017-01-10 23:20:32 -05:00
|
|
|
|
2018-03-05 08:25:56 -05:00
|
|
|
counts = %i(limited_milestones_count limited_notes_count
|
|
|
|
limited_merge_requests_count limited_issues_count
|
2020-02-16 16:08:53 -05:00
|
|
|
limited_blobs_count wiki_blobs_count)
|
2018-03-05 08:25:56 -05:00
|
|
|
counts.all? { |count_method| public_send(count_method).zero? } # rubocop:disable GitlabSecurity/PublicSend
|
2017-01-10 23:20:32 -05:00
|
|
|
end
|
|
|
|
|
2014-08-26 16:32:41 -04:00
|
|
|
private
|
|
|
|
|
2020-05-24 23:08:11 -04:00
|
|
|
def paginated_commits(page, per_page)
|
|
|
|
results = commits(limit: limit_up_to_page(page, per_page))
|
|
|
|
|
|
|
|
Kaminari.paginate_array(results).page(page).per(per_page)
|
|
|
|
end
|
|
|
|
|
2020-05-07 17:09:26 -04:00
|
|
|
def paginated_blobs(blobs, page, per_page)
|
2018-12-02 16:47:33 -05:00
|
|
|
results = Kaminari.paginate_array(blobs).page(page).per(per_page)
|
|
|
|
|
|
|
|
Gitlab::Search::FoundBlob.preload_blobs(results)
|
|
|
|
|
|
|
|
results
|
|
|
|
end
|
|
|
|
|
2020-05-08 11:09:28 -04:00
|
|
|
def paginated_wiki_blobs(blobs, page, per_page)
|
|
|
|
blob_array = paginated_blobs(blobs, page, per_page)
|
|
|
|
blob_array.map! do |blob|
|
|
|
|
Gitlab::Search::FoundWikiPage.new(blob)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-05-07 17:09:26 -04:00
|
|
|
def limit_up_to_page(page, per_page)
|
2020-02-16 16:08:53 -05:00
|
|
|
current_page = page&.to_i || 1
|
|
|
|
offset = per_page * (current_page - 1)
|
|
|
|
count_limit + offset
|
|
|
|
end
|
|
|
|
|
2020-05-07 17:09:26 -04:00
|
|
|
def blobs(limit: count_limit)
|
2017-04-24 11:09:29 -04:00
|
|
|
return [] unless Ability.allowed?(@current_user, :download_code, @project)
|
|
|
|
|
2020-05-07 17:09:26 -04:00
|
|
|
@blobs ||= Gitlab::FileFinder.new(project, repository_project_ref).find(query, content_match_cutoff: limit)
|
2014-08-26 16:32:41 -04:00
|
|
|
end
|
|
|
|
|
2020-05-07 17:09:26 -04:00
|
|
|
def wiki_blobs(limit: count_limit)
|
2017-04-24 11:09:29 -04:00
|
|
|
return [] unless Ability.allowed?(@current_user, :read_wiki, @project)
|
|
|
|
|
2016-11-08 07:21:19 -05:00
|
|
|
@wiki_blobs ||= begin
|
|
|
|
if project.wiki_enabled? && query.present?
|
2020-01-27 16:08:47 -05:00
|
|
|
if project.wiki.empty?
|
2016-11-08 07:21:19 -05:00
|
|
|
[]
|
2020-01-27 16:08:47 -05:00
|
|
|
else
|
2020-05-07 17:09:26 -04:00
|
|
|
Gitlab::WikiFileFinder.new(project, repository_wiki_ref).find(query, content_match_cutoff: limit)
|
2016-11-08 07:21:19 -05:00
|
|
|
end
|
2014-09-09 10:56:33 -04:00
|
|
|
else
|
|
|
|
[]
|
|
|
|
end
|
2014-09-05 06:33:05 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-08-26 16:32:41 -04:00
|
|
|
def notes
|
2018-03-05 08:25:56 -05:00
|
|
|
@notes ||= notes_finder(nil)
|
|
|
|
end
|
|
|
|
|
2018-08-27 11:31:01 -04:00
|
|
|
# rubocop: disable CodeReuse/ActiveRecord
|
2018-03-05 08:25:56 -05:00
|
|
|
def notes_finder(type)
|
2019-07-30 14:25:49 -04:00
|
|
|
NotesFinder.new(@current_user, search: query, target_type: type, project: project).execute.user.order('updated_at DESC')
|
2014-08-26 16:32:41 -04:00
|
|
|
end
|
2018-08-27 11:31:01 -04:00
|
|
|
# rubocop: enable CodeReuse/ActiveRecord
|
2014-08-26 16:32:41 -04:00
|
|
|
|
2020-05-24 23:08:11 -04:00
|
|
|
def commits(limit:)
|
|
|
|
@commits ||= find_commits(query, limit: limit)
|
2016-12-08 09:54:45 -05:00
|
|
|
end
|
|
|
|
|
2020-05-24 23:08:11 -04:00
|
|
|
def find_commits(query, limit:)
|
2016-12-08 09:54:45 -05:00
|
|
|
return [] unless Ability.allowed?(@current_user, :download_code, @project)
|
|
|
|
|
2020-05-24 23:08:11 -04:00
|
|
|
commits = find_commits_by_message(query, limit: limit)
|
2016-12-08 09:54:45 -05:00
|
|
|
commit_by_sha = find_commit_by_sha(query)
|
2017-01-10 23:20:32 -05:00
|
|
|
commits |= [commit_by_sha] if commit_by_sha
|
2016-12-08 09:54:45 -05:00
|
|
|
commits
|
|
|
|
end
|
|
|
|
|
2020-05-24 23:08:11 -04:00
|
|
|
def find_commits_by_message(query, limit:)
|
2020-06-02 20:08:38 -04:00
|
|
|
project.repository.find_commits_by_message(query, repository_project_ref, nil, limit)
|
2016-12-08 09:54:45 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def find_commit_by_sha(query)
|
|
|
|
key = query.strip
|
|
|
|
project.repository.commit(key) if Commit.valid_hash?(key)
|
2015-06-14 18:04:20 -04:00
|
|
|
end
|
2016-03-03 09:10:14 -05:00
|
|
|
|
2019-08-07 10:24:17 -04:00
|
|
|
# rubocop: disable CodeReuse/ActiveRecord
|
2016-03-03 09:10:14 -05:00
|
|
|
def project_ids_relation
|
2019-08-07 10:24:17 -04:00
|
|
|
Project.where(id: project).select(:id).reorder(nil)
|
2016-03-03 09:10:14 -05:00
|
|
|
end
|
2019-08-07 10:24:17 -04:00
|
|
|
# rubocop: enabled CodeReuse/ActiveRecord
|
2018-07-20 09:49:30 -04:00
|
|
|
|
2019-05-20 10:08:31 -04:00
|
|
|
def filter_milestones_by_project(milestones)
|
|
|
|
return Milestone.none unless Ability.allowed?(@current_user, :read_milestone, @project)
|
|
|
|
|
|
|
|
milestones.where(project_id: project.id) # rubocop: disable CodeReuse/ActiveRecord
|
|
|
|
end
|
|
|
|
|
2018-07-20 09:49:30 -04:00
|
|
|
def repository_project_ref
|
|
|
|
@repository_project_ref ||= repository_ref || project.default_branch
|
|
|
|
end
|
|
|
|
|
|
|
|
def repository_wiki_ref
|
|
|
|
@repository_wiki_ref ||= repository_ref || project.wiki.default_branch
|
|
|
|
end
|
2019-05-07 07:08:25 -04:00
|
|
|
|
|
|
|
def issuable_params
|
|
|
|
super.merge(project_id: project.id)
|
|
|
|
end
|
2014-08-26 16:32:41 -04:00
|
|
|
end
|
|
|
|
end
|