Skip to content

Commit b5f5028

Browse files
authored
fix ranges encoding (#155)
1 parent 59be2df commit b5f5028

File tree

7 files changed

+147
-33
lines changed

7 files changed

+147
-33
lines changed

CHANGELOG.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,25 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8-
98
## Unreleased
109

11-
[Compare with 0.6.0](https://github.com/edgedb/edgedb-elixir/compare/v0.6.0...HEAD)
10+
[Compare with 0.6.1](https://github.com/edgedb/edgedb-elixir/compare/v0.6.1...HEAD)
11+
12+
## [0.6.1] - 2023-07-07
13+
14+
[Compare with 0.6.0](https://github.com/edgedb/edgedb-elixir/compare/v0.6.0...v0.6.1)
1215

1316
### Added
1417

1518
- support for `Elixir v1.15` and `Erlang/OTP 26`.
1619

20+
### Fixed
21+
22+
- encoding of `t:EdgeDB.Range.t/0` values.
23+
- constructing `t:EdgeDB.Range.t/0` from `EdgeDB.Range.new/3` with `nil` as values.
24+
- examples in the documentation and the `Inspect` implementation of
25+
`t:EdgeDB.DateDuration.t/0` and `t:EdgeDB.Range.t/0`.
26+
1727
## [0.6.0] - 2023-06-22
1828

1929
[Compare with 0.5.1](https://github.com/edgedb/edgedb-elixir/compare/v0.5.1...v0.6.0)

lib/edgedb/protocol/codecs/range.ex

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,17 @@ defimpl EdgeDB.Protocol.Codec, for: EdgeDB.Protocol.Codecs.Range do
3333
codec = CodecStorage.get(codec_storage, codec)
3434
flags = encode_range_flags(range)
3535

36-
data = [
37-
Codec.encode(codec, range.lower, codec_storage),
38-
Codec.encode(codec, range.upper, codec_storage)
39-
]
40-
41-
[<<IO.iodata_length(data)::uint32(), flags::uint8()>> | data]
36+
data =
37+
Enum.reject(
38+
[
39+
<<flags::uint8()>>,
40+
range.lower && Codec.encode(codec, range.lower, codec_storage),
41+
range.upper && Codec.encode(codec, range.upper, codec_storage)
42+
],
43+
&is_nil/1
44+
)
45+
46+
[<<IO.iodata_length(data)::uint32()>> | data]
4247
end
4348

4449
@impl Codec
@@ -115,6 +120,9 @@ defimpl EdgeDB.Protocol.Codec, for: EdgeDB.Protocol.Codecs.Range do
115120

116121
range.inc_lower ->
117122
Bitwise.bor(flags, @lb_inc)
123+
124+
true ->
125+
flags
118126
end
119127

120128
cond do
@@ -123,6 +131,9 @@ defimpl EdgeDB.Protocol.Codec, for: EdgeDB.Protocol.Codecs.Range do
123131

124132
range.inc_upper ->
125133
Bitwise.bor(flags, @ub_inc)
134+
135+
true ->
136+
flags
126137
end
127138
end
128139
end

lib/edgedb/types/date_duration.ex

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ defmodule EdgeDB.DateDuration do
66
```elixir
77
iex(1)> {:ok, client} = EdgeDB.start_link()
88
iex(2)> EdgeDB.query_required_single!(client, "select <cal::date_duration>'1 year 2 days'")
9-
#EdgeDB.Duration<"P1Y20D">
9+
#EdgeDB.DateDuration<"P1Y2D">
1010
```
1111
"""
1212

@@ -33,12 +33,12 @@ defimpl Inspect, for: EdgeDB.DateDuration do
3333

3434
@impl Inspect
3535
def inspect(%EdgeDB.DateDuration{days: 0, months: 0}, _opts) do
36-
concat(["#EdgeDB.RelativeDuration<\"", "P0D", "\">"])
36+
concat(["#EdgeDB.DateDuration<\"", "P0D", "\">"])
3737
end
3838

3939
@impl Inspect
4040
def inspect(%EdgeDB.DateDuration{} = duration, _opts) do
41-
concat(["#EdgeDB.RelativeDuration<\"", format_date("P", duration), "\">"])
41+
concat(["#EdgeDB.DateDuration<\"", format_date("P", duration), "\">"])
4242
end
4343

4444
defp format_date(formatted_repr, %EdgeDB.DateDuration{} = duration) do

lib/edgedb/types/range.ex

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,20 @@ defmodule EdgeDB.Range do
1818
is_empty: false
1919
]
2020

21+
@typedoc since: "0.6.1"
2122
@typedoc """
22-
A value representing some interval of values.
23+
A type that is acceptable by EdgeDB ranges.
24+
"""
25+
@type value() ::
26+
integer()
27+
| float()
28+
| Decimal.t()
29+
| DateTime.t()
30+
| NaiveDateTime.t()
31+
| Date.t()
32+
33+
@typedoc """
34+
A value of `t:value/0` type representing some interval of values.
2335
2436
Fields:
2537
@@ -38,9 +50,9 @@ defmodule EdgeDB.Range do
3850
}
3951

4052
@typedoc """
41-
A value representing some interval of values.
53+
A value of `t:value/0` type representing some interval of values.
4254
"""
43-
@type t() :: t(term())
55+
@type t() :: t(value())
4456

4557
@typedoc """
4658
Options for `EdgeDB.Range.new/3` function.
@@ -66,7 +78,7 @@ defmodule EdgeDB.Range do
6678
"""
6779
@spec empty() :: t()
6880
def empty do
69-
new(nil, nil, empty: true, inc_lower: false)
81+
new(nil, nil, empty: true)
7082
end
7183

7284
@doc """
@@ -77,19 +89,38 @@ defmodule EdgeDB.Range do
7789
#EdgeDB.Range<[1.1, 3.3]>
7890
```
7991
"""
80-
@spec new(value, value, list(creation_option())) :: t(value) when value: term()
92+
@spec new(value | nil, value | nil, list(creation_option())) :: t(value) when value: value()
8193
def new(lower, upper, opts \\ []) do
94+
empty? = Keyword.get(opts, :empty, false)
8295
inc_lower? = Keyword.get(opts, :inc_lower, true)
8396
inc_upper? = Keyword.get(opts, :inc_upper, false)
84-
empty? = Keyword.get(opts, :empty, false)
8597

86-
%__MODULE__{
87-
lower: lower,
88-
upper: upper,
89-
inc_lower: inc_lower?,
90-
inc_upper: inc_upper?,
91-
is_empty: empty?
92-
}
98+
cond do
99+
empty? and (not is_nil(lower) or not is_nil(upper)) ->
100+
raise EdgeDB.InvalidArgumentError.new(
101+
"conflicting arguments to construct range: " <>
102+
":empty is `true` while the specified bounds " <>
103+
"suggest otherwise"
104+
)
105+
106+
empty? ->
107+
%__MODULE__{
108+
lower: nil,
109+
upper: nil,
110+
inc_lower: false,
111+
inc_upper: false,
112+
is_empty: true
113+
}
114+
115+
true ->
116+
%__MODULE__{
117+
lower: lower,
118+
upper: upper,
119+
inc_lower: not is_nil(lower) and inc_lower?,
120+
inc_upper: not is_nil(upper) and inc_upper?,
121+
is_empty: false
122+
}
123+
end
93124
end
94125
end
95126

@@ -107,7 +138,7 @@ defimpl Inspect, for: EdgeDB.Range do
107138
"#EdgeDB.Range<",
108139
if(range.inc_lower, do: "[", else: "("),
109140
if(range.lower, do: Inspect.inspect(range.lower, opts), else: empty()),
110-
",",
141+
", ",
111142
if(range.upper, do: Inspect.inspect(range.upper, opts), else: empty()),
112143
if(range.inc_upper, do: "]", else: ")"),
113144
">"

mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ defmodule EdgeDB.MixProject do
22
use Mix.Project
33

44
@app :edgedb
5-
@version "0.6.0"
5+
@version "0.6.1"
66
@source_url "https://github.com/edgedb/edgedb-elixir"
77
@description "EdgeDB client for Elixir"
88

test/docs/docs_test.exs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ defmodule Tests.DocsTest do
1919
doctest EdgeDB.RelativeDuration
2020
doctest EdgeDB.Set
2121

22+
skip_before(version: 2)
23+
doctest EdgeDB.DateDuration
24+
25+
skip_before(version: 2)
26+
doctest EdgeDB.Range
27+
2228
defp drop_tickets(client) do
2329
EdgeDB.query!(client, "delete Ticket")
2430

test/edgedb/protocol/codecs/range_test.exs

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,66 @@ defmodule Tests.EdgeDB.Protocol.Codecs.RangeTest do
44
skip_before(version: 2, scope: :module)
55

66
@input_ranges %{
7+
"range<int32>" => [
8+
EdgeDB.Range.new(1, 2),
9+
{EdgeDB.Range.new(1, 2, inc_upper: true), EdgeDB.Range.new(1, 3)},
10+
EdgeDB.Range.empty(),
11+
{EdgeDB.Range.new(1, 1), EdgeDB.Range.empty()},
12+
EdgeDB.Range.new(nil, nil)
13+
],
714
"range<int64>" => [
8-
EdgeDB.Range.new(1, 2, inc_lower: true, inc_upper: false),
9-
{EdgeDB.Range.new(1, 2, inc_lower: true, inc_upper: true),
10-
EdgeDB.Range.new(1, 3, inc_lower: true, inc_upper: false)},
15+
EdgeDB.Range.new(1, 2),
16+
{EdgeDB.Range.new(1, 2, inc_upper: true), EdgeDB.Range.new(1, 3)},
17+
EdgeDB.Range.empty(),
18+
{EdgeDB.Range.new(1, 1), EdgeDB.Range.empty()},
19+
EdgeDB.Range.new(nil, nil)
20+
],
21+
"range<float32>" => [
22+
EdgeDB.Range.new(1.5, 2.5),
23+
{EdgeDB.Range.new(1.5, 2.5, inc_upper: true), EdgeDB.Range.new(1.5, 2.5, inc_upper: true)},
24+
EdgeDB.Range.empty(),
25+
{EdgeDB.Range.new(1.5, 1.5), EdgeDB.Range.empty()},
26+
EdgeDB.Range.new(nil, nil)
27+
],
28+
"range<float64>" => [
29+
EdgeDB.Range.new(1.5, 2.5),
30+
{EdgeDB.Range.new(1.5, 2.5, inc_upper: true), EdgeDB.Range.new(1.5, 2.5, inc_upper: true)},
31+
EdgeDB.Range.empty(),
32+
{EdgeDB.Range.new(1.5, 1.5), EdgeDB.Range.empty()},
33+
EdgeDB.Range.new(nil, nil)
34+
],
35+
"range<decimal>" => [
36+
EdgeDB.Range.new(Decimal.new(1), Decimal.new(2)),
37+
{EdgeDB.Range.new(Decimal.new(1), Decimal.new(2), inc_upper: true),
38+
EdgeDB.Range.new(Decimal.new(1), Decimal.new(2), inc_upper: true)},
39+
EdgeDB.Range.empty(),
40+
{EdgeDB.Range.new(Decimal.new(1), Decimal.new(1)), EdgeDB.Range.empty()},
41+
EdgeDB.Range.new(nil, nil)
42+
],
43+
"range<datetime>" => [
44+
EdgeDB.Range.new(~U[2022-07-01 00:00:00Z], ~U[2022-12-01 00:00:00Z]),
45+
{EdgeDB.Range.new(~U[2022-07-01 00:00:00Z], ~U[2022-12-01 00:00:00Z], inc_upper: true),
46+
EdgeDB.Range.new(~U[2022-07-01 00:00:00Z], ~U[2022-12-01 00:00:00Z], inc_upper: true)},
47+
EdgeDB.Range.empty(),
48+
{EdgeDB.Range.new(~U[2022-07-01 00:00:00Z], ~U[2022-07-01 00:00:00Z]),
49+
EdgeDB.Range.empty()},
50+
EdgeDB.Range.new(nil, nil)
51+
],
52+
"range<cal::local_datetime>" => [
53+
EdgeDB.Range.new(~N[2022-07-01 00:00:00Z], ~N[2022-12-01 00:00:00Z]),
54+
{EdgeDB.Range.new(~N[2022-07-01 00:00:00Z], ~N[2022-12-01 00:00:00Z], inc_upper: true),
55+
EdgeDB.Range.new(~N[2022-07-01 00:00:00Z], ~N[2022-12-01 00:00:00Z], inc_upper: true)},
56+
EdgeDB.Range.empty(),
57+
{EdgeDB.Range.new(~N[2022-07-01 00:00:00Z], ~N[2022-07-01 00:00:00Z]),
58+
EdgeDB.Range.empty()},
59+
EdgeDB.Range.new(nil, nil)
60+
],
61+
"range<cal::local_date>" => [
62+
EdgeDB.Range.new(~D[2022-07-01], ~D[2022-12-01]),
63+
{EdgeDB.Range.new(~D[2022-07-01], ~D[2022-12-01], inc_upper: true),
64+
EdgeDB.Range.new(~D[2022-07-01], ~D[2022-12-02])},
1165
EdgeDB.Range.empty(),
12-
{EdgeDB.Range.new(1, 1, inc_lower: true, inc_upper: false), EdgeDB.Range.empty()},
66+
{EdgeDB.Range.new(~D[2022-07-01], ~D[2022-07-01]), EdgeDB.Range.empty()},
1367
EdgeDB.Range.new(nil, nil)
1468
]
1569
}
@@ -73,10 +127,12 @@ defmodule Tests.EdgeDB.Protocol.Codecs.RangeTest do
73127
{value, value}
74128
end
75129

76-
test "encoding #{inspect(input)} as #{inspect(type)} with expecting #{inspect(output)} in the end",
130+
test "encoding #{inspect(input)} as #{inspect(type)} with expecting #{inspect(output)} as the result",
77131
%{client: client} do
78-
value = "value"
79-
assert ^value = EdgeDB.query_single!(client, "select <short_str>$0", [value])
132+
type = unquote(type)
133+
input = unquote(Macro.escape(input))
134+
output = unquote(Macro.escape(output))
135+
assert ^output = EdgeDB.query_single!(client, "select <#{type}>$0", [input])
80136
end
81137
end
82138
end

0 commit comments

Comments
 (0)