-module(parrot@codegen). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([gleam_type_to_string/1, sqlc_type_to_gleam/1, gen_column_name/2, gen_query_type/1, gen_query_function/1, gen_query_decoder/1, comment_dont_edit/0, gen_gleam_module/1, codegen_from_config/1]). -export_type([gleam_type/0]). -type gleam_type() :: gleam_string | gleam_int | gleam_float | gleam_bool | gleam_timestamp | gleam_dynamic. -file("src/parrot/codegen.gleam", 70). -spec gleam_type_to_string(gleam_type()) -> binary(). gleam_type_to_string(Gleamtype) -> case Gleamtype of gleam_bool -> <<"Bool"/utf8>>; gleam_float -> <<"Float"/utf8>>; gleam_int -> <<"Int"/utf8>>; gleam_string -> <<"String"/utf8>>; gleam_timestamp -> <<"Timestamp"/utf8>>; gleam_dynamic -> <<"decode.Dynamic"/utf8>> end. -file("src/parrot/codegen.gleam", 81). -spec sqlc_type_to_gleam(binary()) -> gleam_type(). sqlc_type_to_gleam(Sqltype) -> Sqltype@1 = case Sqltype of <<"pg_catalog."/utf8, X/binary>> -> X; X@1 -> X@1 end, case string:lowercase(Sqltype@1) of <<"int"/utf8, _/binary>> -> gleam_int; <<"integer"/utf8>> -> gleam_int; <<"bigint"/utf8>> -> gleam_int; <<"bigserial"/utf8>> -> gleam_int; <<"float"/utf8>> -> gleam_float; <<"decimal"/utf8>> -> gleam_float; <<"real"/utf8>> -> gleam_float; <<"numeric"/utf8>> -> gleam_float; <<"double precision"/utf8>> -> gleam_float; <<"smallserial"/utf8>> -> gleam_float; <<"serial"/utf8>> -> gleam_float; <<"bigserial"/utf8>> -> gleam_float; <<"text"/utf8>> -> gleam_string; <<"varchar"/utf8>> -> gleam_string; <<"uuid"/utf8>> -> gleam_string; <<"datetime"/utf8>> -> gleam_timestamp; <<"timestamp"/utf8>> -> gleam_timestamp; _ -> gleam_dynamic end. -file("src/parrot/codegen.gleam", 102). -spec gen_column_name( parrot@internal@sqlc:'query'(), parrot@internal@sqlc:table_column() ) -> binary(). gen_column_name(Query, Col) -> Occ = begin _pipe = erlang:element(6, Query), gleam@list:count( _pipe, fun(Col2) -> erlang:element(2, Col) =:= erlang:element(2, Col2) end ) end, Result = case Occ of 0 -> erlang:error(#{gleam_error => panic, message => <<"could not find column name"/utf8>>, module => <<"parrot/codegen"/utf8>>, function => <<"gen_column_name"/utf8>>, line => 107}); 1 -> erlang:element(2, Col); _ -> case erlang:element(15, Col) of none -> erlang:element(2, Col); {some, T} -> <<<<(erlang:element(4, T))/binary, "_"/utf8>>/binary, (erlang:element(2, Col))/binary>> end end, parrot@internal@string_case:snake_case(Result). -file("src/parrot/codegen.gleam", 119). -spec gen_query_type(parrot@internal@sqlc:'query'()) -> binary(). gen_query_type(Query) -> Name = parrot@internal@string_case:pascal_case(erlang:element(3, Query)), Args = begin _pipe = erlang:element(6, Query), _pipe@1 = gleam@list:map( _pipe, fun(Col) -> Gleam_type = sqlc_type_to_gleam( erlang:element(4, erlang:element(16, Col)) ), Col_type = gleam_type_to_string(Gleam_type), Col_type@1 = case erlang:element(3, Col) of true -> Col_type; false -> <<<<"Option("/utf8, Col_type/binary>>/binary, ")"/utf8>> end, Col_name = gen_column_name(Query, Col), <<<>/binary, Col_type@1/binary>> end ), _pipe@2 = gleam@list:map( _pipe@1, fun(Str) -> <<" "/utf8, Str/binary>> end ), gleam@string:join(_pipe@2, <<",\n"/utf8>>) end, _pipe@3 = [<<<<"pub type "/utf8, Name/binary>>/binary, " {"/utf8>>, <<<<" "/utf8, Name/binary>>/binary, "("/utf8>>, Args, <<" )"/utf8>>, <<"}"/utf8>>], gleam@string:join(_pipe@3, <<"\n"/utf8>>). -file("src/parrot/codegen.gleam", 141). -spec gen_query_function(parrot@internal@sqlc:'query'()) -> binary(). gen_query_function(Query) -> Fn_name = parrot@internal@string_case:snake_case(erlang:element(3, Query)), Def_fn_args = begin _pipe = erlang:element(9, Query), _pipe@1 = gleam@list:map( _pipe, fun(P) -> Gleam_type = sqlc_type_to_gleam( erlang:element(4, erlang:element(16, erlang:element(3, P))) ), <<<<(erlang:element(2, erlang:element(3, P)))/binary, ": "/utf8>>/binary, (gleam_type_to_string(Gleam_type))/binary>> end ), gleam@string:join(_pipe@1, <<", "/utf8>>) end, Def_return_params = case erlang:element(9, Query) of [] -> <<"Nil"/utf8>>; Args -> <<<<"["/utf8, (begin _pipe@2 = Args, _pipe@3 = gleam@list:map( _pipe@2, fun(Arg) -> Arg_type = sqlc_type_to_gleam( erlang:element( 4, erlang:element( 16, erlang:element(3, Arg) ) ) ), Param = case Arg_type of gleam_int -> <<"parrot.ParamInt"/utf8>>; gleam_string -> <<"parrot.ParamString"/utf8>>; gleam_float -> <<"parrot.ParamFloat"/utf8>>; gleam_bool -> <<"parrot.ParamBool"/utf8>>; gleam_timestamp -> <<"parrot.ParamTimestamp"/utf8>>; gleam_dynamic -> <<"parrot.ParamDynamic"/utf8>> end, <<<<<>/binary, (erlang:element( 2, erlang:element(3, Arg) ))/binary>>/binary, ")"/utf8>> end ), gleam@string:join(_pipe@3, <<", "/utf8>>) end)/binary>>/binary, "]"/utf8>> end, Def_fn = <<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary, "("/utf8>>/binary, Def_fn_args/binary>>/binary, ")"/utf8>>, Def_sql = <<<<"let sql = \""/utf8, (erlang:element(2, Query))/binary>>/binary, "\""/utf8>>, Def_return = <<<<"#(sql, "/utf8, Def_return_params/binary>>/binary, ")"/utf8>>, _pipe@4 = [<>, <<" "/utf8, Def_sql/binary>>, <<" "/utf8, Def_return/binary>>, <<"}"/utf8>>], gleam@string:join(_pipe@4, <<"\n"/utf8>>). -file("src/parrot/codegen.gleam", 181). -spec gen_query_decoder(parrot@internal@sqlc:'query'()) -> binary(). gen_query_decoder(Query) -> case erlang:length(erlang:element(6, Query)) of 0 -> <<""/utf8>>; _ -> Type_name = parrot@internal@string_case:pascal_case( erlang:element(3, Query) ), Fn_name = <<(parrot@internal@string_case:snake_case( erlang:element(3, Query) ))/binary, "_decoder"/utf8>>, Decoder_fields = begin _pipe = erlang:element(6, Query), _pipe@1 = gleam@list:index_map( _pipe, fun(Col, Index) -> Col_type = sqlc_type_to_gleam( erlang:element(4, erlang:element(16, Col)) ), Decoder_type = case Col_type of gleam_int -> <<"decode.int"/utf8>>; gleam_string -> <<"decode.string"/utf8>>; gleam_bool -> <<"decode.bool"/utf8>>; gleam_float -> <<"decode.float"/utf8>>; gleam_timestamp -> <<"parrot.datetime_decoder()"/utf8>>; gleam_dynamic -> <<"decode.dynamic"/utf8>> end, Decoder = case erlang:element(3, Col) of true -> Decoder_type; false -> <<<<"decode.optional("/utf8, Decoder_type/binary>>/binary, ")"/utf8>> end, Col_name = gen_column_name(Query, Col), <<<<<<<<<<<<" use "/utf8, Col_name/binary>>/binary, " <- decode.field("/utf8>>/binary, (erlang:integer_to_binary(Index))/binary>>/binary, ", "/utf8>>/binary, Decoder/binary>>/binary, ")"/utf8>> end ), gleam@string:join(_pipe@1, <<"\n"/utf8>>) end, Constructor_args = begin _pipe@2 = erlang:element(6, Query), _pipe@3 = gleam@list:map( _pipe@2, fun(Col@1) -> <<(gen_column_name(Query, Col@1))/binary, ": "/utf8>> end ), gleam@string:join(_pipe@3, <<", "/utf8>>) end, Success_line = <<<<<<<<" decode.success("/utf8, Type_name/binary>>/binary, "("/utf8>>/binary, Constructor_args/binary>>/binary, "))"/utf8>>, <<<<<<<<<<<<<<<<"\n\npub fn "/utf8, Fn_name/binary>>/binary, "() -> decode.Decoder("/utf8>>/binary, Type_name/binary>>/binary, ") {\n"/utf8>>/binary, Decoder_fields/binary>>/binary, "\n"/utf8>>/binary, Success_line/binary>>/binary, "\n}"/utf8>> end. -file("src/parrot/codegen.gleam", 52). -spec gen_query(parrot@internal@sqlc:'query'()) -> binary(). gen_query(Query) -> Type_str = case erlang:length(erlang:element(6, Query)) of 0 -> <<""/utf8>>; _ -> <<(gen_query_type(Query))/binary, "\n\n"/utf8>> end, <<<>/binary, (gen_query_decoder(Query))/binary>>. -file("src/parrot/codegen.gleam", 280). -spec comment_dont_edit() -> binary(). comment_dont_edit() -> _pipe = <<" //// Code generated by parrot. DO NOT EDIT. //// "/utf8>>, parrot@internal@lib:dedent(_pipe). -file("src/parrot/codegen.gleam", 238). -spec gen_gleam_module(parrot@internal@sqlc:sqlc()) -> binary(). gen_gleam_module(Schema) -> Queries = begin _pipe = erlang:element(6, Schema), _pipe@1 = gleam@list:map(_pipe, fun gen_query/1), gleam@string:join(_pipe@1, <<"\n\n"/utf8>>) end, Uses_timestamp = gleam@list:any( erlang:element(6, Schema), fun(Query) -> Col_ts = gleam@list:any( erlang:element(6, Query), fun(Col) -> case sqlc_type_to_gleam( erlang:element(4, erlang:element(16, Col)) ) of gleam_timestamp -> true; _ -> false end end ), Param_ts = gleam@list:any( erlang:element(9, Query), fun(Param) -> case sqlc_type_to_gleam( erlang:element( 4, erlang:element(16, erlang:element(3, Param)) ) ) of gleam_timestamp -> true; _ -> false end end ), gleam@bool:'or'(Col_ts, Param_ts) end ), Timestamp_import = case Uses_timestamp of false -> <<""/utf8>>; true -> <<"import gleam/time/timestamp.{type Timestamp}\n"/utf8>> end, Imports = <<<<<<<<<<"import gleam/option.{type Option}"/utf8, "\n"/utf8>>/binary, "import gleam/dynamic/decode"/utf8>>/binary, "\n"/utf8>>/binary, Timestamp_import/binary>>/binary, "import parrot"/utf8>>, <<<<<<<<(comment_dont_edit())/binary, "\n\n"/utf8>>/binary, Imports/binary>>/binary, "\n\n"/utf8>>/binary, Queries/binary>>. -file("src/parrot/codegen.gleam", 18). -spec codegen_from_config(parrot@config:config()) -> {ok, nil} | {error, nil}. codegen_from_config(Config) -> parrot@internal@lib:try_nil( parrot@config:get_json_file(Config), fun(Json_string) -> parrot@internal@lib:try_nil( gleam@json:parse( Json_string, {decoder, fun gleam@dynamic@decode:decode_dynamic/1} ), fun(Dyn_json) -> _assert_subject = parrot@internal@sqlc:decode_sqlc(Dyn_json), {ok, Parsed} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"parrot/codegen"/utf8>>, function => <<"codegen_from_config"/utf8>>, line => 23}) end, gleam@list:each( erlang:element(6, Parsed), fun(Query) -> gleam@list:each( erlang:element(6, Query), fun(Col) -> case sqlc_type_to_gleam( erlang:element( 4, erlang:element(16, Col) ) ) of gleam_dynamic -> gleam_stdlib:println( parrot@internal@colored:yellow( <<"unknown column type: "/utf8, (erlang:element( 4, erlang:element( 16, Col ) ))/binary>> ) ); _ -> nil end end ) end ), gleam_stdlib:println(<<""/utf8>>), Module_contents = gen_gleam_module(Parsed), _ = begin _pipe = parrot@config:get_module_directory(Config), simplifile:create_directory_all(_pipe) end, _ = simplifile:write( parrot@config:get_module_path(Config), Module_contents ), {ok, nil} end ) end ).