-module(pg_value). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/pg_value.gleam"). -export([offset/1, minutes/2, bool/1, int/1, float/1, text/1, bytea/1, time/1, date/1, timestamp/1, timestamptz/2, interval/1, array/2, nullable/2, decode/2, encode/2, to_string/1]). -export_type([offset/0, value/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC( " PostgreSQL values, along with their encoders and decoders. Can\n" " be used by PostgreSQL client libraries written in gleam.\n" " Currently used by [pgl][1].\n" "\n" " [1]: https://github.com/stndrs/pgl\n" ). -type offset() :: {offset, integer(), integer()}. -type value() :: null | {bool, boolean()} | {int, integer()} | {float, float()} | {text, binary()} | {bytea, bitstring()} | {time, gleam@time@calendar:time_of_day()} | {date, gleam@time@calendar:date()} | {timestamp, gleam@time@timestamp:timestamp()} | {timestamptz, gleam@time@timestamp:timestamp(), offset()} | {interval, pg_value@interval:interval()} | {array, list(value())}. -file("src/pg_value.gleam", 40). ?DOC(" Returns an Offset with the provided hours and 0 minutes.\n"). -spec offset(integer()) -> offset(). offset(Hours) -> {offset, Hours, 0}. -file("src/pg_value.gleam", 45). ?DOC(" Applies some number of minutes to the Offset\n"). -spec minutes(offset(), integer()) -> offset(). minutes(Offset, Minutes) -> {offset, erlang:element(2, Offset), Minutes}. -file("src/pg_value.gleam", 75). -spec bool(boolean()) -> value(). bool(Bool) -> {bool, Bool}. -file("src/pg_value.gleam", 79). -spec int(integer()) -> value(). int(Int) -> {int, Int}. -file("src/pg_value.gleam", 83). -spec float(float()) -> value(). float(Float) -> {float, Float}. -file("src/pg_value.gleam", 87). -spec text(binary()) -> value(). text(Text) -> {text, Text}. -file("src/pg_value.gleam", 91). -spec bytea(bitstring()) -> value(). bytea(Bytea) -> {bytea, Bytea}. -file("src/pg_value.gleam", 95). -spec time(gleam@time@calendar:time_of_day()) -> value(). time(Time_of_day) -> {time, Time_of_day}. -file("src/pg_value.gleam", 99). -spec date(gleam@time@calendar:date()) -> value(). date(Date) -> {date, Date}. -file("src/pg_value.gleam", 103). -spec timestamp(gleam@time@timestamp:timestamp()) -> value(). timestamp(Timestamp) -> {timestamp, Timestamp}. -file("src/pg_value.gleam", 107). -spec timestamptz(gleam@time@timestamp:timestamp(), offset()) -> value(). timestamptz(Timestamp, Offset) -> {timestamptz, Timestamp, Offset}. -file("src/pg_value.gleam", 111). -spec interval(pg_value@interval:interval()) -> value(). interval(Interval) -> {interval, Interval}. -file("src/pg_value.gleam", 115). -spec array(list(EEB), fun((EEB) -> value())) -> value(). array(Elements, Kind) -> _pipe = Elements, _pipe@1 = gleam@list:map(_pipe, Kind), {array, _pipe@1}. -file("src/pg_value.gleam", 132). ?DOC( " Checks if the provided value is `option.Some` or `option.None`. If\n" " `None` then the value returned is `value.Null`. If `Some` value is\n" " provided then it is passed to the `inner_type` function.\n" "\n" " Example:\n" "\n" " ```gleam\n" " let int = pg_value.nullable(pg_value.int, Some(10))\n" "\n" " let null = pg_value.nullable(pg_value.int, None)\n" " ```\n" ). -spec nullable(fun((EED) -> value()), gleam@option:option(EED)) -> value(). nullable(Inner_type, Optional) -> case Optional of {some, Term} -> Inner_type(Term); none -> null end. -file("src/pg_value.gleam", 179). -spec bool_to_string(boolean()) -> binary(). bool_to_string(Bool) -> case Bool of true -> <<"TRUE"/utf8>>; false -> <<"FALSE"/utf8>> end. -file("src/pg_value.gleam", 235). -spec offset_to_duration(offset()) -> gleam@time@duration:duration(). offset_to_duration(Offset) -> Sign = case erlang:element(2, Offset) < 0 of true -> 1; false -> -1 end, _pipe = gleam@int:absolute_value(erlang:element(2, Offset)), _pipe@1 = gleam@int:multiply(_pipe, 60), _pipe@2 = gleam@int:add(_pipe@1, erlang:element(3, Offset)), _pipe@3 = gleam@int:multiply(_pipe@2, Sign), gleam@time@duration:minutes(_pipe@3). -file("src/pg_value.gleam", 248). -spec single_quote(binary()) -> binary(). single_quote(Value) -> <<<<"'"/utf8, Value/binary>>/binary, "'"/utf8>>. -file("src/pg_value.gleam", 157). -spec text_to_string(binary()) -> binary(). text_to_string(Text) -> Val = gleam@string:replace(Text, <<"'"/utf8>>, <<"\\'"/utf8>>), single_quote(Val). -file("src/pg_value.gleam", 187). -spec bytea_to_string(bitstring()) -> binary(). bytea_to_string(Bytea) -> Val = <<"\\x"/utf8, (gleam_stdlib:base16_encode(Bytea))/binary>>, single_quote(Val). -file("src/pg_value.gleam", 221). -spec timestamp_to_string(gleam@time@timestamp:timestamp()) -> binary(). timestamp_to_string(Timestamp) -> _pipe = gleam@time@timestamp:to_rfc3339(Timestamp, {duration, 0, 0}), single_quote(_pipe). -file("src/pg_value.gleam", 226). -spec timestamptz_to_string(gleam@time@timestamp:timestamp(), offset()) -> binary(). timestamptz_to_string(Timestamp, Offset) -> _pipe = offset_to_duration(Offset), _pipe@1 = gleam@time@timestamp:add(Timestamp, _pipe), timestamp_to_string(_pipe@1). -file("src/pg_value.gleam", 252). -spec pad_zero(integer()) -> binary(). pad_zero(N) -> case N < 10 of true -> <<"0"/utf8, (erlang:integer_to_binary(N))/binary>>; false -> erlang:integer_to_binary(N) end. -file("src/pg_value.gleam", 193). -spec date_to_string(gleam@time@calendar:date()) -> binary(). date_to_string(Date) -> Year = erlang:integer_to_binary(erlang:element(2, Date)), Month = begin _pipe = gleam@time@calendar:month_to_int(erlang:element(3, Date)), pad_zero(_pipe) end, Day = pad_zero(erlang:element(4, Date)), Date@1 = <<<<<<<>/binary, Month/binary>>/binary, "-"/utf8>>/binary, Day/binary>>, single_quote(Date@1). -file("src/pg_value.gleam", 203). -spec time_to_string(gleam@time@calendar:time_of_day()) -> binary(). time_to_string(Time_of_day) -> Hours = pad_zero(erlang:element(2, Time_of_day)), Minutes = pad_zero(erlang:element(3, Time_of_day)), Seconds = pad_zero(erlang:element(4, Time_of_day)), Milliseconds = erlang:element(5, Time_of_day) div 1000000, Msecs = case Milliseconds < 100 of true when Milliseconds =:= 0 -> <<""/utf8>>; true when Milliseconds < 10 -> <<".00"/utf8, (erlang:integer_to_binary(Milliseconds))/binary>>; true -> <<".0"/utf8, (erlang:integer_to_binary(Milliseconds))/binary>>; false -> <<"."/utf8, (erlang:integer_to_binary(Milliseconds))/binary>> end, Time = <<<<<<<<<>/binary, Minutes/binary>>/binary, ":"/utf8>>/binary, Seconds/binary>>/binary, Msecs/binary>>, single_quote(Time). -file("src/pg_value.gleam", 282). -spec validate_typesend( binary(), pg_value@type_info:type_info(), fun(() -> {ok, EEI} | {error, binary()}) ) -> {ok, EEI} | {error, binary()}. validate_typesend(Expected, Info, Next) -> gleam@bool:lazy_guard( Expected =:= erlang:element(4, Info), Next, fun() -> {error, <<<<<<"Attempted to encode "/utf8, Expected/binary>>/binary, " as "/utf8>>/binary, (erlang:element(4, Info))/binary>>} end ). -file("src/pg_value.gleam", 314). -spec arr_dims(list(value())) -> list(integer()). arr_dims(Elems) -> case Elems of [] -> []; [{array, Inner} | _] -> Inner_dims = arr_dims(Inner), Dim = erlang:length(Elems), [Dim | Inner_dims]; Elems@1 -> Dim@1 = erlang:length(Elems@1), [Dim@1] end. -file("src/pg_value.gleam", 349). -spec array_header(list(integer()), boolean(), integer()) -> bitstring(). array_header(Dimensions, Has_nulls, Elem_type_oid) -> Num_dims = erlang:length(Dimensions), Flags = case Has_nulls of true -> 1; false -> 0 end, Encoded_dimensions = begin _pipe = Dimensions, _pipe@1 = gleam@list:map( _pipe, fun(Dim) -> <> end ), gleam_stdlib:bit_array_concat(_pipe@1) end, _pipe@2 = [<>, Encoded_dimensions], gleam_stdlib:bit_array_concat(_pipe@2). -file("src/pg_value.gleam", 329). -spec do_encode_array( list(integer()), boolean(), pg_value@type_info:type_info(), list(bitstring()) ) -> {ok, bitstring()} | {error, binary()}. do_encode_array(Dimensions, Has_nulls, Info, Encoded) -> Header = array_header(Dimensions, Has_nulls, erlang:element(2, Info)), Encoder = fun(Bits) -> Len = erlang:byte_size(Bits), {ok, <>} end, case Encoded of [] -> Encoder(Header); _ -> _pipe = gleam_stdlib:bit_array_concat([Header | Encoded]), Encoder(_pipe) end. -file("src/pg_value.gleam", 373). -spec encode_null() -> {ok, bitstring()} | {error, binary()}. encode_null() -> {ok, <<-1:32/big-integer>>}. -file("src/pg_value.gleam", 377). -spec encode_bool(boolean(), pg_value@type_info:type_info()) -> {ok, bitstring()} | {error, binary()}. encode_bool(Bool, Info) -> validate_typesend(<<"boolsend"/utf8>>, Info, fun() -> case Bool of true -> {ok, <<1:32/big-integer, 1:8/big-integer>>}; false -> {ok, <<1:32/big-integer, 0:8/big-integer>>} end end). -file("src/pg_value.gleam", 448). -spec encode_float4(float(), pg_value@type_info:type_info()) -> {ok, bitstring()} | {error, binary()}. encode_float4(Num, Info) -> validate_typesend( <<"float4send"/utf8>>, Info, fun() -> {ok, <<4:32/big-integer, Num:32/big-float>>} end ). -file("src/pg_value.gleam", 457). -spec encode_float8(float(), pg_value@type_info:type_info()) -> {ok, bitstring()} | {error, binary()}. encode_float8(Num, Info) -> validate_typesend( <<"float8send"/utf8>>, Info, fun() -> {ok, <<8:32/big-integer, Num:64/big-float>>} end ). -file("src/pg_value.gleam", 437). -spec encode_float(float(), pg_value@type_info:type_info()) -> {ok, bitstring()} | {error, binary()}. encode_float(Num, Info) -> case erlang:element(4, Info) of <<"float4send"/utf8>> -> encode_float4(Num, Info); <<"float8send"/utf8>> -> encode_float8(Num, Info); _ -> {error, <<"Unsupported float type"/utf8>>} end. -file("src/pg_value.gleam", 466). -spec encode_text(binary(), pg_value@type_info:type_info()) -> {ok, bitstring()} | {error, binary()}. encode_text(Text, Info) -> Encoder = fun(Text@1) -> Bits = gleam_stdlib:identity(Text@1), Len = erlang:byte_size(Bits), {ok, <>} end, case erlang:element(4, Info) of <<"varcharsend"/utf8>> -> Encoder(Text); <<"textsend"/utf8>> -> Encoder(Text); <<"charsend"/utf8>> -> Encoder(Text); <<"namesend"/utf8>> -> Encoder(Text); _ -> {error, <<<<<<"Attempted to encode '"/utf8, Text/binary>>/binary, "' as "/utf8>>/binary, (erlang:element(4, Info))/binary>>} end. -file("src/pg_value.gleam", 486). -spec encode_bytea(bitstring(), pg_value@type_info:type_info()) -> {ok, bitstring()} | {error, binary()}. encode_bytea(Bits, Info) -> validate_typesend( <<"byteasend"/utf8>>, Info, fun() -> Len = erlang:byte_size(Bits), {ok, <>} end ). -file("src/pg_value.gleam", 641). -spec do_decode_array(integer(), bitstring(), list({integer(), integer()})) -> {ok, {bitstring(), list({integer(), integer()})}} | {error, binary()}. do_decode_array(Count, Bits, Acc) -> case Count of 0 -> {ok, {Bits, Acc}}; Idx -> case Bits of <> -> Current = {Nbr, L_bound}, Data_info1 = gleam@list:prepend(Acc, Current), do_decode_array((Idx - 1), Rest1, Data_info1); _ -> {error, <<"invalid array"/utf8>>} end end. -file("src/pg_value.gleam", 667). -spec decode_array_elems( bitstring(), fun((bitstring()) -> {ok, gleam@dynamic:dynamic_()} | {error, binary()}), list(gleam@dynamic:dynamic_()) ) -> {ok, list(gleam@dynamic:dynamic_())} | {error, binary()}. decode_array_elems(Bits, Decoder, Acc) -> case Bits of <<>> -> {ok, lists:reverse(Acc)}; <<-1:32/big-signed-integer, Rest/bitstring>> -> _pipe = gleam@list:prepend(Acc, gleam@dynamic:nil()), decode_array_elems(Rest, Decoder, _pipe); <> -> Elem_len = Size * 8, case Rest@1 of <> -> gleam@result:'try'( Decoder(Val_bin), fun(Decoded) -> _pipe@1 = gleam@list:prepend(Acc, Decoded), decode_array_elems(Rest1, Decoder, _pipe@1) end ); _ -> {error, <<"invalid array"/utf8>>} end; _ -> {error, <<"invalid array"/utf8>>} end. -file("src/pg_value.gleam", 621). -spec decode_array( bitstring(), fun((bitstring()) -> {ok, gleam@dynamic:dynamic_()} | {error, binary()}) ) -> {ok, gleam@dynamic:dynamic_()} | {error, binary()}. decode_array(Bits, Decoder) -> case Bits of <> -> gleam@result:'try'( do_decode_array(Dimensions, Rest, []), fun(Data) -> _pipe = decode_array_elems( erlang:element(1, Data), Decoder, [] ), gleam@result:map(_pipe, fun erlang:list_to_tuple/1) end ); _ -> {error, <<"invalid array"/utf8>>} end. -file("src/pg_value.gleam", 695). -spec decode_bool(bitstring()) -> {ok, gleam@dynamic:dynamic_()} | {error, binary()}. decode_bool(Bits) -> case Bits of <<1:8/big-signed-integer>> -> {ok, gleam_stdlib:identity(true)}; <<0:8/big-signed-integer>> -> {ok, gleam_stdlib:identity(false)}; _ -> {error, <<"invalid bool"/utf8>>} end. -file("src/pg_value.gleam", 703). -spec decode_int2(bitstring()) -> {ok, gleam@dynamic:dynamic_()} | {error, binary()}. decode_int2(Bits) -> case Bits of <> -> {ok, gleam_stdlib:identity(Num)}; _ -> {error, <<"invalid int2"/utf8>>} end. -file("src/pg_value.gleam", 710). -spec decode_oid(bitstring()) -> {ok, gleam@dynamic:dynamic_()} | {error, binary()}. decode_oid(Bits) -> case Bits of <> -> {ok, gleam_stdlib:identity(Num)}; _ -> {error, <<"invalid oid"/utf8>>} end. -file("src/pg_value.gleam", 718). -spec decode_int4(bitstring()) -> {ok, gleam@dynamic:dynamic_()} | {error, binary()}. decode_int4(Bits) -> case Bits of <> -> {ok, gleam_stdlib:identity(Num)}; _ -> {error, <<"invalid int4"/utf8>>} end. -file("src/pg_value.gleam", 725). -spec decode_int8(bitstring()) -> {ok, gleam@dynamic:dynamic_()} | {error, binary()}. decode_int8(Bits) -> case Bits of <> -> {ok, gleam_stdlib:identity(Num)}; _ -> {error, <<"invalid int8"/utf8>>} end. -file("src/pg_value.gleam", 732). -spec decode_float4(bitstring()) -> {ok, gleam@dynamic:dynamic_()} | {error, binary()}. decode_float4(Bits) -> case Bits of <> -> _pipe = gleam@float:to_precision(Value, 4), _pipe@1 = gleam_stdlib:identity(_pipe), {ok, _pipe@1}; _ -> {error, <<"invalid float4"/utf8>>} end. -file("src/pg_value.gleam", 743). -spec decode_float8(bitstring()) -> {ok, gleam@dynamic:dynamic_()} | {error, binary()}. decode_float8(Bits) -> case Bits of <> -> _pipe = gleam@float:to_precision(Value, 8), _pipe@1 = gleam_stdlib:identity(_pipe), {ok, _pipe@1}; _ -> {error, <<"invalid float8"/utf8>>} end. -file("src/pg_value.gleam", 754). -spec decode_varchar(bitstring()) -> {ok, gleam@dynamic:dynamic_()} | {error, binary()}. decode_varchar(Bits) -> _pipe = gleam@bit_array:to_string(Bits), _pipe@1 = gleam@result:map(_pipe, fun gleam_stdlib:identity/1), gleam@result:replace_error(_pipe@1, <<"invalid varchar"/utf8>>). -file("src/pg_value.gleam", 760). -spec decode_text(bitstring()) -> {ok, gleam@dynamic:dynamic_()} | {error, binary()}. decode_text(Bits) -> _pipe = gleam@bit_array:to_string(Bits), _pipe@1 = gleam@result:map(_pipe, fun gleam_stdlib:identity/1), gleam@result:replace_error(_pipe@1, <<"invalid text"/utf8>>). -file("src/pg_value.gleam", 766). -spec decode_bytea(bitstring()) -> {ok, gleam@dynamic:dynamic_()} | {error, binary()}. decode_bytea(Bits) -> {ok, gleam_stdlib:identity(Bits)}. -file("src/pg_value.gleam", 835). -spec decode_interval(bitstring()) -> {ok, gleam@dynamic:dynamic_()} | {error, binary()}. decode_interval(Bits) -> case Bits of <> -> _pipe = erlang:list_to_tuple( [gleam_stdlib:identity(Months), gleam_stdlib:identity(Days), gleam_stdlib:identity(Microseconds)] ), {ok, _pipe}; _ -> {error, <<"invalid interval"/utf8>>} end. -file("src/pg_value.gleam", 386). -spec encode_oid(integer(), pg_value@type_info:type_info()) -> {ok, bitstring()} | {error, binary()}. encode_oid(Num, Info) -> validate_typesend( <<"oidsend"/utf8>>, Info, fun() -> case (0 =< Num) andalso (Num =< 16#FFFFFFFF) of true -> {ok, <<4:32/big-integer, Num:32/big-integer>>}; false -> {error, <<"Out of range for oid"/utf8>>} end end ). -file("src/pg_value.gleam", 410). -spec encode_int2(integer(), pg_value@type_info:type_info()) -> {ok, bitstring()} | {error, binary()}. encode_int2(Num, Info) -> validate_typesend( <<"int2send"/utf8>>, Info, fun() -> case (- 16#8000 =< Num) andalso (Num =< 16#7FFF) of true -> {ok, <<2:32/big-integer, Num:16/big-integer>>}; false -> {error, <<"Out of range for int2"/utf8>>} end end ). -file("src/pg_value.gleam", 419). -spec encode_int4(integer(), pg_value@type_info:type_info()) -> {ok, bitstring()} | {error, binary()}. encode_int4(Num, Info) -> validate_typesend( <<"int4send"/utf8>>, Info, fun() -> case (- 16#80000000 =< Num) andalso (Num =< 16#7FFFFFFF) of true -> {ok, <<4:32/big-integer, Num:32/big-integer>>}; false -> {error, <<"Out of range for int4"/utf8>>} end end ). -file("src/pg_value.gleam", 428). -spec encode_int8(integer(), pg_value@type_info:type_info()) -> {ok, bitstring()} | {error, binary()}. encode_int8(Num, Info) -> validate_typesend( <<"int8send"/utf8>>, Info, fun() -> case (- 16#8000000000000000 =< Num) andalso (Num =< 16#7FFFFFFFFFFFFFFF) of true -> {ok, <<8:32/big-integer, Num:64/big-integer>>}; false -> {error, <<"Out of range for int8"/utf8>>} end end ). -file("src/pg_value.gleam", 395). -spec encode_int(integer(), pg_value@type_info:type_info()) -> {ok, bitstring()} | {error, binary()}. encode_int(Num, Info) -> case erlang:element(4, Info) of <<"oidsend"/utf8>> -> encode_oid(Num, Info); <<"int2send"/utf8>> -> encode_int2(Num, Info); <<"int4send"/utf8>> -> encode_int4(Num, Info); <<"int8send"/utf8>> -> encode_int8(Num, Info); _ -> Message = <<<<<<"Attempted to encode "/utf8, (erlang:integer_to_binary(Num))/binary>>/binary, " as "/utf8>>/binary, (erlang:element(4, Info))/binary>>, {error, Message} end. -file("src/pg_value.gleam", 803). -spec handle_timestamp(integer()) -> gleam@dynamic:dynamic_(). handle_timestamp(Microseconds) -> Seconds_since_unix_epoch = begin _pipe = (Microseconds div 1000000), _pipe@1 = gleam@int:add(_pipe, 63113904000), gleam@int:subtract(_pipe@1, 62167219200) end, Usecs_since_unix_epoch = Seconds_since_unix_epoch * 1000000, _pipe@2 = Usecs_since_unix_epoch, _pipe@3 = gleam@int:add(_pipe@2, (Microseconds rem 1000000)), gleam_stdlib:identity(_pipe@3). -file("src/pg_value.gleam", 787). -spec decode_timestamp(bitstring()) -> {ok, gleam@dynamic:dynamic_()} | {error, binary()}. decode_timestamp(Bits) -> Pos_infinity = 16#7FFFFFFFFFFFFFFF, Neg_infinity = - 16#8000000000000000, case Bits of <> -> case Num of _ when Num =:= Pos_infinity -> {ok, gleam_stdlib:identity(<<"infinity"/utf8>>)}; _ when Num =:= Neg_infinity -> {ok, gleam_stdlib:identity(<<"-infinity"/utf8>>)}; _ -> {ok, handle_timestamp(Num)} end; _ -> {error, <<"invalid timestamp"/utf8>>} end. -file("src/pg_value.gleam", 878). -spec unix_seconds_before_postgres_epoch() -> gleam@time@duration:duration(). unix_seconds_before_postgres_epoch() -> _pipe = 62167219200, _pipe@1 = gleam@int:subtract(_pipe, 63113904000), gleam@time@duration:seconds(_pipe@1). -file("src/pg_value.gleam", 497). -spec encode_date(gleam@time@calendar:date(), pg_value@type_info:type_info()) -> {ok, bitstring()} | {error, binary()}. encode_date(Date, Info) -> validate_typesend( <<"date_send"/utf8>>, Info, fun() -> Gregorian_days = calendar:date_to_gregorian_days( erlang:element(2, Date), gleam@time@calendar:month_to_int(erlang:element(3, Date)), erlang:element(4, Date) ), Pg_days = Gregorian_days - 730485, {ok, <<4:32/big-integer, Pg_days:32/big-integer>>} end ). -file("src/pg_value.gleam", 862). -spec days_to_date(integer()) -> {ok, gleam@time@calendar:date()} | {error, nil}. days_to_date(Days) -> {Year, Month, Day} = calendar:gregorian_days_to_date(Days + 730485), _pipe = gleam@time@calendar:month_from_int(Month), gleam@result:map(_pipe, fun(Month@1) -> {date, Year, Month@1, Day} end). -file("src/pg_value.gleam", 816). -spec decode_date(bitstring()) -> {ok, gleam@dynamic:dynamic_()} | {error, binary()}. decode_date(Bits) -> case Bits of <> -> _pipe = days_to_date(Days), _pipe@1 = gleam@result:map( _pipe, fun(Date) -> Month = gleam@time@calendar:month_to_int( erlang:element(3, Date) ), erlang:list_to_tuple( [gleam_stdlib:identity(erlang:element(2, Date)), gleam_stdlib:identity(Month), gleam_stdlib:identity(erlang:element(4, Date))] ) end ), gleam@result:replace_error(_pipe@1, <<"Invalid month"/utf8>>); _ -> {error, <<"invalid date"/utf8>>} end. -file("src/pg_value.gleam", 530). -spec encode_interval( pg_value@interval:interval(), pg_value@type_info:type_info() ) -> {ok, bitstring()} | {error, binary()}. encode_interval(Interval, Info) -> validate_typesend( <<"interval_send"/utf8>>, Info, fun() -> {interval, Months, Days, Seconds, Microseconds} = Interval, Usecs = (Seconds * 1000000) + Microseconds, Encoded = <<16:32/big-integer, Usecs:64/big-integer, Days:32/big-integer, Months:32/big-integer>>, {ok, Encoded} end ). -file("src/pg_value.gleam", 853). -spec from_microseconds(integer()) -> gleam@time@calendar:time_of_day(). from_microseconds(Usecs) -> Seconds = case 1000000 of 0 -> 0; Gleam@denominator -> Usecs div Gleam@denominator end, Nanoseconds = (case 1000000 of 0 -> 0; Gleam@denominator@1 -> Usecs rem Gleam@denominator@1 end) * 1000, {Hours, Minutes, Seconds@1} = calendar:seconds_to_time(Seconds), {time_of_day, Hours, Minutes, Seconds@1, Nanoseconds}. -file("src/pg_value.gleam", 770). -spec decode_time(bitstring()) -> {ok, gleam@dynamic:dynamic_()} | {error, binary()}. decode_time(Bits) -> case Bits of <> -> Tod = from_microseconds(Microseconds), _pipe = erlang:list_to_tuple( [gleam_stdlib:identity(erlang:element(2, Tod)), gleam_stdlib:identity(erlang:element(3, Tod)), gleam_stdlib:identity(erlang:element(4, Tod)), gleam_stdlib:identity(erlang:element(5, Tod) div 1000)] ), {ok, _pipe}; _ -> {error, <<"invalid time"/utf8>>} end. -file("src/pg_value.gleam", 588). ?DOC( " Decodes binary PostgreSQL data into a Dynamic value. Dynamic values\n" " can then be decoded using [gleam/dynamic/decode][1].\n" "\n" " [1]: https://hexdocs.pm/gleam_stdlib/gleam/dynamic/decode.html\n" ). -spec decode(bitstring(), pg_value@type_info:type_info()) -> {ok, gleam@dynamic:dynamic_()} | {error, binary()}. decode(Bits, Info) -> case erlang:element(5, Info) of <<"array_recv"/utf8>> -> decode_array(Bits, fun(Elem) -> case erlang:element(10, Info) of {some, Elem_ti} -> decode(Elem, Elem_ti); none -> {error, <<"elem type missing"/utf8>>} end end); <<"boolrecv"/utf8>> -> decode_bool(Bits); <<"oidrecv"/utf8>> -> decode_oid(Bits); <<"int2recv"/utf8>> -> decode_int2(Bits); <<"int4recv"/utf8>> -> decode_int4(Bits); <<"int8recv"/utf8>> -> decode_int8(Bits); <<"float4recv"/utf8>> -> decode_float4(Bits); <<"float8recv"/utf8>> -> decode_float8(Bits); <<"textrecv"/utf8>> -> decode_text(Bits); <<"varcharrecv"/utf8>> -> decode_varchar(Bits); <<"namerecv"/utf8>> -> decode_text(Bits); <<"charrecv"/utf8>> -> decode_text(Bits); <<"bytearecv"/utf8>> -> decode_bytea(Bits); <<"time_recv"/utf8>> -> decode_time(Bits); <<"date_recv"/utf8>> -> decode_date(Bits); <<"timestamp_recv"/utf8>> -> decode_timestamp(Bits); <<"timestamptz_recv"/utf8>> -> decode_timestamp(Bits); <<"interval_recv"/utf8>> -> decode_interval(Bits); _ -> {error, <<"Unsupported type"/utf8>>} end. -file("src/pg_value.gleam", 869). -spec to_microseconds(EHZ, fun((EHZ) -> {integer(), integer()})) -> integer(). to_microseconds(Kind, To_seconds_and_nanoseconds) -> {Seconds, Nanoseconds} = To_seconds_and_nanoseconds(Kind), (Seconds * 1000000) + (case 1000 of 0 -> 0; Gleam@denominator -> Nanoseconds div Gleam@denominator end). -file("src/pg_value.gleam", 514). -spec encode_time( gleam@time@calendar:time_of_day(), pg_value@type_info:type_info() ) -> {ok, bitstring()} | {error, binary()}. encode_time(Time_of_day, Info) -> validate_typesend( <<"time_send"/utf8>>, Info, fun() -> Usecs = begin _pipe = gleam@time@duration:hours( erlang:element(2, Time_of_day) ), _pipe@1 = gleam@time@duration:add( _pipe, gleam@time@duration:minutes(erlang:element(3, Time_of_day)) ), _pipe@2 = gleam@time@duration:add( _pipe@1, gleam@time@duration:seconds(erlang:element(4, Time_of_day)) ), _pipe@3 = gleam@time@duration:add( _pipe@2, gleam@time@duration:nanoseconds( erlang:element(5, Time_of_day) ) ), to_microseconds( _pipe@3, fun gleam@time@duration:to_seconds_and_nanoseconds/1 ) end, {ok, <<8:32/big-integer, Usecs:64/big-integer>>} end ). -file("src/pg_value.gleam", 550). -spec encode_timestamp( gleam@time@timestamp:timestamp(), pg_value@type_info:type_info() ) -> {ok, bitstring()} | {error, binary()}. encode_timestamp(Timestamp, Info) -> validate_typesend( <<"timestamp_send"/utf8>>, Info, fun() -> Timestamp_int = begin _pipe = unix_seconds_before_postgres_epoch(), _pipe@1 = gleam@time@timestamp:add(Timestamp, _pipe), to_microseconds( _pipe@1, fun gleam@time@timestamp:to_unix_seconds_and_nanoseconds/1 ) end, {ok, <<8:32/big-integer, Timestamp_int:64/big-integer>>} end ). -file("src/pg_value.gleam", 564). -spec encode_timestamptz( gleam@time@timestamp:timestamp(), offset(), pg_value@type_info:type_info() ) -> {ok, bitstring()} | {error, binary()}. encode_timestamptz(Timestamp, Offset, Info) -> validate_typesend( <<"timestamptz_send"/utf8>>, Info, fun() -> Offset_dur = offset_to_duration(Offset), Timestamp_int = begin _pipe = unix_seconds_before_postgres_epoch(), _pipe@1 = gleam@time@duration:add(_pipe, Offset_dur), _pipe@2 = gleam@time@timestamp:add(Timestamp, _pipe@1), to_microseconds( _pipe@2, fun gleam@time@timestamp:to_unix_seconds_and_nanoseconds/1 ) end, {ok, <<8:32/big-integer, Timestamp_int:64/big-integer>>} end ). -file("src/pg_value.gleam", 292). -spec encode_array(list(value()), pg_value@type_info:type_info()) -> {ok, bitstring()} | {error, binary()}. encode_array(Elems, Info) -> validate_typesend( <<"array_send"/utf8>>, Info, fun() -> Dimensions = arr_dims(Elems), case erlang:element(10, Info) of {some, Elem_ti} -> _pipe = Elems, _pipe@1 = gleam@list:try_map( _pipe, fun(_capture) -> encode(_capture, Elem_ti) end ), gleam@result:'try'( _pipe@1, fun(Encoded_elems) -> Has_nulls = gleam@list:contains( Encoded_elems, <<-1:32/big-integer>> ), do_encode_array( Dimensions, Has_nulls, Elem_ti, Encoded_elems ) end ); none -> {error, <<"Missing elem type info"/utf8>>} end end ). -file("src/pg_value.gleam", 262). ?DOC(" Encodes a Value as a PostgreSQL data type\n"). -spec encode(value(), pg_value@type_info:type_info()) -> {ok, bitstring()} | {error, binary()}. encode(Value, Info) -> case Value of null -> encode_null(); {bool, Val} -> encode_bool(Val, Info); {int, Val@1} -> encode_int(Val@1, Info); {float, Val@2} -> encode_float(Val@2, Info); {text, Val@3} -> encode_text(Val@3, Info); {bytea, Val@4} -> encode_bytea(Val@4, Info); {time, Val@5} -> encode_time(Val@5, Info); {date, Val@6} -> encode_date(Val@6, Info); {timestamp, Val@7} -> encode_timestamp(Val@7, Info); {timestamptz, Ts, Offset} -> encode_timestamptz(Ts, Offset, Info); {interval, Val@8} -> encode_interval(Val@8, Info); {array, Val@9} -> encode_array(Val@9, Info) end. -file("src/pg_value.gleam", 164). -spec array_to_string(list(value())) -> binary(). array_to_string(Array) -> Elems = case Array of [] -> <<""/utf8>>; [Val] -> to_string(Val); Vals -> _pipe = Vals, _pipe@1 = gleam@list:map(_pipe, fun to_string/1), gleam@string:join(_pipe@1, <<", "/utf8>>) end, <<<<"ARRAY["/utf8, Elems/binary>>/binary, "]"/utf8>>. -file("src/pg_value.gleam", 140). ?DOC(" Converts a `Value` to a string formatted properly for PostgreSQL\n"). -spec to_string(value()) -> binary(). to_string(Value) -> case Value of null -> <<"NULL"/utf8>>; {bool, Val} -> bool_to_string(Val); {int, Val@1} -> erlang:integer_to_binary(Val@1); {float, Val@2} -> gleam_stdlib:float_to_string(Val@2); {text, Val@3} -> text_to_string(Val@3); {bytea, Val@4} -> bytea_to_string(Val@4); {time, Val@5} -> time_to_string(Val@5); {date, Val@6} -> date_to_string(Val@6); {timestamp, Val@7} -> timestamp_to_string(Val@7); {timestamptz, Ts, Offset} -> timestamptz_to_string(Ts, Offset); {interval, Val@8} -> _pipe = pg_value@interval:to_iso8601_string(Val@8), single_quote(_pipe); {array, Vals} -> array_to_string(Vals) end.