Skip to content

Commit b876381

Browse files
committed
Refactor generated handling in column_type
1 parent 62603f8 commit b876381

File tree

1 file changed

+57
-78
lines changed

1 file changed

+57
-78
lines changed

lib/ecto/adapters/postgres/connection.ex

Lines changed: 57 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,7 @@ if Code.ensure_loaded?(Postgrex) do
9090
do: []
9191

9292
defp strip_quotes(quoted) do
93-
size = byte_size(quoted) - 2
94-
<<_, unquoted::binary-size(size), _>> = quoted
95-
unquoted
93+
binary_part(quoted, 1, byte_size(quoted) - 2)
9694
end
9795

9896
## Query
@@ -1760,104 +1758,85 @@ if Code.ensure_loaded?(Postgrex) do
17601758
defp options_expr(options),
17611759
do: [?\s, options]
17621760

1763-
defp column_type({:array, type}, opts) do
1764-
[type, opts] = column_type(type, opts)
1765-
[[type, "[]"], opts]
1766-
end
1761+
defp column_type(type, opts) do
1762+
type_name = column_type_name(type, opts)
17671763

1768-
defp column_type(type, opts) when type in ~w(time utc_datetime naive_datetime)a do
1769-
generated = Keyword.get(opts, :generated)
1770-
[[ecto_to_db(type), "(0)"], generated_expr(generated)]
1771-
end
1764+
case Keyword.get(opts, :generated) do
1765+
nil when type == :identity ->
1766+
cleanup = fn v -> is_integer(v) and v > 0 end
17721767

1773-
defp column_type(type, opts)
1774-
when type in ~w(time_usec utc_datetime_usec naive_datetime_usec)a do
1775-
precision = Keyword.get(opts, :precision)
1776-
generated = Keyword.get(opts, :generated)
1777-
type_name = ecto_to_db(type)
1768+
sequence =
1769+
[Keyword.get(opts, :start_value)]
1770+
|> Enum.filter(cleanup)
1771+
|> Enum.map(&"START WITH #{&1}")
1772+
|> Kernel.++(
1773+
[Keyword.get(opts, :increment)]
1774+
|> Enum.filter(cleanup)
1775+
|> Enum.map(&"INCREMENT BY #{&1}")
1776+
)
1777+
1778+
case sequence do
1779+
[] -> [type_name, " GENERATED BY DEFAULT AS IDENTITY"]
1780+
_ -> [type_name, " GENERATED BY DEFAULT AS IDENTITY(", Enum.join(sequence, " "), ") "]
1781+
end
17781782

1779-
type =
1780-
if precision do
1781-
[type_name, ?(, to_string(precision), ?)]
1782-
else
1783+
nil ->
17831784
type_name
1784-
end
17851785

1786-
[type, generated_expr(generated)]
1786+
expr when is_binary(expr) ->
1787+
[type_name, " GENERATED ", expr]
1788+
1789+
other ->
1790+
raise ArgumentError,
1791+
"the `:generated` option only accepts strings, received: #{inspect(other)}"
1792+
end
17871793
end
17881794

1789-
defp column_type(:identity, opts) do
1790-
start_value = [Keyword.get(opts, :start_value)]
1791-
increment = [Keyword.get(opts, :increment)]
1792-
generated = Keyword.get(opts, :generated)
1793-
type_name = ecto_to_db(:identity)
1795+
defp column_type_name({:array, type}, opts) do
1796+
[column_type_name(type, opts), "[]"]
1797+
end
17941798

1795-
if generated do
1796-
[type_name, generated_expr(generated)]
1797-
else
1798-
cleanup = fn v -> is_integer(v) and v > 0 end
1799-
1800-
sequence =
1801-
start_value
1802-
|> Enum.filter(cleanup)
1803-
|> Enum.map(&"START WITH #{&1}")
1804-
|> Kernel.++(
1805-
increment
1806-
|> Enum.filter(cleanup)
1807-
|> Enum.map(&"INCREMENT BY #{&1}")
1808-
)
1799+
defp column_type_name(type, _opts) when type in ~w(time utc_datetime naive_datetime)a do
1800+
[ecto_to_db(type), "(0)"]
1801+
end
18091802

1810-
case sequence do
1811-
[] -> [type_name, " GENERATED BY DEFAULT AS IDENTITY"]
1812-
_ -> [type_name, " GENERATED BY DEFAULT AS IDENTITY(", Enum.join(sequence, " "), ") "]
1813-
end
1803+
defp column_type_name(type, opts)
1804+
when type in ~w(time_usec utc_datetime_usec naive_datetime_usec)a do
1805+
precision = Keyword.get(opts, :precision)
1806+
type_name = ecto_to_db(type)
1807+
1808+
if precision do
1809+
[type_name, ?(, to_string(precision), ?)]
1810+
else
1811+
type_name
18141812
end
18151813
end
18161814

1817-
defp column_type(:duration, opts) do
1815+
defp column_type_name(:duration, opts) do
18181816
precision = Keyword.get(opts, :precision)
18191817
fields = Keyword.get(opts, :fields)
1820-
generated = Keyword.get(opts, :generated)
18211818
type_name = ecto_to_db(:duration)
18221819

1823-
type =
1824-
cond do
1825-
fields && precision -> [type_name, " ", fields, ?(, to_string(precision), ?)]
1826-
precision -> [type_name, ?(, to_string(precision), ?)]
1827-
fields -> [type_name, " ", fields]
1828-
true -> [type_name]
1829-
end
1830-
1831-
[type, generated_expr(generated)]
1820+
cond do
1821+
fields && precision -> [type_name, " ", fields, ?(, to_string(precision), ?)]
1822+
precision -> [type_name, ?(, to_string(precision), ?)]
1823+
fields -> [type_name, " ", fields]
1824+
true -> [type_name]
1825+
end
18321826
end
18331827

1834-
defp column_type(type, opts) do
1828+
defp column_type_name(type, opts) do
18351829
size = Keyword.get(opts, :size)
18361830
precision = Keyword.get(opts, :precision)
18371831
scale = Keyword.get(opts, :scale)
1838-
generated = Keyword.get(opts, :generated)
18391832
type_name = ecto_to_db(type)
18401833

1841-
type =
1842-
cond do
1843-
size -> [type_name, ?(, to_string(size), ?)]
1844-
precision -> [type_name, ?(, to_string(precision), ?,, to_string(scale || 0), ?)]
1845-
type == :string -> [type_name, "(255)"]
1846-
true -> type_name
1847-
end
1848-
1849-
[type, generated_expr(generated)]
1850-
end
1851-
1852-
defp generated_expr(nil), do: []
1853-
1854-
defp generated_expr(expr) when is_binary(expr) do
1855-
[" GENERATED ", expr]
1856-
end
1857-
1858-
defp generated_expr(other) do
1859-
raise ArgumentError,
1860-
"the `:generated` option only accepts strings, received: #{inspect(other)}"
1834+
cond do
1835+
size -> [type_name, ?(, to_string(size), ?)]
1836+
precision -> [type_name, ?(, to_string(precision), ?,, to_string(scale || 0), ?)]
1837+
type == :string -> [type_name, "(255)"]
1838+
true -> type_name
1839+
end
18611840
end
18621841

18631842
defp reference_expr(%Reference{} = ref, table, name) do

0 commit comments

Comments
 (0)