-
Notifications
You must be signed in to change notification settings - Fork 41
/
moebius.ex
60 lines (49 loc) · 1.76 KB
/
moebius.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#this is the default database that is entirely optional
defmodule Moebius.Db do
use Moebius.Database
end
defmodule Moebius do
use Application
def start(_type, _args) do
Moebius.get_connection |> Moebius.Db.start_link
end
@doc """
A convenience tool for assembling large queries with multiple commands which we use for testing.
These functions hand off to PSQL because Postgrex can't run more than
one command per query.
"""
def run_with_psql(sql, opts) do
db = opts[:database] || opts[:db]
args = ["-d", db, "-c", sql, "--quiet", "--set", "ON_ERROR_STOP=1", "--no-psqlrc"]
System.cmd "psql", args
end
def get_connection(), do: get_connection(:connection)
def get_connection(key) when is_atom(key) do
opts = Application.get_env(:moebius, key)
cond do
Keyword.has_key?(opts, :url) -> Keyword.merge(opts, parse_connection(opts[:url]))
true -> opts
end
end
#thanks to the Ecto team for this code!
def parse_connection(url) when is_binary(url) do
info = url |> URI.decode() |> URI.parse()
if is_nil(info.host) do
raise "Invalid URL: host is not present"
end
if is_nil(info.path) or not (info.path =~ ~r"^/([^/])+$") do
raise "Invalid URL: path should be a database name"
end
destructure [username, password], info.userinfo && String.split(info.userinfo, ":")
"/" <> database = info.path
opts = [username: username,
password: password,
database: database,
hostname: info.host,
port: info.port]
#strip off any nils
opts = Enum.reject(opts, fn {_k, v} -> is_nil(v) end)
#send the values to a char list because that's what :epgsql likes
# opts = for {k, v} <- opts, into: %{}, do: {k, String.to_char_list(v)}
end
end