Guest User

Untitled

a guest
Jan 24th, 2018
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.07 KB | None | 0 0
  1. defmodule JsonApi.Paginator do
  2. # ...
  3. # ...
  4.  
  5. alias SomeProject.Repo
  6.  
  7. import Ecto.Query
  8.  
  9. @doc """
  10. Helper function used to paginate index queries
  11. """
  12. @spec paginate(conn :: Plug.Conn.t(), page_params :: map, query :: module) :: Plug.Conn.t()
  13. def paginate(conn, page_params, query) do
  14. page_number = validate_int(page_params["number"], 1, -1)
  15. page_size = validate_int(page_params["size"], default_page_size(), maximum_page_size())
  16.  
  17. handle_pagination(conn, page_number, page_size, query)
  18. end
  19.  
  20. # Handle invalid page params
  21. @spec handle_pagination(conn :: Plug.Conn.t(), page :: number | atom, page_size :: number | atom, query :: module) :: Plug.Conn.t()
  22. defp handle_pagination(conn, :error, _page_size, _query) do
  23. Response.send_error_resp(conn, :bad_request, "Invalid page value", "page[number] has to be positive number.")
  24. end
  25.  
  26. defp handle_pagination(conn, _page, :error, _query) do
  27. Response.send_error_resp(conn, :bad_request, "Invalid page value", "page[size] has to be positive number (maximum value is #{maximum_page_size()}).")
  28. end
  29.  
  30. # Paginate
  31. defp handle_pagination(conn, page, page_size, query) do
  32. config = %Scrivener.Config{
  33. module: Repo,
  34. page_number: page, page_size: page_size,
  35. options: [total_entries: total_entries(conn, query)]
  36. }
  37. query |> Scrivener.paginate(config)
  38. end
  39.  
  40. # Retrieves the estimated record count
  41. @spec total_entries(conn :: Plug.Conn.t(), query :: module) :: number
  42. defp total_entries(_conn, query) do
  43. table_name = table_name(query)
  44. {:ok, result} = Ecto.Adapters.SQL.query(Repo, "SELECT reltuples::BIGINT AS estimate FROM pg_class WHERE relname=$1", [table_name])
  45. result.rows |> List.first |> List.first
  46. end
  47.  
  48. # Determines the table name based on a given query
  49. @spec table_name(query :: module) :: module
  50. defp table_name(query) do
  51. module(query).__schema__(:source)
  52. end
  53.  
  54. # Retrieves the model module from a given query
  55. @spec module(module :: module) :: module
  56. defp module(%{from: {_table, module}}), do: module
  57. defp module(module), do: module
  58.  
  59. # ...
  60. # ...
  61. end
Add Comment
Please, Sign In to add comment