Class: Gitlab::Graphql::Pagination::Keyset::OrderInfo

Inherits:
Object
  • Object
show all
Defined in:
lib/gitlab/graphql/pagination/keyset/order_info.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(order_value) ⇒ OrderInfo

Returns a new instance of OrderInfo.


10
11
12
13
14
15
16
17
# File 'lib/gitlab/graphql/pagination/keyset/order_info.rb', line 10

def initialize(order_value)
  @attribute_name, @sort_direction, @named_function =
    if order_value.is_a?(String)
      extract_nulls_last_order(order_value)
    else
      extract_attribute_values(order_value)
    end
end

Instance Attribute Details

#attribute_nameObject (readonly)

Returns the value of attribute attribute_name


8
9
10
# File 'lib/gitlab/graphql/pagination/keyset/order_info.rb', line 8

def attribute_name
  @attribute_name
end

#named_functionObject (readonly)

Returns the value of attribute named_function


8
9
10
# File 'lib/gitlab/graphql/pagination/keyset/order_info.rb', line 8

def named_function
  @named_function
end

#sort_directionObject (readonly)

Returns the value of attribute sort_direction


8
9
10
# File 'lib/gitlab/graphql/pagination/keyset/order_info.rb', line 8

def sort_direction
  @sort_direction
end

Class Method Details

.build_order_list(relation) ⇒ Object

Only allow specific node types


29
30
31
32
33
34
35
# File 'lib/gitlab/graphql/pagination/keyset/order_info.rb', line 29

def self.build_order_list(relation)
  order_list = relation.order_values.select do |value|
    supported_order_value?(value)
  end

  order_list.map { |info| OrderInfo.new(info) }
end

.supported_order_value?(order_value) ⇒ Boolean

Returns:

  • (Boolean)

60
61
62
63
64
65
66
67
# File 'lib/gitlab/graphql/pagination/keyset/order_info.rb', line 60

def self.supported_order_value?(order_value)
  return true if order_value.is_a?(Arel::Nodes::Ascending) || order_value.is_a?(Arel::Nodes::Descending)
  return false unless order_value.is_a?(String)

  tokens = order_value.downcase.split

  tokens.last(2) == %w(nulls last) && tokens.count == 4
end

.validate_ordering(relation, order_list) ⇒ Object


37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/gitlab/graphql/pagination/keyset/order_info.rb', line 37

def self.validate_ordering(relation, order_list)
  if order_list.empty?
    raise ArgumentError.new('A minimum of 1 ordering field is required')
  end

  if order_list.count > 2
    # Keep in mind an order clause for primary key is added if one is not present
    # lib/gitlab/graphql/pagination/keyset/connection.rb:97
    raise ArgumentError.new('A maximum of 2 ordering fields are allowed')
  end

  # make sure the last ordering field is non-nullable
  attribute_name = order_list.last&.attribute_name

  if relation.columns_hash[attribute_name].null
    raise ArgumentError.new("Column `#{attribute_name}` must not allow NULL")
  end

  if order_list.last.attribute_name != relation.primary_key
    raise ArgumentError.new("Last ordering field must be the primary key, `#{relation.primary_key}`")
  end
end

Instance Method Details

#operator_for(before_or_after) ⇒ Object


19
20
21
22
23
24
25
26
# File 'lib/gitlab/graphql/pagination/keyset/order_info.rb', line 19

def operator_for(before_or_after)
  case before_or_after
  when :before
    sort_direction == :asc ? '<' : '>'
  when :after
    sort_direction == :asc ? '>' : '<'
  end
end