Packages

PostgreSQL driver for Elixir compatible with CockroachDB

Current section

Files

Jump to
postgrex_cdb lib postgrex extensions date.ex
Raw

lib/postgrex/extensions/date.ex

defmodule Postgrex.Extensions.Date do
@moduledoc false
import Postgrex.BinaryUtils, warn: false
use Postgrex.BinaryExtension, send: "date_send"
@gd_epoch :calendar.date_to_gregorian_days({2000, 1, 1})
@max_year 5874897
def init(opts), do: Keyword.fetch!(opts, :date)
def encode(:postgrex) do
quote location: :keep do
%Postgrex.Date{} = date ->
unquote(__MODULE__).encode_postgrex(date)
other ->
raise ArgumentError, Postgrex.Utils.encode_msg(other, Postgrex.Date)
end
end
def encode(:elixir) do
quote location: :keep do
%Date{} = date ->
unquote(__MODULE__).encode_elixir(date)
other ->
raise ArgumentError, Postgrex.Utils.encode_msg(other, Date)
end
end
def decode(:postgrex) do
quote location: :keep do
<<4 :: int32, days :: int32>> ->
unquote(__MODULE__).day_to_postgrex(days)
end
end
def decode(:elixir) do
quote location: :keep do
<<4 :: int32, days :: int32>> ->
unquote(__MODULE__).day_to_elixir(days)
end
end
## Helpers
def encode_postgrex(%Postgrex.Date{year: year, month: month, day: day})
when year <= @max_year do
date = {year, month, day}
<<4 :: int32, :calendar.date_to_gregorian_days(date) - @gd_epoch :: int32>>
end
def encode_postgrex(%Postgrex.Date{} = date) do
raise ArgumentError,
"#{inspect date} is beyond the maximum year #{@max_year}"
end
def day_to_postgrex(days) do
{year, month, day} = erl_date(days)
%Postgrex.Date{year: year, month: month, day: day}
end
defp erl_date(days) do
:calendar.gregorian_days_to_date(days + @gd_epoch)
end
def encode_elixir(%Date{year: year, month: month, day: day})
when year <= @max_year do
date = {year, month, day}
<<4 :: int32, :calendar.date_to_gregorian_days(date) - @gd_epoch :: int32>>
end
def encode_elixir(%Date{} = date) do
raise ArgumentError,
"#{inspect date} is beyond the maximum year #{@max_year}"
end
def day_to_elixir(days) do
days
|> erl_date()
|> Date.from_erl!()
end
end