Current section

Files

Jump to
scrivener lib scrivener.ex
Raw

lib/scrivener.ex

defmodule Scrivener do
import Ecto.Query
alias Scrivener.Config
defmacro __using__(opts) do
quote do
@scrivener_defaults unquote(opts)
def paginate(query, options \\ []) do
Scrivener.paginate(__MODULE__, @scrivener_defaults, query, options)
end
end
end
def paginate(query, %Config{} = config) do
%Scrivener.Page{
page_size: config.page_size,
page_number: config.page_number,
entries: entries(query, config.repo, config.page_number, config.page_size),
total_pages: total_pages(query, config.repo, config.page_size)
}
end
def paginate(repo, defaults, query, opts) do
paginate(query, Config.new(repo, defaults, opts))
end
defp ceiling(float) do
t = trunc(float)
case float - t do
neg when neg < 0 ->
t
pos when pos > 0 ->
t + 1
_ -> t
end
end
defp entries(query, repo, page_number, page_size) do
offset = page_size * (page_number - 1)
query
|> limit([_], ^page_size)
|> offset([_], ^offset)
|> repo.all
end
def total_pages(query, repo, page_size) do
count = query
|> exclude(:order_by)
|> exclude(:preload)
|> exclude(:select)
|> select([e], count(e.id))
|> repo.one
ceiling(count / page_size)
end
end