-module(cake@internal@write_query). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([to_insert_query/1, update_to_write_query/1, delete_to_write_query/1, to_prepared_statement/3]). -export_type([write_query/1, returning/0, insert/1, insert_into_table/0, insert_columns/0, insert_modifier/0, insert_source/1, insert_row/0, insert_value/0, insert_conflict_strategy/1, insert_confict_target/0, update/1, update_modifier/0, update_table/0, update_sets/0, update_set/0, delete/1, delete_modifier/0, delete_table/0, delete_using/0]). -type write_query(PXM) :: {insert_query, insert(PXM)} | {update_query, update(PXM)} | {delete_query, delete(PXM)}. -type returning() :: no_returning | {returning, list(binary())}. -type insert(PXN) :: {insert, insert_into_table(), insert_columns(), insert_modifier(), insert_source(PXN), insert_conflict_strategy(PXN), returning(), cake@internal@query:epilog(), cake@internal@query:comment()}. -type insert_into_table() :: {insert_into_table, binary()}. -type insert_columns() :: {insert_columns, list(binary())}. -type insert_modifier() :: no_insert_modifier | {insert_modifier, binary()}. -type insert_source(PXO) :: insert_source_default | {insert_source_records, list(PXO), fun((PXO) -> insert_row())} | {insert_source_rows, list(insert_row())} | {insert_source_query, cake@internal@query:'query'()}. -type insert_row() :: {insert_row, list(insert_value())}. -type insert_value() :: {insert_param, binary(), cake@param:param()} | {insert_default, binary()}. -type insert_conflict_strategy(PXP) :: insert_conflict_error | {insert_conflict_ignore, insert_confict_target(), cake@internal@query:where()} | {insert_conflict_update, insert_confict_target(), cake@internal@query:where(), update(PXP)}. -type insert_confict_target() :: {insert_conflict_target, list(binary())} | {insert_conflict_target_constraint, binary()}. -type update(PXQ) :: {update, update_table(), update_modifier(), update_sets(), cake@internal@query:from(), cake@internal@query:joins(), cake@internal@query:where(), returning(), cake@internal@query:epilog(), cake@internal@query:comment()} | {gleam_phantom, PXQ}. -type update_modifier() :: no_update_modifier | {update_modifier, binary()}. -type update_table() :: {update_table, binary()}. -type update_sets() :: {update_sets, list(update_set())}. -type update_set() :: {update_param_set, binary(), cake@param:param()} | {update_expression_set, list(binary()), binary()} | {update_sub_query_set, list(binary()), cake@internal@query:'query'()}. -type delete(PXR) :: {delete, delete_modifier(), delete_table(), delete_using(), cake@internal@query:where(), returning(), cake@internal@query:epilog(), cake@internal@query:comment()} | {gleam_phantom, PXR}. -type delete_modifier() :: no_delete_modifier | {delete_modifier, binary()}. -type delete_table() :: {delete_table, binary()}. -type delete_using() :: no_delete_using | {delete_using, list(cake@internal@query:from())}. -spec returning_apply( cake@internal@prepared_statement:prepared_statement(), returning() ) -> cake@internal@prepared_statement:prepared_statement(). returning_apply(Prp_stm, Rtrn) -> case Rtrn of no_returning -> Prp_stm; {returning, Cols} -> _pipe = Prp_stm, _pipe@1 = cake@internal@prepared_statement:append_sql( _pipe, <<" RETURNING "/utf8>> ), cake@internal@prepared_statement:append_sql( _pipe@1, begin _pipe@2 = Cols, gleam@string:join(_pipe@2, <<", "/utf8>>) end ) end. -spec to_insert_query(insert(PXW)) -> write_query(PXW). to_insert_query(Insert) -> _pipe = Insert, {insert_query, _pipe}. -spec insert_modifier_apply( cake@internal@prepared_statement:prepared_statement(), insert_modifier() ) -> cake@internal@prepared_statement:prepared_statement(). insert_modifier_apply(Prp_stm, Isrt_mdfr) -> case Isrt_mdfr of no_insert_modifier -> Prp_stm; {insert_modifier, Mdfr} -> _pipe = Prp_stm, cake@internal@prepared_statement:append_sql( _pipe, <<" "/utf8, Mdfr/binary>> ) end. -spec row_apply( cake@internal@prepared_statement:prepared_statement(), list(insert_value()) ) -> cake@internal@prepared_statement:prepared_statement(). row_apply(New_prp_stm, Row) -> _pipe = Row, gleam@list:fold( _pipe, New_prp_stm, fun(New_prp_stm_inner, Insert_value) -> case Insert_value of {insert_param, _, Param} -> case New_prp_stm_inner =:= New_prp_stm of true -> _pipe@1 = New_prp_stm_inner, cake@internal@prepared_statement:append_param( _pipe@1, Param ); false -> _pipe@2 = New_prp_stm_inner, _pipe@3 = cake@internal@prepared_statement:append_sql( _pipe@2, <<", "/utf8>> ), cake@internal@prepared_statement:append_param( _pipe@3, Param ) end; {insert_default, _} -> case New_prp_stm_inner =:= New_prp_stm of true -> _pipe@4 = New_prp_stm_inner, cake@internal@prepared_statement:append_sql( _pipe@4, <<"DEFAULT"/utf8>> ); false -> _pipe@5 = New_prp_stm_inner, cake@internal@prepared_statement:append_sql( _pipe@5, <<", DEFAULT"/utf8>> ) end end end ). -spec insert_from_params_apply( cake@internal@prepared_statement:prepared_statement(), list(PYC), fun((PYC) -> insert_row()) ) -> cake@internal@prepared_statement:prepared_statement(). insert_from_params_apply(Prp_stm, Src, Cstr) -> Prp_stm@1 = begin _pipe = Prp_stm, cake@internal@prepared_statement:append_sql(_pipe, <<" ("/utf8>>) end, Prp_stm@2 = begin _pipe@1 = Src, gleam@list:fold( _pipe@1, Prp_stm@1, fun(New_prp_stm, Rcrd) -> {insert_row, Row} = begin _pipe@2 = Rcrd, Cstr(_pipe@2) end, case New_prp_stm =:= Prp_stm@1 of true -> _pipe@3 = New_prp_stm, row_apply(_pipe@3, Row); false -> _pipe@4 = New_prp_stm, _pipe@5 = cake@internal@prepared_statement:append_sql( _pipe@4, <<"), ("/utf8>> ), row_apply(_pipe@5, Row) end end ) end, Prp_stm@3 = begin _pipe@6 = Prp_stm@2, cake@internal@prepared_statement:append_sql(_pipe@6, <<")"/utf8>>) end, Prp_stm@3. -spec insert_from_values_apply( cake@internal@prepared_statement:prepared_statement(), list(insert_row()) ) -> cake@internal@prepared_statement:prepared_statement(). insert_from_values_apply(Prp_stm, Src) -> Prp_stm@1 = begin _pipe = Prp_stm, cake@internal@prepared_statement:append_sql(_pipe, <<" ("/utf8>>) end, Prp_stm@2 = begin _pipe@1 = Src, gleam@list:fold( _pipe@1, Prp_stm@1, fun(New_prp_stm, Row) -> {insert_row, Row@1} = Row, case New_prp_stm =:= Prp_stm@1 of true -> _pipe@2 = New_prp_stm, row_apply(_pipe@2, Row@1); false -> _pipe@3 = New_prp_stm, _pipe@4 = cake@internal@prepared_statement:append_sql( _pipe@3, <<"), ("/utf8>> ), row_apply(_pipe@4, Row@1) end end ) end, Prp_stm@3 = begin _pipe@5 = Prp_stm@2, cake@internal@prepared_statement:append_sql(_pipe@5, <<")"/utf8>>) end, Prp_stm@3. -spec insert_from_query_apply( cake@internal@prepared_statement:prepared_statement(), cake@internal@query:'query'() ) -> cake@internal@prepared_statement:prepared_statement(). insert_from_query_apply(Prp_stm, Qry) -> _pipe = Prp_stm, _pipe@1 = cake@internal@prepared_statement:append_sql(_pipe, <<" ("/utf8>>), _pipe@2 = cake@internal@query:apply(_pipe@1, Qry), cake@internal@prepared_statement:append_sql(_pipe@2, <<")"/utf8>>). -spec on_conflict_target_apply( cake@internal@prepared_statement:prepared_statement(), insert_confict_target() ) -> cake@internal@prepared_statement:prepared_statement(). on_conflict_target_apply(Prp_stm, Cflt_trgt) -> case Cflt_trgt of {insert_conflict_target, Cols} -> _pipe = Prp_stm, cake@internal@prepared_statement:append_sql( _pipe, begin _pipe@1 = Cols, gleam@string:join(_pipe@1, <<", "/utf8>>) end ); {insert_conflict_target_constraint, Cnstrnt} -> _pipe@2 = Prp_stm, cake@internal@prepared_statement:append_sql(_pipe@2, Cnstrnt) end. -spec update_to_write_query(update(PYN)) -> write_query(PYN). update_to_write_query(Insert) -> _pipe = Insert, {update_query, _pipe}. -spec update_modifier_apply( cake@internal@prepared_statement:prepared_statement(), update_modifier() ) -> cake@internal@prepared_statement:prepared_statement(). update_modifier_apply(Prp_stm, Updt_mdfr) -> case Updt_mdfr of no_update_modifier -> Prp_stm; {update_modifier, Mdfr} -> _pipe = Prp_stm, cake@internal@prepared_statement:append_sql( _pipe, <<" "/utf8, Mdfr/binary>> ) end. -spec update_sets_apply( cake@internal@prepared_statement:prepared_statement(), list(update_set()) ) -> cake@internal@prepared_statement:prepared_statement(). update_sets_apply(Prp_stm, Updt_sts) -> Apply_columns = fun(New_prp_stm, Cols) -> case Cols of [] -> _pipe = New_prp_stm, cake@internal@prepared_statement:append_sql(_pipe, <<" "/utf8>>); [Col] -> _pipe@1 = New_prp_stm, cake@internal@prepared_statement:append_sql( _pipe@1, <>) end)/binary>>/binary, ")"/utf8>> ), cake@internal@prepared_statement:append_sql( _pipe@4, <<" ="/utf8>> ) end end, _pipe@5 = Updt_sts, gleam@list:fold( _pipe@5, Prp_stm, fun(New_prp_stm@1, Updt_st) -> New_prp_stm@2 = case New_prp_stm@1 =:= Prp_stm of true -> _pipe@6 = New_prp_stm@1, cake@internal@prepared_statement:append_sql( _pipe@6, <<" "/utf8>> ); false -> _pipe@7 = New_prp_stm@1, cake@internal@prepared_statement:append_sql( _pipe@7, <<", "/utf8>> ) end, case Updt_st of {update_param_set, Col@1, Prm} -> _pipe@8 = New_prp_stm@2, _pipe@9 = Apply_columns(_pipe@8, [Col@1]), _pipe@10 = cake@internal@prepared_statement:append_sql( _pipe@9, <<" "/utf8>> ), cake@internal@prepared_statement:append_param(_pipe@10, Prm); {update_expression_set, Cols@1, Expr} -> _pipe@11 = New_prp_stm@2, _pipe@12 = Apply_columns(_pipe@11, Cols@1), cake@internal@prepared_statement:append_sql( _pipe@12, <<" "/utf8, Expr/binary>> ); {update_sub_query_set, Cols@2, Qry} -> _pipe@13 = Prp_stm, _pipe@14 = Apply_columns(_pipe@13, Cols@2), _pipe@15 = cake@internal@prepared_statement:append_sql( _pipe@14, <<" ("/utf8>> ), _pipe@16 = cake@internal@query:apply(_pipe@15, Qry), cake@internal@prepared_statement:append_sql( _pipe@16, <<")"/utf8>> ) end end ). -spec update_apply( cake@internal@prepared_statement:prepared_statement(), update(any()) ) -> cake@internal@prepared_statement:prepared_statement(). update_apply(Prp_stm, Updt) -> {update_table, Updt_tbl} = erlang:element(2, Updt), {update_sets, Updt_sets} = erlang:element(4, Updt), _pipe = Prp_stm, _pipe@1 = cake@internal@prepared_statement:append_sql( _pipe, <<"UPDATE "/utf8, Updt_tbl/binary>> ), _pipe@2 = update_modifier_apply(_pipe@1, erlang:element(3, Updt)), _pipe@3 = cake@internal@prepared_statement:append_sql( _pipe@2, <<" SET"/utf8>> ), _pipe@4 = update_sets_apply(_pipe@3, Updt_sets), _pipe@5 = cake@internal@query:from_clause_apply( _pipe@4, erlang:element(5, Updt) ), _pipe@6 = cake@internal@query:join_clause_apply( _pipe@5, erlang:element(6, Updt) ), _pipe@7 = cake@internal@query:where_clause_apply( _pipe@6, erlang:element(7, Updt) ), _pipe@8 = returning_apply(_pipe@7, erlang:element(8, Updt)), _pipe@9 = cake@internal@query:comment_apply( _pipe@8, erlang:element(10, Updt) ), cake@internal@query:epilog_apply(_pipe@9, erlang:element(9, Updt)). -spec on_conflict_apply( cake@internal@prepared_statement:prepared_statement(), insert_conflict_strategy(any()) ) -> cake@internal@prepared_statement:prepared_statement(). on_conflict_apply(Prp_stm, On_cnf) -> case On_cnf of insert_conflict_error -> Prp_stm; {insert_conflict_ignore, Cflt_trgt, Whr} -> _pipe = Prp_stm, _pipe@1 = cake@internal@prepared_statement:append_sql( _pipe, <<" ON CONFLICT"/utf8>> ), _pipe@2 = on_conflict_target_apply(_pipe@1, Cflt_trgt), _pipe@3 = cake@internal@query:where_clause_apply(_pipe@2, Whr), cake@internal@prepared_statement:append_sql( _pipe@3, <<" DO NOTHING"/utf8>> ); {insert_conflict_update, Cflt_trgt@1, Whr@1, Upt} -> _pipe@4 = Prp_stm, _pipe@5 = cake@internal@prepared_statement:append_sql( _pipe@4, <<" ON CONFLICT ("/utf8>> ), _pipe@6 = on_conflict_target_apply(_pipe@5, Cflt_trgt@1), _pipe@7 = cake@internal@query:where_clause_apply(_pipe@6, Whr@1), _pipe@8 = cake@internal@prepared_statement:append_sql( _pipe@7, <<" DO "/utf8>> ), update_apply(_pipe@8, Upt) end. -spec insert_apply( cake@internal@prepared_statement:prepared_statement(), insert(any()) ) -> cake@internal@prepared_statement:prepared_statement(). insert_apply(Prp_stm, Isrt) -> {insert_into_table, Tbl_name} = erlang:element(2, Isrt), {insert_columns, Insert_columns} = erlang:element(3, Isrt), Prp_stm@1 = begin _pipe = Prp_stm, _pipe@2 = cake@internal@prepared_statement:append_sql( _pipe, <<<<<<<<"INSERT INTO "/utf8, Tbl_name/binary>>/binary, " ("/utf8>>/binary, (begin _pipe@1 = Insert_columns, gleam@string:join(_pipe@1, <<", "/utf8>>) end)/binary>>/binary, ")"/utf8>> ), insert_modifier_apply(_pipe@2, erlang:element(4, Isrt)) end, Prp_stm@2 = case erlang:element(5, Isrt) of {insert_source_records, Src, Cstr} -> _pipe@3 = Prp_stm@1, _pipe@4 = cake@internal@prepared_statement:append_sql( _pipe@3, <<" VALUES"/utf8>> ), insert_from_params_apply(_pipe@4, Src, Cstr); {insert_source_rows, Src@1} -> _pipe@5 = Prp_stm@1, _pipe@6 = cake@internal@prepared_statement:append_sql( _pipe@5, <<" VALUES"/utf8>> ), insert_from_values_apply(_pipe@6, Src@1); {insert_source_query, Qry} -> _pipe@7 = Prp_stm@1, _pipe@8 = cake@internal@prepared_statement:append_sql( _pipe@7, <<" VALUES"/utf8>> ), insert_from_query_apply(_pipe@8, Qry); insert_source_default -> _pipe@9 = Prp_stm@1, cake@internal@prepared_statement:append_sql( _pipe@9, <<" DEFAULT VALUES"/utf8>> ) end, _pipe@10 = Prp_stm@2, _pipe@11 = on_conflict_apply(_pipe@10, erlang:element(6, Isrt)), _pipe@12 = returning_apply(_pipe@11, erlang:element(7, Isrt)), _pipe@13 = cake@internal@query:comment_apply( _pipe@12, erlang:element(9, Isrt) ), cake@internal@query:epilog_apply(_pipe@13, erlang:element(8, Isrt)). -spec delete_to_write_query(delete(PYV)) -> write_query(PYV). delete_to_write_query(Insert) -> _pipe = Insert, {delete_query, _pipe}. -spec delete_modifier_apply( cake@internal@prepared_statement:prepared_statement(), delete_modifier() ) -> cake@internal@prepared_statement:prepared_statement(). delete_modifier_apply(Prp_stm, Updt_mdfr) -> case Updt_mdfr of no_delete_modifier -> Prp_stm; {delete_modifier, Mdfr} -> _pipe = Prp_stm, cake@internal@prepared_statement:append_sql( _pipe, <<" "/utf8, Mdfr/binary>> ) end. -spec using_apply( cake@internal@prepared_statement:prepared_statement(), delete_using() ) -> cake@internal@prepared_statement:prepared_statement(). using_apply(Prp_stm, Updt_usng) -> case Updt_usng of no_delete_using -> Prp_stm; {delete_using, Frms} -> Prp_stm@1 = begin _pipe = Prp_stm, cake@internal@prepared_statement:append_sql( _pipe, <<" USING "/utf8>> ) end, _pipe@1 = Frms, gleam@list:fold( _pipe@1, Prp_stm@1, fun(New_prp_stm, Frm) -> New_prp_stm@1 = case {New_prp_stm =:= Prp_stm@1, Frm} of {true, _} -> New_prp_stm; {_, no_from} -> New_prp_stm; {false, _} -> _pipe@2 = New_prp_stm, cake@internal@prepared_statement:append_sql( _pipe@2, <<", "/utf8>> ) end, case Frm of no_from -> New_prp_stm@1; {from_table, Tbl} -> _pipe@3 = New_prp_stm@1, cake@internal@prepared_statement:append_sql( _pipe@3, Tbl ); {from_sub_query, Qry, Als} -> _pipe@4 = Prp_stm@1, _pipe@5 = cake@internal@prepared_statement:append_sql( _pipe@4, <<" ("/utf8>> ), _pipe@6 = cake@internal@query:apply(_pipe@5, Qry), cake@internal@prepared_statement:append_sql( _pipe@6, <<") AS "/utf8, Als/binary>> ) end end ) end. -spec delete_apply( cake@internal@prepared_statement:prepared_statement(), delete(any()) ) -> cake@internal@prepared_statement:prepared_statement(). delete_apply(Prp_stm, Dlt) -> {delete_table, Dlt_tbl} = erlang:element(3, Dlt), _pipe = Prp_stm, _pipe@1 = cake@internal@prepared_statement:append_sql( _pipe, <<"DELETE "/utf8, Dlt_tbl/binary>> ), _pipe@2 = delete_modifier_apply(_pipe@1, erlang:element(2, Dlt)), _pipe@3 = using_apply(_pipe@2, erlang:element(4, Dlt)), _pipe@4 = cake@internal@query:where_clause_apply( _pipe@3, erlang:element(5, Dlt) ), _pipe@5 = returning_apply(_pipe@4, erlang:element(6, Dlt)), _pipe@6 = cake@internal@query:comment_apply(_pipe@5, erlang:element(8, Dlt)), cake@internal@query:epilog_apply(_pipe@6, erlang:element(7, Dlt)). -spec apply( cake@internal@prepared_statement:prepared_statement(), write_query(any()) ) -> cake@internal@prepared_statement:prepared_statement(). apply(Prp_stm, Qry) -> case Qry of {insert_query, Insert} -> _pipe = Prp_stm, insert_apply(_pipe, Insert); {update_query, Update} -> _pipe@1 = Prp_stm, update_apply(_pipe@1, Update); {delete_query, Delete} -> _pipe@2 = Prp_stm, delete_apply(_pipe@2, Delete) end. -spec to_prepared_statement( write_query(any()), binary(), cake@dialect:dialect() ) -> cake@internal@prepared_statement:prepared_statement(). to_prepared_statement(Qry, Prp_stm_prfx, Dlct) -> _pipe = Prp_stm_prfx, _pipe@1 = cake@internal@prepared_statement:new(_pipe, Dlct), apply(_pipe@1, Qry).