Current section
Files
Jump to
Current section
Files
lib/kvasir/posgres/util.ex
defmodule Kvasir.Postgres.Util do
@moduledoc false
require Logger
### Settings ###
@defaults [
username: "postgres",
password: "postgres",
hostname: "localhost",
database: "postgres"
]
@doc ~S"""
Configure a PostgreSQL connection.
## Examples
Defaults to standard PostgreSQL settings:
```elixir
iex> settings()
[username: "postgres", password: "postgres", hostname: "localhost", database: "postgres"]
```
```elixir
iex> settings(hostname: "example.com", username: nil)
[password: "postgres", database: "postgres", hostname: "example.com"]
```
```elixir
iex> settings(url: "postgres://my-user:my-pass@my-host/my-db")
[username: "my-user", password: "my-pass", hostname: "my-host", database: "my-db"]
```
"""
@spec settings(Keyword.t()) :: Keyword.t()
def settings(opts \\ [])
def settings(opts) do
{u, settings} = Keyword.pop(opts, :url)
@defaults
|> Keyword.merge(url(u))
|> Keyword.merge(settings)
|> Enum.reject(&(elem(&1, 1) == nil))
end
@doc ~S"""
Configure PostgreSQL based on a URI.
## Examples
No URI, no settings:
```elixir
iex> url(nil)
[]
```
Basic configuration:
```elixir
iex> url("postgres://my-host/my-db")
[hostname: "my-host", database: "my-db"]
```
Allows settings username and/or password:
```elixir
iex> url("postgres://my-user:@my-host/my-db")
[username: "my-user", hostname: "my-host", database: "my-db"]
iex> url("postgres://:my-pass@my-host/my-db")
[password: "my-pass", hostname: "my-host", database: "my-db"]
iex> url("postgres://my-user:my-pass@my-host/my-db")
[username: "my-user", password: "my-pass", hostname: "my-host", database: "my-db"]
```
Allows for custom port:
```elixir
iex> url("postgres://my-host:8888/my-db")
[hostname: "my-host", database: "my-db", port: 8888]
```
Scheme must be `postgres`:
```
iex> url("https://example.com/my-db")
[]
```
"""
@spec url(String.t() | nil) :: Keyword.t()
def url(uri)
def url(nil), do: []
def url(uri) do
case URI.parse(uri) do
uri = %URI{scheme: "postgres"} ->
{user, pass} =
case :binary.split(uri.userinfo || "", ":") do
[""] -> {nil, nil}
[a, b] -> {if(a != "", do: a), if(b != "", do: b)}
end
Enum.reject(
[
username: user,
password: pass,
hostname: uri.host,
database: uri.path && String.trim(uri.path, "/"),
port: uri.port
],
&(elem(&1, 1) == nil)
)
_ ->
Logger.error(fn -> "#{inspect(__MODULE__)}: Invalid PostgreSQL URI set." end)
[]
end
end
end