Current section
Files
Jump to
Current section
Files
lib/connection/helper.ex
defmodule MssqlEcto.Connection.Helper do
@moduledoc false
alias MssqlEcto.Connection.Query.Expression
require Logger
def get_source(query, sources, ix, source) do
{expr, name, _schema} = elem(sources, ix)
{expr || Expression.expr(source, sources, query), name}
end
def add_prefix(nil, name) do
name
end
def add_prefix(prefix, name) do
[quote_name(prefix), ".", name]
end
def quote_qualified_name(name, sources, ix) do
{_, source, _} = elem(sources, ix)
[source, ?. | quote_name(name)]
end
def quote_name(name, quoter \\ ?")
def quote_name(nil, _), do: []
def quote_name(names, quoter) when is_list(names) do
names
|> Enum.filter(&(not is_nil(&1)))
|> intersperse_map(?., "e_name(&1, nil))
|> wrap_in(quoter)
end
def quote_name(name, quoter) when is_atom(name) do
quote_name(Atom.to_string(name), quoter)
end
def quote_name(name, quoter) do
if String.contains?(name, "\"") do
error!(nil, "bad name #{inspect(name)}")
end
wrap_in(name, quoter)
end
def wrap_in(value, nil), do: value
def wrap_in(value, {left_wrapper, right_wrapper}) do
[left_wrapper, value, right_wrapper]
end
def wrap_in(value, wrapper) do
[wrapper, value, wrapper]
end
def quote_table(nil, name), do: quote_table(name)
def quote_table(prefix, name), do: [quote_table(prefix), ?., quote_table(name)]
def quote_table(name) when is_atom(name),
do: quote_table(Atom.to_string(name))
def quote_table(name) do
if String.contains?(name, "\"") do
error!(nil, "bad table name #{inspect(name)}")
end
[?", name, ?"]
end
def single_quote(value), do: [?', escape_string(value), ?']
def intersperse_map(list, separator, mapper, acc \\ [])
def intersperse_map([], _separator, _mapper, acc),
do: acc
def intersperse_map([elem], _separator, mapper, acc),
do: [acc | mapper.(elem)]
def intersperse_map([elem | rest], separator, mapper, acc),
do: intersperse_map(rest, separator, mapper, [acc, mapper.(elem), separator])
def intersperse_reduce(list, separator, user_acc, reducer, acc \\ [])
def intersperse_reduce([], _separator, user_acc, _reducer, acc),
do: {acc, user_acc}
def intersperse_reduce([elem], _separator, user_acc, reducer, acc) do
{elem, user_acc} = reducer.(elem, user_acc)
{[acc | elem], user_acc}
end
def intersperse_reduce([elem | rest], separator, user_acc, reducer, acc) do
{elem, user_acc} = reducer.(elem, user_acc)
intersperse_reduce(rest, separator, user_acc, reducer, [acc, elem, separator])
end
def if_do(condition, value) do
if condition, do: value, else: []
end
def escape_string(value) when is_binary(value) do
:binary.replace(value, "'", "''", [:global])
end
def ecto_to_db({:array, t}), do: [ecto_to_db(t), ?[, ?]]
def ecto_to_db(:id), do: "int identity(1,1)"
def ecto_to_db(:serial), do: "int identity(1,1)"
def ecto_to_db(:bigserial), do: "bigint identity(1,1)"
def ecto_to_db(:binary_id), do: "char(36)"
def ecto_to_db(:uuid), do: "char(36)"
def ecto_to_db(:string), do: "nvarchar"
def ecto_to_db(:binary), do: "nvarchar(4000)"
def ecto_to_db(:integer), do: "int"
def ecto_to_db(:boolean), do: "bit"
def ecto_to_db(:map), do: "nvarchar(4000)"
def ecto_to_db({:map, _}), do: "nvarchar(4000)"
def ecto_to_db(:utc_datetime), do: "datetime2"
def ecto_to_db(:utc_datetime_usec), do: "datetime2"
def ecto_to_db(:naive_datetime), do: "datetime2"
def ecto_to_db(:naive_datetime_usec), do: "datetime2"
def ecto_to_db(:timestamp), do: "datetime2"
def ecto_to_db(:bigint), do: "bigint"
def ecto_to_db(:decimal), do: "decimal"
def ecto_to_db(:float), do: "float"
def ecto_to_db(:date), do: "date"
def ecto_to_db(:text), do: "text"
def ecto_to_db(:numeric), do: "numeric"
def ecto_to_db(other) do
Logger.warn("type not explicitly handled: #{other}")
Atom.to_string(other)
end
def error!(nil, message) do
raise ArgumentError, message
end
def error!(query, message) do
raise Ecto.QueryError, query: query, message: message
end
end