Packages
cake
0.1.0
4.1.0
4.0.0
3.0.0
2.2.2
2.2.1
2.2.0
2.1.3
2.1.2
2.1.1
2.1.0
2.0.2
2.0.1
2.0.0
1.1.2
1.1.1
1.1.0
1.0.1
1.0.0
1.0.0-rc.0
retired
0.15.0
retired
0.14.0
retired
0.13.0
retired
0.12.0
retired
0.11.0
retired
0.10.1
retired
0.10.0
retired
0.9.2
retired
0.9.1
retired
0.9.0
retired
0.8.0
retired
0.7.0
retired
0.6.0
retired
0.5.0
retired
0.4.0
retired
0.3.0
retired
0.2.0
retired
0.1.0
retired
0.0.1
retired
🎂 An SQL query builder for Gleam for SQL dialects 🐘PostgreSQL, 🪶SQLite, 🦭MariaDB, and 🐬MySQL
Retired package: Deprecated - a stable release is available, please use >= 1.0.0
Current section
Files
Jump to
Current section
Files
src/cake@internal@query.erl
-module(cake@internal@query).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([order_by_part_to_sql/1, limit_offset_new/2, limit_new/1, offset_new/1, limit_offset_apply/2, limit_offset_get/1, combined_query_new/2, combined_get_select_queries/1, combined_order_by/3, select_order_by/3, epilog_apply/2, qualified_identifier/1, fragment_prepared_split_string/1, fragment_count_placeholders/1, from_part_apply/2, builder_apply/2, select_builder/2, builder_new/2, combined_builder_apply_command_sql/2, combined_builder/2, where_part_apply_clause/2, join_parts_apply_clause/2]).
-export_type(['query'/0, order_by_part/0, order_by_direction_part/0, limit_offset_part/0, combined_kind/0, combined_query/0, select_query/0, select_value/0, from_part/0, where_part/0, where_value/0, join/0, join_part/0, epilog_part/0, fragment/0]).
-type 'query'() :: {select, select_query()} | {combined, combined_query()}.
-type order_by_part() :: {order_by_column_part,
binary(),
order_by_direction_part()}.
-type order_by_direction_part() :: asc |
desc |
asc_nulls_first |
desc_nulls_first.
-type limit_offset_part() :: {limit_offset, integer(), integer()} |
{limit_no_offset, integer()} |
{no_limit_offset, integer()} |
no_limit_no_offset.
-type combined_kind() :: union |
union_all |
except |
except_all |
intersect |
intersect_all.
-type combined_query() :: {combined_query,
combined_kind(),
list(select_query()),
limit_offset_part(),
list(order_by_part()),
epilog_part()}.
-type select_query() :: {select_query,
from_part(),
list(select_value()),
list(join_part()),
where_part(),
limit_offset_part(),
list(order_by_part()),
epilog_part()}.
-type select_value() :: {select_column, binary()} |
{select_param, cake@param:param()} |
{select_fragment, fragment()} |
{select_alias, select_value(), binary()}.
-type from_part() :: {from_table, binary()} |
{from_sub_query, 'query'(), binary()} |
no_from_part.
-type where_part() :: {where_equal, where_value(), where_value()} |
{where_lower, where_value(), where_value()} |
{where_lower_or_equal, where_value(), where_value()} |
{where_greater, where_value(), where_value()} |
{where_greater_or_equal, where_value(), where_value()} |
{where_unequal, where_value(), where_value()} |
{where_is_bool, where_value(), boolean()} |
{where_is_not_bool, where_value(), boolean()} |
{where_is_null, where_value()} |
{where_is_not_null, where_value()} |
{where_like, where_value(), binary()} |
{where_i_like, where_value(), binary()} |
{where_similar, where_value(), binary()} |
{where_in, where_value(), list(where_value())} |
{where_between, where_value(), where_value(), where_value()} |
{and_where, list(where_part())} |
{or_where, list(where_part())} |
{not_where, where_part()} |
no_where_part.
-type where_value() :: {where_column, binary()} |
{where_param, cake@param:param()} |
{where_fragment, fragment()}.
-type join() :: {join_table, binary()} | {join_sub_query, 'query'()}.
-type join_part() :: {cross_join, join(), binary()} |
{inner_join, join(), binary(), where_part()} |
{left_outer_join, join(), binary(), where_part()} |
{right_outer_join, join(), binary(), where_part()} |
{full_outer_join, join(), binary(), where_part()}.
-type epilog_part() :: {epilog, binary()} | no_epilog_part.
-type fragment() :: {fragment_literal, binary()} |
{fragment_prepared, binary(), list(cake@param:param())}.
-spec combined_builder_apply_to_sql(
cake@internal@prepared_statement:prepared_statement(),
combined_query(),
fun((combined_query()) -> binary())
) -> cake@internal@prepared_statement:prepared_statement().
combined_builder_apply_to_sql(Prp_stm, Qry, Mb_fun) ->
_pipe = Prp_stm,
cake@internal@prepared_statement:append_sql(_pipe, Mb_fun(Qry)).
-spec select_builder_apply_to_sql(
cake@internal@prepared_statement:prepared_statement(),
select_query(),
fun((select_query()) -> binary())
) -> cake@internal@prepared_statement:prepared_statement().
select_builder_apply_to_sql(Prp_stm, Qry, Mb_fun) ->
_pipe = Prp_stm,
cake@internal@prepared_statement:append_sql(_pipe, Mb_fun(Qry)).
-spec order_by_part_to_sql(order_by_part()) -> binary().
order_by_part_to_sql(Ordbpt) ->
case erlang:element(3, Ordbpt) of
asc ->
<<"ASC NULLS LAST"/utf8>>;
desc ->
<<"DESC NULLS LAST"/utf8>>;
asc_nulls_first ->
<<"ASC NULLS FIRST"/utf8>>;
desc_nulls_first ->
<<"DESC NULLS FIRST"/utf8>>
end.
-spec combined_builder_maybe_add_order_sql(combined_query()) -> binary().
combined_builder_maybe_add_order_sql(Qry) ->
case erlang:element(5, Qry) of
[] ->
<<""/utf8>>;
_ ->
Order_bys = begin
_pipe = erlang:element(5, Qry),
gleam@list:map(
_pipe,
fun(Ordrb) ->
<<<<(erlang:element(2, Ordrb))/binary, " "/utf8>>/binary,
(order_by_part_to_sql(Ordrb))/binary>>
end
)
end,
<<" ORDER BY "/utf8,
(gleam@string:join(Order_bys, <<", "/utf8>>))/binary>>
end.
-spec select_builder_maybe_add_order_sql(select_query()) -> binary().
select_builder_maybe_add_order_sql(Qry) ->
case erlang:element(7, Qry) of
[] ->
<<""/utf8>>;
_ ->
Order_bys = begin
_pipe = erlang:element(7, Qry),
gleam@list:map(
_pipe,
fun(Ordrb) ->
<<<<(erlang:element(2, Ordrb))/binary, " "/utf8>>/binary,
(order_by_part_to_sql(Ordrb))/binary>>
end
)
end,
<<" ORDER BY "/utf8,
(gleam@string:join(Order_bys, <<", "/utf8>>))/binary>>
end.
-spec limit_offset_new(integer(), integer()) -> limit_offset_part().
limit_offset_new(Lmt, Offst) ->
case {Lmt >= 0, Offst >= 0} of
{true, true} ->
{limit_offset, Lmt, Offst};
{true, false} ->
{limit_no_offset, Lmt};
{false, _} ->
no_limit_no_offset
end.
-spec limit_new(integer()) -> limit_offset_part().
limit_new(Lmt) ->
case Lmt >= 0 of
true ->
{limit_no_offset, Lmt};
false ->
no_limit_no_offset
end.
-spec offset_new(integer()) -> limit_offset_part().
offset_new(Offst) ->
case Offst >= 0 of
true ->
{no_limit_offset, Offst};
false ->
no_limit_no_offset
end.
-spec limit_offset_apply(
cake@internal@prepared_statement:prepared_statement(),
limit_offset_part()
) -> cake@internal@prepared_statement:prepared_statement().
limit_offset_apply(Prp_stm, Lmt_prt) ->
_pipe = case Lmt_prt of
{limit_offset, Lmt, Offst} ->
<<<<<<" LIMIT "/utf8, (gleam@int:to_string(Lmt))/binary>>/binary,
" OFFSET "/utf8>>/binary,
(gleam@int:to_string(Offst))/binary>>;
{limit_no_offset, Lmt@1} ->
<<" LIMIT "/utf8, (gleam@int:to_string(Lmt@1))/binary>>;
{no_limit_offset, Offst@1} ->
<<" OFFSET "/utf8, (gleam@int:to_string(Offst@1))/binary>>;
no_limit_no_offset ->
<<""/utf8>>
end,
cake@internal@prepared_statement:append_sql(Prp_stm, _pipe).
-spec limit_offset_get(select_query()) -> limit_offset_part().
limit_offset_get(Qry) ->
erlang:element(6, Qry).
-spec select_builder_maybe_apply_limit_offset(
cake@internal@prepared_statement:prepared_statement(),
select_query()
) -> cake@internal@prepared_statement:prepared_statement().
select_builder_maybe_apply_limit_offset(Prp_stm, Qry) ->
_pipe = Qry,
_pipe@1 = limit_offset_get(_pipe),
limit_offset_apply(Prp_stm, _pipe@1).
-spec combined_query_remove_order_by_from_selects(list(select_query())) -> list(select_query()).
combined_query_remove_order_by_from_selects(Qrys) ->
_pipe = Qrys,
gleam@list:map(_pipe, fun(Qry) -> erlang:setelement(7, Qry, []) end).
-spec combined_query_new(combined_kind(), list(select_query())) -> combined_query().
combined_query_new(Knd, Qrys) ->
_pipe = Qrys,
_pipe@1 = combined_query_remove_order_by_from_selects(_pipe),
{combined_query, Knd, _pipe@1, no_limit_no_offset, [], no_epilog_part}.
-spec combined_get_select_queries(combined_query()) -> list(select_query()).
combined_get_select_queries(Cmbnd_qry) ->
erlang:element(3, Cmbnd_qry).
-spec combined_order_by(combined_query(), order_by_part(), boolean()) -> combined_query().
combined_order_by(Qry, Ordb, Appnd) ->
case Appnd of
true ->
erlang:setelement(
5,
Qry,
begin
_pipe = erlang:element(5, Qry),
cake@stdlib@listx:append_item(_pipe, Ordb)
end
);
false ->
erlang:setelement(5, Qry, cake@stdlib@listx:wrap(Ordb))
end.
-spec select_order_by(select_query(), order_by_part(), boolean()) -> select_query().
select_order_by(Qry, Ordb, Appnd) ->
case Appnd of
true ->
erlang:setelement(
7,
Qry,
begin
_pipe = erlang:element(7, Qry),
cake@stdlib@listx:append_item(_pipe, Ordb)
end
);
false ->
erlang:setelement(7, Qry, cake@stdlib@listx:wrap(Ordb))
end.
-spec where_part_apply_string(
cake@internal@prepared_statement:prepared_statement(),
binary()
) -> cake@internal@prepared_statement:prepared_statement().
where_part_apply_string(Prp_stm, S) ->
_pipe = Prp_stm,
cake@internal@prepared_statement:append_sql(_pipe, S).
-spec where_part_apply_param(
cake@internal@prepared_statement:prepared_statement(),
cake@param:param()
) -> cake@internal@prepared_statement:prepared_statement().
where_part_apply_param(Prp_stm, Prm) ->
Nxt_plchldr = begin
_pipe = Prp_stm,
cake@internal@prepared_statement:next_placeholder(_pipe)
end,
_pipe@1 = Prp_stm,
cake@internal@prepared_statement:append_sql_and_param(
_pipe@1,
Nxt_plchldr,
Prm
).
-spec epilog_apply(
cake@internal@prepared_statement:prepared_statement(),
epilog_part()
) -> cake@internal@prepared_statement:prepared_statement().
epilog_apply(Prp_stm, Prt) ->
case Prt of
no_epilog_part ->
Prp_stm;
{epilog, Eplg} ->
_pipe = Prp_stm,
cake@internal@prepared_statement:append_sql(_pipe, Eplg)
end.
-spec qualified_identifier(binary()) -> fun((binary()) -> binary()).
qualified_identifier(Scp) ->
fun(Identifier) ->
<<<<Scp/binary, "."/utf8>>/binary, Identifier/binary>>
end.
-spec fragment_prepared_split_string(binary()) -> list(binary()).
fragment_prepared_split_string(Str_frgmt) ->
_pipe = Str_frgmt,
_pipe@1 = gleam@string:to_graphemes(_pipe),
_pipe@2 = gleam@list:fold(
_pipe@1,
[],
fun(Acc, Grapheme) -> case {Grapheme =:= <<"$"/utf8>>, Acc} of
{true, _} ->
[<<"$"/utf8>> | Acc];
{false, []} ->
[Grapheme];
{false, [First | _]} when First =:= <<"$"/utf8>> ->
[Grapheme | Acc];
{false, [First@1 | Rest]} ->
[<<First@1/binary, Grapheme/binary>> | Rest]
end end
),
lists:reverse(_pipe@2).
-spec fragment_count_placeholders(list(binary())) -> integer().
fragment_count_placeholders(S_frgmts) ->
_pipe = S_frgmts,
gleam@list:fold(
_pipe,
0,
fun(Count, S_frgmt) -> case S_frgmt =:= <<"$"/utf8>> of
true ->
Count + 1;
false ->
Count
end end
).
-spec apply_fragment(
cake@internal@prepared_statement:prepared_statement(),
fragment()
) -> cake@internal@prepared_statement:prepared_statement().
apply_fragment(Prp_stm, Frgmt) ->
case Frgmt of
{fragment_literal, Frgmt@1} ->
_pipe = Prp_stm,
cake@internal@prepared_statement:append_sql(_pipe, Frgmt@1);
{fragment_prepared, Frgmt@2, Prms} ->
Frgmt_parts = begin
_pipe@1 = Frgmt@2,
fragment_prepared_split_string(_pipe@1)
end,
Frgmt_plchldr_count = begin
_pipe@2 = Frgmt_parts,
fragment_count_placeholders(_pipe@2)
end,
Prms_count = begin
_pipe@3 = Prms,
erlang:length(_pipe@3)
end,
Prms@1 = case begin
_pipe@4 = Frgmt_plchldr_count,
gleam@int:compare(_pipe@4, Prms_count)
end of
eq ->
Prms;
lt ->
Missing_placeholders = Prms_count - Frgmt_plchldr_count,
_pipe@5 = Prms,
gleam@list:take(_pipe@5, Missing_placeholders + 1);
gt ->
Missing_params = Frgmt_plchldr_count - Prms_count,
_assert_subject = gleam@list:last(Prms),
{ok, Last_item} = 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 => <<"cake/internal/query"/utf8>>,
function => <<"apply_fragment"/utf8>>,
line => 960})
end,
Repeated_last_item = begin
_pipe@6 = Last_item,
gleam@list:repeat(_pipe@6, Missing_params)
end,
_pipe@7 = Prms,
lists:append(_pipe@7, Repeated_last_item)
end,
{New_prp_stm@2, Empty_param_rest} = begin
_pipe@8 = Frgmt_parts,
gleam@list:fold(
_pipe@8,
{Prp_stm, Prms@1},
fun(Acc, Frgmnt_prt) ->
New_prp_stm = erlang:element(1, Acc),
case Frgmnt_prt =:= <<"$"/utf8>> of
true ->
Nxt_plchldr = begin
_pipe@9 = New_prp_stm,
cake@internal@prepared_statement:next_placeholder(
_pipe@9
)
end,
_assert_subject@1 = erlang:element(2, Acc),
[Prm | Rest_prms] = case _assert_subject@1 of
[_ | _] -> _assert_subject@1;
_assert_fail@1 ->
erlang:error(
#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"cake/internal/query"/utf8>>,
function => <<"apply_fragment"/utf8>>,
line => 982}
)
end,
New_prp_stm@1 = begin
_pipe@10 = New_prp_stm,
cake@internal@prepared_statement:append_sql_and_param(
_pipe@10,
Nxt_plchldr,
Prm
)
end,
{New_prp_stm@1, Rest_prms};
false ->
{begin
_pipe@11 = New_prp_stm,
cake@internal@prepared_statement:append_sql(
_pipe@11,
Frgmnt_prt
)
end,
erlang:element(2, Acc)}
end
end
)
end,
[] = case Empty_param_rest of
[] -> Empty_param_rest;
_assert_fail@2 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@2,
module => <<"cake/internal/query"/utf8>>,
function => <<"apply_fragment"/utf8>>,
line => 1000})
end,
New_prp_stm@2
end.
-spec select_value_apply(
cake@internal@prepared_statement:prepared_statement(),
select_value()
) -> cake@internal@prepared_statement:prepared_statement().
select_value_apply(Prp_stm, V) ->
case V of
{select_column, Col} ->
_pipe = Prp_stm,
cake@internal@prepared_statement:append_sql(_pipe, Col);
{select_param, Param} ->
_pipe@1 = Prp_stm,
cake@internal@prepared_statement:append_param(_pipe@1, Param);
{select_fragment, Frgmnt} ->
_pipe@2 = Prp_stm,
apply_fragment(_pipe@2, Frgmnt);
{select_alias, V@1, Als} ->
_pipe@3 = Prp_stm,
_pipe@4 = select_value_apply(_pipe@3, V@1),
cake@internal@prepared_statement:append_sql(
_pipe@4,
<<" AS "/utf8, Als/binary>>
)
end.
-spec select_part_apply_clause(
cake@internal@prepared_statement:prepared_statement(),
list(select_value())
) -> cake@internal@prepared_statement:prepared_statement().
select_part_apply_clause(Prp_stm, Vs) ->
Prp_stm@1 = begin
_pipe = Prp_stm,
cake@internal@prepared_statement:append_sql(_pipe, <<"SELECT "/utf8>>)
end,
case Vs of
[] ->
_pipe@1 = Prp_stm@1,
cake@internal@prepared_statement:append_sql(_pipe@1, <<"*"/utf8>>);
Vs@1 ->
_pipe@2 = Vs@1,
gleam@list:fold(
_pipe@2,
Prp_stm@1,
fun(New_prp_stm, V) -> case New_prp_stm =:= Prp_stm@1 of
true ->
_pipe@3 = New_prp_stm,
select_value_apply(_pipe@3, V);
false ->
_pipe@4 = New_prp_stm,
_pipe@5 = cake@internal@prepared_statement:append_sql(
_pipe@4,
<<", "/utf8>>
),
select_value_apply(_pipe@5, V)
end end
)
end.
-spec select_builder_maybe_apply_select(
cake@internal@prepared_statement:prepared_statement(),
select_query()
) -> cake@internal@prepared_statement:prepared_statement().
select_builder_maybe_apply_select(Prp_stm, Qry) ->
_pipe = Prp_stm,
select_part_apply_clause(_pipe, erlang:element(3, Qry)).
-spec where_part_apply_literal(
cake@internal@prepared_statement:prepared_statement(),
where_value(),
binary()
) -> cake@internal@prepared_statement:prepared_statement().
where_part_apply_literal(Prp_stm, V, Lt) ->
case V of
{where_column, Col} ->
_pipe = Prp_stm,
cake@internal@prepared_statement:append_sql(
_pipe,
<<<<Col/binary, " "/utf8>>/binary, Lt/binary>>
);
{where_param, Prm} ->
Nxt_plchldr = begin
_pipe@1 = Prp_stm,
cake@internal@prepared_statement:next_placeholder(_pipe@1)
end,
_pipe@2 = Prp_stm,
cake@internal@prepared_statement:append_sql_and_param(
_pipe@2,
<<<<Nxt_plchldr/binary, " "/utf8>>/binary, Lt/binary>>,
Prm
);
{where_fragment, Frgmt} ->
_pipe@3 = Prp_stm,
apply_fragment(_pipe@3, Frgmt)
end.
-spec where_part_apply_comparison(
cake@internal@prepared_statement:prepared_statement(),
where_value(),
binary(),
where_value()
) -> cake@internal@prepared_statement:prepared_statement().
where_part_apply_comparison(Prp_stm, Val_a, Oprtr, Val_b) ->
case {Val_a, Val_b} of
{{where_column, Col_a}, {where_column, Col_b}} ->
_pipe = Prp_stm,
where_part_apply_string(
_pipe,
<<<<<<<<Col_a/binary, " "/utf8>>/binary, Oprtr/binary>>/binary,
" "/utf8>>/binary,
Col_b/binary>>
);
{{where_column, Col}, {where_param, Prm}} ->
_pipe@1 = Prp_stm,
_pipe@2 = where_part_apply_string(
_pipe@1,
<<<<<<Col/binary, " "/utf8>>/binary, Oprtr/binary>>/binary,
" "/utf8>>
),
where_part_apply_param(_pipe@2, Prm);
{{where_param, Prm@1}, {where_column, Col@1}} ->
_pipe@3 = Prp_stm,
_pipe@4 = where_part_apply_param(_pipe@3, Prm@1),
where_part_apply_string(
_pipe@4,
<<<<<<" "/utf8, Oprtr/binary>>/binary, " "/utf8>>/binary,
Col@1/binary>>
);
{{where_param, Prm_a}, {where_param, Prm_b}} ->
_pipe@5 = Prp_stm,
_pipe@6 = where_part_apply_param(_pipe@5, Prm_a),
_pipe@7 = where_part_apply_string(
_pipe@6,
<<<<" "/utf8, Oprtr/binary>>/binary, " "/utf8>>
),
where_part_apply_param(_pipe@7, Prm_b);
{{where_fragment, Frgmt}, {where_column, Col@2}} ->
_pipe@8 = Prp_stm,
_pipe@9 = apply_fragment(_pipe@8, Frgmt),
where_part_apply_string(
_pipe@9,
<<<<<<" "/utf8, Oprtr/binary>>/binary, " "/utf8>>/binary,
Col@2/binary>>
);
{{where_column, Col@3}, {where_fragment, Frgmt@1}} ->
_pipe@10 = Prp_stm,
_pipe@11 = where_part_apply_string(
_pipe@10,
<<<<<<Col@3/binary, " "/utf8>>/binary, Oprtr/binary>>/binary,
" "/utf8>>
),
apply_fragment(_pipe@11, Frgmt@1);
{{where_fragment, Frgmt@2}, {where_param, Prm@2}} ->
_pipe@12 = Prp_stm,
_pipe@13 = apply_fragment(_pipe@12, Frgmt@2),
_pipe@14 = where_part_apply_string(
_pipe@13,
<<<<" "/utf8, Oprtr/binary>>/binary, " "/utf8>>
),
where_part_apply_param(_pipe@14, Prm@2);
{{where_param, Prm@3}, {where_fragment, Frgmt@3}} ->
_pipe@15 = Prp_stm,
_pipe@16 = where_part_apply_param(_pipe@15, Prm@3),
_pipe@17 = where_part_apply_string(
_pipe@16,
<<<<" "/utf8, Oprtr/binary>>/binary, " "/utf8>>
),
apply_fragment(_pipe@17, Frgmt@3);
{{where_fragment, Frgmt_a}, {where_fragment, Frgmt_b}} ->
_pipe@18 = Prp_stm,
_pipe@19 = apply_fragment(_pipe@18, Frgmt_a),
_pipe@20 = where_part_apply_string(
_pipe@19,
<<<<" "/utf8, Oprtr/binary>>/binary, " "/utf8>>
),
apply_fragment(_pipe@20, Frgmt_b)
end.
-spec where_part_apply_value_in_values(
cake@internal@prepared_statement:prepared_statement(),
where_value(),
list(where_value())
) -> cake@internal@prepared_statement:prepared_statement().
where_part_apply_value_in_values(Prp_stm, Val, Prms) ->
Prp_stm@1 = begin
_pipe@4 = case Val of
{where_column, Col} ->
_pipe = Prp_stm,
cake@internal@prepared_statement:append_sql(_pipe, Col);
{where_param, Prm} ->
Nxt_plchldr_a = begin
_pipe@1 = Prp_stm,
cake@internal@prepared_statement:next_placeholder(_pipe@1)
end,
_pipe@2 = Prp_stm,
cake@internal@prepared_statement:append_sql_and_param(
_pipe@2,
Nxt_plchldr_a,
Prm
);
{where_fragment, Frgmt} ->
_pipe@3 = Prp_stm,
apply_fragment(_pipe@3, Frgmt)
end,
cake@internal@prepared_statement:append_sql(_pipe@4, <<" IN ("/utf8>>)
end,
_pipe@5 = Prms,
_pipe@12 = gleam@list:fold(
_pipe@5,
Prp_stm@1,
fun(New_prp_stm, V) -> case V of
{where_column, Col@1} ->
case New_prp_stm =:= Prp_stm@1 of
true ->
_pipe@6 = Prp_stm@1,
cake@internal@prepared_statement:append_sql(
_pipe@6,
Col@1
);
false ->
_pipe@7 = New_prp_stm,
cake@internal@prepared_statement:append_sql(
_pipe@7,
<<", "/utf8, Col@1/binary>>
)
end;
{where_param, Prm@1} ->
_pipe@10 = case New_prp_stm =:= Prp_stm@1 of
true ->
_pipe@8 = New_prp_stm,
cake@internal@prepared_statement:next_placeholder(
_pipe@8
);
false ->
<<", "/utf8,
(begin
_pipe@9 = New_prp_stm,
cake@internal@prepared_statement:next_placeholder(
_pipe@9
)
end)/binary>>
end,
cake@internal@prepared_statement:append_sql_and_param(
New_prp_stm,
_pipe@10,
Prm@1
);
{where_fragment, Frgmt@1} ->
_pipe@11 = Prp_stm@1,
apply_fragment(_pipe@11, Frgmt@1)
end end
),
cake@internal@prepared_statement:append_sql(_pipe@12, <<")"/utf8>>).
-spec where_part_apply_between(
cake@internal@prepared_statement:prepared_statement(),
where_value(),
where_value(),
where_value()
) -> cake@internal@prepared_statement:prepared_statement().
where_part_apply_between(Prp_stm, Val_a, Val_b, Val_c) ->
Prp_stm@1 = begin
_pipe@4 = case Val_a of
{where_column, Col} ->
_pipe = Prp_stm,
cake@internal@prepared_statement:append_sql(_pipe, Col);
{where_param, Prm} ->
Nxt_plchldr = begin
_pipe@1 = Prp_stm,
cake@internal@prepared_statement:next_placeholder(_pipe@1)
end,
_pipe@2 = Prp_stm,
cake@internal@prepared_statement:append_sql_and_param(
_pipe@2,
Nxt_plchldr,
Prm
);
{where_fragment, Frgmt} ->
_pipe@3 = Prp_stm,
apply_fragment(_pipe@3, Frgmt)
end,
cake@internal@prepared_statement:append_sql(
_pipe@4,
<<" BETWEEN "/utf8>>
)
end,
Prp_stm@2 = begin
_pipe@9 = case Val_b of
{where_column, Col@1} ->
_pipe@5 = Prp_stm@1,
cake@internal@prepared_statement:append_sql(_pipe@5, Col@1);
{where_param, Prm@1} ->
Nxt_plchldr@1 = begin
_pipe@6 = Prp_stm@1,
cake@internal@prepared_statement:next_placeholder(_pipe@6)
end,
_pipe@7 = Prp_stm@1,
cake@internal@prepared_statement:append_sql_and_param(
_pipe@7,
Nxt_plchldr@1,
Prm@1
);
{where_fragment, Frgmt@1} ->
_pipe@8 = Prp_stm@1,
apply_fragment(_pipe@8, Frgmt@1)
end,
cake@internal@prepared_statement:append_sql(_pipe@9, <<" AND "/utf8>>)
end,
Prp_stm@3 = case Val_c of
{where_column, Col@2} ->
_pipe@10 = Prp_stm@2,
cake@internal@prepared_statement:append_sql(_pipe@10, Col@2);
{where_param, Prm@2} ->
Nxt_plchldr_a = begin
_pipe@11 = Prp_stm@2,
cake@internal@prepared_statement:next_placeholder(_pipe@11)
end,
_pipe@12 = Prp_stm@2,
cake@internal@prepared_statement:append_sql_and_param(
_pipe@12,
Nxt_plchldr_a,
Prm@2
);
{where_fragment, Frgmt@2} ->
_pipe@13 = Prp_stm@2,
apply_fragment(_pipe@13, Frgmt@2)
end,
Prp_stm@3.
-spec from_part_apply(
cake@internal@prepared_statement:prepared_statement(),
from_part()
) -> cake@internal@prepared_statement:prepared_statement().
from_part_apply(Prp_stm, Prt) ->
case Prt of
{from_table, Tbl} ->
_pipe = Prp_stm,
cake@internal@prepared_statement:append_sql(
_pipe,
<<" FROM "/utf8, Tbl/binary>>
);
{from_sub_query, Qry, Als} ->
_pipe@1 = Prp_stm,
_pipe@2 = cake@internal@prepared_statement:append_sql(
_pipe@1,
<<" FROM ("/utf8>>
),
_pipe@3 = builder_apply(_pipe@2, Qry),
cake@internal@prepared_statement:append_sql(
_pipe@3,
<<") AS "/utf8, Als/binary>>
);
no_from_part ->
Prp_stm
end.
-spec builder_apply(
cake@internal@prepared_statement:prepared_statement(),
'query'()
) -> cake@internal@prepared_statement:prepared_statement().
builder_apply(Prp_stm, Qry) ->
case Qry of
{select, Qry@1} ->
_pipe = Prp_stm,
select_builder(_pipe, Qry@1);
{combined, Qry@2} ->
_pipe@1 = Prp_stm,
combined_builder(_pipe@1, Qry@2)
end.
-spec select_builder(
cake@internal@prepared_statement:prepared_statement(),
select_query()
) -> cake@internal@prepared_statement:prepared_statement().
select_builder(Prp_stm, Qry) ->
_pipe = Prp_stm,
_pipe@1 = select_builder_maybe_apply_select(_pipe, Qry),
_pipe@2 = select_builder_maybe_apply_from(_pipe@1, Qry),
_pipe@3 = select_builder_maybe_apply_join(_pipe@2, Qry),
_pipe@4 = select_builder_maybe_apply_where(_pipe@3, Qry),
_pipe@5 = select_builder_apply_to_sql(
_pipe@4,
Qry,
fun select_builder_maybe_add_order_sql/1
),
select_builder_maybe_apply_limit_offset(_pipe@5, Qry).
-spec select_builder_maybe_apply_from(
cake@internal@prepared_statement:prepared_statement(),
select_query()
) -> cake@internal@prepared_statement:prepared_statement().
select_builder_maybe_apply_from(Prp_stm, Qry) ->
_pipe = Prp_stm,
from_part_apply(_pipe, erlang:element(2, Qry)).
-spec builder_new('query'(), binary()) -> cake@internal@prepared_statement:prepared_statement().
builder_new(Qry, Prp_stm_prfx) ->
_pipe = Prp_stm_prfx,
_pipe@1 = cake@internal@prepared_statement:new(_pipe),
builder_apply(_pipe@1, Qry).
-spec combined_builder_apply_command_sql(
cake@internal@prepared_statement:prepared_statement(),
combined_query()
) -> cake@internal@prepared_statement:prepared_statement().
combined_builder_apply_command_sql(Prp_stm, Cmbnd_qry) ->
Sql_command = case erlang:element(2, Cmbnd_qry) of
union ->
<<"UNION"/utf8>>;
union_all ->
<<"UNION ALL"/utf8>>;
except ->
<<"EXCEPT"/utf8>>;
except_all ->
<<"EXCEPT ALL"/utf8>>;
intersect ->
<<"INTERSECT"/utf8>>;
intersect_all ->
<<"INTERSECT ALL"/utf8>>
end,
_pipe = erlang:element(3, Cmbnd_qry),
gleam@list:fold(
_pipe,
Prp_stm,
fun(New_prp_stm, Qry) -> case New_prp_stm =:= Prp_stm of
true ->
_pipe@1 = New_prp_stm,
select_builder(_pipe@1, Qry);
false ->
_pipe@2 = New_prp_stm,
_pipe@3 = cake@internal@prepared_statement:append_sql(
_pipe@2,
<<<<" "/utf8, Sql_command/binary>>/binary, " "/utf8>>
),
select_builder(_pipe@3, Qry)
end end
).
-spec combined_builder(
cake@internal@prepared_statement:prepared_statement(),
combined_query()
) -> cake@internal@prepared_statement:prepared_statement().
combined_builder(Prp_stm, Cmbnd_qry) ->
_pipe = Prp_stm,
_pipe@1 = combined_builder_apply_command_sql(_pipe, Cmbnd_qry),
_pipe@2 = combined_builder_apply_to_sql(
_pipe@1,
Cmbnd_qry,
fun combined_builder_maybe_add_order_sql/1
),
_pipe@3 = limit_offset_apply(_pipe@2, erlang:element(4, Cmbnd_qry)),
epilog_apply(_pipe@3, erlang:element(6, Cmbnd_qry)).
-spec join_part_apply(
cake@internal@prepared_statement:prepared_statement(),
join_part()
) -> cake@internal@prepared_statement:prepared_statement().
join_part_apply(Prp_stm, Prt) ->
case erlang:element(2, Prt) of
{join_table, Tbl} ->
_pipe = Prp_stm,
cake@internal@prepared_statement:append_sql(
_pipe,
<<<<Tbl/binary, " AS "/utf8>>/binary,
(erlang:element(3, Prt))/binary>>
);
{join_sub_query, Qry} ->
_pipe@1 = Prp_stm,
_pipe@2 = cake@internal@prepared_statement:append_sql(
_pipe@1,
<<"("/utf8>>
),
_pipe@3 = builder_apply(_pipe@2, Qry),
cake@internal@prepared_statement:append_sql(
_pipe@3,
<<") AS "/utf8, (erlang:element(3, Prt))/binary>>
)
end.
-spec where_part_apply_logical_operator(
cake@internal@prepared_statement:prepared_statement(),
binary(),
list(where_part())
) -> cake@internal@prepared_statement:prepared_statement().
where_part_apply_logical_operator(Prp_stm, Oprtr, Prts) ->
Prp_stm@1 = begin
_pipe = Prp_stm,
cake@internal@prepared_statement:append_sql(_pipe, <<"("/utf8>>)
end,
_pipe@1 = Prts,
_pipe@5 = gleam@list:fold(
_pipe@1,
Prp_stm@1,
fun(New_prp_stm, Prt) -> case New_prp_stm =:= Prp_stm@1 of
true ->
_pipe@2 = New_prp_stm,
where_part_apply(_pipe@2, Prt);
false ->
_pipe@3 = New_prp_stm,
_pipe@4 = cake@internal@prepared_statement:append_sql(
_pipe@3,
<<<<" "/utf8, Oprtr/binary>>/binary, " "/utf8>>
),
where_part_apply(_pipe@4, Prt)
end end
),
cake@internal@prepared_statement:append_sql(_pipe@5, <<")"/utf8>>).
-spec where_part_apply(
cake@internal@prepared_statement:prepared_statement(),
where_part()
) -> cake@internal@prepared_statement:prepared_statement().
where_part_apply(Prp_stm, Prt) ->
case Prt of
{where_equal, Val_a, Val_b} ->
_pipe = Prp_stm,
where_part_apply_comparison(_pipe, Val_a, <<"="/utf8>>, Val_b);
{where_lower, Val_a@1, Val_b@1} ->
_pipe@1 = Prp_stm,
where_part_apply_comparison(_pipe@1, Val_a@1, <<"<"/utf8>>, Val_b@1);
{where_lower_or_equal, Val_a@2, Val_b@2} ->
_pipe@2 = Prp_stm,
where_part_apply_comparison(
_pipe@2,
Val_a@2,
<<"<="/utf8>>,
Val_b@2
);
{where_greater, Val_a@3, Val_b@3} ->
_pipe@3 = Prp_stm,
where_part_apply_comparison(_pipe@3, Val_a@3, <<">"/utf8>>, Val_b@3);
{where_greater_or_equal, Val_a@4, Val_b@4} ->
_pipe@4 = Prp_stm,
where_part_apply_comparison(
_pipe@4,
Val_a@4,
<<">="/utf8>>,
Val_b@4
);
{where_unequal, Val_a@5, Val_b@5} ->
_pipe@5 = Prp_stm,
where_part_apply_comparison(
_pipe@5,
Val_a@5,
<<"<>"/utf8>>,
Val_b@5
);
{where_is_bool, Val, true} ->
_pipe@6 = Prp_stm,
where_part_apply_literal(_pipe@6, Val, <<"IS TRUE"/utf8>>);
{where_is_bool, Val@1, false} ->
_pipe@7 = Prp_stm,
where_part_apply_literal(_pipe@7, Val@1, <<"IS FALSE"/utf8>>);
{where_is_not_bool, Val@2, true} ->
_pipe@8 = Prp_stm,
where_part_apply_literal(_pipe@8, Val@2, <<"IS NOT TRUE"/utf8>>);
{where_is_not_bool, Val@3, false} ->
_pipe@9 = Prp_stm,
where_part_apply_literal(_pipe@9, Val@3, <<"IS NOT FALSE"/utf8>>);
{where_is_null, Val@4} ->
_pipe@10 = Prp_stm,
where_part_apply_literal(_pipe@10, Val@4, <<"IS NULL"/utf8>>);
{where_is_not_null, Val@5} ->
_pipe@11 = Prp_stm,
where_part_apply_literal(_pipe@11, Val@5, <<"IS NOT NULL"/utf8>>);
{where_like, Val@6, Prm} ->
_pipe@12 = Prp_stm,
where_part_apply_comparison(
_pipe@12,
Val@6,
<<"LIKE"/utf8>>,
{where_param, {string_param, Prm}}
);
{where_i_like, Col, Prm@1} ->
_pipe@13 = Prp_stm,
where_part_apply_comparison(
_pipe@13,
Col,
<<"ILIKE"/utf8>>,
{where_param, {string_param, Prm@1}}
);
{where_similar, Col@1, Prm@2} ->
_pipe@14 = Prp_stm,
_pipe@15 = where_part_apply_comparison(
_pipe@14,
Col@1,
<<"SIMILAR TO"/utf8>>,
{where_param, {string_param, Prm@2}}
),
cake@internal@prepared_statement:append_sql(
_pipe@15,
<<" ESCAPE '/'"/utf8>>
);
{and_where, Prts} ->
_pipe@16 = Prp_stm,
where_part_apply_logical_operator(_pipe@16, <<"AND"/utf8>>, Prts);
{or_where, Prts@1} ->
_pipe@17 = Prp_stm,
where_part_apply_logical_operator(_pipe@17, <<"OR"/utf8>>, Prts@1);
{not_where, Prt@1} ->
_pipe@18 = Prp_stm,
_pipe@19 = cake@internal@prepared_statement:append_sql(
_pipe@18,
<<"NOT ("/utf8>>
),
_pipe@20 = where_part_apply(_pipe@19, Prt@1),
cake@internal@prepared_statement:append_sql(_pipe@20, <<")"/utf8>>);
{where_in, Val@7, Vals} ->
_pipe@21 = Prp_stm,
where_part_apply_value_in_values(_pipe@21, Val@7, Vals);
{where_between, Val_a@6, Val_b@6, Val_c} ->
_pipe@22 = Prp_stm,
where_part_apply_between(_pipe@22, Val_a@6, Val_b@6, Val_c);
no_where_part ->
Prp_stm
end.
-spec where_part_apply_clause(
cake@internal@prepared_statement:prepared_statement(),
where_part()
) -> cake@internal@prepared_statement:prepared_statement().
where_part_apply_clause(Prp_stm, Prt) ->
case Prt of
no_where_part ->
Prp_stm;
Prt@1 ->
_pipe = Prp_stm,
_pipe@1 = cake@internal@prepared_statement:append_sql(
_pipe,
<<" WHERE "/utf8>>
),
where_part_apply(_pipe@1, Prt@1)
end.
-spec select_builder_maybe_apply_where(
cake@internal@prepared_statement:prepared_statement(),
select_query()
) -> cake@internal@prepared_statement:prepared_statement().
select_builder_maybe_apply_where(Prp_stm, Qry) ->
_pipe = Prp_stm,
where_part_apply_clause(_pipe, erlang:element(5, Qry)).
-spec join_parts_apply_clause(
cake@internal@prepared_statement:prepared_statement(),
list(join_part())
) -> cake@internal@prepared_statement:prepared_statement().
join_parts_apply_clause(Prp_stm, Prts) ->
_pipe = Prts,
gleam@list:fold(
_pipe,
Prp_stm,
fun(New_prp_stm, Prt) ->
Apply_join = fun(New_prp_stm@1, Sql_command) ->
_pipe@1 = New_prp_stm@1,
_pipe@2 = cake@internal@prepared_statement:append_sql(
_pipe@1,
<<<<" "/utf8, Sql_command/binary>>/binary, " "/utf8>>
),
join_part_apply(_pipe@2, Prt)
end,
Apply_on = fun(New_prp_stm@2, On) -> _pipe@3 = New_prp_stm@2,
_pipe@4 = cake@internal@prepared_statement:append_sql(
_pipe@3,
<<" ON "/utf8>>
),
where_part_apply(_pipe@4, On) end,
case Prt of
{cross_join, _, _} ->
_pipe@5 = New_prp_stm,
Apply_join(_pipe@5, <<"CROSS JOIN"/utf8>>);
{inner_join, _, _, On@1} ->
_pipe@6 = New_prp_stm,
_pipe@7 = Apply_join(_pipe@6, <<"INNER JOIN"/utf8>>),
Apply_on(_pipe@7, On@1);
{left_outer_join, _, _, On@2} ->
_pipe@8 = New_prp_stm,
_pipe@9 = Apply_join(_pipe@8, <<"LEFT OUTER JOIN"/utf8>>),
Apply_on(_pipe@9, On@2);
{right_outer_join, _, _, On@3} ->
_pipe@10 = New_prp_stm,
_pipe@11 = Apply_join(_pipe@10, <<"RIGHT OUTER JOIN"/utf8>>),
Apply_on(_pipe@11, On@3);
{full_outer_join, _, _, On@4} ->
_pipe@12 = New_prp_stm,
_pipe@13 = Apply_join(_pipe@12, <<"FULL OUTER JOIN"/utf8>>),
Apply_on(_pipe@13, On@4)
end
end
).
-spec select_builder_maybe_apply_join(
cake@internal@prepared_statement:prepared_statement(),
select_query()
) -> cake@internal@prepared_statement:prepared_statement().
select_builder_maybe_apply_join(Prp_stm, Qry) ->
_pipe = Prp_stm,
join_parts_apply_clause(_pipe, erlang:element(4, Qry)).