Packages
ecto
2.2.3
3.14.1
3.14.0
3.13.6
3.13.5
3.13.4
3.13.3
3.13.2
3.13.1
3.13.0
3.12.6
3.12.5
3.12.4
3.12.3
3.12.2
3.12.1
3.12.0
3.11.2
3.11.1
3.11.0
3.10.3
3.10.2
3.10.1
3.10.0
3.9.6
3.9.5
3.9.4
3.9.3
3.9.2
3.9.1
3.9.0
3.8.4
3.8.3
3.8.2
3.8.1
3.8.0
3.7.2
3.7.1
3.7.0
3.6.2
3.6.1
3.6.0
3.5.8
3.5.7
3.5.6
3.5.5
3.5.4
3.5.3
3.5.2
3.5.1
3.5.0
3.5.0-rc.1
3.5.0-rc.0
3.4.6
3.4.5
3.4.4
3.4.3
3.4.2
3.4.1
3.4.0
3.3.4
3.3.3
3.3.2
3.3.1
3.3.0
3.2.5
3.2.4
3.2.3
3.2.2
3.2.1
3.2.0
3.1.7
3.1.6
3.1.5
3.1.4
3.1.3
3.1.2
3.1.1
3.1.0
3.0.9
3.0.8
3.0.7
3.0.6
3.0.5
3.0.4
3.0.3
3.0.2
3.0.1
3.0.0
3.0.0-rc.1
3.0.0-rc.0
2.2.12
2.2.11
2.2.10
2.2.9
2.2.8
2.2.7
2.2.6
2.2.5
2.2.4
2.2.3
2.2.2
2.2.1
2.2.0
2.2.0-rc.1
2.2.0-rc.0
2.1.6
2.1.5
2.1.4
2.1.3
2.1.2
2.1.1
2.1.0
2.1.0-rc.5
2.1.0-rc.4
2.1.0-rc.3
2.1.0-rc.2
2.1.0-rc.1
2.1.0-rc.0
2.0.6
2.0.5
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
2.0.0-rc.6
2.0.0-rc.5
2.0.0-rc.4
2.0.0-rc.3
2.0.0-rc.2
2.0.0-rc.1
2.0.0-rc.0
2.0.0-beta.2
2.0.0-beta.1
2.0.0-beta.0
1.1.9
1.1.8
1.1.7
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.16.0
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.1
0.13.0
0.12.1
0.12.0
0.12.0-rc
0.11.3
0.11.2
0.11.1
0.11.0
0.10.3
0.10.2
0.10.1
0.10.0
0.9.0
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.0
0.5.1
0.5.0
0.4.0
0.3.0
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.0
A toolkit for data mapping and language integrated query for Elixir
Current section
Files
Jump to
Current section
Files
lib/ecto/adapters/postgres/datetime.ex
if Code.ensure_loaded?(Postgrex) do
defmodule Ecto.Adapters.Postgres.Time do
@moduledoc false
import Postgrex.BinaryUtils, warn: false
use Postgrex.BinaryExtension, [send: "time_send"]
def init(opts), do: opts
def encode(_) do
quote location: :keep do
{hour, min, sec, usec} when hour in 0..23 and min in 0..59 and sec in 0..59 and usec in 0..999_999 ->
time = {hour, min, sec}
<<8 :: int32, :calendar.time_to_seconds(time) * 1_000_000 + usec :: int64>>
end
end
def decode(_) do
quote location: :keep do
<<8 :: int32, microsecs :: int64>> ->
secs = div(microsecs, 1_000_000)
usec = rem(microsecs, 1_000_000)
{hour, min, sec} = :calendar.seconds_to_time(secs)
{hour, min, sec, usec}
end
end
end
defmodule Ecto.Adapters.Postgres.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: opts
def encode(_) do
quote location: :keep do
{year, month, day} when year <= unquote(@max_year) ->
date = {year, month, day}
<<4 :: int32, :calendar.date_to_gregorian_days(date) - unquote(@gd_epoch) :: int32>>
end
end
def decode(_) do
quote location: :keep do
<<4 :: int32, days :: int32>> ->
:calendar.gregorian_days_to_date(days + unquote(@gd_epoch))
end
end
end
defmodule Ecto.Adapters.Postgres.Timestamp do
@moduledoc false
import Postgrex.BinaryUtils, warn: false
use Postgrex.BinaryExtension, [send: "timestamp_send"]
@gs_epoch :calendar.datetime_to_gregorian_seconds({{2000, 1, 1}, {0, 0, 0}})
@max_year 294276
def init(opts), do: opts
def encode(_) do
quote location: :keep do
timestamp ->
Ecto.Adapters.Postgres.Timestamp.encode!(timestamp)
end
end
def decode(_) do
quote location: :keep do
<<8 :: int32, microsecs :: int64>> ->
Ecto.Adapters.Postgres.Timestamp.decode!(microsecs)
end
end
## Helpers
def encode!({{year, month, day}, {hour, min, sec, usec}})
when year <= @max_year and hour in 0..23 and min in 0..59 and sec in 0..59 and usec in 0..999_999 do
datetime = {{year, month, day}, {hour, min, sec}}
secs = :calendar.datetime_to_gregorian_seconds(datetime) - @gs_epoch
<<8 :: int32, secs * 1_000_000 + usec :: int64>>
end
def encode!(arg) do
raise ArgumentError, """
could not encode date/time: #{inspect arg}
This error happens when you are by-passing Ecto's Query API by
using either Ecto.Adapters.SQL.query/4 or Ecto fragments. This
makes Ecto unable to properly cast the type. You can fix this by
explicitly telling Ecto which type to use via `type/2` or by
implementing the Ecto.DataType protocol for the given value.
"""
end
def decode!(microsecs) when microsecs < 0 and rem(microsecs, 1_000_000) != 0 do
secs = div(microsecs, 1_000_000) - 1
microsecs = 1_000_000 + rem(microsecs, 1_000_000)
split(secs, microsecs)
end
def decode!(microsecs) do
secs = div(microsecs, 1_000_000)
microsecs = rem(microsecs, 1_000_000)
split(secs, microsecs)
end
defp split(secs, microsecs) do
{date, {hour, min, sec}} = :calendar.gregorian_seconds_to_datetime(secs + @gs_epoch)
{date, {hour, min, sec, microsecs}}
end
end
defmodule Ecto.Adapters.Postgres.TimestampTZ do
@moduledoc false
import Postgrex.BinaryUtils, warn: false
use Postgrex.BinaryExtension, [send: "timestamptz_send"]
def init(opts), do: opts
def encode(_) do
quote location: :keep do
timestamp ->
Ecto.Adapters.Postgres.Timestamp.encode!(timestamp)
end
end
def decode(_) do
quote location: :keep do
<<8 :: int32, microsecs :: int64>> ->
Ecto.Adapters.Postgres.Timestamp.decode!(microsecs)
end
end
end
end