-module(sqlode@codegen@params). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/sqlode/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. -type value_encoder() :: {direct_encode, binary()} | {unwrap_encode, binary(), binary()} | {enum_encode, binary(), binary()} | {array_encode, value_encoder()}. -file("src/sqlode/codegen/params.gleam", 87). -spec queries_have_array_params(list(sqlode@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/codegen/params.gleam", 98). -spec needs_option_import(list(sqlode@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/codegen/params.gleam", 150). -spec param_fields( list(sqlode@model:query_param()), sqlode@model:type_mapping() ) -> list(binary()). param_fields(Params, Type_mapping) -> _pipe = Params, gleam@list:map( _pipe, fun(Param) -> Base_type = sqlode@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/codegen/params.gleam", 195). ?DOC(" Determine the encoding strategy for a scalar type.\n"). -spec plan_encoding(sqlode@model:scalar_type(), sqlode@model:type_mapping()) -> value_encoder(). plan_encoding(Scalar_type, Type_mapping_mode) -> case Scalar_type of {enum_type, Name} -> Runtime_fn = sqlode@type_mapping:scalar_type_to_runtime_function( Scalar_type ), To_str = <<"models."/utf8, (sqlode@type_mapping:enum_to_string_fn(Name))/binary>>, {enum_encode, Runtime_fn, To_str}; {set_type, Name@1} -> Runtime_fn@1 = sqlode@type_mapping:scalar_type_to_runtime_function( Scalar_type ), To_str@1 = <<"models."/utf8, (sqlode@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}; _ -> Runtime_fn@2 = sqlode@type_mapping:scalar_type_to_runtime_function( Scalar_type ), case Type_mapping_mode of strong_mapping -> case sqlode@type_mapping:strong_type_unwrap_fn(Scalar_type) of {some, Fn_name} -> {unwrap_encode, Runtime_fn@2, <<"models."/utf8, Fn_name/binary>>}; none -> {direct_encode, Runtime_fn@2} end; _ -> {direct_encode, Runtime_fn@2} end end. -file("src/sqlode/codegen/params.gleam", 234). ?DOC(" Render the encoder as a function expression (for use in callbacks).\n"). -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>>; {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/codegen/params.gleam", 249). ?DOC(" Render a direct application of the encoder to a value expression.\n"). -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>>; {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/codegen/params.gleam", 263). -spec render_param_value( sqlode@model:query_param(), sqlode@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/codegen/params.gleam", 169). -spec param_accessors( list(sqlode@model:query_param()), sqlode@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/codegen/params.gleam", 294). -spec render_list_param_mapper( sqlode@model:query_param(), sqlode@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/codegen/params.gleam", 281). ?DOC( " Render param values for queries with slice params.\n" " Scalars are wrapped in singleton lists, slices are mapped.\n" ). -spec param_accessors_flattened( list(sqlode@model:query_param()), sqlode@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/codegen/params.gleam", 104). -spec render_params_declaration( sqlode@naming:naming_context(), sqlode@model:analyzed_query(), sqlode@model:type_mapping() ) -> binary(). render_params_declaration(Naming_ctx, Query, Type_mapping) -> Type_name = <<(sqlode@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@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/codegen/params.gleam", 9). -spec render( sqlode@naming:naming_context(), list(sqlode@model:analyzed_query()), sqlode@model:type_mapping(), binary(), binary() ) -> binary(). render(Naming_ctx, Queries, Type_mapping, Module_path, Runtime_import) -> Has_slices = sqlode@codegen@common:queries_have_slices(Queries), Has_arrays = queries_have_array_params(Queries), Has_enums = sqlode@codegen@common:queries_have_enum_params(Queries), Custom_imports = begin _pipe = sqlode@codegen@common:param_scalar_types(Queries), sqlode@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@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>>).