-module(sqlode@internal@codegen@params). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/sqlode/internal/codegen/params.gleam"). -export([render/5]). -export_type([value_encoder/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). -type value_encoder() :: {direct_encode, binary()} | {unwrap_encode, binary(), binary()} | {enum_encode, binary(), binary()} | {hook_encode, binary(), binary()} | {array_encode, value_encoder()}. -file("src/sqlode/internal/codegen/params.gleam", 87). ?DOC(false). -spec queries_have_array_params(list(sqlode@internal@model:analyzed_query())) -> boolean(). queries_have_array_params(Queries) -> gleam@list:any( Queries, fun(Q) -> gleam@list:any( erlang:element(3, Q), fun(P) -> case erlang:element(4, P) of {array_type, _} -> true; _ -> false end end ) end ). -file("src/sqlode/internal/codegen/params.gleam", 98). ?DOC(false). -spec needs_option_import(list(sqlode@internal@model:analyzed_query())) -> boolean(). needs_option_import(Queries) -> gleam@list:any( Queries, fun(Query) -> gleam@list:any( erlang:element(3, Query), fun(Param) -> erlang:element(5, Param) end ) end ). -file("src/sqlode/internal/codegen/params.gleam", 150). ?DOC(false). -spec param_fields( list(sqlode@internal@model:query_param()), sqlode@internal@model:type_mapping() ) -> list(binary()). param_fields(Params, Type_mapping) -> _pipe = Params, gleam@list:map( _pipe, fun(Param) -> Base_type = sqlode@internal@codegen@common:qualified_field_type( erlang:element(4, Param), Type_mapping ), Typed = case erlang:element(6, Param) of true -> <<<<"List("/utf8, Base_type/binary>>/binary, ")"/utf8>>; false -> case erlang:element(5, Param) of true -> <<<<"Option("/utf8, Base_type/binary>>/binary, ")"/utf8>>; false -> Base_type end end, <<<<(erlang:element(3, Param))/binary, ": "/utf8>>/binary, Typed/binary>> end ). -file("src/sqlode/internal/codegen/params.gleam", 264). ?DOC(false). -spec module_alias_for(binary()) -> binary(). module_alias_for(Module_path) -> case gleam@string:split(Module_path, <<"/"/utf8>>) of [] -> Module_path; Segments -> case gleam@list:last(Segments) of {ok, Last} -> Last; {error, _} -> Module_path end end. -file("src/sqlode/internal/codegen/params.gleam", 257). ?DOC(false). -spec qualified_hook_call(gleam@option:option(binary()), binary()) -> binary(). qualified_hook_call(Module, Fn_name) -> case Module of {some, Module_path} -> <<<<(module_alias_for(Module_path))/binary, "."/utf8>>/binary, Fn_name/binary>>; none -> Fn_name end. -file("src/sqlode/internal/codegen/params.gleam", 202). ?DOC(false). -spec plan_encoding( sqlode@internal@model:scalar_type(), sqlode@internal@model:type_mapping() ) -> value_encoder(). plan_encoding(Scalar_type, Type_mapping_mode) -> case Scalar_type of {enum_type, Name} -> Runtime_fn = sqlode@internal@type_mapping:scalar_type_to_runtime_function( Scalar_type ), To_str = <<"models."/utf8, (sqlode@internal@type_mapping:enum_to_string_fn(Name))/binary>>, {enum_encode, Runtime_fn, To_str}; {set_type, Name@1} -> Runtime_fn@1 = sqlode@internal@type_mapping:scalar_type_to_runtime_function( Scalar_type ), To_str@1 = <<"models."/utf8, (sqlode@internal@type_mapping:set_to_string_fn(Name@1))/binary>>, {enum_encode, Runtime_fn@1, To_str@1}; {array_type, Element} -> Inner = plan_encoding(Element, Type_mapping_mode), {array_encode, Inner}; {custom_type, _, Module, _, {some, Hooks}} -> Runtime_fn@2 = sqlode@internal@type_mapping:scalar_type_to_runtime_function( Scalar_type ), Hook_call = qualified_hook_call(Module, erlang:element(2, Hooks)), {hook_encode, Runtime_fn@2, Hook_call}; _ -> Runtime_fn@3 = sqlode@internal@type_mapping:scalar_type_to_runtime_function( Scalar_type ), case Type_mapping_mode of strong_mapping -> case sqlode@internal@type_mapping:strong_type_unwrap_fn( Scalar_type ) of {some, Fn_name} -> {unwrap_encode, Runtime_fn@3, <<"models."/utf8, Fn_name/binary>>}; none -> {direct_encode, Runtime_fn@3} end; _ -> {direct_encode, Runtime_fn@3} end end. -file("src/sqlode/internal/codegen/params.gleam", 276). ?DOC(false). -spec render_encoder_fn(value_encoder()) -> binary(). render_encoder_fn(Encoder) -> case Encoder of {direct_encode, Runtime_fn} -> Runtime_fn; {unwrap_encode, Runtime_fn@1, Unwrap_fn} -> <<<<<<<<"fn(v) { "/utf8, Runtime_fn@1/binary>>/binary, "("/utf8>>/binary, Unwrap_fn/binary>>/binary, "(v)) }"/utf8>>; {enum_encode, Runtime_fn@2, To_string_fn} -> <<<<<<<<"fn(v) { "/utf8, Runtime_fn@2/binary>>/binary, "("/utf8>>/binary, To_string_fn/binary>>/binary, "(v)) }"/utf8>>; {hook_encode, Runtime_fn@3, Hook_call} -> <<<<<<<<"fn(v) { "/utf8, Runtime_fn@3/binary>>/binary, "("/utf8>>/binary, Hook_call/binary>>/binary, "(v)) }"/utf8>>; {array_encode, Element_encoder} -> Mapper = render_encoder_fn(Element_encoder), <<<<"fn(v) { runtime.array(list.map(v, "/utf8, Mapper/binary>>/binary, ")) }"/utf8>> end. -file("src/sqlode/internal/codegen/params.gleam", 293). ?DOC(false). -spec render_encoder_apply(value_encoder(), binary()) -> binary(). render_encoder_apply(Encoder, Value_expr) -> case Encoder of {direct_encode, Runtime_fn} -> <<<<<>/binary, Value_expr/binary>>/binary, ")"/utf8>>; {unwrap_encode, Runtime_fn@1, Unwrap_fn} -> <<<<<<<<<>/binary, Unwrap_fn/binary>>/binary, "("/utf8>>/binary, Value_expr/binary>>/binary, "))"/utf8>>; {enum_encode, Runtime_fn@2, To_string_fn} -> <<<<<<<<<>/binary, To_string_fn/binary>>/binary, "("/utf8>>/binary, Value_expr/binary>>/binary, "))"/utf8>>; {hook_encode, Runtime_fn@3, Hook_call} -> <<<<<<<<<>/binary, Hook_call/binary>>/binary, "("/utf8>>/binary, Value_expr/binary>>/binary, "))"/utf8>>; {array_encode, Element_encoder} -> Mapper = render_encoder_fn(Element_encoder), <<<<<<<<"runtime.array(list.map("/utf8, Value_expr/binary>>/binary, ", "/utf8>>/binary, Mapper/binary>>/binary, "))"/utf8>> end. -file("src/sqlode/internal/codegen/params.gleam", 309). ?DOC(false). -spec render_param_value( sqlode@internal@model:query_param(), sqlode@internal@model:type_mapping() ) -> binary(). render_param_value(Param, Type_mapping_mode) -> Value_expr = <<"params."/utf8, (erlang:element(3, Param))/binary>>, Encoder = plan_encoding(erlang:element(4, Param), Type_mapping_mode), case erlang:element(5, Param) of true -> Encode_fn = render_encoder_fn(Encoder), <<<<<<<<"runtime.nullable("/utf8, Value_expr/binary>>/binary, ", "/utf8>>/binary, Encode_fn/binary>>/binary, ")"/utf8>>; false -> render_encoder_apply(Encoder, Value_expr) end. -file("src/sqlode/internal/codegen/params.gleam", 169). ?DOC(false). -spec param_accessors( list(sqlode@internal@model:query_param()), sqlode@internal@model:type_mapping() ) -> list(binary()). param_accessors(Params, Type_mapping) -> _pipe = Params, gleam@list:map( _pipe, fun(_capture) -> render_param_value(_capture, Type_mapping) end ). -file("src/sqlode/internal/codegen/params.gleam", 340). ?DOC(false). -spec render_list_param_mapper( sqlode@internal@model:query_param(), sqlode@internal@model:type_mapping() ) -> binary(). render_list_param_mapper(Param, Type_mapping_mode) -> Value_expr = <<"params."/utf8, (erlang:element(3, Param))/binary>>, Encoder = plan_encoding(erlang:element(4, Param), Type_mapping_mode), Mapper = render_encoder_fn(Encoder), <<<<<<<<"list.map("/utf8, Value_expr/binary>>/binary, ", "/utf8>>/binary, Mapper/binary>>/binary, ")"/utf8>>. -file("src/sqlode/internal/codegen/params.gleam", 327). ?DOC(false). -spec param_accessors_flattened( list(sqlode@internal@model:query_param()), sqlode@internal@model:type_mapping() ) -> list(binary()). param_accessors_flattened(Params, Type_mapping) -> _pipe = Params, gleam@list:map(_pipe, fun(Param) -> case erlang:element(6, Param) of true -> render_list_param_mapper(Param, Type_mapping); false -> <<<<"["/utf8, (render_param_value(Param, Type_mapping))/binary>>/binary, "]"/utf8>> end end). -file("src/sqlode/internal/codegen/params.gleam", 104). ?DOC(false). -spec render_params_declaration( sqlode@internal@naming:naming_context(), sqlode@internal@model:analyzed_query(), sqlode@internal@model:type_mapping() ) -> binary(). render_params_declaration(Naming_ctx, Query, Type_mapping) -> Type_name = <<(sqlode@internal@naming:to_pascal_case( Naming_ctx, erlang:element(2, erlang:element(2, Query)) ))/binary, "Params"/utf8>>, Function_name = <<(erlang:element(3, erlang:element(2, Query)))/binary, "_values"/utf8>>, case erlang:element(3, Query) of [] -> <<""/utf8>>; Params -> Has_slices = sqlode@internal@codegen@common:has_slices(Params), Values_body = case Has_slices of true -> <<<<" list.flatten(["/utf8, (gleam@string:join( param_accessors_flattened(Params, Type_mapping), <<", "/utf8>> ))/binary>>/binary, "])"/utf8>>; false -> <<<<" ["/utf8, (gleam@string:join( param_accessors(Params, Type_mapping), <<", "/utf8>> ))/binary>>/binary, "]"/utf8>> end, gleam@string:join( [<<<<"pub type "/utf8, Type_name/binary>>/binary, " {"/utf8>>, <<<<<<<<" "/utf8, Type_name/binary>>/binary, "("/utf8>>/binary, (gleam@string:join( param_fields(Params, Type_mapping), <<", "/utf8>> ))/binary>>/binary, ")"/utf8>>, <<"}"/utf8>>, <<""/utf8>>, <<<<<<<<"pub fn "/utf8, Function_name/binary>>/binary, "(params: "/utf8>>/binary, Type_name/binary>>/binary, ") -> List(Value) {"/utf8>>, Values_body, <<"}"/utf8>>], <<"\n"/utf8>> ) end. -file("src/sqlode/internal/codegen/params.gleam", 9). ?DOC(false). -spec render( sqlode@internal@naming:naming_context(), list(sqlode@internal@model:analyzed_query()), sqlode@internal@model:type_mapping(), binary(), binary() ) -> binary(). render(Naming_ctx, Queries, Type_mapping, Module_path, Runtime_import) -> Has_slices = sqlode@internal@codegen@common:queries_have_slices(Queries), Has_arrays = queries_have_array_params(Queries), Has_enums = sqlode@internal@codegen@common:queries_have_enum_params(Queries), Custom_imports = begin _pipe = sqlode@internal@codegen@common:param_scalar_types(Queries), sqlode@internal@codegen@common:custom_type_imports(_pipe) end, Needs_models_for_rich = ((Type_mapping =:= strong_mapping) orelse (Type_mapping =:= rich_mapping)) andalso gleam@list:any( Queries, fun(Q) -> gleam@list:any( erlang:element(3, Q), fun(P) -> sqlode@internal@type_mapping:is_rich_type( erlang:element(4, P) ) end ) end ), Runtime_import_line = <<<<"import "/utf8, Runtime_import/binary>>/binary, ".{type Value}"/utf8>>, Option_import = case needs_option_import(Queries) of true -> [<<"import gleam/option.{type Option}"/utf8>>]; false -> [] end, Imports = lists:append([case Has_slices orelse Has_arrays of true -> [<<"import gleam/list"/utf8>>]; false -> [] end, Option_import, [Runtime_import_line], case Has_enums orelse Needs_models_for_rich of true -> [<<<<"import "/utf8, Module_path/binary>>/binary, "/models"/utf8>>]; false -> [] end, Custom_imports]), Queries_with_params = gleam@list:filter( Queries, fun(Q@1) -> not gleam@list:is_empty(erlang:element(3, Q@1)) end ), Declarations = begin _pipe@1 = Queries_with_params, _pipe@2 = gleam@list:map( _pipe@1, fun(_capture) -> render_params_declaration(Naming_ctx, _capture, Type_mapping) end ), gleam@string:join(_pipe@2, <<"\n\n"/utf8>>) end, Effective_imports = case Queries_with_params of [] -> []; _ -> Imports end, Lines = lists:append( [[<<"// Code generated by sqlode. DO NOT EDIT."/utf8>>, <<""/utf8>>], Effective_imports, case Declarations of <<""/utf8>> -> []; _ -> [<<""/utf8>>, Declarations] end] ), gleam@string:join(Lines, <<"\n"/utf8>>).