-module(squirrel@internal@query). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([add_types/3, string/1, var/2, list/1, 'fun'/3, record/2, decoder/2, pipe_call/3, to_function/1, from_file/1]). -export_type(['query'/0, typed_query/0]). -type 'query'() :: {'query', binary(), binary(), binary()}. -type typed_query() :: {typed_query, binary(), binary(), binary(), list(squirrel@internal@gleam:type()), list(squirrel@internal@gleam:field())}. -spec add_types( 'query'(), list(squirrel@internal@gleam:type()), list(squirrel@internal@gleam:field()) ) -> typed_query(). add_types(Query, Params, Returns) -> {'query', File, Name, Content} = Query, {typed_query, File, Name, Content, Params, Returns}. -spec take_name(bitstring(), bitstring(), integer()) -> binary(). take_name(Original, String, Size) -> case String of <<>> -> _assert_subject = gleam_stdlib:bit_array_slice(Original, 0, Size), {ok, Name} = 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 => <<"squirrel/internal/query"/utf8>>, function => <<"take_name"/utf8>>, line => 95}) end, _assert_subject@1 = gleam@bit_array:to_string(Name), {ok, Name@1} = case _assert_subject@1 of {ok, _} -> _assert_subject@1; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@1, module => <<"squirrel/internal/query"/utf8>>, function => <<"take_name"/utf8>>, line => 96}) end, gleam@string:trim(Name@1); <<"\n"/utf8, _/bitstring>> -> _assert_subject = gleam_stdlib:bit_array_slice(Original, 0, Size), {ok, Name} = 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 => <<"squirrel/internal/query"/utf8>>, function => <<"take_name"/utf8>>, line => 95}) end, _assert_subject@1 = gleam@bit_array:to_string(Name), {ok, Name@1} = case _assert_subject@1 of {ok, _} -> _assert_subject@1; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@1, module => <<"squirrel/internal/query"/utf8>>, function => <<"take_name"/utf8>>, line => 96}) end, gleam@string:trim(Name@1); <<_, Rest/bitstring>> -> take_name(Original, Rest, Size + 1); _ -> erlang:error(#{gleam_error => panic, message => <<"non byte aligned Gleam String"/utf8>>, module => <<"squirrel/internal/query"/utf8>>, function => <<"take_name"/utf8>>, line => 100}) end. -spec name_comment(bitstring()) -> {ok, binary()} | {error, nil}. name_comment(String) -> case String of <<" "/utf8, Rest/bitstring>> -> name_comment(Rest); <<"\t"/utf8, Rest/bitstring>> -> name_comment(Rest); <<"\r"/utf8, Rest/bitstring>> -> name_comment(Rest); <<"name:"/utf8, Rest@1/bitstring>> -> {ok, take_name(Rest@1, Rest@1, 0)}; <<_, _/bitstring>> -> {error, nil}; <<>> -> {error, nil}; _ -> erlang:error(#{gleam_error => panic, message => <<"non byte aligned Gleam String"/utf8>>, module => <<"squirrel/internal/query"/utf8>>, function => <<"name_comment"/utf8>>, line => 88}) end. -spec gleam_type_to_decoder(squirrel@internal@gleam:type()) -> binary(). gleam_type_to_decoder(Type_) -> case Type_ of {list, Type_@1} -> <<<<"decode.list("/utf8, (gleam_type_to_decoder(Type_@1))/binary>>/binary, ")"/utf8>>; int -> <<"decode.int"/utf8>>; float -> <<"decode.float"/utf8>>; bool -> <<"decode.bool"/utf8>>; string -> <<"decode.string"/utf8>>; {option, Type_@2} -> <<<<"decode.option("/utf8, (gleam_type_to_decoder(Type_@2))/binary>>/binary, ")"/utf8>> end. -spec gleam_type_to_encoder(squirrel@internal@gleam:type(), binary()) -> binary(). gleam_type_to_encoder(Type_, Name) -> case Type_ of {list, Type_@1} -> <<<<"pgo.array(list.map(name, fn(a) {"/utf8, (gleam_type_to_encoder(Type_@1, <<"a"/utf8>>))/binary>>/binary, "}))"/utf8>>; {option, Type_@2} -> <<<<<<<<"pgo.nullable(fn(a) {"/utf8, (gleam_type_to_encoder(Type_@2, <<"a"/utf8>>))/binary>>/binary, "}, "/utf8>>/binary, Name/binary>>/binary, ")"/utf8>>; int -> <<<<"pgo.int("/utf8, Name/binary>>/binary, ")"/utf8>>; float -> <<<<"pgo.float("/utf8, Name/binary>>/binary, ")"/utf8>>; bool -> <<<<"pgo.bool("/utf8, Name/binary>>/binary, ")"/utf8>>; string -> <<<<"pgo.text("/utf8, Name/binary>>/binary, ")"/utf8>> end. -spec string(binary()) -> glam@doc:document(). string(Content) -> Escaped_string = begin _pipe = Content, _pipe@1 = gleam@string:replace(_pipe, <<"\\"/utf8>>, <<"\\\\"/utf8>>), _pipe@2 = gleam@string:replace(_pipe@1, <<"\""/utf8>>, <<"\\\""/utf8>>), glam@doc:from_string(_pipe@2) end, _pipe@3 = [glam@doc:from_string(<<"\""/utf8>>), Escaped_string, glam@doc:from_string(<<"\""/utf8>>)], glam@doc:concat(_pipe@3). -spec var(binary(), glam@doc:document()) -> glam@doc:document(). var(Name, Body) -> _pipe@3 = [glam@doc:from_string( <<<<"let "/utf8, Name/binary>>/binary, " ="/utf8>> ), begin _pipe = [{break, <<" "/utf8>>, <<""/utf8>>}, Body], _pipe@1 = glam@doc:concat(_pipe), _pipe@2 = glam@doc:group(_pipe@1), glam@doc:nest(_pipe@2, 2) end], glam@doc:concat(_pipe@3). -spec block(list(glam@doc:document())) -> glam@doc:document(). block(Body) -> _pipe@2 = [glam@doc:from_string(<<"{"/utf8>>), begin _pipe = [{line, 1} | Body], _pipe@1 = glam@doc:concat(_pipe), glam@doc:nest(_pipe@1, 2) end, {line, 1}, glam@doc:from_string(<<"}"/utf8>>)], _pipe@3 = glam@doc:concat(_pipe@2), glam@doc:force_break(_pipe@3). -spec call_block(binary(), list(glam@doc:document())) -> glam@doc:document(). call_block(Function, Body) -> _pipe = [glam@doc:from_string(<>), block(Body), glam@doc:from_string(<<")"/utf8>>)], _pipe@1 = glam@doc:concat(_pipe), glam@doc:group(_pipe@1). -spec comma_list(binary(), list(glam@doc:document()), binary()) -> glam@doc:document(). comma_list(Open, Content, Close) -> _pipe@3 = [glam@doc:from_string(Open), begin _pipe = [{break, <<""/utf8>>, <<""/utf8>>}, glam@doc:join( Content, glam@doc:break(<<", "/utf8>>, <<","/utf8>>) )], _pipe@1 = glam@doc:concat(_pipe), _pipe@2 = glam@doc:group(_pipe@1), glam@doc:nest(_pipe@2, 2) end, glam@doc:break(<<""/utf8>>, <<","/utf8>>), glam@doc:from_string(Close)], _pipe@4 = glam@doc:concat(_pipe@3), glam@doc:group(_pipe@4). -spec list(list(glam@doc:document())) -> glam@doc:document(). list(Elems) -> comma_list(<<"["/utf8>>, Elems, <<"]"/utf8>>). -spec 'fun'(binary(), list(binary()), list(glam@doc:document())) -> glam@doc:document(). 'fun'(Name, Args, Body) -> Args@1 = gleam@list:map(Args, fun glam@doc:from_string/1), _pipe@1 = [glam@doc:from_string(<<"pub fn "/utf8, Name/binary>>), comma_list(<<"("/utf8>>, Args@1, <<") "/utf8>>), block( [begin _pipe = Body, glam@doc:join(_pipe, glam@doc:lines(2)) end] ), {line, 1}], _pipe@2 = glam@doc:concat(_pipe@1), glam@doc:group(_pipe@2). -spec call(binary(), list(glam@doc:document())) -> glam@doc:document(). call(Function, Args) -> _pipe = [glam@doc:from_string(Function), comma_list(<<"("/utf8>>, Args, <<")"/utf8>>)], _pipe@1 = glam@doc:concat(_pipe), glam@doc:group(_pipe@1). -spec pretty_gleam_type(squirrel@internal@gleam:type()) -> glam@doc:document(). pretty_gleam_type(Type_) -> case Type_ of {list, Type_@1} -> call(<<"List"/utf8>>, [pretty_gleam_type(Type_@1)]); {option, Type_@2} -> call(<<"Option"/utf8>>, [pretty_gleam_type(Type_@2)]); int -> glam@doc:from_string(<<"Int"/utf8>>); float -> glam@doc:from_string(<<"Float"/utf8>>); bool -> glam@doc:from_string(<<"Bool"/utf8>>); string -> glam@doc:from_string(<<"String"/utf8>>) end. -spec record(binary(), list(squirrel@internal@gleam:field())) -> glam@doc:document(). record(Name, Fields) -> Fields@1 = gleam@list:map( Fields, fun(Field) -> _pipe = [glam@doc:from_string( <<(erlang:element(2, Field))/binary, ": "/utf8>> ), pretty_gleam_type(erlang:element(3, Field))], _pipe@1 = glam@doc:concat(_pipe), glam@doc:group(_pipe@1) end ), _pipe@4 = [glam@doc:from_string( <<<<"pub type "/utf8, Name/binary>>/binary, " {"/utf8>> ), begin _pipe@2 = [{line, 1}, call(Name, Fields@1)], _pipe@3 = glam@doc:concat(_pipe@2), glam@doc:nest(_pipe@3, 2) end, {line, 1}, glam@doc:from_string(<<"}"/utf8>>)], _pipe@5 = glam@doc:concat(_pipe@4), glam@doc:group(_pipe@5). -spec decoder(binary(), list(squirrel@internal@gleam:field())) -> glam@doc:document(). decoder(Constructor, Returns) -> Parameters = gleam@list:map( Returns, fun(Field) -> glam@doc:from_string( <<<<"use "/utf8, (erlang:element(2, Field))/binary>>/binary, " <- decode.parameter"/utf8>> ) end ), Pipes = gleam@list:index_map( Returns, fun(Field@1, I) -> Position = begin _pipe = gleam@int:to_string(I), glam@doc:from_string(_pipe) end, Decoder = begin _pipe@1 = gleam_type_to_decoder(erlang:element(3, Field@1)), glam@doc:from_string(_pipe@1) end, call(<<"|> decode.field"/utf8>>, [Position, Decoder]) end ), Labelled_names = gleam@list:map( Returns, fun(Field@2) -> glam@doc:from_string( <<<<(erlang:element(2, Field@2))/binary, ": "/utf8>>/binary, (erlang:element(2, Field@2))/binary>> ) end ), _pipe@2 = [call_block( <<"decode.into"/utf8>>, [glam@doc:join(Parameters, {line, 1}), {line, 1}, call(Constructor, Labelled_names)] ), {line, 1}, glam@doc:join(Pipes, {line, 1})], _pipe@3 = glam@doc:concat(_pipe@2), glam@doc:group(_pipe@3). -spec pipe_call(binary(), glam@doc:document(), list(glam@doc:document())) -> glam@doc:document(). pipe_call(Function, First, Rest) -> _pipe = [First, {line, 1}, call(<<"|> "/utf8, Function/binary>>, Rest)], glam@doc:concat(_pipe). -spec to_function(typed_query()) -> binary(). to_function(Query) -> {typed_query, File, Name, Content, Params, Returns} = Query, Arg_name = fun(I) -> <<"arg_"/utf8, (gleam@int:to_string(I + 1))/binary>> end, Inputs = gleam@list:index_map(Params, fun(_, I@1) -> Arg_name(I@1) end), Inputs_encoders = gleam@list:index_map( Params, fun(P, I@2) -> _pipe = gleam_type_to_encoder(P, Arg_name(I@2)), glam@doc:from_string(_pipe) end ), Record_doc = <<<<<<<<"/// A row you get from running the `"/utf8, Name/binary>>/binary, "` query /// defined in `"/utf8>>/binary, File/binary>>/binary, "`. /// /// > 🐿️ This type definition was generated automatically using v1.0.0 of the /// > [squirrel package](link!!). ///"/utf8>>, Fun_doc = <<<<<<<<"/// Runs the `"/utf8, Name/binary>>/binary, "` query /// defined in `"/utf8>>/binary, File/binary>>/binary, "`. /// /// > 🐿️ This function was generated automatically using v1.0.0 of the /// > [squirrel package](link!!). ///"/utf8>>, Name@1 = squirrel@internal@gleam:to_function_name(Name), Constructor_name = <<(justin:pascal_case(Name@1))/binary, "Row"/utf8>>, _pipe@1 = [glam@doc:from_string(Record_doc), {line, 1}, record(Constructor_name, Returns), glam@doc:lines(2), glam@doc:from_string(Fun_doc), {line, 1}, 'fun'( Name@1, [<<"db"/utf8>> | Inputs], [var(<<"decoder"/utf8>>, decoder(Constructor_name, Returns)), pipe_call( <<"pgo.execute"/utf8>>, string(Content), [glam@doc:from_string(<<"db"/utf8>>), list(Inputs_encoders), glam@doc:from_string(<<"decode.from(decoder, _)"/utf8>>)] )] )], _pipe@2 = glam@doc:concat(_pipe@1), glam@doc:to_string(_pipe@2, 80). -spec parse_query( binary(), bitstring(), bitstring(), binary(), integer(), integer(), list('query'()) ) -> list('query'()). parse_query(File, Original, String, Name, Start, Position, Queries) -> case String of <<>> -> _assert_subject = gleam_stdlib:bit_array_slice( Original, Start, Position - Start ), {ok, Query} = 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 => <<"squirrel/internal/query"/utf8>>, function => <<"parse_query"/utf8>>, line => 115}) end, _assert_subject@1 = gleam@bit_array:to_string(Query), {ok, Content} = case _assert_subject@1 of {ok, _} -> _assert_subject@1; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@1, module => <<"squirrel/internal/query"/utf8>>, function => <<"parse_query"/utf8>>, line => 116}) end, Query@1 = {'query', File, Name, Content}, lists:reverse([Query@1 | Queries]); <<"--"/utf8, Rest/bitstring>> -> case name_comment(Rest) of {error, _} -> parse_query( File, Original, Rest, Name, Start, Position + 2, Queries ); {ok, _} -> _assert_subject@2 = gleam_stdlib:bit_array_slice( Original, Start, Position - Start ), {ok, Query@2} = case _assert_subject@2 of {ok, _} -> _assert_subject@2; _assert_fail@2 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@2, module => <<"squirrel/internal/query"/utf8>>, function => <<"parse_query"/utf8>>, line => 127}) end, _assert_subject@3 = gleam@bit_array:to_string(Query@2), {ok, Content@1} = case _assert_subject@3 of {ok, _} -> _assert_subject@3; _assert_fail@3 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@3, module => <<"squirrel/internal/query"/utf8>>, function => <<"parse_query"/utf8>>, line => 129}) end, Query@3 = {'query', File, Name, Content@1}, parse_queries( File, Original, String, Position, [Query@3 | Queries] ) end; <<_, Rest@1/bitstring>> -> parse_query( File, Original, Rest@1, Name, Start, Position + 1, Queries ); _ -> erlang:error(#{gleam_error => panic, message => <<"non byte aligned Gleam String"/utf8>>, module => <<"squirrel/internal/query"/utf8>>, function => <<"parse_query"/utf8>>, line => 138}) end. -spec parse_queries( binary(), bitstring(), bitstring(), integer(), list('query'()) ) -> list('query'()). parse_queries(File, Original, String, Position, Queries) -> case String of <<>> -> lists:reverse(Queries); <<"--"/utf8, Rest/bitstring>> -> case name_comment(Rest) of {error, _} -> parse_queries(File, Original, Rest, Position + 2, Queries); {ok, Name} -> parse_query( File, Original, Rest, Name, Position, Position + 2, Queries ) end; <<_, Rest@1/bitstring>> -> parse_queries(File, Original, Rest@1, Position + 1, Queries); _ -> erlang:error(#{gleam_error => panic, message => <<"non byte aligned Gleam String"/utf8>>, module => <<"squirrel/internal/query"/utf8>>, function => <<"parse_queries"/utf8>>, line => 73}) end. -spec from_file(binary()) -> {ok, list('query'())} | {error, simplifile:file_error()}. from_file(File) -> gleam@result:map( simplifile:read(File), fun(Content) -> Content@1 = <>, parse_queries(File, Content@1, Content@1, 0, []) end ).