Skip to content

Instantly share code, notes, and snippets.

@felipegasparini
Last active November 5, 2018 02:18
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save felipegasparini/7c9a6fa0c2c463c17540b8e8544f16cf to your computer and use it in GitHub Desktop.
Ecto Postgres tsrange data type
defmodule Postgrex.Extension.TSRange do
@behaviour Ecto.Type
def type, do: :tsrange
def cast([lower, upper]) do
case apply_func([lower, upper], &Ecto.DateTime.cast/1) do
{:ok, [lower, upper]} -> {:ok, [lower, upper]}
:error -> :error
end
end
def cast(_), do: :error
def load(%Postgrex.Range{lower: lower, upper: upper}) do
apply_func([lower, upper], &Ecto.DateTime.load/1)
end
def load(_), do: :error
def dump([lower, upper]) do
case apply_func([lower, upper], &Ecto.DateTime.dump/1) do
{:ok, [lower, upper]} -> {:ok, %Postgrex.Range{lower: lower, upper: upper, upper_inclusive: false}}
:error -> :error
end
end
def dump(_), do: :error
defp to_float(value) do
value |> Decimal.to_string |> Float.parse
end
defp apply_func([lower, upper], fun) do
lower = apply_func(lower, fun)
upper = apply_func(upper, fun)
if lower != :error and upper != :error do
{:ok, [lower, upper]}
else
:error
end
end
defp apply_func(target, fun) do
case fun.(target) do
{:ok, target} -> target
:error -> :error
end
end
end
@jgautsch
Copy link

jgautsch commented Nov 5, 2018

FYI here's a repo implementing tsrange and tstzrange columns, as well as examples of how to query for overlapping ranges: https://github.com/jgautsch/ecto_time_ranges

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment