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
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/api/groups.rb16
-rw-r--r--lib/api/helpers/pagination_strategies.rb36
-rw-r--r--lib/gitlab/database/load_balancing/sidekiq_client_middleware.rb6
-rw-r--r--lib/gitlab/database/load_balancing/sidekiq_server_middleware.rb2
-rw-r--r--lib/gitlab/database_importers/work_items/base_type_importer.rb15
-rw-r--r--lib/gitlab/pagination/cursor_based_keyset.rb27
-rw-r--r--lib/gitlab/pagination/keyset/cursor_based_request_context.rb15
7 files changed, 100 insertions, 17 deletions
diff --git a/lib/api/groups.rb b/lib/api/groups.rb
index 0896357cc73..a1123b6291b 100644
--- a/lib/api/groups.rb
+++ b/lib/api/groups.rb
@@ -108,6 +108,20 @@ module API
present paginate(groups), options
end
+ def present_groups_with_pagination_strategies(params, groups)
+ return present_groups(params, groups) if current_user.present? || Feature.disabled?(:keyset_pagination_for_groups_api)
+
+ options = {
+ with: Entities::Group,
+ current_user: nil,
+ statistics: false
+ }
+
+ groups, options = with_custom_attributes(groups, options)
+
+ present paginate_with_strategies(groups), options
+ end
+
def delete_group(group)
destroy_conditionally!(group) do |group|
::Groups::DestroyService.new(group, current_user).async_execute
@@ -168,7 +182,7 @@ module API
end
get do
groups = find_groups(declared_params(include_missing: false), params[:id])
- present_groups params, groups
+ present_groups_with_pagination_strategies params, groups
end
desc 'Create a group. Available only for users who can create groups.' do
diff --git a/lib/api/helpers/pagination_strategies.rb b/lib/api/helpers/pagination_strategies.rb
index 61cff37e4ab..8c2186768ea 100644
--- a/lib/api/helpers/pagination_strategies.rb
+++ b/lib/api/helpers/pagination_strategies.rb
@@ -3,10 +3,16 @@
module API
module Helpers
module PaginationStrategies
- def paginate_with_strategies(relation, request_scope)
+ def paginate_with_strategies(relation, request_scope = nil)
paginator = paginator(relation, request_scope)
- yield(paginator.paginate(relation)).tap do |records, _|
+ result = if block_given?
+ yield(paginator.paginate(relation))
+ else
+ paginator.paginate(relation)
+ end
+
+ result.tap do |records, _|
paginator.finalize(records)
end
end
@@ -20,17 +26,31 @@ module API
private
def keyset_paginator(relation)
- request_context = Gitlab::Pagination::Keyset::RequestContext.new(self)
- unless Gitlab::Pagination::Keyset.available?(request_context, relation)
+ if cursor_based_keyset_pagination_supported?(relation)
+ request_context_class = Gitlab::Pagination::Keyset::CursorBasedRequestContext
+ paginator_class = Gitlab::Pagination::Keyset::CursorPager
+ availability_checker = Gitlab::Pagination::CursorBasedKeyset
+ else
+ request_context_class = Gitlab::Pagination::Keyset::RequestContext
+ paginator_class = Gitlab::Pagination::Keyset::Pager
+ availability_checker = Gitlab::Pagination::Keyset
+ end
+
+ request_context = request_context_class.new(self)
+
+ unless availability_checker.available?(request_context, relation)
return error!('Keyset pagination is not yet available for this type of request', 405)
end
- Gitlab::Pagination::Keyset::Pager.new(request_context)
+ paginator_class.new(request_context)
end
def offset_paginator(relation, request_scope)
offset_limit = limit_for_scope(request_scope)
- if Gitlab::Pagination::Keyset.available_for_type?(relation) && offset_limit_exceeded?(offset_limit)
+ if (Gitlab::Pagination::Keyset.available_for_type?(relation) ||
+ cursor_based_keyset_pagination_supported?(relation)) &&
+ offset_limit_exceeded?(offset_limit)
+
return error!("Offset pagination has a maximum allowed offset of #{offset_limit} " \
"for requests that return objects of type #{relation.klass}. " \
"Remaining records can be retrieved using keyset pagination.", 405)
@@ -39,6 +59,10 @@ module API
Gitlab::Pagination::OffsetPagination.new(self)
end
+ def cursor_based_keyset_pagination_supported?(relation)
+ Gitlab::Pagination::CursorBasedKeyset.available_for_type?(relation)
+ end
+
def keyset_pagination_enabled?
params[:pagination] == 'keyset'
end
diff --git a/lib/gitlab/database/load_balancing/sidekiq_client_middleware.rb b/lib/gitlab/database/load_balancing/sidekiq_client_middleware.rb
index acb4842db31..518a812b406 100644
--- a/lib/gitlab/database/load_balancing/sidekiq_client_middleware.rb
+++ b/lib/gitlab/database/load_balancing/sidekiq_client_middleware.rb
@@ -32,12 +32,10 @@ module Gitlab
def set_data_consistency_locations!(job)
# Once we add support for multiple databases to our load balancer, we would use something like this:
# job['wal_locations'] = Gitlab::Database::DATABASES.transform_values do |connection|
- # connection.load_balancer.primary_write_location.
+ # connection.load_balancer.primary_write_location
# end
#
- # TODO: Replace hardcoded database config name :main when we merge unification strategy
- # https://gitlab.com/gitlab-org/gitlab/-/issues/336566
- job['wal_locations'] = { main: wal_location } if wal_location
+ job['wal_locations'] = { Gitlab::Database::MAIN_DATABASE_NAME.to_sym => wal_location } if wal_location
end
def wal_location
diff --git a/lib/gitlab/database/load_balancing/sidekiq_server_middleware.rb b/lib/gitlab/database/load_balancing/sidekiq_server_middleware.rb
index 2555f693a5d..f7fda14b215 100644
--- a/lib/gitlab/database/load_balancing/sidekiq_server_middleware.rb
+++ b/lib/gitlab/database/load_balancing/sidekiq_server_middleware.rb
@@ -66,7 +66,7 @@ module Gitlab
def legacy_wal_location(job)
wal_location = job['database_write_location'] || job['database_replica_location']
- { main: wal_location } if wal_location
+ { Gitlab::Database::MAIN_DATABASE_NAME.to_sym => wal_location } if wal_location
end
def load_balancing_available?(worker_class)
diff --git a/lib/gitlab/database_importers/work_items/base_type_importer.rb b/lib/gitlab/database_importers/work_items/base_type_importer.rb
new file mode 100644
index 00000000000..c5acdb41de5
--- /dev/null
+++ b/lib/gitlab/database_importers/work_items/base_type_importer.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module DatabaseImporters
+ module WorkItems
+ module BaseTypeImporter
+ def self.import
+ WorkItem::Type::BASE_TYPES.each do |type, attributes|
+ WorkItem::Type.create!(base_type: type, **attributes.slice(:name, :icon_name))
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/pagination/cursor_based_keyset.rb b/lib/gitlab/pagination/cursor_based_keyset.rb
new file mode 100644
index 00000000000..f19cdf06d9a
--- /dev/null
+++ b/lib/gitlab/pagination/cursor_based_keyset.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Pagination
+ module CursorBasedKeyset
+ SUPPORTED_ORDERING = {
+ Group => { name: :asc }
+ }.freeze
+
+ def self.available_for_type?(relation)
+ SUPPORTED_ORDERING.key?(relation.klass)
+ end
+
+ def self.available?(cursor_based_request_context, relation)
+ available_for_type?(relation) &&
+ order_satisfied?(relation, cursor_based_request_context)
+ end
+
+ def self.order_satisfied?(relation, cursor_based_request_context)
+ order_by_from_request = cursor_based_request_context.order_by
+
+ SUPPORTED_ORDERING[relation.klass] == order_by_from_request
+ end
+ private_class_method :order_satisfied?
+ end
+ end
+end
diff --git a/lib/gitlab/pagination/keyset/cursor_based_request_context.rb b/lib/gitlab/pagination/keyset/cursor_based_request_context.rb
index d9c118ceef5..18390f5b59d 100644
--- a/lib/gitlab/pagination/keyset/cursor_based_request_context.rb
+++ b/lib/gitlab/pagination/keyset/cursor_based_request_context.rb
@@ -4,11 +4,12 @@ module Gitlab
module Pagination
module Keyset
class CursorBasedRequestContext
- attr_reader :request
- delegate :params, :header, to: :request
+ DEFAULT_SORT_DIRECTION = :desc
+ attr_reader :request_context
+ delegate :params, to: :request_context
- def initialize(request)
- @request = request
+ def initialize(request_context)
+ @request_context = request_context
end
def per_page
@@ -21,9 +22,13 @@ module Gitlab
def apply_headers(cursor_for_next_page)
Gitlab::Pagination::Keyset::HeaderBuilder
- .new(self)
+ .new(request_context)
.add_next_page_header({ cursor: cursor_for_next_page })
end
+
+ def order_by
+ { params[:order_by].to_sym => params[:sort]&.to_sym || DEFAULT_SORT_DIRECTION }
+ end
end
end
end