debian-mirror-gitlab/lib/gitlab/pagination/keyset/pager.rb

50 lines
1.2 KiB
Ruby
Raw Normal View History

2020-01-01 13:55:28 +05:30
# frozen_string_literal: true
module Gitlab
module Pagination
module Keyset
2020-03-13 15:44:24 +05:30
class Pager < Gitlab::Pagination::Base
2020-01-01 13:55:28 +05:30
attr_reader :request
def initialize(request)
@request = request
end
def paginate(relation)
# Validate assumption: The last two columns must match the page order_by
validate_order!(relation)
2020-03-13 15:44:24 +05:30
relation.limit(page.per_page) # rubocop: disable CodeReuse/ActiveRecord
end
2020-01-01 13:55:28 +05:30
2020-03-13 15:44:24 +05:30
def finalize(records)
apply_headers(records.last)
2020-01-01 13:55:28 +05:30
end
private
2020-03-13 15:44:24 +05:30
def apply_headers(last_record_in_page)
return unless last_record_in_page
2020-01-01 13:55:28 +05:30
2020-03-13 15:44:24 +05:30
lower_bounds = last_record_in_page&.slice(page.order_by.keys)
next_page = page.next(lower_bounds)
2020-01-01 13:55:28 +05:30
request.apply_headers(next_page)
end
def page
@page ||= request.page
end
def validate_order!(rel)
present_order = rel.order_values.map { |val| [val.expr.name.to_sym, val.direction] }.last(2).to_h
unless page.order_by == present_order
raise ArgumentError, "Page's order_by does not match the relation's order: #{present_order} vs #{page.order_by}"
end
end
end
end
end
end