看起來@TheAnh有正確的方法,但這裏是真正清盤的工作me:
defmodule Myapp.TsRange do
@behaviour Ecto.Type
def type, do: :tsrange
def cast(nil), do: {:ok, nil}
def cast([lower, upper]), do: {:ok, [lower, upper]}
def cast(_), do: :error
def load(%Postgrex.Range{lower: lower, upper: upper}) do
lower = lower |> to_datetime
upper = upper |> to_datetime
case [lower, upper] do
[nil, nil] -> {:ok, [nil, nil]}
[{:ok, lower}, {:ok, upper}] -> {:ok, [lower, upper]}
_ -> :error
end
end
def load(_), do: :error
def dump([lower, upper]) do
{:ok, %Postgrex.Range{lower: lower |> from_datetime,
upper: upper |> from_datetime,
upper_inclusive: false}}
end
def dump(_), do: :error
defp to_datetime(nil), do: nil
defp to_datetime({{y, m, d}, {h, min, s, ms}}) do
NaiveDateTime.new(y, m, d, h, min, s, ms)
end
defp from_datetime(nil), do: nil
defp from_datetime(dt) do
{{dt.year, dt.month, dt.day}, {dt.hour, dt.minute, dt.second, elem(dt.microsecond, 0)}}
end
end
您並不需要第一個'load'子句。第二個條款將以完全相同的方式處理'nil'情況。 – Dogbert
啊,非常感謝! – TheAnh