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-12-17 14:59:07 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-12-17 14:59:07 +0300
commit8b573c94895dc0ac0e1d9d59cf3e8745e8b539ca (patch)
tree544930fb309b30317ae9797a9683768705d664c4 /lib/gitlab/pagination
parent4b1de649d0168371549608993deac953eb692019 (diff)
Add latest changes from gitlab-org/gitlab@13-7-stable-eev13.7.0-rc42
Diffstat (limited to 'lib/gitlab/pagination')
-rw-r--r--lib/gitlab/pagination/gitaly_keyset_pager.rb21
-rw-r--r--lib/gitlab/pagination/offset_header_builder.rb65
-rw-r--r--lib/gitlab/pagination/offset_pagination.rb54
3 files changed, 96 insertions, 44 deletions
diff --git a/lib/gitlab/pagination/gitaly_keyset_pager.rb b/lib/gitlab/pagination/gitaly_keyset_pager.rb
index 651e3d5a807..1350168967e 100644
--- a/lib/gitlab/pagination/gitaly_keyset_pager.rb
+++ b/lib/gitlab/pagination/gitaly_keyset_pager.rb
@@ -15,6 +15,7 @@ module Gitlab
# and supports pagination via gitaly.
def paginate(finder)
return paginate_via_gitaly(finder) if keyset_pagination_enabled?
+ return paginate_first_page_via_gitaly(finder) if paginate_first_page?
branches = ::Kaminari.paginate_array(finder.execute)
Gitlab::Pagination::OffsetPagination
@@ -25,7 +26,11 @@ module Gitlab
private
def keyset_pagination_enabled?
- Feature.enabled?(:branch_list_keyset_pagination, project) && params[:pagination] == 'keyset'
+ Feature.enabled?(:branch_list_keyset_pagination, project, default_enabled: true) && params[:pagination] == 'keyset'
+ end
+
+ def paginate_first_page?
+ Feature.enabled?(:branch_list_keyset_pagination, project, default_enabled: true) && (params[:page].blank? || params[:page].to_i == 1)
end
def paginate_via_gitaly(finder)
@@ -34,6 +39,20 @@ module Gitlab
end
end
+ # When first page is requested, we paginate the data via Gitaly
+ # Headers are added to immitate offset pagination, while it is the default option
+ def paginate_first_page_via_gitaly(finder)
+ finder.execute(gitaly_pagination: true).tap do |records|
+ total = project.repository.branch_count
+ per_page = params[:per_page].presence || Kaminari.config.default_per_page
+
+ Gitlab::Pagination::OffsetHeaderBuilder.new(
+ request_context: request_context, per_page: per_page, page: 1, next_page: 2,
+ total: total, total_pages: total / per_page + 1
+ ).execute
+ end
+ end
+
def apply_headers(records)
if records.count == params[:per_page]
Gitlab::Pagination::Keyset::HeaderBuilder
diff --git a/lib/gitlab/pagination/offset_header_builder.rb b/lib/gitlab/pagination/offset_header_builder.rb
new file mode 100644
index 00000000000..32089e40932
--- /dev/null
+++ b/lib/gitlab/pagination/offset_header_builder.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Pagination
+ class OffsetHeaderBuilder
+ attr_reader :request_context, :per_page, :page, :next_page, :prev_page, :total, :total_pages
+
+ delegate :params, :header, :request, to: :request_context
+
+ def initialize(request_context:, per_page:, page:, next_page:, prev_page: nil, total:, total_pages:)
+ @request_context = request_context
+ @per_page = per_page
+ @page = page
+ @next_page = next_page
+ @prev_page = prev_page
+ @total = total
+ @total_pages = total_pages
+ end
+
+ def execute(exclude_total_headers: false, data_without_counts: false)
+ header 'X-Per-Page', per_page.to_s
+ header 'X-Page', page.to_s
+ header 'X-Next-Page', next_page.to_s
+ header 'X-Prev-Page', prev_page.to_s
+ header 'Link', pagination_links(data_without_counts)
+
+ return if exclude_total_headers || data_without_counts
+
+ header 'X-Total', total.to_s
+ header 'X-Total-Pages', total_pages.to_s
+ end
+
+ private
+
+ def pagination_links(data_without_counts)
+ [].tap do |links|
+ links << %(<#{page_href(page: prev_page)}>; rel="prev") if prev_page
+ links << %(<#{page_href(page: next_page)}>; rel="next") if next_page
+ links << %(<#{page_href(page: 1)}>; rel="first")
+
+ links << %(<#{page_href(page: total_pages)}>; rel="last") unless data_without_counts
+ end.join(', ')
+ 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 build_page_url(query_params:)
+ base_request_uri.tap do |uri|
+ uri.query = query_params
+ end.to_s
+ end
+
+ def page_href(next_page_params = {})
+ query_params = params.merge(**next_page_params, per_page: params[:per_page]).to_query
+
+ build_page_url(query_params: query_params)
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/pagination/offset_pagination.rb b/lib/gitlab/pagination/offset_pagination.rb
index 46c74b8fe3c..2805b12d95d 100644
--- a/lib/gitlab/pagination/offset_pagination.rb
+++ b/lib/gitlab/pagination/offset_pagination.rb
@@ -48,58 +48,26 @@ module Gitlab
end
def add_pagination_headers(paginated_data, exclude_total_headers)
- header 'X-Per-Page', paginated_data.limit_value.to_s
- header 'X-Page', paginated_data.current_page.to_s
- header 'X-Next-Page', paginated_data.next_page.to_s
- header 'X-Prev-Page', paginated_data.prev_page.to_s
- header 'Link', pagination_links(paginated_data)
-
- return if exclude_total_headers || data_without_counts?(paginated_data)
-
- header 'X-Total', paginated_data.total_count.to_s
- header 'X-Total-Pages', total_pages(paginated_data).to_s
- end
-
- def pagination_links(paginated_data)
- [].tap do |links|
- links << %(<#{page_href(page: paginated_data.prev_page)}>; rel="prev") if paginated_data.prev_page
- links << %(<#{page_href(page: paginated_data.next_page)}>; rel="next") if paginated_data.next_page
- links << %(<#{page_href(page: 1)}>; rel="first")
-
- links << %(<#{page_href(page: total_pages(paginated_data))}>; rel="last") unless data_without_counts?(paginated_data)
- end.join(', ')
- end
-
- def total_pages(paginated_data)
- # Ensure there is in total at least 1 page
- [paginated_data.total_pages, 1].max
+ Gitlab::Pagination::OffsetHeaderBuilder.new(
+ request_context: self, per_page: paginated_data.limit_value, page: paginated_data.current_page,
+ next_page: paginated_data.next_page, prev_page: paginated_data.prev_page,
+ total: total_count(paginated_data), total_pages: total_pages(paginated_data)
+ ).execute(exclude_total_headers: exclude_total_headers, data_without_counts: data_without_counts?(paginated_data))
end
def data_without_counts?(paginated_data)
paginated_data.is_a?(Kaminari::PaginatableWithoutCount)
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
+ def total_count(paginated_data)
+ paginated_data.total_count unless data_without_counts?(paginated_data)
end
- def build_page_url(query_params:)
- base_request_uri.tap do |uri|
- uri.query = query_params
- end.to_s
- end
-
- def page_href(next_page_params = {})
- query_params = params.merge(**next_page_params, per_page: per_page).to_query
-
- build_page_url(query_params: query_params)
- end
+ def total_pages(paginated_data)
+ return if data_without_counts?(paginated_data)
- def per_page
- @per_page ||= params[:per_page]
+ # Ensure there is in total at least 1 page
+ [paginated_data.total_pages, 1].max
end
end
end