Packages
exandra
0.11.0
1.1.0
1.0.0
0.16.0
0.15.0
0.14.0
0.13.0
0.12.0
0.11.0
0.10.3
0.10.2
0.10.1
0.10.1-rc.5
0.10.0
0.10.0-rc.5
0.10.0-rc.4
0.10.0-rc.3
0.10.0-rc.2
0.10.0-rc.1
0.9.1
0.9.0
0.8.1
0.8.0
0.7.5
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.1
0.5.0
0.4.1
0.4.0
0.3.1
0.3.0
0.2.1
0.2.0
0.1.16
0.1.15
0.1.14
0.1.13
0.1.12
0.1.11
0.1.10
Exandra is an Elixir library that brings the power of Scylla/Cassandra to Ecto.
Current section
Files
Jump to
Current section
Files
lib/exandra/types.ex
defmodule Exandra.Types do
@moduledoc false
alias Exandra.UDT
@timestamp_types [
:datetime,
:naive_datetime,
:naive_datetime_usec,
:utc_datetime,
:utc_datetime_usec
]
@spec for(Ecto.Type.t()) :: {:ok, String.t()} | :error
def for(type, opts \\ [])
def for(:id, _), do: {:ok, "uuid"}
def for(:binary_id, _), do: {:ok, "uuid"}
def for(:integer, _), do: {:ok, "int"}
def for(:string, _), do: {:ok, "text"}
def for(:binary, _), do: {:ok, "blob"}
def for(:map, _), do: {:ok, "text"}
def for(UDT, opts), do: {:ok, "FROZEN<#{UDT.__validate__(opts)[:type]}>"}
def for(type, _opts) when type in @timestamp_types, do: {:ok, "timestamp"}
def for({:array, UDT}, opts) do
with {:ok, subtype} <- __MODULE__.for(UDT, opts), do: {:ok, "FROZEN<list<#{subtype}>>"}
end
def for({:array, subtype}, _opts) do
with {:ok, subtype} <- __MODULE__.for(subtype), do: {:ok, "list<#{subtype}>"}
end
def for({:parameterized, Ecto.Embedded, _}, _opts), do: {:ok, "text"}
def for({:parameterized, Ecto.Enum, _}, _opts), do: {:ok, "text"}
def for(ecto_type, _opts) when is_atom(ecto_type) do
if Code.ensure_loaded?(ecto_type) and function_exported?(ecto_type, :type, 0) do
{:ok, to_string(ecto_type.type())}
else
{:ok, Atom.to_string(ecto_type)}
end
end
def for(_ecto_type, _opts), do: :error
@spec check_type!(module(), any(), keyword()) :: Ecto.Type.t()
def check_type!(name, type, opts) when is_atom(type) do
cond do
Ecto.Type.base?(type) -> type
Code.ensure_compiled(type) == {:module, type} -> check_parameterized(name, type, opts)
true -> raise ArgumentError, "#{name}: not a valid type parameter, got #{inspect(type)}"
end
end
def check_type!(name, {composite, inner}, opts) do
if Ecto.Type.composite?(composite) do
inner = check_type!(name, inner, opts)
{composite, inner}
else
raise ArgumentError, "#{name}: expected Ecto composite type, got: #{inspect(composite)}"
end
end
def check_type!(name, any, _opts),
do: raise(ArgumentError, "#{name}: unknown type parameter, got: #{inspect(any)}")
defp check_parameterized(name, type, opts) do
cond do
function_exported?(type, :type, 0) ->
type
function_exported?(type, :type, 1) ->
Ecto.ParameterizedType.init(type, opts)
true ->
raise ArgumentError,
"#{name}: expected Ecto.Type/Ecto.ParameterizedType, got: #{inspect(type)}"
end
end
end