Skip to content

Instantly share code, notes, and snippets.

@edipox
Last active May 16, 2022 17:24
Show Gist options
  • Save edipox/c755f5b723000933a7ff693cc1a157bf to your computer and use it in GitHub Desktop.
Save edipox/c755f5b723000933a7ff693cc1a157bf to your computer and use it in GitHub Desktop.
elixir scrivener handle slow couting example
# 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment