Skip to content

Commit

Permalink
Allow open-ended ranges
Browse files Browse the repository at this point in the history
  • Loading branch information
maennchen committed Mar 25, 2024
1 parent 9d4bbc6 commit 6e4ee91
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 10 deletions.
2 changes: 2 additions & 0 deletions lib/pg_ranges/numrange.ex
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ defmodule PgRanges.NumRange do
struct!(__MODULE__, fields)
end

defp to_decimal(value)
defp to_decimal(nil), do: nil
defp to_decimal(value) when is_float(value), do: Decimal.from_float(value)
defp to_decimal(value), do: Decimal.new(value)
end
13 changes: 11 additions & 2 deletions lib/pg_ranges/tstzrange.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,20 @@ defmodule PgRanges.TstzRange do
@impl true
def new(lower, upper, opts \\ []) do
time_zone_database = Keyword.get(opts, :time_zone_database, Calendar.get_time_zone_database())
{:ok, lower} = DateTime.shift_zone(lower, "Etc/UTC", time_zone_database)
{:ok, upper} = DateTime.shift_zone(upper, "Etc/UTC", time_zone_database)

lower = shift_to_utc(lower, time_zone_database)
upper = shift_to_utc(upper, time_zone_database)

fields = Keyword.merge(opts, lower: lower, upper: upper)

struct!(__MODULE__, fields)
end

defp shift_to_utc(date_time, time_zone_database)
defp shift_to_utc(nil, _time_zone_database), do: nil

defp shift_to_utc(date_time, time_zone_database) do
{:ok, date_time} = DateTime.shift_zone(date_time, "UTC", time_zone_database)
date_time
end
end
23 changes: 15 additions & 8 deletions test/pg_ranges_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ defmodule PgRanges.PgRangesTest do
NumRange
}

setup do
test "querying" do
date_range = DateRange.new(~D[2018-04-21], ~D[2018-04-22])
ts_range = TsRange.new(~N[2018-04-21 15:00:00], ~N[2018-04-22 01:00:00])

Expand All @@ -28,7 +28,7 @@ defmodule PgRanges.PgRangesTest do
int8_range = Int8Range.new(0, 1_000_000_000)
num_range = NumRange.new(0, 9.9, upper_inclusive: true)

{:ok, m} =
{:ok, _model} =
Model.changeset(%Model{}, %{
date: date_range,
ts: ts_range,
Expand All @@ -39,15 +39,22 @@ defmodule PgRanges.PgRangesTest do
})
|> Repo.insert()

{:ok, model: m}
end

test "querying" do
range = Int4Range.new(1, 4)
search_range = Int4Range.new(1, 4)

models =
Repo.all(from(m in Model, where: fragment("? @> ?", m.int4, type(^range, Int4Range))))
Repo.all(
from(m in Model, where: fragment("? @> ?", m.int4, type(^search_range, Int4Range)))
)

assert length(models) == 1
end

test "can create open ended ranges" do
assert %DateRange{lower: nil, upper: nil} = DateRange.new(nil, nil)
assert %TsRange{lower: nil, upper: nil} = TsRange.new(nil, nil)
assert %TstzRange{lower: nil, upper: nil} = TstzRange.new(nil, nil)
assert %Int4Range{lower: nil, upper: nil} = Int4Range.new(nil, nil)
assert %Int8Range{lower: nil, upper: nil} = Int8Range.new(nil, nil)
assert %NumRange{lower: nil, upper: nil} = NumRange.new(nil, nil)
end
end

0 comments on commit 6e4ee91

Please sign in to comment.