Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- defmodule JsonApi.Paginator do
- # ...
- # ...
- alias SomeProject.Repo
- import Ecto.Query
- @doc """
- Helper function used to paginate index queries
- """
- @spec paginate(conn :: Plug.Conn.t(), page_params :: map, query :: module) :: Plug.Conn.t()
- def paginate(conn, page_params, query) do
- page_number = validate_int(page_params["number"], 1, -1)
- page_size = validate_int(page_params["size"], default_page_size(), maximum_page_size())
- handle_pagination(conn, page_number, page_size, query)
- end
- # Handle invalid page params
- @spec handle_pagination(conn :: Plug.Conn.t(), page :: number | atom, page_size :: number | atom, query :: module) :: Plug.Conn.t()
- defp handle_pagination(conn, :error, _page_size, _query) do
- Response.send_error_resp(conn, :bad_request, "Invalid page value", "page[number] has to be positive number.")
- end
- defp handle_pagination(conn, _page, :error, _query) do
- Response.send_error_resp(conn, :bad_request, "Invalid page value", "page[size] has to be positive number (maximum value is #{maximum_page_size()}).")
- end
- # Paginate
- defp handle_pagination(conn, page, page_size, query) do
- config = %Scrivener.Config{
- module: Repo,
- page_number: page, page_size: page_size,
- options: [total_entries: total_entries(conn, query)]
- }
- query |> Scrivener.paginate(config)
- end
- # Retrieves the estimated record count
- @spec total_entries(conn :: Plug.Conn.t(), query :: module) :: number
- defp total_entries(_conn, query) do
- table_name = table_name(query)
- {:ok, result} = Ecto.Adapters.SQL.query(Repo, "SELECT reltuples::BIGINT AS estimate FROM pg_class WHERE relname=$1", [table_name])
- result.rows |> List.first |> List.first
- end
- # Determines the table name based on a given query
- @spec table_name(query :: module) :: module
- defp table_name(query) do
- module(query).__schema__(:source)
- end
- # Retrieves the model module from a given query
- @spec module(module :: module) :: module
- defp module(%{from: {_table, module}}), do: module
- defp module(module), do: module
- # ...
- # ...
- end
Add Comment
Please, Sign In to add comment