diff --git a/lib/postgrex/utils.ex b/lib/postgrex/utils.ex index 7923221a..73b067b6 100644 --- a/lib/postgrex/utils.ex +++ b/lib/postgrex/utils.ex @@ -84,16 +84,22 @@ defmodule Postgrex.Utils do @doc """ Fills in the given `opts` with default options. + Only adds keys extracted via PGHOST if no endpoint-related keys are explicitly provided. """ @spec default_opts(Keyword.t()) :: Keyword.t() def default_opts(opts) do {field, value} = extract_host(System.get_env("PGHOST")) + endpoint_keys = [:socket, :socket_dir, :hostname, :endpoints] + has_endpoint? = Enum.any?(endpoint_keys, &Keyword.has_key?(opts, &1)) + opts |> Keyword.put_new(:username, System.get_env("PGUSER") || System.get_env("USER")) |> Keyword.put_new(:password, System.get_env("PGPASSWORD")) |> Keyword.put_new(:database, System.get_env("PGDATABASE")) - |> Keyword.put_new(field, value) + |> then(fn opts -> + if has_endpoint?, do: opts, else: Keyword.put(opts, field, value) + end) |> Keyword.put_new(:port, System.get_env("PGPORT")) |> Keyword.update!(:port, &normalize_port/1) |> Keyword.put_new(:types, Postgrex.DefaultTypes) diff --git a/test/utils/envs_test.exs b/test/utils/envs_test.exs index bf6de333..7a3cb9a1 100644 --- a/test/utils/envs_test.exs +++ b/test/utils/envs_test.exs @@ -72,4 +72,37 @@ defmodule Utils.EnvsTest do assert ctx.opts[:socket] == <<0, "foo">> end end + + describe "PGHOST with manual overrides" do + @env PGHOST: "/test/socket" + test "respects explicit hostname even if PGHOST is set" do + opts = Postgrex.Utils.default_opts(hostname: "localhost") + + assert Keyword.get(opts, :hostname) == "localhost" + refute Keyword.has_key?(opts, :socket_dir) + end + + @env PGHOST: "/test/socket" + test "respects explicit endpoints even if PGHOST is set" do + opts = Postgrex.Utils.default_opts(endpoints: [{"localhost", 5432}]) + + assert Keyword.get(opts, :endpoints) == [{"localhost", 5432}] + refute Keyword.has_key?(opts, :socket_dir) + end + + @env PGHOST: "/test/socket" + test "respects explicit socket even if PGHOST is set" do + opts = Postgrex.Utils.default_opts(socket: "/var/run/postgresql") + + assert Keyword.get(opts, :socket) == "/var/run/postgresql" + refute Keyword.has_key?(opts, :socket_dir) + end + + @env PGHOST: "/test/socket" + test "respects explicit socket_dir even if PGHOST is set" do + opts = Postgrex.Utils.default_opts(socket_dir: "/another/test/socket") + + assert Keyword.get(opts, :socket_dir) == "/another/test/socket" + end + end end