Current section
Files
Jump to
Current section
Files
src/pgl@internal@type_cache.erl
-module(pgl@internal@type_cache).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/pgl/internal/type_cache.gleam").
-export([on_connect/2, load/1, lookup/2, shutdown/1, new/0, start/1, supervised/1]).
-export_type([type_cache/0, 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.
?MODULEDOC(false).
-opaque type_cache() :: {type_cache,
gleam@erlang@process:name(message()),
fun(() -> {ok, pgl@internal@socket:socket()} | {error, nil})}.
-opaque message() :: {load,
gleam@erlang@process:subject({ok, nil} | {error, nil}),
pgl@internal@socket:socket()} |
{lookup,
gleam@erlang@process:subject({ok, list(pg_value@type_info:type_info())} |
{error, nil}),
list(integer())} |
shutdown.
-file("src/pgl/internal/type_cache.gleam", 38).
?DOC(false).
-spec on_connect(
type_cache(),
fun(() -> {ok, pgl@internal@socket:socket()} | {error, nil})
) -> type_cache().
on_connect(Type_cache, Handle_connect) ->
{type_cache, erlang:element(2, Type_cache), Handle_connect}.
-file("src/pgl/internal/type_cache.gleam", 67).
?DOC(false).
-spec load(type_cache()) -> {ok, nil} | {error, nil}.
load(Type_cache) ->
_pipe = (erlang:element(3, Type_cache))(),
_pipe@1 = gleam@result:map_error(_pipe, fun(_) -> nil end),
gleam@result:'try'(
_pipe@1,
fun(Sock) ->
Res = begin
_pipe@2 = erlang:element(2, Type_cache),
_pipe@3 = gleam@erlang@process:named_subject(_pipe@2),
gleam@otp@actor:call(
_pipe@3,
1000,
fun(_capture) -> {load, _capture, Sock} end
)
end,
_ = pgl@internal@socket:shutdown(Sock),
Res
end
).
-file("src/pgl/internal/type_cache.gleam", 81).
?DOC(false).
-spec lookup(type_cache(), list(integer())) -> {ok,
list(pg_value@type_info:type_info())} |
{error, nil}.
lookup(Type_cache, Oids) ->
Do_lookup = fun(Oids@1) -> _pipe = erlang:element(2, Type_cache),
_pipe@1 = gleam@erlang@process:named_subject(_pipe),
gleam@otp@actor:call(
_pipe@1,
1000,
fun(_capture) -> {lookup, _capture, Oids@1} end
) end,
_pipe@2 = Do_lookup(Oids),
gleam@result:lazy_or(_pipe@2, fun() -> _pipe@3 = load(Type_cache),
gleam@result:'try'(_pipe@3, fun(_) -> Do_lookup(Oids) end) end).
-file("src/pgl/internal/type_cache.gleam", 98).
?DOC(false).
-spec shutdown(type_cache()) -> nil.
shutdown(Type_cache) ->
_pipe = gleam@erlang@process:named_subject(erlang:element(2, Type_cache)),
gleam@otp@actor:send(_pipe, shutdown).
-file("src/pgl/internal/type_cache.gleam", 143).
?DOC(false).
-spec handle_lookup(
rasa@table:table(integer(), pg_value@type_info:type_info()),
list(integer()),
gleam@erlang@process:subject({ok, list(pg_value@type_info:type_info())} |
{error, nil})
) -> gleam@otp@actor:next(rasa@table:table(integer(), pg_value@type_info:type_info()), any()).
handle_lookup(Table, Oids, Client) ->
_pipe = Oids,
_pipe@1 = gleam@list:try_map(
_pipe,
fun(_capture) -> rasa@table:lookup(Table, _capture) end
),
gleam@otp@actor:send(Client, _pipe@1),
gleam@otp@actor:continue(Table).
-file("src/pgl/internal/type_cache.gleam", 155).
?DOC(false).
-spec parse_type_infos(
rasa@table:table(integer(), pg_value@type_info:type_info()),
list(pg_value@type_info:type_info())
) -> rasa@table:table(integer(), pg_value@type_info:type_info()).
parse_type_infos(Table, Infos) ->
Oid_to_info = begin
_pipe = Infos,
_pipe@1 = gleam@list:map(
_pipe,
fun(Ti) -> {erlang:element(2, Ti), Ti} end
),
maps:from_list(_pipe@1)
end,
_pipe@2 = Oid_to_info,
gleam@dict:fold(
_pipe@2,
Table,
fun(Table@1, Oid, Info) ->
_ = begin
_pipe@3 = erlang:element(12, Info),
_pipe@4 = gleam@list:try_map(
_pipe@3,
fun(_capture) ->
gleam_stdlib:map_get(Oid_to_info, _capture)
end
),
_pipe@7 = gleam@result:'try'(
_pipe@4,
fun(Comp_types) ->
gleam@result:map(
gleam_stdlib:map_get(
Oid_to_info,
erlang:element(9, Info)
),
fun(Elem_type) -> _pipe@5 = Info,
_pipe@6 = pg_value@type_info:elem_type(
_pipe@5,
{some, Elem_type}
),
pg_value@type_info:comp_types(
_pipe@6,
{some, Comp_types}
) end
)
end
),
_pipe@8 = gleam@result:unwrap(_pipe@7, Info),
rasa@table:insert(Table@1, Oid, _pipe@8)
end,
Table@1
end
).
-file("src/pgl/internal/type_cache.gleam", 238).
?DOC(false).
-spec do_parse_comp_oids(binary()) -> {ok, list(integer())} | {error, nil}.
do_parse_comp_oids(Oids) ->
_pipe = gleam@string:split(Oids, <<"}"/utf8>>),
_pipe@1 = gleam@list:first(_pipe),
gleam@result:'try'(
_pipe@1,
fun(Oids1) -> _pipe@2 = gleam@string:split(Oids1, <<","/utf8>>),
_pipe@4 = gleam@list:try_fold(
_pipe@2,
[],
fun(Acc, Oid) -> _pipe@3 = gleam_stdlib:parse_int(Oid),
gleam@result:map(
_pipe@3,
fun(_capture) -> gleam@list:prepend(Acc, _capture) end
) end
),
gleam@result:map(_pipe@4, fun lists:reverse/1) end
).
-file("src/pgl/internal/type_cache.gleam", 225).
?DOC(false).
-spec parse_comp_oids(bitstring()) -> {ok, list(integer())} | {error, nil}.
parse_comp_oids(Bits) ->
case Bits of
<<0>> ->
{ok, []};
<<>> ->
{ok, []};
<<"{}"/utf8>> ->
{ok, []};
<<"{"/utf8, Rest/bitstring>> ->
_pipe = gleam@bit_array:to_string(Rest),
gleam@result:'try'(_pipe, fun do_parse_comp_oids/1);
_ ->
{error, nil}
end.
-file("src/pgl/internal/type_cache.gleam", 251).
?DOC(false).
-spec bits_to_int(bitstring()) -> {ok, integer()} | {error, nil}.
bits_to_int(Bits) ->
_pipe = gleam@bit_array:to_string(Bits),
gleam@result:'try'(_pipe, fun gleam_stdlib:parse_int/1).
-file("src/pgl/internal/type_cache.gleam", 255).
?DOC(false).
-spec bits_to_oid(bitstring()) -> {ok, integer()} | {error, nil}.
bits_to_oid(Bits) ->
bits_to_int(Bits).
-file("src/pgl/internal/type_cache.gleam", 183).
?DOC(false).
-spec parse_type_info(list(gleam@option:option(bitstring()))) -> {ok,
pg_value@type_info:type_info()} |
{error, nil}.
parse_type_info(Row) ->
case Row of
[{some, <<Oid/bitstring>>},
{some, <<Name/bitstring>>},
{some, <<Typesend/bitstring>>},
{some, <<Typereceive/bitstring>>},
{some, <<Typelen/bitstring>>},
{some, <<Output/bitstring>>},
{some, <<Input/bitstring>>},
{some, <<Elem_oid/bitstring>>},
{some, <<Base_oid/bitstring>>},
{some, <<Comp_oids/bitstring>>}] ->
begin
gleam@result:'try'(
bits_to_oid(Oid),
fun(Oid@1) ->
gleam@result:'try'(
gleam@bit_array:to_string(Name),
fun(Name@1) ->
gleam@result:'try'(
gleam@bit_array:to_string(Typesend),
fun(Typesend@1) ->
gleam@result:'try'(
gleam@bit_array:to_string(
Typereceive
),
fun(Typereceive@1) ->
gleam@result:'try'(
bits_to_int(Typelen),
fun(Typelen@1) ->
gleam@result:'try'(
gleam@bit_array:to_string(
Output
),
fun(Output@1) ->
gleam@result:'try'(
gleam@bit_array:to_string(
Input
),
fun(Input@1) ->
gleam@result:'try'(
bits_to_oid(
Elem_oid
),
fun(
Elem_oid@1
) ->
gleam@result:'try'(
bits_to_oid(
Base_oid
),
fun(
Base_oid@1
) ->
gleam@result:map(
parse_comp_oids(
Comp_oids
),
fun(
Comp_oids@1
) ->
_pipe = pg_value@type_info:new(
Oid@1
),
_pipe@1 = pg_value@type_info:name(
_pipe,
Name@1
),
_pipe@2 = pg_value@type_info:typesend(
_pipe@1,
Typesend@1
),
_pipe@3 = pg_value@type_info:typereceive(
_pipe@2,
Typereceive@1
),
_pipe@4 = pg_value@type_info:typelen(
_pipe@3,
Typelen@1
),
_pipe@5 = pg_value@type_info:output(
_pipe@4,
Output@1
),
_pipe@6 = pg_value@type_info:input(
_pipe@5,
Input@1
),
_pipe@7 = pg_value@type_info:elem_oid(
_pipe@6,
Elem_oid@1
),
_pipe@8 = pg_value@type_info:base_oid(
_pipe@7,
Base_oid@1
),
pg_value@type_info:comp_oids(
_pipe@8,
Comp_oids@1
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end;
_ ->
{error, nil}
end.
-file("src/pgl/internal/type_cache.gleam", 32).
?DOC(false).
-spec new() -> type_cache().
new() ->
_pipe = <<"pgl_type_cache"/utf8>>,
_pipe@1 = gleam_erlang_ffi:new_name(_pipe),
{type_cache, _pipe@1, fun() -> {error, nil} end}.
-file("src/pgl/internal/type_cache.gleam", 113).
?DOC(false).
-spec handle_load(
rasa@table:table(integer(), pg_value@type_info:type_info()),
pgl@internal@socket:socket(),
gleam@erlang@process:subject({ok, nil} | {error, nil})
) -> gleam@otp@actor:next(rasa@table:table(integer(), pg_value@type_info:type_info()), any()).
handle_load(Table, Sock, Client) ->
_pipe = <<"SELECT t.oid AS oid, t.typname AS name, t.typsend AS typesend, t.typreceive AS typereceive, t.typlen AS typelen, t.typoutput AS output, t.typinput AS input, t.typelem AS elem_oid, coalesce(r.rngsubtype, 0) AS base_oid, ARRAY (SELECT a.atttypid FROM pg_attribute AS a WHERE a.attrelid = t.typrelid AND a.attnum > 0 AND NOT a.attisdropped ORDER BY a.attnum) AS comp_oids FROM pg_type AS t LEFT JOIN pg_range AS r ON r.rngtypid = t.oid OR (t.typbasetype <> 0 AND r.rngtypid = t.typbasetype) ORDER BY t.oid"/utf8>>,
_pipe@1 = pgl@internal@encode:'query'(_pipe),
_pipe@2 = pgl@internal@protocol:simple(_pipe@1, Sock),
_pipe@3 = gleam@result:map(
_pipe@2,
fun(Rows) -> case gleam@list:try_map(Rows, fun parse_type_info/1) of
{ok, Infos} ->
gleam@otp@actor:send(Client, {ok, nil}),
parse_type_infos(Table, Infos);
{error, _} ->
gleam@otp@actor:send(Client, {error, nil}),
Table
end end
),
_pipe@4 = gleam@result:lazy_unwrap(
_pipe@3,
fun() ->
gleam@otp@actor:send(Client, {error, nil}),
Table
end
),
gleam@otp@actor:continue(_pipe@4).
-file("src/pgl/internal/type_cache.gleam", 102).
?DOC(false).
-spec handle_message(
rasa@table:table(integer(), pg_value@type_info:type_info()),
message()
) -> gleam@otp@actor:next(rasa@table:table(integer(), pg_value@type_info:type_info()), any()).
handle_message(Table, Message) ->
case Message of
{load, Client, Sock} ->
handle_load(Table, Sock, Client);
{lookup, Client@1, Oids} ->
handle_lookup(Table, Oids, Client@1);
shutdown ->
gleam@otp@actor:stop()
end.
-file("src/pgl/internal/type_cache.gleam", 45).
?DOC(false).
-spec start(type_cache()) -> {ok, gleam@otp@actor:started(nil)} |
{error, gleam@otp@actor:start_error()}.
start(Type_cache) ->
_pipe@6 = gleam@otp@actor:new_with_initialiser(
1000,
fun(Subj) ->
Selector = begin
_pipe = gleam_erlang_ffi:new_selector(),
gleam@erlang@process:select(_pipe, Subj)
end,
_pipe@1 = rasa@table:new(),
_pipe@2 = rasa@table:with_access(_pipe@1, private),
_pipe@3 = rasa@table:build(_pipe@2),
_pipe@4 = gleam@otp@actor:initialised(_pipe@3),
_pipe@5 = gleam@otp@actor:selecting(_pipe@4, Selector),
{ok, _pipe@5}
end
),
_pipe@7 = gleam@otp@actor:named(_pipe@6, erlang:element(2, Type_cache)),
_pipe@8 = gleam@otp@actor:on_message(_pipe@7, fun handle_message/2),
gleam@otp@actor:start(_pipe@8).
-file("src/pgl/internal/type_cache.gleam", 61).
?DOC(false).
-spec supervised(type_cache()) -> gleam@otp@supervision:child_specification(nil).
supervised(Type_cache) ->
_pipe = gleam@otp@supervision:worker(fun() -> start(Type_cache) end),
_pipe@1 = gleam@otp@supervision:timeout(_pipe, 1000),
gleam@otp@supervision:restart(_pipe@1, transient).