diaspora/lib/api/paging/time_paginator.rb
2018-12-30 11:50:58 -05:00

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