Packages
postgrex
0.19.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/interval.ex
defmodule Postgrex.Extensions.Interval do
@moduledoc false
import Postgrex.BinaryUtils, warn: false
use Postgrex.BinaryExtension, send: "interval_send"
def init(opts) do
case Keyword.get(opts, :interval_decode_type, Postgrex.Interval) do
type when type in [Postgrex.Interval, Duration] ->
type
other ->
raise ArgumentError,
"#{inspect(other)} is not valid for `:interval_decode_type`. Please use either `Postgrex.Interval` or `Duration`"
end
end
if Code.ensure_loaded?(Duration) do
import Bitwise, warn: false
@default_precision 6
@precision_mask 0xFFFF
# 0xFFFF: user did not specify precision (2's complement version of -1)
# nil: coming from a super type that does not pass modifier for sub-type
@unspecified_precision [0xFFFF, nil]
def encode(_) do
quote location: :keep do
%Postgrex.Interval{months: months, days: days, secs: seconds, microsecs: microseconds} ->
microseconds = 1_000_000 * seconds + microseconds
<<16::int32(), microseconds::int64(), days::int32(), months::int32()>>
%Duration{
year: years,
month: months,
week: weeks,
day: days,
hour: hours,
minute: minutes,
second: seconds,
microsecond: {microseconds, _precision}
} ->
months = 12 * years + months
days = 7 * weeks + days
microseconds = 1_000_000 * (3600 * hours + 60 * minutes + seconds) + microseconds
<<16::int32(), microseconds::int64(), days::int32(), months::int32()>>
other ->
raise DBConnection.EncodeError,
Postgrex.Utils.encode_msg(other, {Postgrex.Interval, Duration})
end
end
def decode(type) do
quote location: :keep, generated: true do
<<16::int32(), microseconds::int64(), days::int32(), months::int32()>> ->
unquote(__MODULE__).decode_interval(
microseconds,
days,
months,
var!(mod),
unquote(type)
)
end
end
## Helpers
def decode_interval(microseconds, days, months, _type_mod, Postgrex.Interval) do
seconds = div(microseconds, 1_000_000)
microseconds = rem(microseconds, 1_000_000)
%Postgrex.Interval{
months: months,
days: days,
secs: seconds,
microsecs: microseconds
}
end
def decode_interval(microseconds, days, months, type_mod, Duration) do
years = div(months, 12)
months = rem(months, 12)
weeks = div(days, 7)
days = rem(days, 7)
seconds = div(microseconds, 1_000_000)
microseconds = rem(microseconds, 1_000_000)
minutes = div(seconds, 60)
seconds = rem(seconds, 60)
hours = div(minutes, 60)
minutes = rem(minutes, 60)
precision = if type_mod, do: type_mod &&& unquote(@precision_mask)
precision =
if precision in unquote(@unspecified_precision),
do: unquote(@default_precision),
else: precision
Duration.new!(
year: years,
month: months,
week: weeks,
day: days,
hour: hours,
minute: minutes,
second: seconds,
microsecond: {microseconds, precision}
)
end
else
def encode(_) do
quote location: :keep do
%Postgrex.Interval{months: months, days: days, secs: seconds, microsecs: microseconds} ->
microseconds = 1_000_000 * seconds + microseconds
<<16::int32(), microseconds::int64(), days::int32(), months::int32()>>
other ->
raise DBConnection.EncodeError, Postgrex.Utils.encode_msg(other, Postgrex.Interval)
end
end
def decode(_) do
quote location: :keep do
<<16::int32(), microseconds::int64(), days::int32(), months::int32()>> ->
unquote(__MODULE__).decode_interval(microseconds, days, months, Postgrex.Interval)
end
end
## Helpers
def decode_interval(microseconds, days, months, Postgrex.Interval) do
seconds = div(microseconds, 1_000_000)
microseconds = rem(microseconds, 1_000_000)
%Postgrex.Interval{
months: months,
days: days,
secs: seconds,
microsecs: microseconds
}
end
end
end