defmodule Mix.Tasks.Continuum.Partitions.List do @moduledoc """ Lists managed `continuum_events` partitions and their row counts. mix continuum.partitions.list mix continuum.partitions.list --repo MyApp.Repo """ use Mix.Task @shortdoc "Lists continuum_events partitions" @impl true def run(args) do {opts, rest, invalid} = OptionParser.parse(args, strict: [repo: :string]) if invalid != [] or rest != [] do Mix.raise("unexpected partition list arguments: #{Enum.join(args, " ")}") end Mix.Task.run("app.start") repo = parse_repo(opts) repo |> partitions() |> Enum.each(fn partition -> %{rows: [[count]]} = repo.query!("SELECT count(*) FROM #{quote_ident(partition)}") Mix.shell().info("#{partition}\t#{count}") end) end defp partitions(repo) do %{rows: rows} = repo.query!(""" SELECT c.relname FROM pg_inherits i JOIN pg_class c ON c.oid = i.inhrelid JOIN pg_class p ON p.oid = i.inhparent WHERE p.relname = 'continuum_events' ORDER BY c.relname """) Enum.map(rows, fn [name] -> name end) end defp parse_repo(opts) do case opts[:repo] do nil -> Application.get_env(:continuum, :repo) || Mix.raise("no repo configured. Pass --repo MyApp.Repo or set :continuum, :repo") repo -> Module.concat([repo]) end end defp quote_ident(name), do: ~s("#{String.replace(name, ~s("), ~s(""))}") end