# Paginate @spec handle_pagination(conn :: Plug.Conn.t(), page :: number | atom, page_size :: number | atom, query :: module) :: Plug.Conn.t() 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(query)] } query |> Scrivener.paginate(config) end # Retrieves the estimated record count @spec total_entries(query :: module) :: number defp total_entries(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_from_query(query).__schema__(:source) end # Retrieves the model module from a given query @spec module_from_query(module :: module) :: module defp module_from_query(%{from: {_table, module}}), do: module defp module_from_query(module), do: module