Created
February 8, 2023 13:16
-
-
Save Dowwie/d69de06af2e9f8799287d8b4236e7ed7 to your computer and use it in GitHub Desktop.
Elixir Ecto tsrange type
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule My.Postgres.TsRange do | |
@moduledoc """ | |
Wraps a `Postgrex.Range` and casts to a PostgreSQL `tsrange` type. | |
Works w/ecto 3.8.0, postgrex 0.16 | |
""" | |
use Ecto.Type | |
alias Postgrex.Range | |
defstruct lower: nil, | |
lower_inclusive: true, | |
upper: nil, | |
upper_inclusive: false | |
@type t :: %__MODULE__{ | |
lower: NaiveDateTime.t() | :unbound, | |
lower_inclusive: boolean(), | |
upper: NaiveDateTime.t() | :unbound, | |
upper_inclusive: boolean() | |
} | |
@spec new(any, any) :: __MODULE__.t() | |
def new(lower, upper) do | |
struct!(__MODULE__, lower: lower, upper: upper) | |
end | |
@spec type :: :tsrange | |
@doc false | |
def type, do: :tsrange | |
@spec from_postgrex(Range.t()) :: __MODULE__.t() | |
def from_postgrex(%Range{} = range), | |
do: struct!(__MODULE__, Map.from_struct(range)) | |
@doc false | |
@spec to_postgrex(__MODULE__.t()) :: Range.t() | |
def to_postgrex(%__MODULE__{} = range), | |
do: struct!(Range, Map.from_struct(range)) | |
@spec cast(any) :: :error | {:ok, nil | Dispatch.Postgres.TsRange.t()} | |
@doc false | |
def cast(nil), do: {:ok, nil} | |
def cast(%Range{} = range), do: {:ok, from_postgrex(range)} | |
def cast(%__MODULE__{} = range), do: {:ok, range} | |
def cast(_), do: :error | |
@spec load(any) :: :error | {:ok, nil | Dispatch.Postgres.TsRange.t()} | |
@doc false | |
def load(nil), do: {:ok, nil} | |
def load(%Range{} = range), do: {:ok, from_postgrex(range)} | |
def load(_), do: :error | |
@spec dump(any) :: :error | {:ok, nil | Postgrex.Range.t()} | |
@doc false | |
def dump(nil), do: {:ok, nil} | |
def dump(%__MODULE__{} = range), do: {:ok, to_postgrex(range)} | |
def dump(_), do: :error | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment