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:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-08-20 21:42:06 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-08-20 21:42:06 +0300
commit6e4e1050d9dba2b7b2523fdd1768823ab85feef4 (patch)
tree78be5963ec075d80116a932011d695dd33910b4e /lib/gitlab/pagination
parent1ce776de4ae122aba3f349c02c17cebeaa8ecf07 (diff)
Add latest changes from gitlab-org/gitlab@13-3-stable-ee
Diffstat (limited to 'lib/gitlab/pagination')
-rw-r--r--lib/gitlab/pagination/gitaly_keyset_pager.rb54
-rw-r--r--lib/gitlab/pagination/keyset/header_builder.rb45
-rw-r--r--lib/gitlab/pagination/keyset/request_context.rb27
3 files changed, 105 insertions, 21 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
diff --git a/lib/gitlab/pagination/keyset/header_builder.rb b/lib/gitlab/pagination/keyset/header_builder.rb
new file mode 100644
index 00000000000..69c468207f6
--- /dev/null
+++ b/lib/gitlab/pagination/keyset/header_builder.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Pagination
+ module Keyset
+ class HeaderBuilder
+ attr_reader :request_context
+ delegate :params, :header, :request, to: :request_context
+
+ def initialize(request_context)
+ @request_context = request_context
+ end
+
+ def add_next_page_header(query_params)
+ link = next_page_link(page_href(query_params))
+ header('Links', link)
+ header('Link', link)
+ end
+
+ private
+
+ def next_page_link(href)
+ %(<#{href}>; rel="next")
+ end
+
+ def page_href(query_params)
+ base_request_uri.tap do |uri|
+ uri.query = updated_params(query_params).to_query
+ end.to_s
+ end
+
+ def base_request_uri
+ @base_request_uri ||= URI.parse(request.url).tap do |uri|
+ uri.host = Gitlab.config.gitlab.host
+ uri.port = Gitlab.config.gitlab.port
+ end
+ end
+
+ def updated_params(query_params)
+ params.merge(query_params)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/pagination/keyset/request_context.rb b/lib/gitlab/pagination/keyset/request_context.rb
index 070fa844347..ba17fb03681 100644
--- a/lib/gitlab/pagination/keyset/request_context.rb
+++ b/lib/gitlab/pagination/keyset/request_context.rb
@@ -24,9 +24,11 @@ module Gitlab
end
def apply_headers(next_page)
- link = pagination_links(next_page)
- request.header('Links', link)
- request.header('Link', link)
+ Gitlab::Pagination::Keyset::HeaderBuilder
+ .new(request)
+ .add_next_page_header(
+ query_params_for(next_page)
+ )
end
private
@@ -63,25 +65,8 @@ module Gitlab
end
end
- def page_href(page)
- base_request_uri.tap do |uri|
- uri.query = query_params_for(page).to_query
- end.to_s
- end
-
- def pagination_links(next_page)
- %(<#{page_href(next_page)}>; rel="next")
- end
-
- def base_request_uri
- @base_request_uri ||= URI.parse(request.request.url).tap do |uri|
- uri.host = Gitlab.config.gitlab.host
- uri.port = Gitlab.config.gitlab.port
- end
- end
-
def query_params_for(page)
- request.params.merge(lower_bounds_params(page))
+ lower_bounds_params(page)
end
end
end