Packages
postgrex
0.12.2
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
Current section
Files
Jump to
Current section
Files
lib/postgrex/extensions/record.ex
defmodule Postgrex.Extensions.Record do
@moduledoc false
alias Postgrex.TypeInfo
alias Postgrex.Types
import Postgrex.BinaryUtils
use Postgrex.BinaryExtension, [] # send: "record_send" hard cored in types
def encode(%TypeInfo{comp_elems: elem_oids}, tuple, types, _) when is_tuple(tuple),
do: encode_record(tuple, elem_oids, types)
def encode(type_info, value, _, _) do
raise ArgumentError, Postgrex.Utils.encode_msg(type_info, value, "a tuple")
end
def decode(_, bin, types, _),
do: decode_record(bin, types)
## Helpers
defp encode_record(tuple, elem_oids, types) do
list = Tuple.to_list(tuple)
zipped = :lists.zip(list, elem_oids)
{data, count} =
Enum.map_reduce(zipped, 0, fn
{nil, oid}, count ->
{<<oid::uint32, -1::int32>>, count + 1}
{value, oid}, count ->
data = Types.encode(oid, value, types)
data = [<<oid::uint32>>, <<IO.iodata_length(data)::int32>>, data]
{data, count + 1}
end)
[<<count :: int32>>, data]
end
defp decode_record(<<num :: int32, rest :: binary>>, types) do
decoder = &Types.decode(&1, &2, types)
record_elements(rest, num, decoder) |> List.to_tuple
end
defp record_elements(<<>>, 0, _decoder) do
[]
end
defp record_elements(<<_oid :: uint32, -1 :: int32, rest :: binary>>, num, decoder) do
[nil | record_elements(rest, num-1, decoder)]
end
defp record_elements(<<oid :: uint32, size :: int32, elem :: binary(size), rest :: binary>>,
num, decoder) do
value = decoder.(oid, elem)
[value | record_elements(rest, num-1, decoder)]
end
end