Current section

Files

Jump to
postgleam src postgleam@message.erl
Raw

src/postgleam@message.erl

-module(postgleam@message).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/postgleam/message.gleam").
-export([decode_cstring/1, extract_row_values/1, decode_backend/1, encode_frontend/1]).
-export_type([transaction_status/0, format/0, row_field/0, auth_type/0, describe_type/0, backend_message/0, decode_result/0, frontend_message/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.
-type transaction_status() :: idle | in_transaction | failed_transaction.
-type format() :: text_format | binary_format.
-type row_field() :: {row_field,
binary(),
integer(),
integer(),
integer(),
integer(),
integer(),
format()}.
-type auth_type() :: auth_ok |
auth_kerberos |
auth_cleartext |
{auth_md5, bitstring()} |
auth_scm |
auth_gss |
{auth_gss_continue, bitstring()} |
auth_sspi |
{auth_sasl, list(binary())} |
{auth_sasl_continue, bitstring()} |
{auth_sasl_final, bitstring()}.
-type describe_type() :: describe_statement | describe_portal.
-type backend_message() :: {authentication_msg, auth_type()} |
{backend_key_data, integer(), integer()} |
{ready_for_query, transaction_status()} |
{parameter_status, binary(), binary()} |
{row_description, list(row_field())} |
{data_row, bitstring()} |
{command_complete, binary()} |
parse_complete |
bind_complete |
close_complete |
no_data |
portal_suspended |
empty_query_response |
{error_response, gleam@dict:dict(binary(), binary())} |
{notice_response, gleam@dict:dict(binary(), binary())} |
{notification_response, integer(), binary(), binary()} |
{parameter_description, list(integer())} |
{copy_in_response, format(), list(format())} |
{copy_out_response, format(), list(format())} |
{copy_both_response, format(), list(format())} |
{copy_data, bitstring()} |
copy_done.
-type decode_result() :: {decoded, backend_message(), bitstring()} |
incomplete |
{decode_failed, binary()}.
-type frontend_message() :: {startup_message, list({binary(), binary()})} |
{password_message, binary()} |
{s_a_s_l_initial_response, binary(), bitstring()} |
{s_a_s_l_response, bitstring()} |
{simple_query, binary()} |
{parse, binary(), binary(), list(integer())} |
{describe, describe_type(), binary()} |
{bind,
binary(),
binary(),
list(format()),
list(gleam@option:option(bitstring())),
list(format())} |
{execute, binary(), integer()} |
{close, describe_type(), binary()} |
sync |
flush |
terminate |
s_s_l_request |
{cancel_request, integer(), integer()} |
{copy_data_msg, bitstring()} |
copy_done_msg |
{copy_fail, binary()}.
-file("src/postgleam/message.gleam", 179).
-spec encode_oids(list(integer()), bitstring()) -> bitstring().
encode_oids(Oids, Acc) ->
case Oids of
[] ->
Acc;
[Oid | Rest] ->
encode_oids(Rest, <<Acc/bitstring, Oid:32/big>>)
end.
-file("src/postgleam/message.gleam", 216).
-spec encode_params(list(gleam@option:option(bitstring())), bitstring()) -> bitstring().
encode_params(Params, Acc) ->
case Params of
[] ->
Acc;
[{some, Data} | Rest] ->
Len = erlang:byte_size(Data),
encode_params(Rest, <<Acc/bitstring, Len:32/big, Data/bitstring>>);
[none | Rest@1] ->
Null_marker = <<255, 255, 255, 255>>,
encode_params(Rest@1, <<Acc/bitstring, Null_marker/bitstring>>)
end.
-file("src/postgleam/message.gleam", 244).
-spec encode_no_type(bitstring()) -> bitstring().
encode_no_type(Data) ->
Size = erlang:byte_size(Data) + 4,
<<Size:32/big, Data/bitstring>>.
-file("src/postgleam/message.gleam", 249).
-spec describe_byte(describe_type()) -> integer().
describe_byte(Type_) ->
case Type_ of
describe_statement ->
16#53;
describe_portal ->
16#50
end.
-file("src/postgleam/message.gleam", 256).
-spec format_to_int(format()) -> integer().
format_to_int(F) ->
case F of
text_format ->
0;
binary_format ->
1
end.
-file("src/postgleam/message.gleam", 209).
-spec encode_formats(list(format()), bitstring()) -> bitstring().
encode_formats(Formats, Acc) ->
case Formats of
[] ->
Acc;
[F | Rest] ->
encode_formats(Rest, <<Acc/bitstring, (format_to_int(F)):16/big>>)
end.
-file("src/postgleam/message.gleam", 267).
-spec string_bytes(binary()) -> bitstring().
string_bytes(S) ->
gleam_stdlib:identity(S).
-file("src/postgleam/message.gleam", 162).
-spec encode_startup_params(list({binary(), binary()}), bitstring()) -> bitstring().
encode_startup_params(Params, Acc) ->
case Params of
[] ->
Acc;
[{Key, Value} | Rest] ->
Entry = <<(string_bytes(Key))/bitstring,
0,
(string_bytes(Value))/bitstring,
0>>,
encode_startup_params(Rest, <<Acc/bitstring, Entry/bitstring>>)
end.
-file("src/postgleam/message.gleam", 238).
-spec encode_with_type(binary(), bitstring()) -> bitstring().
encode_with_type(Type_str, Data) ->
Type_byte@1 = case gleam_stdlib:bit_array_slice(
string_bytes(Type_str),
0,
1
) of
{ok, Type_byte} -> Type_byte;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"postgleam/message"/utf8>>,
function => <<"encode_with_type"/utf8>>,
line => 239,
value => _assert_fail,
start => 7449,
'end' => 7521,
pattern_start => 7460,
pattern_end => 7473})
end,
Size = erlang:byte_size(Data) + 4,
<<Type_byte@1/bitstring, Size:32/big, Data/bitstring>>.
-file("src/postgleam/message.gleam", 172).
-spec encode_parse(binary(), binary(), list(integer())) -> bitstring().
encode_parse(Name, Statement, Oids) ->
Num_oids = erlang:length(Oids),
Oid_bytes = encode_oids(Oids, <<>>),
Data = <<(string_bytes(Name))/bitstring,
0,
(string_bytes(Statement))/bitstring,
0,
Num_oids:16/big,
Oid_bytes/bitstring>>,
encode_with_type(<<"P"/utf8>>, Data).
-file("src/postgleam/message.gleam", 186).
-spec encode_bind(
binary(),
binary(),
list(format()),
list(gleam@option:option(bitstring())),
list(format())
) -> bitstring().
encode_bind(Portal, Statement, Param_formats, Params, Result_formats) ->
Pf_bytes = encode_formats(Param_formats, <<>>),
Rf_bytes = encode_formats(Result_formats, <<>>),
Num_pf = erlang:length(Param_formats),
Num_rf = erlang:length(Result_formats),
Num_params = erlang:length(Params),
Param_bytes = encode_params(Params, <<>>),
Data = <<(string_bytes(Portal))/bitstring,
0,
(string_bytes(Statement))/bitstring,
0,
Num_pf:16/big,
Pf_bytes/bitstring,
Num_params:16/big,
Param_bytes/bitstring,
Num_rf:16/big,
Rf_bytes/bitstring>>,
encode_with_type(<<"B"/utf8>>, Data).
-file("src/postgleam/message.gleam", 232).
-spec encode_sasl_initial(binary(), bitstring()) -> bitstring().
encode_sasl_initial(Mechanism, Data) ->
Data_len = erlang:byte_size(Data),
Payload = <<(string_bytes(Mechanism))/bitstring,
0,
Data_len:32/big,
Data/bitstring>>,
encode_with_type(<<"p"/utf8>>, Payload).
-file("src/postgleam/message.gleam", 263).
-spec password_bytes(binary()) -> bitstring().
password_bytes(Password) ->
<<(string_bytes(Password))/bitstring, 0>>.
-file("src/postgleam/message.gleam", 397).
-spec decode_backend_key(bitstring(), bitstring()) -> decode_result().
decode_backend_key(Payload, Rest) ->
case Payload of
<<Pid:32/big-signed, Key:32/big-signed>> ->
{decoded, {backend_key_data, Pid, Key}, Rest};
_ ->
{decode_failed, <<"Invalid BackendKeyData"/utf8>>}
end.
-file("src/postgleam/message.gleam", 405).
-spec decode_ready(bitstring(), bitstring()) -> decode_result().
decode_ready(Payload, Rest) ->
case Payload of
<<16#49>> ->
{decoded, {ready_for_query, idle}, Rest};
<<16#54>> ->
{decoded, {ready_for_query, in_transaction}, Rest};
<<16#45>> ->
{decoded, {ready_for_query, failed_transaction}, Rest};
_ ->
{decode_failed, <<"Invalid ReadyForQuery status"/utf8>>}
end.
-file("src/postgleam/message.gleam", 477).
-spec decode_data_row(bitstring(), bitstring()) -> decode_result().
decode_data_row(Payload, Rest) ->
case Payload of
<<_:16/big-unsigned, Values/bitstring>> ->
{decoded, {data_row, Values}, Rest};
_ ->
{decode_failed, <<"Invalid DataRow"/utf8>>}
end.
-file("src/postgleam/message.gleam", 523).
-spec decode_field_type(integer()) -> binary().
decode_field_type(Byte) ->
case Byte of
16#53 ->
<<"severity"/utf8>>;
16#56 ->
<<"severity_v"/utf8>>;
16#43 ->
<<"code"/utf8>>;
16#4D ->
<<"message"/utf8>>;
16#44 ->
<<"detail"/utf8>>;
16#48 ->
<<"hint"/utf8>>;
16#50 ->
<<"position"/utf8>>;
16#70 ->
<<"internal_position"/utf8>>;
16#71 ->
<<"internal_query"/utf8>>;
16#57 ->
<<"where"/utf8>>;
16#73 ->
<<"schema"/utf8>>;
16#74 ->
<<"table"/utf8>>;
16#63 ->
<<"column"/utf8>>;
16#64 ->
<<"data_type"/utf8>>;
16#6E ->
<<"constraint"/utf8>>;
16#46 ->
<<"file"/utf8>>;
16#4C ->
<<"line"/utf8>>;
16#52 ->
<<"routine"/utf8>>;
_ ->
<<"unknown"/utf8>>
end.
-file("src/postgleam/message.gleam", 579).
-spec decode_oid_list(bitstring(), integer(), list(integer())) -> list(integer()).
decode_oid_list(Data, Count, Acc) ->
case Count of
0 ->
lists:reverse(Acc);
_ ->
case Data of
<<Oid:32/big-unsigned, Remaining/bitstring>> ->
decode_oid_list(Remaining, Count - 1, [Oid | Acc]);
_ ->
lists:reverse(Acc)
end
end.
-file("src/postgleam/message.gleam", 569).
-spec decode_parameter_desc(bitstring(), bitstring()) -> decode_result().
decode_parameter_desc(Payload, Rest) ->
case Payload of
<<Num_params:16/big-unsigned, Oids_data/bitstring>> ->
Oids = decode_oid_list(Oids_data, Num_params, []),
{decoded, {parameter_description, Oids}, Rest};
_ ->
{decode_failed, <<"Invalid ParameterDescription"/utf8>>}
end.
-file("src/postgleam/message.gleam", 620).
-spec int_to_format(integer()) -> format().
int_to_format(N) ->
case N of
1 ->
binary_format;
_ ->
text_format
end.
-file("src/postgleam/message.gleam", 607).
-spec decode_column_formats(bitstring(), integer(), list(format())) -> list(format()).
decode_column_formats(Data, Count, Acc) ->
case Count of
0 ->
lists:reverse(Acc);
_ ->
case Data of
<<F:16/big-unsigned, Remaining/bitstring>> ->
decode_column_formats(
Remaining,
Count - 1,
[int_to_format(F) | Acc]
);
_ ->
lists:reverse(Acc)
end
end.
-file("src/postgleam/message.gleam", 592).
-spec decode_copy_response(
bitstring(),
fun((format(), list(format())) -> backend_message()),
bitstring()
) -> decode_result().
decode_copy_response(Payload, Constructor, Rest) ->
case Payload of
<<Format_byte:8/unsigned, Num_cols:16/big-unsigned, Col_data/bitstring>> ->
Format = int_to_format(Format_byte),
Columns = decode_column_formats(Col_data, Num_cols, []),
{decoded, Constructor(Format, Columns), Rest};
_ ->
{decode_failed, <<"Invalid CopyResponse"/utf8>>}
end.
-file("src/postgleam/message.gleam", 637).
-spec decode_cstring_loop(bitstring(), bitstring()) -> {ok,
{binary(), bitstring()}} |
{error, nil}.
decode_cstring_loop(Data, Acc) ->
case Data of
<<0, Remaining/bitstring>> ->
case gleam@bit_array:to_string(Acc) of
{ok, S} ->
{ok, {S, Remaining}};
{error, _} ->
{error, nil}
end;
<<Byte:8, Remaining@1/bitstring>> ->
decode_cstring_loop(Remaining@1, <<Acc/bitstring, Byte>>);
_ ->
{error, nil}
end.
-file("src/postgleam/message.gleam", 633).
?DOC(
" Decode a null-terminated C string from a BitArray.\n"
" Returns the string and the remaining bytes after the null terminator.\n"
).
-spec decode_cstring(bitstring()) -> {ok, {binary(), bitstring()}} |
{error, nil}.
decode_cstring(Data) ->
decode_cstring_loop(Data, <<>>).
-file("src/postgleam/message.gleam", 384).
-spec decode_sasl_mechanisms(bitstring(), list(binary())) -> list(binary()).
decode_sasl_mechanisms(Data, Acc) ->
case Data of
<<0>> ->
lists:reverse(Acc);
<<>> ->
lists:reverse(Acc);
_ ->
case decode_cstring(Data) of
{ok, {Mechanism, Remaining}} ->
decode_sasl_mechanisms(Remaining, [Mechanism | Acc]);
{error, _} ->
lists:reverse(Acc)
end
end.
-file("src/postgleam/message.gleam", 357).
-spec decode_auth(bitstring(), integer(), bitstring()) -> decode_result().
decode_auth(Payload, _, Rest) ->
case Payload of
<<0:32/big-signed>> ->
{decoded, {authentication_msg, auth_ok}, Rest};
<<2:32/big-signed>> ->
{decoded, {authentication_msg, auth_kerberos}, Rest};
<<3:32/big-signed>> ->
{decoded, {authentication_msg, auth_cleartext}, Rest};
<<5:32/big-signed, Salt/bitstring>> ->
case erlang:byte_size(Salt) >= 4 of
true ->
Salt4@1 = case gleam_stdlib:bit_array_slice(Salt, 0, 4) of
{ok, Salt4} -> Salt4;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"postgleam/message"/utf8>>,
function => <<"decode_auth"/utf8>>,
line => 365,
value => _assert_fail,
start => 11580,
'end' => 11630,
pattern_start => 11591,
pattern_end => 11600})
end,
{decoded, {authentication_msg, {auth_md5, Salt4@1}}, Rest};
false ->
{decode_failed, <<"MD5 auth missing salt"/utf8>>}
end;
<<7:32/big-signed>> ->
{decoded, {authentication_msg, auth_gss}, Rest};
<<8:32/big-signed, Data/bitstring>> ->
{decoded, {authentication_msg, {auth_gss_continue, Data}}, Rest};
<<9:32/big-signed>> ->
{decoded, {authentication_msg, auth_sspi}, Rest};
<<10:32/big-signed, Mechanisms_data/bitstring>> ->
Mechanisms = decode_sasl_mechanisms(Mechanisms_data, []),
{decoded, {authentication_msg, {auth_sasl, Mechanisms}}, Rest};
<<11:32/big-signed, Data@1/bitstring>> ->
{decoded, {authentication_msg, {auth_sasl_continue, Data@1}}, Rest};
<<12:32/big-signed, Data@2/bitstring>> ->
{decoded, {authentication_msg, {auth_sasl_final, Data@2}}, Rest};
_ ->
{decode_failed, <<"Unknown auth type"/utf8>>}
end.
-file("src/postgleam/message.gleam", 414).
-spec decode_parameter_status(bitstring(), bitstring()) -> decode_result().
decode_parameter_status(Payload, Rest) ->
case decode_cstring(Payload) of
{ok, {Name, Remaining}} ->
case decode_cstring(Remaining) of
{ok, {Value, _}} ->
{decoded, {parameter_status, Name, Value}, Rest};
{error, _} ->
{decode_failed, <<"Invalid ParameterStatus value"/utf8>>}
end;
{error, _} ->
{decode_failed, <<"Invalid ParameterStatus name"/utf8>>}
end.
-file("src/postgleam/message.gleam", 438).
-spec decode_row_fields(bitstring(), integer(), list(row_field())) -> {ok,
list(row_field())} |
{error, binary()}.
decode_row_fields(Data, Count, Acc) ->
case Count of
0 ->
{ok, lists:reverse(Acc)};
_ ->
case decode_cstring(Data) of
{ok, {Name, Remaining}} ->
case Remaining of
<<Table_oid:32/big-unsigned,
Column:16/big-signed,
Type_oid:32/big-unsigned,
Type_size:16/big-signed,
Type_mod:32/big-signed,
Format_code:16/big-signed,
Field_rest/bitstring>> ->
Format = case Format_code of
1 ->
binary_format;
_ ->
text_format
end,
Field = {row_field,
Name,
Table_oid,
Column,
Type_oid,
Type_size,
Type_mod,
Format},
decode_row_fields(
Field_rest,
Count - 1,
[Field | Acc]
);
_ ->
{error, <<"Invalid row field data"/utf8>>}
end;
{error, _} ->
{error, <<"Invalid row field name"/utf8>>}
end
end.
-file("src/postgleam/message.gleam", 426).
-spec decode_row_description(bitstring(), bitstring()) -> decode_result().
decode_row_description(Payload, Rest) ->
case Payload of
<<Num_fields:16/big-unsigned, Fields_data/bitstring>> ->
case decode_row_fields(Fields_data, Num_fields, []) of
{ok, Fields} ->
{decoded, {row_description, Fields}, Rest};
{error, E} ->
{decode_failed, E}
end;
_ ->
{decode_failed, <<"Invalid RowDescription"/utf8>>}
end.
-file("src/postgleam/message.gleam", 487).
-spec decode_command_complete(bitstring(), bitstring()) -> decode_result().
decode_command_complete(Payload, Rest) ->
case decode_cstring(Payload) of
{ok, {Tag, _}} ->
{decoded, {command_complete, Tag}, Rest};
{error, _} ->
{decode_failed, <<"Invalid CommandComplete"/utf8>>}
end.
-file("src/postgleam/message.gleam", 506).
-spec decode_error_fields(bitstring(), gleam@dict:dict(binary(), binary())) -> gleam@dict:dict(binary(), binary()).
decode_error_fields(Data, Acc) ->
case Data of
<<0>> ->
Acc;
<<>> ->
Acc;
<<Field_type:8/unsigned, Remaining/bitstring>> ->
case decode_cstring(Remaining) of
{ok, {Value, Next}} ->
Key = decode_field_type(Field_type),
decode_error_fields(
Next,
gleam@dict:insert(Acc, Key, Value)
);
{error, _} ->
Acc
end;
_ ->
Acc
end.
-file("src/postgleam/message.gleam", 494).
-spec decode_error_notice(bitstring(), boolean(), bitstring()) -> decode_result().
decode_error_notice(Payload, Is_error, Rest) ->
Fields = decode_error_fields(Payload, maps:new()),
case Is_error of
true ->
{decoded, {error_response, Fields}, Rest};
false ->
{decoded, {notice_response, Fields}, Rest}
end.
-file("src/postgleam/message.gleam", 547).
-spec decode_notification(bitstring(), bitstring()) -> decode_result().
decode_notification(Payload, Rest) ->
case Payload of
<<Pg_pid:32/big-signed, Remaining/bitstring>> ->
case decode_cstring(Remaining) of
{ok, {Channel, Remaining2}} ->
case decode_cstring(Remaining2) of
{ok, {Payload_str, _}} ->
{decoded,
{notification_response,
Pg_pid,
Channel,
Payload_str},
Rest};
{error, _} ->
{decode_failed,
<<"Invalid notification payload"/utf8>>}
end;
{error, _} ->
{decode_failed, <<"Invalid notification channel"/utf8>>}
end;
_ ->
{decode_failed, <<"Invalid NotificationResponse"/utf8>>}
end.
-file("src/postgleam/message.gleam", 662).
-spec extract_row_values_loop(
bitstring(),
list(gleam@option:option(bitstring()))
) -> list(gleam@option:option(bitstring())).
extract_row_values_loop(Data, Acc) ->
case Data of
<<>> ->
Acc;
<<-1:32/big-signed, Remaining/bitstring>> ->
extract_row_values_loop(Remaining, [none | Acc]);
<<Len:32/big-signed, Value:Len/binary, Remaining@1/bitstring>> ->
extract_row_values_loop(Remaining@1, [{some, Value} | Acc]);
_ ->
Acc
end.
-file("src/postgleam/message.gleam", 657).
?DOC(
" Extract column values from a DataRow's raw value bytes.\n"
" Returns a list of Option(BitArray) — None for NULL columns.\n"
).
-spec extract_row_values(bitstring()) -> list(gleam@option:option(bitstring())).
extract_row_values(Values) ->
_pipe = extract_row_values_loop(Values, []),
lists:reverse(_pipe).
-file("src/postgleam/message.gleam", 694).
-spec hex_char(integer()) -> {ok, binary()} | {error, nil}.
hex_char(N) ->
case N of
0 ->
{ok, <<"0"/utf8>>};
1 ->
{ok, <<"1"/utf8>>};
2 ->
{ok, <<"2"/utf8>>};
3 ->
{ok, <<"3"/utf8>>};
4 ->
{ok, <<"4"/utf8>>};
5 ->
{ok, <<"5"/utf8>>};
6 ->
{ok, <<"6"/utf8>>};
7 ->
{ok, <<"7"/utf8>>};
8 ->
{ok, <<"8"/utf8>>};
9 ->
{ok, <<"9"/utf8>>};
10 ->
{ok, <<"A"/utf8>>};
11 ->
{ok, <<"B"/utf8>>};
12 ->
{ok, <<"C"/utf8>>};
13 ->
{ok, <<"D"/utf8>>};
14 ->
{ok, <<"E"/utf8>>};
15 ->
{ok, <<"F"/utf8>>};
_ ->
{error, nil}
end.
-file("src/postgleam/message.gleam", 678).
-spec int_to_hex(integer()) -> binary().
int_to_hex(N) ->
case N of
_ when N < 16 ->
C@1 = case hex_char(N) of
{ok, C} -> C;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"postgleam/message"/utf8>>,
function => <<"int_to_hex"/utf8>>,
line => 681,
value => _assert_fail,
start => 21467,
'end' => 21497,
pattern_start => 21478,
pattern_end => 21483})
end,
<<"0x0"/utf8, C@1/binary>>;
_ ->
Hi = N div 16,
Lo = N rem 16,
H@1 = case hex_char(Hi) of
{ok, H} -> H;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"postgleam/message"/utf8>>,
function => <<"int_to_hex"/utf8>>,
line => 687,
value => _assert_fail@1,
start => 21582,
'end' => 21613,
pattern_start => 21593,
pattern_end => 21598})
end,
L@1 = case hex_char(Lo) of
{ok, L} -> L;
_assert_fail@2 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"postgleam/message"/utf8>>,
function => <<"int_to_hex"/utf8>>,
line => 688,
value => _assert_fail@2,
start => 21620,
'end' => 21651,
pattern_start => 21631,
pattern_end => 21636})
end,
<<<<"0x"/utf8, H@1/binary>>/binary, L@1/binary>>
end.
-file("src/postgleam/message.gleam", 300).
-spec decode_message(integer(), bitstring(), integer(), bitstring()) -> decode_result().
decode_message(Type_byte, Payload, Size, Rest) ->
case Type_byte of
16#52 ->
decode_auth(Payload, Size, Rest);
16#4B ->
decode_backend_key(Payload, Rest);
16#5A ->
decode_ready(Payload, Rest);
16#53 ->
decode_parameter_status(Payload, Rest);
16#54 ->
decode_row_description(Payload, Rest);
16#44 ->
decode_data_row(Payload, Rest);
16#43 ->
decode_command_complete(Payload, Rest);
16#31 ->
{decoded, parse_complete, Rest};
16#32 ->
{decoded, bind_complete, Rest};
16#33 ->
{decoded, close_complete, Rest};
16#6E ->
{decoded, no_data, Rest};
16#73 ->
{decoded, portal_suspended, Rest};
16#49 ->
{decoded, empty_query_response, Rest};
16#45 ->
decode_error_notice(Payload, true, Rest);
16#4E ->
decode_error_notice(Payload, false, Rest);
16#41 ->
decode_notification(Payload, Rest);
16#74 ->
decode_parameter_desc(Payload, Rest);
16#47 ->
decode_copy_response(
Payload,
fun(Field@0, Field@1) -> {copy_in_response, Field@0, Field@1} end,
Rest
);
16#48 ->
decode_copy_response(
Payload,
fun(Field@0, Field@1) -> {copy_out_response, Field@0, Field@1} end,
Rest
);
16#57 ->
decode_copy_response(
Payload,
fun(Field@0, Field@1) -> {copy_both_response, Field@0, Field@1} end,
Rest
);
16#64 ->
{decoded, {copy_data, Payload}, Rest};
16#63 ->
{decoded, copy_done, Rest};
_ ->
{decode_failed,
<<"Unknown message type byte: "/utf8,
(int_to_hex(Type_byte))/binary>>}
end.
-file("src/postgleam/message.gleam", 277).
?DOC(
" Try to decode one backend message from a byte buffer.\n"
" Returns Decoded(msg, remaining_bytes), Incomplete, or DecodeFailed.\n"
).
-spec decode_backend(bitstring()) -> decode_result().
decode_backend(Buffer) ->
Buf_size = erlang:byte_size(Buffer),
case Buf_size < 5 of
true ->
incomplete;
false ->
{Type_byte@1, Length@1} = case {ok, Buffer} of
{ok,
<<Type_byte:8/unsigned, Length:32/big-signed, _/bitstring>>} -> {
Type_byte,
Length};
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"postgleam/message"/utf8>>,
function => <<"decode_backend"/utf8>>,
line => 283,
value => _assert_fail,
start => 8688,
'end' => 8782,
pattern_start => 8699,
pattern_end => 8761})
end,
Payload_size = Length@1 - 4,
Total_size = 1 + Length@1,
case Buf_size < Total_size of
true ->
incomplete;
false ->
Payload@1 = case gleam_stdlib:bit_array_slice(
Buffer,
5,
Payload_size
) of
{ok, Payload} -> Payload;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"postgleam/message"/utf8>>,
function => <<"decode_backend"/utf8>>,
line => 291,
value => _assert_fail@1,
start => 9000,
'end' => 9065,
pattern_start => 9011,
pattern_end => 9022})
end,
Rest@1 = case gleam_stdlib:bit_array_slice(
Buffer,
Total_size,
Buf_size - Total_size
) of
{ok, Rest} -> Rest;
_assert_fail@2 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"postgleam/message"/utf8>>,
function => <<"decode_backend"/utf8>>,
line => 292,
value => _assert_fail@2,
start => 9076,
'end' => 9156,
pattern_start => 9087,
pattern_end => 9095})
end,
decode_message(Type_byte@1, Payload@1, Payload_size, Rest@1)
end
end.
-file("src/postgleam/message.gleam", 154).
-spec encode_startup(list({binary(), binary()})) -> bitstring().
encode_startup(Params) ->
Vsn = <<3:16/big, 0:16/big>>,
Param_bytes = encode_startup_params(Params, <<>>),
Data = <<Vsn/bitstring, Param_bytes/bitstring, 0>>,
Size = erlang:byte_size(Data) + 4,
<<Size:32/big, Data/bitstring>>.
-file("src/postgleam/message.gleam", 131).
?DOC(" Encode a frontend message to bytes ready to send on the wire\n").
-spec encode_frontend(frontend_message()) -> bitstring().
encode_frontend(Msg) ->
case Msg of
{startup_message, Params} ->
encode_startup(Params);
{password_message, Password} ->
encode_with_type(
<<"p"/utf8>>,
<<(password_bytes(Password))/bitstring>>
);
{s_a_s_l_initial_response, Mechanism, Data} ->
encode_sasl_initial(Mechanism, Data);
{s_a_s_l_response, Data@1} ->
encode_with_type(<<"p"/utf8>>, Data@1);
{simple_query, Statement} ->
encode_with_type(
<<"Q"/utf8>>,
<<(string_bytes(Statement))/bitstring, 0>>
);
{parse, Name, Statement@1, Oids} ->
encode_parse(Name, Statement@1, Oids);
{describe, Type_, Name@1} ->
encode_with_type(
<<"D"/utf8>>,
<<(describe_byte(Type_)), (string_bytes(Name@1))/bitstring, 0>>
);
{bind, Portal, Statement@2, Pf, Params@1, Rf} ->
encode_bind(Portal, Statement@2, Pf, Params@1, Rf);
{execute, Portal@1, Max_rows} ->
encode_with_type(
<<"E"/utf8>>,
<<(string_bytes(Portal@1))/bitstring, 0, Max_rows:32/big>>
);
{close, Type_@1, Name@2} ->
encode_with_type(
<<"C"/utf8>>,
<<(describe_byte(Type_@1)),
(string_bytes(Name@2))/bitstring,
0>>
);
sync ->
encode_with_type(<<"S"/utf8>>, <<>>);
flush ->
encode_with_type(<<"H"/utf8>>, <<>>);
terminate ->
encode_with_type(<<"X"/utf8>>, <<>>);
s_s_l_request ->
encode_no_type(<<1234:16/big, 5679:16/big>>);
{cancel_request, Pid, Key} ->
encode_no_type(<<1234:16/big, 5678:16/big, Pid:32/big, Key:32/big>>);
{copy_data_msg, Data@2} ->
encode_with_type(<<"d"/utf8>>, Data@2);
copy_done_msg ->
encode_with_type(<<"c"/utf8>>, <<>>);
{copy_fail, Message} ->
encode_with_type(
<<"f"/utf8>>,
<<(string_bytes(Message))/bitstring, 0>>
)
end.