diff options
Diffstat (limited to 'lib/gitlab/diff/file_collection')
4 files changed, 93 insertions, 33 deletions
diff --git a/lib/gitlab/diff/file_collection/compare.rb b/lib/gitlab/diff/file_collection/compare.rb index 6d8395d048d..df0d71f3db2 100644 --- a/lib/gitlab/diff/file_collection/compare.rb +++ b/lib/gitlab/diff/file_collection/compare.rb @@ -4,7 +4,15 @@ module Gitlab module Diff module FileCollection class Compare < Base + delegate :limit_value, :current_page, :next_page, :prev_page, :total_count, :total_pages, to: :@pagination + def initialize(compare, project:, diff_options:, diff_refs: nil) + @pagination = Gitlab::PaginationDelegate.new( + page: diff_options&.delete(:page), + per_page: diff_options&.delete(:per_page), + count: diff_options&.delete(:count) + ) + super(compare, project: project, diff_options: diff_options, diff --git a/lib/gitlab/diff/file_collection/merge_request_diff_batch.rb b/lib/gitlab/diff/file_collection/merge_request_diff_batch.rb index 0a601bde612..56027d6a4de 100644 --- a/lib/gitlab/diff/file_collection/merge_request_diff_batch.rb +++ b/lib/gitlab/diff/file_collection/merge_request_diff_batch.rb @@ -10,6 +10,8 @@ module Gitlab # separate file keys (https://gitlab.com/gitlab-org/gitlab/issues/30550). # class MergeRequestDiffBatch < MergeRequestDiffBase + include PaginatedDiffs + DEFAULT_BATCH_PAGE = 1 DEFAULT_BATCH_SIZE = 30 @@ -25,41 +27,8 @@ module Gitlab } end - override :diffs - def diffs - strong_memoize(:diffs) do - @merge_request_diff.opening_external_diff do - # Avoiding any extra queries. - collection = @paginated_collection.to_a - - # The offset collection and calculation is required so that we - # know how much has been loaded in previous batches, collapsing - # the current paginated set accordingly (collection limit calculation). - # See: https://docs.gitlab.com/ee/development/diffs.html#diff-collection-limits - # - offset_index = collection.first&.index - options = diff_options.dup - - collection = - if offset_index && offset_index > 0 - offset_collection = relation.limit(offset_index) # rubocop:disable CodeReuse/ActiveRecord - options[:offset_index] = offset_index - offset_collection + collection - else - collection - end - - Gitlab::Git::DiffCollection.new(collection.map(&:to_hash), options) - end - end - end - private - def relation - @merge_request_diff.merge_request_diff_files - end - # rubocop: disable CodeReuse/ActiveRecord def load_paginated_collection(batch_page, batch_size, diff_options) batch_page ||= DEFAULT_BATCH_PAGE diff --git a/lib/gitlab/diff/file_collection/paginated_diffs.rb b/lib/gitlab/diff/file_collection/paginated_diffs.rb new file mode 100644 index 00000000000..63c186affe9 --- /dev/null +++ b/lib/gitlab/diff/file_collection/paginated_diffs.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +module Gitlab + module Diff + module FileCollection + module PaginatedDiffs + include Gitlab::Utils::StrongMemoize + extend ::Gitlab::Utils::Override + + override :diffs + def diffs + merge_request_diff.opening_external_diff do + # Avoiding any extra queries. + collection = paginated_collection.to_a + + # The offset collection and calculation is required so that we + # know how much has been loaded in previous batches, collapsing + # the current paginated set accordingly (collection limit calculation). + # See: https://docs.gitlab.com/ee/development/diffs.html#diff-collection-limits + # + offset_index = collection.first&.index + options = diff_options.dup + + collection = + if offset_index && offset_index > 0 + offset_collection = relation.limit(offset_index) # rubocop:disable CodeReuse/ActiveRecord + options[:offset_index] = offset_index + offset_collection + collection + else + collection + end + + Gitlab::Git::DiffCollection.new(collection.map(&:to_hash), options) + end + end + strong_memoize_attr :diffs + + private + + attr_reader :merge_request_diff, :paginated_collection + + def relation + merge_request_diff.merge_request_diff_files + end + end + end + end +end diff --git a/lib/gitlab/diff/file_collection/paginated_merge_request_diff.rb b/lib/gitlab/diff/file_collection/paginated_merge_request_diff.rb new file mode 100644 index 00000000000..37abad81305 --- /dev/null +++ b/lib/gitlab/diff/file_collection/paginated_merge_request_diff.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module Gitlab + module Diff + module FileCollection + # Builds a traditional paginated diff file collection using Kaminari + # `per` and `per_page` which is different from how `MergeRequestDiffBatch` + # works (e.g. supports gradual loading). + class PaginatedMergeRequestDiff < MergeRequestDiffBase + include PaginatedDiffs + + DEFAULT_PAGE = 1 + DEFAULT_PER_PAGE = 30 + + delegate :limit_value, :current_page, :next_page, :prev_page, :total_count, + :total_pages, to: :paginated_collection + + def initialize(merge_request_diff, page, per_page) + super(merge_request_diff, diff_options: nil) + + @paginated_collection = load_paginated_collection(page, per_page) + end + + private + + def load_paginated_collection(page, per_page) + page ||= DEFAULT_PAGE + per_page ||= DEFAULT_PER_PAGE + + relation.page(page).per([per_page.to_i, DEFAULT_PER_PAGE].min) + end + end + end + end +end |