Current section
Files
Jump to
Current section
Files
lib/ecto/cursor_pagination.ex
defmodule Ecto.CursorPagination do
@moduledoc """
Cursor / Value based pagination using Ecto
http://blog.novatec-gmbh.de/art-pagination-offset-vs-value-based-paging/
"""
import Ecto.Query, only: [limit: 2, where: 3, order_by: 2]
@per_page Application.fetch_env!(:ecto_cursor_pagination, :per_page)
@doc """
Efficiently returns a maximum of `per_page` configured results.
Assumes cursor_ids are integers and incremented as inserted in order.
It returns an Ecto Query that is the combination
of the inputted query and the cursor pagination.
If an unknown or nil direction is inputted,
it returns the original query in the default order.
"""
@spec paginate(Ecto.Query.t, pos_integer, String.t) :: Ecto.Query.t
def paginate(query, last_seen_id, direction)
def paginate(query, last_seen_id, "prev") do
query
|> order_by(desc: ^cursor_id())
|> where([q], field(q, ^cursor_id()) < ^last_seen_id)
|> limit(@per_page)
end
def paginate(query, last_seen_id, "next") do
query
|> order_by(asc: ^cursor_id())
|> where([q], field(q, ^cursor_id()) > ^last_seen_id)
|> limit(@per_page)
end
def paginate(query, _, _) do
query
|> order_by(desc: ^cursor_id())
|> limit(@per_page)
end
defp cursor_id, do: Application.fetch_env!(:ecto_cursor_pagination, :cursor_id)
end