defmodule HAHandler.PGSQL do @supervisor HAHandler.PGSQL.Supervisor @version_query "SELECT version();" @is_in_recovery_query "SELECT pg_is_in_recovery();" def get_instances() do watchers = Supervisor.which_children(@supervisor) for {hostname, pid, _type, _modules} <- watchers do {hostname, pid} end end def get_version({hostname, pid}) do case GenServer.call(pid, {:execute, @version_query, []}) do {:ok, %Postgrex.Result{rows: [[raw_version_string]]}} -> version = case Regex.run(~r/^PostgreSQL (\d+\.\d+)/, raw_version_string) do [_, version_number] -> version_number _ -> "unknown" end %{hostname: hostname, version: version, status: "up"} {:error, %DBConnection.ConnectionError{message: _msg, reason: err}} -> %{hostname: hostname, version: "unknown", status: err} _ -> %{hostname: hostname, version: "unknown", status: :unknown} end end def get_operation_mode({_hostname, pid}) do case GenServer.call(pid, {:execute, @is_in_recovery_query, []}) do {:ok, %Postgrex.Result{rows: [[false]]}} -> :primary {:ok, %Postgrex.Result{rows: [[true]]}} -> :secondary _ -> :unknown end end def get_stats() do get_instances() |> Enum.map(fn instance -> get_version(instance) |> Map.put(:mode, get_operation_mode(instance)) end) end end