analytics/lib/plausible/pagination.ex

46 lines
1.0 KiB
Elixir

defmodule Plausible.Pagination do
@moduledoc """
Cursor-based pagination.
"""
@limit 10
@maximum_limit 100
@spec paginate(Ecto.Queryable.t(), map(), Keyword.t(), Keyword.t()) :: Paginator.Page.t()
def paginate(queryable, params, opts, repo_opts \\ []) do
opts = Keyword.merge([limit: @limit, maximum_limit: @maximum_limit], opts)
Paginator.paginate(
queryable,
Keyword.merge(opts, to_pagination_opts(params)),
Plausible.Repo,
repo_opts
)
end
defp to_pagination_opts(params) do
Enum.reduce(params, Keyword.new(), fn
{"after", cursor}, acc ->
Keyword.put(acc, :after, cursor)
{"before", cursor}, acc ->
Keyword.put(acc, :before, cursor)
{"limit", limit}, acc ->
limit = to_int(limit)
if limit > 0 and limit <= @maximum_limit do
Keyword.put(acc, :limit, limit)
else
acc
end
_, acc ->
acc
end)
end
defp to_int(x) when is_binary(x), do: String.to_integer(x)
defp to_int(x) when is_integer(x), do: x
end