/
ddl.ex
143 lines (108 loc) · 3.58 KB
/
ddl.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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
defmodule Cldr.Unit.DDL do
@moduledoc """
Functions to return SQL DDL commands that support the
creation and deletion of the `cldr_unit` database
type and associated aggregate functions.
"""
# @doc since: "2.7.0"
@default_db :postgres
@supported_db_types :code.priv_dir(:ex_cldr_units_sql)
|> Path.join("SQL")
|> File.ls!()
|> Enum.map(&String.to_atom/1)
@doc """
Returns the SQL string which when executed will
define the `money_with_currency` data type.
## Arguments
* `db_type`: the type of the database for which the SQL
string should be returned. Defaults to `:postgres` which
is currently the only supported database type.
"""
def create_cldr_unit(db_type \\ @default_db) do
read_sql_file(db_type, "create_cldr_unit.sql")
end
@doc """
Returns the SQL string which when executed will
drop the `money_with_currency` data type.
## Arguments
* `db_type`: the type of the database for which the SQL
string should be returned. Defaults to `:postgres` which
is currently the only supported database type.
"""
def drop_cldr_unit(db_type \\ @default_db) do
read_sql_file(db_type, "drop_cldr_unit.sql")
end
@doc """
Returns the SQL string which when executed will
define aggregate functions for the `money_with_currency`
data type.
## Arguments
* `db_type`: the type of the database for which the SQL
string should be returned. Defaults to `:postgres` which
is currently the only supported database type.
"""
def define_aggregate_functions(db_type \\ @default_db) do
read_sql_file(db_type, "define_aggregate_functions.sql")
end
@doc """
Returns the SQL string which when executed will
drop the aggregate functions for the `money_with_currency`
data type.
## Arguments
* `db_type`: the type of the database for which the SQL
string should be returned. Defaults to `:postgres` which
is currently the only supported database type.
"""
def drop_aggregate_functions(db_type \\ @default_db) do
read_sql_file(db_type, "drop_aggregate_functions.sql")
end
@doc """
Returns a string that will Ecto `execute` each SQL
command.
## Arguments
* `sql` is a string of SQL commands that are
separated by three newlines ("\\n"),
that is to say two blank lines between commands
in the file.
## Example
iex> Money.DDL.execute "SELECT name FROM customers;\n\n\nSELECT id FROM orders;"
"execute \"\"\"\nSELECT name FROM customers;\n\n\nSELECT id FROM orders;\n\"\"\""
"""
def execute_each(sql) do
sql
|> String.split("\n\n\n")
|> Enum.map(&execute/1)
|> Enum.join("\n")
end
@doc """
Returns a string that will Ecto `execute` a single SQL
command.
## Arguments
* `sql` is a single SQL command
## Example
iex> Money.DDL.execute "SELECT name FROM customers;"
"execute \"SELECT name FROM customers;\""
"""
def execute(sql) do
sql = String.trim_trailing(sql, "\n")
if String.contains?(sql, "\n") do
"execute \"\"\"\n" <> sql <> "\n\"\"\""
else
"execute " <> inspect(sql)
end
end
defp read_sql_file(db_type, file_name) when db_type in @supported_db_types do
base_dir(db_type)
|> Path.join(file_name)
|> File.read!()
end
defp read_sql_file(db_type, file_name) do
raise ArgumentError,
"Database type #{db_type} does not have a SQL definition " <> "file #{inspect(file_name)}"
end
@app Mix.Project.config[:app]
defp base_dir(db_type) do
:code.priv_dir(@app)
|> Path.join(["SQL", "/#{db_type}"])
end
end