Module: ParamsReady::Pagination::Direction

Included in:
After, Before
Defined in:
lib/params_ready/pagination/direction.rb

Defined Under Namespace

Modules: After, Before

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.instance(dir) ⇒ Object



10
11
12
13
14
15
16
17
# File 'lib/params_ready/pagination/direction.rb', line 10

def self.instance(dir)
  case dir
  when :bfr, :before then Before
  when :aft, :after then After
  else
    raise ParamsReadyError, "Unexpected direction: '#{dir}'"
  end
end

Instance Method Details

#build_cursor(keyset, ordering, arel_table, context) ⇒ Object



59
60
61
62
63
64
65
66
# File 'lib/params_ready/pagination/direction.rb', line 59

def build_cursor(keyset, ordering, arel_table, context)
  builder = CursorBuilder.new(keyset, arel_table, context)
  ordering.to_array_with_context(context).each do |(key, _)|
    column = ordering.definition.columns[key]
    builder.add(key, column)
  end
  builder.build
end

#check_primary_keys_presence(keyset, primary_keys) ⇒ Object



31
32
33
34
35
# File 'lib/params_ready/pagination/direction.rb', line 31

def check_primary_keys_presence(keyset, primary_keys)
  primary_keys.all? do |pk|
    keyset.key?(pk) && !keyset[pk].nil?
  end
end

#cursor_predicate(columns, cursor, ordering, arel_table, context, primary_keys) ⇒ Object



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

def cursor_predicate(columns, cursor, ordering, arel_table, context, primary_keys)
  tuple, *rest = columns
  key, column_ordering = tuple
  column = ordering.definition.columns[key]

  value_expression = cursor.rvalue(key)
  column_expression = column.attribute(key, arel_table, context)

  primary_keys.delete(key) if column.pk

  if column.pk && primary_keys.empty?
    pk_predicate(column_ordering, column_expression, value_expression)
  else
    nested = cursor_predicate(rest, cursor, ordering, arel_table, context, primary_keys)
    if column.nulls == :default
      non_nullable_predicate(column_ordering, column_expression, value_expression, nested)
    else
      nullable_predicate(column_ordering, column.nulls, column_expression, value_expression, nested)
    end
  end
end

#cursor_predicates(keyset, ordering, arel_table, context) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
# File 'lib/params_ready/pagination/direction.rb', line 19

def cursor_predicates(keyset, ordering, arel_table, context)
  primary_keys = ordering.definition.primary_keys.dup
  return [nil, nil] unless check_primary_keys_presence(keyset, primary_keys)

  cursor = build_cursor(keyset, ordering, arel_table, context)
  columns = ordering.to_array_with_context(context)

  predicate = cursor_predicate(columns, cursor, ordering, arel_table, context, primary_keys)
  grouping = Arel::Nodes::Grouping.new(predicate)
  [cursor, grouping]
end

#non_nullable_predicate(ordering, column, value, nested) ⇒ Object



72
73
74
# File 'lib/params_ready/pagination/direction.rb', line 72

def non_nullable_predicate(ordering, column, value, nested)
  tendency(ordering).non_nullable_predicate(column, value, nested)
end

#nullable_predicate(ordering, nulls, column, value, nested) ⇒ Object



76
77
78
79
80
81
82
83
84
85
# File 'lib/params_ready/pagination/direction.rb', line 76

def nullable_predicate(ordering, nulls, column, value, nested)
  strategy = nulls_strategy(nulls)
  if_null = strategy.if_null_predicate(column, nested)
  tendency = tendency(ordering)
  expression = Arel::Nodes::Grouping.new(value)
  if_not_null = strategy.if_not_null_predicate(tendency, column, value, nested)
  Arel::Nodes::Case.new.when(expression.eq(nil))
                       .then(if_null)
                       .else(if_not_null)
end

#pk_predicate(ordering, column, value) ⇒ Object



68
69
70
# File 'lib/params_ready/pagination/direction.rb', line 68

def pk_predicate(ordering, column, value)
  tendency(ordering).comparison_predicate(column, value)
end