-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, <>}, {some, <>}, {some, <>}, {some, <>}, {some, <>}, {some, <>}, {some, <>}, {some, <>}, {some, <>}, {some, <>}] -> 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).