109 lines
2.8 KiB
Ruby
109 lines
2.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Api
|
|
module Paging
|
|
class TimePaginator
|
|
def initialize(opts={})
|
|
@query_base = opts[:query_base]
|
|
@query_time_field = opts[:query_time_field]
|
|
@data_time_field = opts[:data_time_field]
|
|
@current_time = opts[:current_time]
|
|
@limit = opts[:limit]
|
|
@is_descending = opts[:is_descending]
|
|
direction = if @is_descending
|
|
"<"
|
|
else
|
|
">"
|
|
end
|
|
@time_query_string = "#{@query_time_field} #{direction} ?"
|
|
@sort_string = if @is_descending
|
|
"#{@query_time_field} DESC"
|
|
else
|
|
"#{@query_time_field} ASC"
|
|
end
|
|
end
|
|
|
|
def page_data
|
|
return @data if @data
|
|
|
|
@data = @query_base.where([@time_query_string, @current_time.iso8601(3)]).limit(@limit).order(@sort_string)
|
|
time_data = @data.map {|d| d[@data_time_field] }.sort
|
|
@min_time = time_data.first
|
|
@max_time = time_data.last + 0.001.seconds if time_data.last
|
|
|
|
@data
|
|
end
|
|
|
|
def next_page(for_url=true)
|
|
page_data
|
|
return nil unless next_time
|
|
|
|
return next_page_as_query_parameter if for_url
|
|
|
|
TimePaginator.new(
|
|
query_base: @query_base,
|
|
query_time_field: @query_time_field,
|
|
query_data_field: @data_time_field,
|
|
current_time: next_time,
|
|
is_descending: @is_descending,
|
|
limit: @limit
|
|
)
|
|
end
|
|
|
|
def previous_page(for_url=true)
|
|
page_data
|
|
return nil unless previous_time
|
|
|
|
return previous_page_as_query_parameter if for_url
|
|
|
|
TimePaginator.new(
|
|
query_base: @query_base,
|
|
query_time_field: @query_time_field,
|
|
query_data_field: @data_time_field,
|
|
current_time: previous_time,
|
|
is_descending: !@is_descending,
|
|
limit: @limit
|
|
)
|
|
end
|
|
|
|
def filter_parameters(parameters)
|
|
parameters.delete(:before)
|
|
parameters.delete(:after)
|
|
end
|
|
|
|
private
|
|
|
|
def next_time
|
|
if @is_descending
|
|
@min_time
|
|
else
|
|
@max_time
|
|
end
|
|
end
|
|
|
|
def previous_time
|
|
if @is_descending
|
|
@max_time
|
|
else
|
|
@min_time
|
|
end
|
|
end
|
|
|
|
def next_page_as_query_parameter
|
|
if @is_descending
|
|
"before=#{next_time.iso8601(3)}"
|
|
else
|
|
"after=#{next_time.iso8601(3)}"
|
|
end
|
|
end
|
|
|
|
def previous_page_as_query_parameter
|
|
if @is_descending
|
|
"after=#{previous_time.iso8601(3)}"
|
|
else
|
|
"before=#{previous_time.iso8601(3)}"
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|