Packages
postgrex
0.22.1
1.0.0-rc.1
retired
1.0.0-rc.0
retired
0.22.3
0.22.2
0.22.1
0.22.0
0.21.1
0.21.0
0.20.0
0.19.3
0.19.2
0.19.1
0.19.0
0.18.0
0.17.5
0.17.4
0.17.3
0.17.2
0.17.1
0.17.0
0.16.5
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.13
0.15.12
0.15.11
0.15.10
0.15.9
0.15.8
0.15.7
0.15.6
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.14.0-rc.1
0.14.0-rc.0
0.13.5
0.13.4
0.13.3
0.13.2
0.13.1
0.13.0
0.13.0-rc.0
0.12.2
0.12.1
0.12.0
0.11.2
0.11.1
0.11.0
0.10.0
0.9.1
0.9.0
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.0
0.6.0
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.2
PostgreSQL driver for Elixir
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/postgrex/extensions/range.ex
defmodule Postgrex.Extensions.Range do
@moduledoc false
import Postgrex.BinaryUtils, warn: false
import Bitwise
@behaviour Postgrex.SuperExtension
@range_empty 0x01
@range_lb_inc 0x02
@range_ub_inc 0x04
@range_lb_inf 0x08
@range_ub_inf 0x10
def init(_), do: nil
def matching(_), do: [send: "range_send"]
def format(_), do: :super_binary
def oids(%Postgrex.TypeInfo{base_type: base_oid}, _) do
[base_oid]
end
def encode(_) do
quote location: :keep do
%Postgrex.Range{lower: lower, upper: upper} = range, [_oid], [type] ->
# encode_value/2 defined by TypeModule
lower = if is_atom(lower), do: lower, else: encode_value(lower, type)
upper = if is_atom(upper), do: upper, else: encode_value(upper, type)
unquote(__MODULE__).encode(range, lower, upper)
other, _, _ ->
raise DBConnection.EncodeError, Postgrex.Utils.encode_msg(other, Postgrex.Range)
end
end
def decode(_) do
quote location: :keep do
<<len::int32(), binary::binary-size(len)>>, [_oid], [type] ->
<<flags, data::binary>> = binary
# decode_list/2 defined by TypeModule
sub_type_with_mod =
case type do
{extension, sub_oids, sub_types} -> {extension, sub_oids, sub_types, nil}
extension -> {extension, nil}
end
case decode_list(data, sub_type_with_mod) do
[upper, lower] ->
unquote(__MODULE__).decode(flags, [lower, upper])
empty_or_one ->
unquote(__MODULE__).decode(flags, empty_or_one)
end
end
end
## Helpers
def encode(_range, :empty, :empty) do
[<<1::int32(), @range_empty>>]
end
def encode(%{lower_inclusive: lower_inc, upper_inclusive: upper_inc}, lower, upper) do
flags = 0
{flags, data} =
if is_atom(lower) do
{flags ||| @range_lb_inf, []}
else
{flags, lower}
end
{flags, data} =
if is_atom(upper) do
{flags ||| @range_ub_inf, data}
else
{flags, [data | upper]}
end
flags =
case lower_inc do
true -> flags ||| @range_lb_inc
false -> flags
end
flags =
case upper_inc do
true -> flags ||| @range_ub_inc
false -> flags
end
[<<IO.iodata_length(data) + 1::int32()>>, flags | data]
end
def decode(flags, []) when (flags &&& @range_empty) != 0 do
%Postgrex.Range{
lower: :empty,
upper: :empty,
lower_inclusive: false,
upper_inclusive: false
}
end
def decode(flags, elems) do
{lower, elems} =
if (flags &&& @range_lb_inf) != 0 do
{:unbound, elems}
else
[lower | rest] = elems
{lower, rest}
end
{upper, []} =
if (flags &&& @range_ub_inf) != 0 do
{:unbound, elems}
else
[upper | rest] = elems
{upper, rest}
end
lower_inclusive? = (flags &&& @range_lb_inc) != 0
upper_inclusive? = (flags &&& @range_ub_inc) != 0
%Postgrex.Range{
lower: lower,
upper: upper,
lower_inclusive: lower_inclusive?,
upper_inclusive: upper_inclusive?
}
end
end