Skip to content

Instantly share code, notes, and snippets.

@felipegasparini
Last active March 8, 2024 22:37
Show Gist options
  • Save felipegasparini/7c9a6fa0c2c463c17540b8e8544f16cf to your computer and use it in GitHub Desktop.
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
@walter
Copy link

walter commented Dec 2, 2016

Is to_float/1 needed?

@jgautsch
Copy link

jgautsch commented Oct 2, 2018

No it's not.
Also to those stumbling upon this, it's outdated. Ecto.DateTime is deprecated.
Here is a more up-to-date version: https://gist.github.com/jgautsch/85bda57d53ada9f2d0106b3d4a379472

@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