1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
# frozen_string_literal: true
module Gitlab
module Pagination
module CursorBasedKeyset
SUPPORTED_ORDERING = {
Group => { name: :asc },
AuditEvent => { id: :desc },
::Ci::Build => { id: :desc },
::Packages::BuildInfo => { id: :desc }
}.freeze
SUPPORTED_MULTI_ORDERING = {
Group => { name: [:asc] },
AuditEvent => { id: [:desc] },
User => {
id: [:asc, :desc],
name: [:asc, :desc],
username: [:asc, :desc],
created_at: [:asc, :desc],
updated_at: [:asc, :desc]
},
::Ci::Build => { id: [:desc] },
::Packages::BuildInfo => { id: [:desc] }
}.freeze
# Relation types that are enforced in this list
# enforce the use of keyset pagination, thus erroring out requests
# made with offset pagination above a certain limit.
#
# In many cases this could introduce a breaking change
# so enforcement is optional.
ENFORCED_TYPES = [Group].freeze
def self.available_for_type?(relation)
if Feature.enabled?(:api_keyset_pagination_multi_order)
SUPPORTED_MULTI_ORDERING.key?(relation.klass)
else
SUPPORTED_ORDERING.key?(relation.klass)
end
end
def self.available?(cursor_based_request_context, relation)
available_for_type?(relation) &&
order_satisfied?(relation, cursor_based_request_context)
end
def self.enforced_for_type?(relation)
ENFORCED_TYPES.include?(relation.klass)
end
def self.order_satisfied?(relation, cursor_based_request_context)
if Feature.enabled?(:api_keyset_pagination_multi_order)
order_by_from_request = cursor_based_request_context.order
sort_from_request = cursor_based_request_context.sort
SUPPORTED_MULTI_ORDERING[relation.klass][order_by_from_request]&.include?(sort_from_request)
else
order_by_from_request = cursor_based_request_context.order_by
SUPPORTED_ORDERING[relation.klass] == order_by_from_request
end
end
private_class_method :order_satisfied?
end
end
end
|