Packages
exandra
0.8.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/udt.ex
defmodule Exandra.UDT do
opts_schema = [
type: [
type: :atom,
required: true,
doc: "The UDT."
],
encoded_fields: [
type: {:list, :atom},
doc: "JSON encoded fields."
],
field: [
type: :atom,
doc: false
],
schema: [
type: :atom,
doc: false
]
]
@moduledoc """
`Ecto.ParameterizedType` for **User-Defined Types** (UDTs).
## Options
#{NimbleOptions.docs(opts_schema)}
## Examples
For example, if you have defined an `email` UDT in your database, you can
use it in your schema like this:
schema "users" do
field :email, Exandra.UDT, type: :email
end
"""
use Ecto.ParameterizedType
@type t :: map()
@opts_schema NimbleOptions.new!(opts_schema)
@impl Ecto.ParameterizedType
def type(_params), do: :udt
@impl Ecto.ParameterizedType
def init(opts) do
opts
|> __validate__()
|> Map.new()
end
@impl Ecto.ParameterizedType
def cast(data, %{type: _udt}), do: {:ok, data}
@impl Ecto.ParameterizedType
def load(data, _loader, params) do
{:ok, coerce_data(data, params, :load)}
end
@impl Ecto.ParameterizedType
def dump(data, _dumper, params) do
# Stringify all keys.
data = for {field, value} <- data || %{}, into: %{}, do: {"#{field}", value}
data = coerce_data(data, params, :dump)
{:ok, data}
end
@doc false
defp coerce_data(data, params, type) do
data = data || %{}
if fields_to_encode = params[:encoded_fields] do
for field <- fields_to_encode, into: data do
stringified_field = Atom.to_string(field)
{stringified_field, json_parse(data, stringified_field, type)}
end
else
data
end
end
@doc false
def json_parse(data, field, :dump),
do: data |> Map.get(field, %{}) |> Jason.encode!()
@doc false
def json_parse(data, field, :load),
do: data |> Map.get(field, "{}") |> Jason.decode!()
@doc false
def __validate__(opts), do: NimbleOptions.validate!(opts, @opts_schema)
end