Current section

Files

Jump to
ecto_psql_extras lib ecto_psql_extras.ex
Raw

lib/ecto_psql_extras.ex

defmodule EctoPSQLExtras do
@moduledoc """
The entry point for each function.
"""
@callback info :: %{
required(:title) => binary,
required(:columns) => [%{name: atom, type: atom}],
optional(:order_by) => [{atom, :asc | :desc}],
optional(:limit) => pos_integer
}
@callback query :: binary
@doc """
Returns all queries and their modules.
"""
def queries do
%{
bloat: EctoPSQLExtras.Bloat,
blocking: EctoPSQLExtras.Blocking,
cache_hit: EctoPSQLExtras.CacheHit,
calls: EctoPSQLExtras.Calls,
extensions: EctoPSQLExtras.Extensions,
table_cache_hit: EctoPSQLExtras.TableCacheHit,
index_cache_hit: EctoPSQLExtras.IndexCacheHit,
index_size: EctoPSQLExtras.IndexSize,
index_usage: EctoPSQLExtras.IndexUsage,
locks: EctoPSQLExtras.Locks,
all_locks: EctoPSQLExtras.AllLocks,
long_running_queries: EctoPSQLExtras.LongRunningQueries,
mandelbrot: EctoPSQLExtras.Mandelbrot,
outliers: EctoPSQLExtras.Outliers,
records_rank: EctoPSQLExtras.RecordsRank,
seq_scans: EctoPSQLExtras.SeqScans,
table_indexes_size: EctoPSQLExtras.TableIndexesSize,
table_size: EctoPSQLExtras.TableSize,
total_index_size: EctoPSQLExtras.TotalIndexSize,
total_table_size: EctoPSQLExtras.TotalTableSize,
unused_indexes: EctoPSQLExtras.UnusedIndexes,
vacuum_stats: EctoPSQLExtras.VacuumStats,
kill_all: EctoPSQLExtras.KillAll
}
end
@doc """
Run a query with `name`, on `repo`, in the given `format`.
`format` is either `:ascii` or `:raw`.
"""
def query(name, repo, format \\ :ascii) do
query_module = queries()[name]
result = repo.query!(query_module.query)
format(format, query_module.info, result)
end
defp format(:ascii, info, result) do
rows =
if result.rows == [] do
[["No results", nil]]
else
Enum.map(result.rows, &parse_row/1)
end
names = Enum.map(info.columns, & &1.name)
rows
|> TableRex.quick_render!(names, info.title)
|> IO.puts()
end
defp format(:raw, _info, result) do
result
end
defp parse_row(list) do
Enum.map(list, &parse_column/1)
end
defp parse_column(%struct{} = decimal) when struct == Decimal, do: Decimal.to_float(decimal)
defp parse_column(binary) when is_binary(binary), do: binary
defp parse_column(other), do: inspect(other)
end