def self.paginate(query, pagination, root_resource:)
return query unless pagination.paginator
paginator = pagination.paginator
q = if paginator.page
offset(query, (paginator.page - 1) * paginator.items)
else
oclause = if pagination.order.nil? || pagination.order.empty?
direction = :asc
order(query, [{ asc: paginator.by }], root_resource: root_resource)
else
first_ordering = pagination.order.items.first
direction = first_ordering.keys.first
unless first_ordering[direction].to_sym == pagination.paginator.by.to_sym
string_clause = pagination.order.items.map do |h|
dir, name = h.first
"#{name} #{dir}"
end.join(',')
raise PaginationException,
"Ordering clause [#{string_clause}] is incompatible with pagination by field '#{pagination.paginator.by}'. " \
"When paginating by a field value, one cannot specify the 'order' clause " \
"unless the clause's primary field matches the pagination field."
end
order(query, pagination.order, root_resource: root_resource)
end
if paginator.from
if direction == :desc
where_lt(oclause, paginator.by, paginator.from)
else
where_gt(oclause, paginator.by, paginator.from)
end
else
oclause
end
end
limit(q, paginator.items)
end