From 6e4ee91c3cc0f8a836c619299981a2d1bc91ceeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20M=C3=A4nnchen?= Date: Mon, 25 Mar 2024 16:40:10 +0100 Subject: [PATCH] Allow open-ended ranges --- lib/pg_ranges/numrange.ex | 2 ++ lib/pg_ranges/tstzrange.ex | 13 +++++++++++-- test/pg_ranges_test.exs | 23 +++++++++++++++-------- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/lib/pg_ranges/numrange.ex b/lib/pg_ranges/numrange.ex index c96f1da..66d6117 100644 --- a/lib/pg_ranges/numrange.ex +++ b/lib/pg_ranges/numrange.ex @@ -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 diff --git a/lib/pg_ranges/tstzrange.ex b/lib/pg_ranges/tstzrange.ex index a01e937..52854ad 100644 --- a/lib/pg_ranges/tstzrange.ex +++ b/lib/pg_ranges/tstzrange.ex @@ -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 diff --git a/test/pg_ranges_test.exs b/test/pg_ranges_test.exs index 6057a53..665ba00 100644 --- a/test/pg_ranges_test.exs +++ b/test/pg_ranges_test.exs @@ -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]) @@ -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, @@ -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