Current section
Files
Jump to
Current section
Files
src/sqlode@codegen@queries.erl
-module(sqlode@codegen@queries).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/sqlode/codegen/queries.gleam").
-export([render/5]).
-file("src/sqlode/codegen/queries.gleam", 130).
-spec engine_placeholder_style_expr(sqlode@model:engine()) -> binary().
engine_placeholder_style_expr(Engine) ->
case Engine of
postgre_s_q_l ->
<<"runtime.DollarNumbered"/utf8>>;
my_s_q_l ->
<<"runtime.QuestionPositional"/utf8>>;
s_q_lite ->
<<"runtime.QuestionNumbered"/utf8>>
end.
-file("src/sqlode/codegen/queries.gleam", 138).
-spec render_query_function(
sqlode@naming:naming_context(),
sqlode@model:analyzed_query(),
boolean(),
binary()
) -> binary().
render_query_function(Naming_ctx, Query, Emit_sql_as_comment, Style_expr) ->
Has_params = not gleam@list:is_empty(erlang:element(3, Query)),
Comment = case Emit_sql_as_comment of
true ->
[<<"// SQL: "/utf8,
(erlang:element(5, erlang:element(2, Query)))/binary>>];
false ->
[]
end,
Return_type = case Has_params of
true ->
Params_type = <<(sqlode@naming:to_pascal_case(
Naming_ctx,
erlang:element(2, erlang:element(2, Query))
))/binary,
"Params"/utf8>>,
<<<<"runtime.RawQuery(params."/utf8, Params_type/binary>>/binary,
")"/utf8>>;
false ->
<<"runtime.RawQuery(Nil)"/utf8>>
end,
Encode_line = case Has_params of
true ->
Values_fn = <<(erlang:element(3, erlang:element(2, Query)))/binary,
"_values"/utf8>>,
<<<<" encode: params."/utf8, Values_fn/binary>>/binary,
","/utf8>>;
false ->
<<" encode: fn(_) { [] },"/utf8>>
end,
Slice_params = gleam@list:filter(
erlang:element(3, Query),
fun(P) -> erlang:element(6, P) end
),
Slice_info_line = case Slice_params of
[] ->
<<" slice_info: fn(_) { [] },"/utf8>>;
_ ->
Entries = begin
_pipe = Slice_params,
_pipe@1 = gleam@list:map(
_pipe,
fun(P@1) ->
<<<<<<<<"#("/utf8,
(erlang:integer_to_binary(
erlang:element(2, P@1)
))/binary>>/binary,
", list.length(p."/utf8>>/binary,
(erlang:element(3, P@1))/binary>>/binary,
"))"/utf8>>
end
),
gleam@string:join(_pipe@1, <<", "/utf8>>)
end,
<<<<" slice_info: fn(p) { ["/utf8, Entries/binary>>/binary,
"] },"/utf8>>
end,
gleam@string:join(
lists:append(
[Comment,
[<<<<<<<<"pub fn "/utf8,
(erlang:element(3, erlang:element(2, Query)))/binary>>/binary,
"() -> "/utf8>>/binary,
Return_type/binary>>/binary,
" {"/utf8>>,
<<" runtime.RawQuery("/utf8>>,
<<<<" name: \""/utf8,
(sqlode@codegen@common:escape_string(
erlang:element(2, erlang:element(2, Query))
))/binary>>/binary,
"\","/utf8>>,
<<<<" sql: \""/utf8,
(sqlode@codegen@common:escape_string(
erlang:element(5, erlang:element(2, Query))
))/binary>>/binary,
"\","/utf8>>,
<<<<" command: runtime."/utf8,
(sqlode@model:query_command_to_string(
erlang:element(4, erlang:element(2, Query))
))/binary>>/binary,
","/utf8>>,
<<<<" param_count: "/utf8,
(erlang:integer_to_binary(
erlang:element(7, erlang:element(2, Query))
))/binary>>/binary,
","/utf8>>,
<<<<" placeholder_style: "/utf8, Style_expr/binary>>/binary,
","/utf8>>,
Encode_line,
Slice_info_line,
<<" )"/utf8>>,
<<"}"/utf8>>]]
),
<<"\n"/utf8>>
).
-file("src/sqlode/codegen/queries.gleam", 209).
-spec has_result_columns(sqlode@model:analyzed_query()) -> boolean().
has_result_columns(Query) ->
case erlang:element(4, erlang:element(2, Query)) of
query_one ->
not gleam@list:is_empty(erlang:element(4, Query));
query_many ->
not gleam@list:is_empty(erlang:element(4, Query));
_ ->
false
end.
-file("src/sqlode/codegen/queries.gleam", 216).
-spec render_decoder_function(
sqlode@naming:naming_context(),
sqlode@model:analyzed_query(),
sqlode@model:engine(),
binary(),
gleam@dict:dict(binary(), binary()),
boolean()
) -> binary().
render_decoder_function(
Naming_ctx,
Query,
Engine,
_,
Table_matches,
Emit_exact_table_names
) ->
Type_name = <<(sqlode@naming:to_pascal_case(
Naming_ctx,
erlang:element(2, erlang:element(2, Query))
))/binary,
"Row"/utf8>>,
Constructor_name = case gleam_stdlib:map_get(
Table_matches,
erlang:element(3, erlang:element(2, Query))
) of
{ok, Table_type} ->
Table_type;
{error, _} ->
Type_name
end,
{_, Field_lines} = gleam@list:fold(
erlang:element(4, Query),
{0, []},
fun(Acc, Col) ->
{Idx, Lines} = Acc,
case Col of
{scalar_result, {result_column, Name, Scalar_type, Nullable, _}} ->
Field_name = sqlode@naming:to_snake_case(Naming_ctx, Name),
Base = sqlode@type_mapping:scalar_type_to_decoder(
Engine,
Scalar_type
),
Decoder = case Nullable of
true ->
<<<<"decode.optional("/utf8, Base/binary>>/binary,
")"/utf8>>;
false ->
Base
end,
Line = <<<<<<<<<<<<" use "/utf8, Field_name/binary>>/binary,
" <- decode.field("/utf8>>/binary,
(erlang:integer_to_binary(Idx))/binary>>/binary,
", "/utf8>>/binary,
Decoder/binary>>/binary,
")"/utf8>>,
{Idx + 1, lists:append(Lines, [Line])};
{embedded_result,
{embedded_column, Embed_name, Embed_table_name, Embed_cols}} ->
Embed_field_name = sqlode@naming:to_snake_case(
Naming_ctx,
Embed_name
),
Embed_type_name = sqlode@naming:table_type_name(
Naming_ctx,
Embed_table_name,
Emit_exact_table_names
),
{New_idx, Decode_lines} = gleam@list:fold(
Embed_cols,
{Idx, []},
fun(Inner_acc, C) ->
{I, Ls} = Inner_acc,
Field_name@1 = sqlode@naming:to_snake_case(
Naming_ctx,
erlang:element(2, C)
),
Base@1 = sqlode@type_mapping:scalar_type_to_decoder(
Engine,
erlang:element(3, C)
),
Decoder@1 = case erlang:element(4, C) of
true ->
<<<<"decode.optional("/utf8, Base@1/binary>>/binary,
")"/utf8>>;
false ->
Base@1
end,
Line@1 = <<<<<<<<<<<<" use "/utf8,
Field_name@1/binary>>/binary,
" <- decode.field("/utf8>>/binary,
(erlang:integer_to_binary(I))/binary>>/binary,
", "/utf8>>/binary,
Decoder@1/binary>>/binary,
")"/utf8>>,
{I + 1, lists:append(Ls, [Line@1])}
end
),
Embed_constructor_fields = begin
_pipe = gleam@list:map(
Embed_cols,
fun(C@1) ->
<<(sqlode@naming:to_snake_case(
Naming_ctx,
erlang:element(2, C@1)
))/binary,
":"/utf8>>
end
),
gleam@string:join(_pipe, <<", "/utf8>>)
end,
Constructor_line = <<<<<<<<<<<<" let "/utf8,
Embed_field_name/binary>>/binary,
" = models."/utf8>>/binary,
Embed_type_name/binary>>/binary,
"("/utf8>>/binary,
Embed_constructor_fields/binary>>/binary,
")"/utf8>>,
All_lines = lists:append(Decode_lines, [Constructor_line]),
{New_idx, lists:append(Lines, All_lines)}
end
end
),
Constructor_fields = begin
_pipe@1 = erlang:element(4, Query),
_pipe@2 = gleam@list:flat_map(_pipe@1, fun(Col@1) -> case Col@1 of
{scalar_result, {result_column, Name@1, _, _, _}} ->
[<<(sqlode@naming:to_snake_case(Naming_ctx, Name@1))/binary,
":"/utf8>>];
{embedded_result, {embedded_column, Name@2, _, _}} ->
[<<(sqlode@naming:to_snake_case(Naming_ctx, Name@2))/binary,
":"/utf8>>]
end end),
gleam@string:join(_pipe@2, <<", "/utf8>>)
end,
gleam@string:join(
lists:append(
[[<<<<<<<<"pub fn "/utf8,
(erlang:element(3, erlang:element(2, Query)))/binary>>/binary,
"_decoder() -> decode.Decoder(models."/utf8>>/binary,
Type_name/binary>>/binary,
") {"/utf8>>],
Field_lines,
[<<<<<<<<" decode.success(models."/utf8,
Constructor_name/binary>>/binary,
"("/utf8>>/binary,
Constructor_fields/binary>>/binary,
"))"/utf8>>,
<<"}"/utf8>>]]
),
<<"\n"/utf8>>
).
-file("src/sqlode/codegen/queries.gleam", 346).
-spec render_query_info_literal(sqlode@model:parsed_query()) -> binary().
render_query_info_literal(Query) ->
<<<<<<<<<<<<<<<<"runtime.QueryInfo(name: \""/utf8,
(sqlode@codegen@common:escape_string(
erlang:element(2, Query)
))/binary>>/binary,
"\", sql: \""/utf8>>/binary,
(sqlode@codegen@common:escape_string(
erlang:element(5, Query)
))/binary>>/binary,
"\", command: runtime."/utf8>>/binary,
(sqlode@model:query_command_to_string(
erlang:element(4, Query)
))/binary>>/binary,
", param_count: "/utf8>>/binary,
(erlang:integer_to_binary(erlang:element(7, Query)))/binary>>/binary,
")"/utf8>>.
-file("src/sqlode/codegen/queries.gleam", 11).
-spec render(
sqlode@naming:naming_context(),
sqlode@model:sql_block(),
list(sqlode@model:analyzed_query()),
gleam@dict:dict(binary(), binary()),
boolean()
) -> binary().
render(Naming_ctx, Block, Queries, Table_matches, Emit_exact_table_names) ->
{sql_block, _, Engine, _, _, Gleam, _} = Block,
{gleam_output, Out, Runtime, _, _, _, _, _, _} = Gleam,
Module_path = sqlode@codegen@common:out_to_module_path(Out),
Emit_sql_as_comment = erlang:element(5, Gleam),
Has_slices = sqlode@codegen@common:queries_have_slices(Queries),
Style_expr = engine_placeholder_style_expr(Engine),
Query_functions = begin
_pipe = Queries,
_pipe@1 = gleam@list:map(
_pipe,
fun(_capture) ->
render_query_function(
Naming_ctx,
_capture,
Emit_sql_as_comment,
Style_expr
)
end
),
gleam@string:join(_pipe@1, <<"\n\n"/utf8>>)
end,
All_items = case Queries of
[] ->
<<"[]"/utf8>>;
_ ->
_pipe@2 = Queries,
_pipe@3 = gleam@list:map(
_pipe@2,
fun(Query) ->
render_query_info_literal(erlang:element(2, Query))
end
),
_pipe@4 = gleam@string:join(_pipe@3, <<", "/utf8>>),
(fun(Items) -> <<<<"["/utf8, Items/binary>>/binary, "]"/utf8>> end)(
_pipe@4
)
end,
Has_any_params = gleam@list:any(
Queries,
fun(Q) -> not gleam@list:is_empty(erlang:element(3, Q)) end
),
Decoder_queries = begin
_pipe@5 = Queries,
gleam@list:filter(_pipe@5, fun(Q@1) -> has_result_columns(Q@1) end)
end,
Decoder_functions = case Decoder_queries of
[] ->
<<""/utf8>>;
_ ->
_pipe@6 = Decoder_queries,
_pipe@7 = gleam@list:map(
_pipe@6,
fun(_capture@1) ->
render_decoder_function(
Naming_ctx,
_capture@1,
Engine,
Module_path,
Table_matches,
Emit_exact_table_names
)
end
),
gleam@string:join(_pipe@7, <<"\n\n"/utf8>>)
end,
Has_decoders = not gleam@list:is_empty(Decoder_queries),
Has_nullable = Has_decoders andalso gleam@list:any(
Decoder_queries,
fun(Q@2) ->
gleam@list:any(erlang:element(4, Q@2), fun(Col) -> case Col of
{scalar_result, {result_column, _, _, true, _}} ->
true;
_ ->
false
end end)
end
),
Imports = lists:append([case Has_slices of
true ->
[<<"import gleam/list"/utf8>>];
false ->
[]
end, case Has_decoders of
true ->
[<<"import gleam/dynamic/decode"/utf8>>];
false ->
[]
end, case Has_nullable of
true ->
[<<"import gleam/option.{type Option}"/utf8>>];
false ->
[]
end, [<<"import "/utf8,
(sqlode@codegen@common:runtime_import_path(Gleam))/binary>>], case Has_any_params of
true ->
[<<<<"import "/utf8, Module_path/binary>>/binary,
"/params"/utf8>>];
false ->
[]
end, case Has_decoders of
true ->
[<<<<"import "/utf8, Module_path/binary>>/binary,
"/models"/utf8>>];
false ->
[]
end]),
gleam@string:join(
lists:append(
[[<<"// Code generated by sqlode. DO NOT EDIT."/utf8>>,
<<"// engine: "/utf8,
(sqlode@model:engine_to_string(Engine))/binary>>,
<<"// runtime: "/utf8,
(sqlode@model:runtime_to_string(Runtime))/binary>>,
<<""/utf8>>],
Imports,
[<<""/utf8>>,
<<"pub fn all() -> List(runtime.QueryInfo) {"/utf8>>,
<<" "/utf8, All_items/binary>>,
<<"}"/utf8>>,
<<""/utf8>>,
Query_functions],
case Decoder_functions of
<<""/utf8>> ->
[];
_ ->
[<<""/utf8>>, Decoder_functions]
end]
),
<<"\n"/utf8>>
).