Current section
Files
Jump to
Current section
Files
src/based.erl
-module(based).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([register/2, new_query/1, with_values/2, execute/2, string/1, decode/2, all/3, one/3, int/1, float/1, bool/1, null/0]).
-export_type([value/0, based_error/0, 'query'/0, based_adapter/3, returned/1, db/0, message/0]).
-type value() :: {string, binary()} |
{int, integer()} |
{float, float()} |
{bool, boolean()} |
null.
-type based_error() :: {based_error, binary(), binary(), binary()}.
-type 'query'() :: {'query', binary(), list(value())}.
-type based_adapter(HFB, HFC, HFD) :: {based_adapter,
fun((HFB, fun((HFC) -> HFD)) -> HFD),
HFB,
fun(('query'(), HFC) -> {ok, list(gleam@dynamic:dynamic_())} |
{error, based_error()})}.
-type returned(HFE) :: {returned, integer(), list(HFE)}.
-opaque db() :: {db, gleam@erlang@process:subject(message())}.
-type message() :: {execute,
gleam@erlang@process:subject({ok, list(gleam@dynamic:dynamic_())} |
{error, based_error()}),
'query'()} |
shutdown.
-spec shutdown(gleam@erlang@process:subject(message())) -> nil.
shutdown(Actor) ->
gleam@erlang@process:send(Actor, shutdown).
-spec handle_message(
message(),
{HFY,
fun(('query'(), HFY) -> {ok, list(gleam@dynamic:dynamic_())} |
{error, based_error()})}
) -> gleam@otp@actor:next(message(), {HFY,
fun(('query'(), HFY) -> {ok, list(gleam@dynamic:dynamic_())} |
{error, based_error()})}).
handle_message(Message, Backend) ->
case Message of
shutdown ->
{stop, normal};
{execute, Client, Query} ->
{Conn, Service} = Backend,
gleam@erlang@process:send(Client, Service(Query, Conn)),
gleam@otp@actor:continue(Backend)
end.
-spec start(
HFS,
fun(('query'(), HFS) -> {ok, list(gleam@dynamic:dynamic_())} |
{error, based_error()})
) -> {ok, gleam@erlang@process:subject(message())} |
{error, gleam@otp@actor:start_error()}.
start(Conn, Service) ->
gleam@otp@actor:start({Conn, Service}, fun handle_message/2).
-spec register(based_adapter(any(), any(), HFO), fun((db()) -> HFO)) -> HFO.
register(Based_adapter, Callback) ->
{based_adapter, With_connection, Conf, Service} = Based_adapter,
With_connection(
Conf,
fun(Connection) ->
_assert_subject = start(Connection, Service),
{ok, Actor} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"based"/utf8>>,
function => <<"register"/utf8>>,
line => 68})
end,
Result = Callback({db, Actor}),
shutdown(Actor),
Result
end
).
-spec new_query(binary()) -> 'query'().
new_query(Sql) ->
{'query', Sql, []}.
-spec with_values('query'(), list(value())) -> 'query'().
with_values(Query, Values) ->
{'query',
erlang:element(2, Query),
lists:append(erlang:element(3, Query), Values)}.
-spec execute('query'(), db()) -> {ok, list(gleam@dynamic:dynamic_())} |
{error, based_error()}.
execute(Query, Db) ->
{db, Subject} = Db,
gleam@erlang@process:call(
Subject,
fun(_capture) -> {execute, _capture, Query} end,
100
).
-spec string(binary()) -> value().
string(Value) ->
{string, Value}.
-spec decode_error(list(gleam@dynamic:decode_error())) -> based_error().
decode_error(Errors) ->
[{decode_error, Expected, Actual, Path} | _] = case Errors of
[{decode_error, _, _, _} | _] -> Errors;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"based"/utf8>>,
function => <<"decode_error"/utf8>>,
line => 171})
end,
Path@1 = gleam@string:join(Path, <<"."/utf8>>),
Message = <<<<<<<<<<"Decoder failed, expected "/utf8, Expected/binary>>/binary,
", got "/utf8>>/binary,
Actual/binary>>/binary,
" in "/utf8>>/binary,
Path@1/binary>>,
{based_error, <<""/utf8>>, <<"decode_error"/utf8>>, Message}.
-spec decode(
list(gleam@dynamic:dynamic_()),
fun((gleam@dynamic:dynamic_()) -> {ok, HGR} |
{error, list(gleam@dynamic:decode_error())})
) -> {ok, returned(HGR)} | {error, based_error()}.
decode(Rows, Decoder) ->
gleam@result:'try'(
begin
_pipe = gleam@list:try_map(Rows, Decoder),
gleam@result:map_error(_pipe, fun decode_error/1)
end,
fun(Rows@1) -> _pipe@1 = erlang:length(Rows@1),
_pipe@2 = {returned, _pipe@1, Rows@1},
{ok, _pipe@2} end
).
-spec all(
'query'(),
db(),
fun((gleam@dynamic:dynamic_()) -> {ok, HGE} |
{error, list(gleam@dynamic:decode_error())})
) -> {ok, returned(HGE)} | {error, based_error()}.
all(Query, Db, Decoder) ->
gleam@result:'try'(
execute(Query, Db),
fun(Rows) -> decode(Rows, Decoder) end
).
-spec one(
'query'(),
db(),
fun((gleam@dynamic:dynamic_()) -> {ok, HGJ} |
{error, list(gleam@dynamic:decode_error())})
) -> {ok, HGJ} | {error, based_error()}.
one(Query, Db, Decoder) ->
gleam@result:'try'(
execute(Query, Db),
fun(Rows) ->
Returned = decode(Rows, Decoder),
gleam@result:'try'(
Returned,
fun(Returned@1) ->
{returned, _, Rows@1} = Returned@1,
gleam@result:'try'(
begin
_pipe = Rows@1,
_pipe@1 = gleam@list:first(_pipe),
gleam@result:replace_error(
_pipe@1,
{based_error,
<<""/utf8>>,
<<"not_found"/utf8>>,
<<"Expected one row but found none"/utf8>>}
)
end,
fun(Row) -> {ok, Row} end
)
end
)
end
).
-spec int(integer()) -> value().
int(Value) ->
{int, Value}.
-spec float(float()) -> value().
float(Value) ->
{float, Value}.
-spec bool(boolean()) -> value().
bool(Value) ->
{bool, Value}.
-spec null() -> value().
null() ->
null.