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/pagination/gitaly_keyset_pager.rb')
-rw-r--r--lib/gitlab/pagination/gitaly_keyset_pager.rb54
1 files changed, 54 insertions, 0 deletions
diff --git a/lib/gitlab/pagination/gitaly_keyset_pager.rb b/lib/gitlab/pagination/gitaly_keyset_pager.rb
new file mode 100644
index 00000000000..651e3d5a807
--- /dev/null
+++ b/lib/gitlab/pagination/gitaly_keyset_pager.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Pagination
+ class GitalyKeysetPager
+ attr_reader :request_context, :project
+ delegate :params, to: :request_context
+
+ def initialize(request_context, project)
+ @request_context = request_context
+ @project = project
+ end
+
+ # It is expected that the given finder will respond to `execute` method with `gitaly_pagination: true` option
+ # and supports pagination via gitaly.
+ def paginate(finder)
+ return paginate_via_gitaly(finder) if keyset_pagination_enabled?
+
+ branches = ::Kaminari.paginate_array(finder.execute)
+ Gitlab::Pagination::OffsetPagination
+ .new(request_context)
+ .paginate(branches)
+ end
+
+ private
+
+ def keyset_pagination_enabled?
+ Feature.enabled?(:branch_list_keyset_pagination, project) && params[:pagination] == 'keyset'
+ end
+
+ def paginate_via_gitaly(finder)
+ finder.execute(gitaly_pagination: true).tap do |records|
+ apply_headers(records)
+ end
+ end
+
+ def apply_headers(records)
+ if records.count == params[:per_page]
+ Gitlab::Pagination::Keyset::HeaderBuilder
+ .new(request_context)
+ .add_next_page_header(
+ query_params_for(records.last)
+ )
+ end
+ end
+
+ def query_params_for(record)
+ # NOTE: page_token is name for now, but it could be dynamic if we have other gitaly finders
+ # that is based on something other than name
+ { page_token: record.name }
+ end
+ end
+ end
+end