Current section

Files

Jump to
cake src cake@update.erl
Raw

src/cake@update.erl

-module(cake@update).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/cake/update.gleam").
-export([to_query/1, new/0, table/2, get_table/1, set_bool/2, set_true/1, set_false/1, set_float/2, set_int/2, set_string/2, set_null/1, set_date/2, set_expression/2, set_sub_query/2, set_fragment/2, sets_expression/2, sets_sub_query/2, get_set/1, set/2, set_replace/2, sets/2, sets_replace/2, from_table/2, from_sub_query/3, no_from/1, get_from/1, join/2, replace_join/2, joins/2, replace_joins/2, no_join/1, get_joins/1, where/2, or_where/2, xor_where/2, not_where/2, replace_where/2, no_where/1, get_where/1, returning/2, no_returning/1, epilog/2, no_epilog/1, get_epilog/1, comment/2, no_comment/1, get_comment/1]).
-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(
" A DSL to build `UPDATE` queries.\n"
"\n"
" ## Aliases\n"
"\n"
" ```gleam\n"
" import cake/update as u\n"
" import cake/where as w\n"
" import cake/join as j\n"
" ```\n"
"\n"
" ---\n"
"\n"
" ## Query Lifecycle\n"
"\n"
" ```mermaid\n"
" flowchart LR\n"
" A[u.new] --> B[u.table]\n"
" B --> C[u.set / u.sets]\n"
" C --> D[u.from_table / u.from_sub_query]\n"
" D --> E[u.join]\n"
" E --> F[u.where]\n"
" F --> G[u.returning]\n"
" G --> H[u.to_query]\n"
" ```\n"
"\n"
" ---\n"
"\n"
" ## Constructor\n"
"\n"
" ### `new() -> Update(a)`\n"
"\n"
" Creates an empty `Update` query.\n"
"\n"
" ### `to_query(update: Update(a)) -> WriteQuery(a)`\n"
"\n"
" Converts an `Update` into a `WriteQuery` for execution.\n"
"\n"
" ---\n"
"\n"
" ## Table\n"
"\n"
" ### `table(update, name) -> Update(a)`\n"
"\n"
" Sets the target table for the `UPDATE`.\n"
"\n"
" ```gleam\n"
" u.new() |> u.table(\"users\")\n"
" // UPDATE users SET ...\n"
" ```\n"
"\n"
" ---\n"
"\n"
" ## SET clauses\n"
"\n"
" Each `UpdateSet` represents one `column = value` assignment. You accumulate\n"
" sets with `set()` / `sets()`, then Cake renders them as a `SET col = val, ...`\n"
" clause.\n"
"\n"
" ### Value setters\n"
"\n"
" | Function | SQL equivalent |\n"
" | ----------------------------- | -------------------- |\n"
" | `set_bool(col, value)` | `col = TRUE/FALSE` |\n"
" | `set_true(col)` | `col = TRUE` |\n"
" | `set_false(col)` | `col = FALSE` |\n"
" | `set_float(col, value)` | `col = $n` (float) |\n"
" | `set_int(col, value)` | `col = $n` (int) |\n"
" | `set_string(col, value)` | `col = $n` (string) |\n"
" | `set_null(col)` | `col = NULL` |\n"
" | `set_date(col, date)` | `col = $n` (date) |\n"
" | `set_expression(col, expr)` | `col = raw_expr` |\n"
" | `set_sub_query(col, query)` | `col = (SELECT ...)` |\n"
" | `set_fragment(col, fragment)` | `col = <fragment>` |\n"
"\n"
" ```gleam\n"
" u.new()\n"
" |> u.table(\"users\")\n"
" |> u.set(u.set_string(\"name\", \"Alice\"))\n"
" |> u.set(u.set_int(\"age\", 31))\n"
" |> u.set(u.set_null(\"deleted_at\"))\n"
" // UPDATE users SET name = $1, age = $2, deleted_at = NULL\n"
" ```\n"
"\n"
" ### `set_expression(col, expr) -> UpdateSet`\n"
"\n"
" Injects a raw SQL expression on the right-hand side. Useful for\n"
" self-referencing updates or database functions.\n"
"\n"
" ```gleam\n"
" u.set_expression(\"score\", \"score + 10\")\n"
" // score = score + 10\n"
"\n"
" u.set_expression(\"updated_at\", \"NOW()\")\n"
" // updated_at = NOW()\n"
" ```\n"
"\n"
" ### `set_fragment(col, fragment) -> UpdateSet`\n"
"\n"
" Binds a prepared fragment as the RHS. Preferred over `set_expression` when\n"
" user-controlled values are involved.\n"
"\n"
" ```gleam\n"
" import cake/fragment as f\n"
"\n"
" u.set_fragment(\n"
" \"org_id\",\n"
" f.prepared(\"?::uuid\", [f.string(\"0000-0000-4000-a000-a00000000000\")]),\n"
" )\n"
" ```\n"
"\n"
" ### `set_sub_query(col, query) -> UpdateSet`\n"
"\n"
" Sets a column to the result of a sub-query.\n"
"\n"
" ```gleam\n"
" import cake/select as s\n"
"\n"
" let sub =\n"
" s.new()\n"
" |> s.from_table(\"profiles\")\n"
" |> s.col(\"display_name\")\n"
" |> s.where(w.eq(w.col(\"profiles.user_id\"), w.col(\"users.id\")))\n"
" |> s.to_query\n"
"\n"
" u.new()\n"
" |> u.table(\"users\")\n"
" |> u.set(u.set_sub_query(\"cached_name\", sub))\n"
" ```\n"
"\n"
" ### Multi-column setters\n"
"\n"
" | Function | Notes |\n"
" | ----------------------------- | ---------------------------------------- |\n"
" | `sets_expression(cols, expr)` | Expression must return same column count |\n"
" | `sets_sub_query(cols, query)` | Sub-query must return same column count |\n"
"\n"
" ### Accumulating vs replacing sets\n"
"\n"
" | Function | Effect |\n"
" | ---------------------------- | ---------------------------------- |\n"
" | `set(update, set)` | Append one `UpdateSet` |\n"
" | `set_replace(update, set)` | Replace all with one `UpdateSet` |\n"
" | `sets(update, sets)` | Append many `UpdateSet`s |\n"
" | `sets_replace(update, sets)` | Replace all with many `UpdateSet`s |\n"
"\n"
" ---\n"
"\n"
" ## FROM clause\n"
"\n"
" On 🐘 PostgreSQL and 🪶 SQLite an `UPDATE` supports a `FROM` clause to join\n"
" additional tables for use in `SET` expressions or `WHERE` conditions.\n"
"\n"
" > 🦭 MariaDB and 🐬 MySQL do not use `FROM` in `UPDATE`; use `JOIN` instead.\n"
"\n"
" ### `from_table(update, name) -> Update(a)`\n"
"\n"
" ```gleam\n"
" u.new()\n"
" |> u.table(\"employees\")\n"
" |> u.from_table(\"departments\")\n"
" |> u.set(u.set_expression(\"salary\", \"departments.budget / 10\"))\n"
" |> u.where(w.eq(w.col(\"employees.dept_id\"), w.col(\"departments.id\")))\n"
" // UPDATE employees SET salary = departments.budget / 10\n"
" // FROM departments WHERE employees.dept_id = departments.id\n"
" ```\n"
"\n"
" ### `from_sub_query(update, query, alias) -> Update(a)`\n"
"\n"
" Use an aliased sub-query as the `FROM` source.\n"
"\n"
" ### `no_from(update) -> Update(a)`\n"
"\n"
" Remove the `FROM` clause.\n"
"\n"
" ---\n"
"\n"
" ## JOIN\n"
"\n"
" On 🦭 MariaDB and 🐬 MySQL `JOIN` is the standard way to reference other\n"
" tables in an `UPDATE`.\n"
"\n"
" > On 🐘 PostgreSQL and 🪶 SQLite, `JOIN` is only allowed when a `FROM` clause\n"
" > is also set.\n"
"\n"
" ```gleam\n"
" u.new()\n"
" |> u.table(\"orders\")\n"
" |> u.join(j.inner(\n"
" with: j.table(\"users\"),\n"
" on: w.eq(w.col(\"orders.user_id\"), w.col(\"users.id\")),\n"
" alias: \"users\",\n"
" ))\n"
" |> u.set(u.set_expression(\"orders.status\", \"'shipped'\"))\n"
" |> u.where(w.eq(w.col(\"users.tier\"), w.string(\"premium\")))\n"
" ```\n"
"\n"
" | Function | Effect |\n"
" | ------------------------------ | -------------------------- |\n"
" | `join(update, join)` | Append one join |\n"
" | `replace_join(update, join)` | Replace all joins with one |\n"
" | `joins(update, joins)` | Append many joins |\n"
" | `replace_joins(update, joins)` | Replace all joins |\n"
" | `no_join(update)` | Remove all joins |\n"
"\n"
" ---\n"
"\n"
" ## WHERE clause\n"
"\n"
" See [`cake/where`](where.md) for building `Where` values.\n"
"\n"
" ### `where(update, where) -> Update(a)`\n"
"\n"
" Adds a condition with `AND` semantics.\n"
"\n"
" ```gleam\n"
" u.new()\n"
" |> u.table(\"users\")\n"
" |> u.set(u.set_bool(\"active\", False))\n"
" |> u.where(w.lt(w.col(\"last_login\"), w.date(cutoff_date)))\n"
" // UPDATE users SET active = $1 WHERE last_login < $2\n"
" ```\n"
"\n"
" ### `or_where(update, where) -> Update(a)`\n"
"\n"
" Combines with `OR` semantics.\n"
"\n"
" ### `xor_where(update, where) -> Update(a)`\n"
"\n"
" Combines with exactly-one-true `XOR` semantics. Implemented via a custom\n"
" `OR / AND / NOT` expansion on all adapters — native `XOR` is not used on any\n"
" adapter, including 🦭 MariaDB / 🐬 MySQL.\n"
"\n"
" > For odd-parity XOR (matching 🦭 MariaDB / 🐬 MySQL native `XOR`), use\n"
" > `w.xor_parity` instead.\n"
"\n"
" ### `not_where(update, where) -> Update(a)`\n"
"\n"
" Negates the given condition with `NOT` and combines with `AND` semantics.\n"
"\n"
" - If there is no current WHERE, the condition is set as a standalone `NOT`.\n"
" - If the outermost WHERE is an `AndWhere`, the negated condition is appended to it.\n"
" - Otherwise, the existing WHERE and the new `NOT` condition are wrapped in an `AndWhere`.\n"
"\n"
" | Function | Effect |\n"
" | ------------------------------ | ------------------------ |\n"
" | `replace_where(update, where)` | Replace the entire WHERE |\n"
" | `no_where(update)` | Remove WHERE clause |\n"
"\n"
" ---\n"
"\n"
" ## RETURNING\n"
"\n"
" Fetch column values from the updated rows.\n"
"\n"
" > Only supported by 🐘 PostgreSQL and 🪶 SQLite.\n"
" > 🦭 MariaDB and 🐬 MySQL do not support `RETURNING` in `UPDATE`.\n"
"\n"
" ```gleam\n"
" u.new()\n"
" |> u.table(\"users\")\n"
" |> u.set(u.set_int(\"login_count\", 1))\n"
" |> u.returning([\"id\", \"login_count\"])\n"
" // UPDATE users SET login_count = $1 RETURNING id, login_count\n"
" ```\n"
"\n"
" | Function | Effect |\n"
" | ------------------------- | ------------------------- |\n"
" | `returning(update, cols)` | Return the listed columns |\n"
" | `no_returning(update)` | Remove RETURNING clause |\n"
"\n"
" ---\n"
"\n"
" ## Epilog and Comment\n"
"\n"
" ```gleam\n"
" u.new()\n"
" |> u.table(\"sessions\")\n"
" |> u.set(u.set_expression(\"expires_at\", \"NOW() + INTERVAL '1 hour'\"))\n"
" |> u.epilog(\"RETURNING id\")\n"
" |> u.comment(\"extend active sessions\")\n"
" ```\n"
"\n"
" ---\n"
"\n"
" ## Full Example\n"
"\n"
" ```gleam\n"
" import cake/update as u\n"
" import cake/where as w\n"
" import cake/fragment as f\n"
"\n"
" u.new()\n"
" |> u.table(\"products\")\n"
" |> u.sets([\n"
" u.set_expression(\"price\", \"price * 0.9\"),\n"
" u.set_fragment(\"updated_at\", f.literal(\"NOW()\")),\n"
" ])\n"
" |> u.where(w.and([\n"
" w.eq(w.col(\"category\"), w.string(\"electronics\")),\n"
" w.gt(w.col(\"stock\"), w.int(0)),\n"
" ]))\n"
" |> u.returning([\"id\", \"price\"])\n"
" |> u.to_query\n"
" ```\n"
"\n"
"\n"
" <!-- html assets for docs gen -->\n"
" <style>\n"
" .page {\n"
" display: block;\n"
" }\n"
" .content {\n"
" width: auto;\n"
" max-width: none;\n"
" }\n"
" </style>\n"
" <!--<script src=\"https://cdn.jsdelivr.net/npm/@mermaid-js/tiny@11/dist/mermaid.tiny.js\"></script>-->\n"
" <script\n"
" src=\"https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js\"\n"
" integrity=\"sha256-cBN+d7snO7LvlyuG6LBADMqL5TyyW/xFkRoYbcmGZd4=\"\n"
" crossorigin=\"anonymous\"\n"
" ></script>\n"
" <script>\n"
" (callback => document.readyState !== 'loading' ? callback() : document.addEventListener('DOMContentLoaded', callback, { once: true }))(() => {\n"
" mermaid.initialize({ startOnLoad: false })\n"
" mermaid.run({\n"
" querySelector: \".language-mermaid\",\n"
" })\n"
" })\n"
" </script>\n"
"\n"
).
-file("src/cake/update.gleam", 396).
?DOC(" Creates a `WriteQuery` from an `Update` query.\n").
-spec to_query(cake@internal@write_query:update(GJQ)) -> cake@internal@write_query:write_query(GJQ).
to_query(Update) ->
_pipe = Update,
{update_query, _pipe}.
-file("src/cake/update.gleam", 404).
?DOC(" Creates an empty `Update` query.\n").
-spec new() -> cake@internal@write_query:update(any()).
new() ->
{update,
no_update_table,
no_update_modifier,
no_update_sets,
no_from,
no_joins,
no_where,
no_returning,
no_epilog,
no_comment}.
-file("src/cake/update.gleam", 422).
?DOC(" Sets the table of the `Update` query.\n").
-spec table(cake@internal@write_query:update(GJV), binary()) -> cake@internal@write_query:update(GJV).
table(Update, Name) ->
{update,
begin
_pipe = Name,
{update_table, _pipe}
end,
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
erlang:element(6, Update),
erlang:element(7, Update),
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)}.
-file("src/cake/update.gleam", 428).
?DOC(" Get the table of the `Update` query.\n").
-spec get_table(cake@internal@write_query:update(any())) -> cake@internal@write_query:update_table().
get_table(Update) ->
erlang:element(2, Update).
-file("src/cake/update.gleam", 436).
?DOC(" Sets a column to a `Bool` `UpdateParamSet`.\n").
-spec set_bool(binary(), boolean()) -> cake@internal@write_query:update_set().
set_bool(Column, Value) ->
_pipe = Value,
_pipe@1 = {bool_param, _pipe},
{update_param_set, Column, _pipe@1}.
-file("src/cake/update.gleam", 442).
?DOC(" Sets a column to a `True` `UpdateParamSet`.\n").
-spec set_true(binary()) -> cake@internal@write_query:update_set().
set_true(Column) ->
_pipe = true,
_pipe@1 = {bool_param, _pipe},
{update_param_set, Column, _pipe@1}.
-file("src/cake/update.gleam", 448).
?DOC(" Sets a column to a `False` `UpdateParamSet`.\n").
-spec set_false(binary()) -> cake@internal@write_query:update_set().
set_false(Column) ->
_pipe = false,
_pipe@1 = {bool_param, _pipe},
{update_param_set, Column, _pipe@1}.
-file("src/cake/update.gleam", 454).
?DOC(" Sets a column to a `Float` `UpdateParamSet`.\n").
-spec set_float(binary(), float()) -> cake@internal@write_query:update_set().
set_float(Column, Value) ->
_pipe = Value,
_pipe@1 = {float_param, _pipe},
{update_param_set, Column, _pipe@1}.
-file("src/cake/update.gleam", 460).
?DOC(" Sets a column to a `Int` `UpdateParamSet`.\n").
-spec set_int(binary(), integer()) -> cake@internal@write_query:update_set().
set_int(Column, Value) ->
_pipe = Value,
_pipe@1 = {int_param, _pipe},
{update_param_set, Column, _pipe@1}.
-file("src/cake/update.gleam", 466).
?DOC(" Sets a column to a string `UpdateParamSet`.\n").
-spec set_string(binary(), binary()) -> cake@internal@write_query:update_set().
set_string(Column, Value) ->
_pipe = Value,
_pipe@1 = {string_param, _pipe},
{update_param_set, Column, _pipe@1}.
-file("src/cake/update.gleam", 472).
?DOC(" Sets a column to an SQL `NULL` `UpdateParamSet`.\n").
-spec set_null(binary()) -> cake@internal@write_query:update_set().
set_null(Column) ->
_pipe = null_param,
{update_param_set, Column, _pipe}.
-file("src/cake/update.gleam", 478).
?DOC(" Sets a column to a `calendar.Date` `UpdateParamSet`.\n").
-spec set_date(binary(), gleam@time@calendar:date()) -> cake@internal@write_query:update_set().
set_date(Column, Date) ->
_pipe = Date,
_pipe@1 = {date_param, _pipe},
{update_param_set, Column, _pipe@1}.
-file("src/cake/update.gleam", 484).
?DOC(" Sets a column to an expression value.\n").
-spec set_expression(binary(), binary()) -> cake@internal@write_query:update_set().
set_expression(Column, Expression) ->
_pipe = [Column],
{update_expression_set, _pipe, Expression}.
-file("src/cake/update.gleam", 493).
?DOC(" Sets a column to a sub-query value.\n").
-spec set_sub_query(binary(), cake@internal@read_query:read_query()) -> cake@internal@write_query:update_set().
set_sub_query(Column, Query) ->
_pipe = [Column],
{update_sub_query_set, _pipe, Query}.
-file("src/cake/update.gleam", 511).
?DOC(
" Sets a column to a fragment value with parameter binding.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" import cake/fragment as f\n"
" import cake/update as u\n"
"\n"
" \"org_id\" |> u.set_fragment(f.prepared(\"$::uuid\", [f.string(\"0000000000-0000-4000-a000-a00000000000\")]))\n"
" ```\n"
).
-spec set_fragment(binary(), cake@internal@read_query:fragment()) -> cake@internal@write_query:update_set().
set_fragment(Column, Value) ->
{update_fragment_set, Column, Value}.
-file("src/cake/update.gleam", 519).
?DOC(
" Sets many columns to an expression value.\n"
"\n"
" NOTICE: the expression must return an equal count of columns.\n"
).
-spec sets_expression(list(binary()), binary()) -> cake@internal@write_query:update_set().
sets_expression(Columns, Expression) ->
_pipe = Columns,
{update_expression_set, _pipe, Expression}.
-file("src/cake/update.gleam", 530).
?DOC(
" Sets many columns to a sub-query value.\n"
"\n"
" NOTICE: the sub-query must return an equal count of columns.\n"
).
-spec sets_sub_query(list(binary()), cake@internal@read_query:read_query()) -> cake@internal@write_query:update_set().
sets_sub_query(Columns, Query) ->
_pipe = Columns,
{update_sub_query_set, _pipe, Query}.
-file("src/cake/update.gleam", 539).
?DOC(" Get the `SET`s of the `Update` query.\n").
-spec get_set(cake@internal@write_query:update(any())) -> list(cake@internal@write_query:update_set()).
get_set(Update) ->
case erlang:element(4, Update) of
no_update_sets ->
[];
{update_sets, Items} ->
Items
end.
-file("src/cake/update.gleam", 548).
?DOC(" Sets or appends one column set in an `Update` query.\n").
-spec set(
cake@internal@write_query:update(GKF),
cake@internal@write_query:update_set()
) -> cake@internal@write_query:update(GKF).
set(Update, Set) ->
case erlang:element(4, Update) of
no_update_sets ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
begin
_pipe = [Set],
{update_sets, _pipe}
end,
erlang:element(5, Update),
erlang:element(6, Update),
erlang:element(7, Update),
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)};
{update_sets, Items} ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
begin
_pipe@1 = Items,
_pipe@2 = lists:append(_pipe@1, [Set]),
{update_sets, _pipe@2}
end,
erlang:element(5, Update),
erlang:element(6, Update),
erlang:element(7, Update),
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)}
end.
-file("src/cake/update.gleam", 558).
?DOC(" Sets or replaces one column set in an `Update` query.\n").
-spec set_replace(
cake@internal@write_query:update(GKI),
cake@internal@write_query:update_set()
) -> cake@internal@write_query:update(GKI).
set_replace(Update, Set) ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
begin
_pipe = [Set],
{update_sets, _pipe}
end,
erlang:element(5, Update),
erlang:element(6, Update),
erlang:element(7, Update),
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)}.
-file("src/cake/update.gleam", 564).
?DOC(" Sets or appends many column sets in an `Update` query.\n").
-spec sets(
cake@internal@write_query:update(GKL),
list(cake@internal@write_query:update_set())
) -> cake@internal@write_query:update(GKL).
sets(Update, Sets) ->
case erlang:element(4, Update) of
no_update_sets ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
begin
_pipe = Sets,
{update_sets, _pipe}
end,
erlang:element(5, Update),
erlang:element(6, Update),
erlang:element(7, Update),
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)};
{update_sets, Items} ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
begin
_pipe@1 = Items,
_pipe@2 = lists:append(_pipe@1, Sets),
{update_sets, _pipe@2}
end,
erlang:element(5, Update),
erlang:element(6, Update),
erlang:element(7, Update),
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)}
end.
-file("src/cake/update.gleam", 574).
?DOC(" Sets or replaces many column sets in an `Update` query.\n").
-spec sets_replace(
cake@internal@write_query:update(GKP),
list(cake@internal@write_query:update_set())
) -> cake@internal@write_query:update(GKP).
sets_replace(Update, Sets) ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
begin
_pipe = Sets,
{update_sets, _pipe}
end,
erlang:element(5, Update),
erlang:element(6, Update),
erlang:element(7, Update),
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)}.
-file("src/cake/update.gleam", 585).
?DOC(" Sets the `FROM` clause of the `Update` query to a table name.\n").
-spec from_table(cake@internal@write_query:update(GKT), binary()) -> cake@internal@write_query:update(GKT).
from_table(Update, Table_name) ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
begin
_pipe = Table_name,
{from_table, _pipe}
end,
erlang:element(6, Update),
erlang:element(7, Update),
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)}.
-file("src/cake/update.gleam", 594).
?DOC(" Sets the `FROM` clause of the `Update` query to an aliased sub-query.\n").
-spec from_sub_query(
cake@internal@write_query:update(GKW),
cake@internal@read_query:read_query(),
binary()
) -> cake@internal@write_query:update(GKW).
from_sub_query(Update, Query, Alias) ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
begin
_pipe = Query,
{from_sub_query, _pipe, Alias}
end,
erlang:element(6, Update),
erlang:element(7, Update),
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)}.
-file("src/cake/update.gleam", 604).
?DOC(" Removes the `FROM` clause of the `Update` query.\n").
-spec no_from(cake@internal@write_query:update(GKZ)) -> cake@internal@write_query:update(GKZ).
no_from(Update) ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
no_from,
erlang:element(6, Update),
erlang:element(7, Update),
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)}.
-file("src/cake/update.gleam", 610).
?DOC(" Gets the `FROM` clause of the `Update` query.\n").
-spec get_from(cake@internal@write_query:update(any())) -> cake@internal@read_query:from().
get_from(Update) ->
erlang:element(5, Update).
-file("src/cake/update.gleam", 621).
?DOC(
" Adds a `Join` to the `Update` query.\n"
"\n"
" NOTICE: On 🐘PostgreSQL and 🪶SQLite `Joins` are only allowed if the `FROM`\n"
" clause is set as well.\n"
).
-spec join(
cake@internal@write_query:update(GLE),
cake@internal@read_query:join()
) -> cake@internal@write_query:update(GLE).
join(Update, Join) ->
case erlang:element(6, Update) of
{joins, Existing_joins} ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
begin
_pipe = Existing_joins,
_pipe@1 = lists:append(_pipe, [Join]),
{joins, _pipe@1}
end,
erlang:element(7, Update),
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)};
no_joins ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
begin
_pipe@2 = [Join],
{joins, _pipe@2}
end,
erlang:element(7, Update),
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)}
end.
-file("src/cake/update.gleam", 634).
?DOC(
" Replaces any `Join`s of the `Update` query with a single `Join`.\n"
"\n"
" NOTICE: On 🐘PostgreSQL and 🪶SQLite `Joins` are only allowed if the `FROM`\n"
" clause is set as well.\n"
).
-spec replace_join(
cake@internal@write_query:update(GLH),
cake@internal@read_query:join()
) -> cake@internal@write_query:update(GLH).
replace_join(Update, Join) ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
begin
_pipe = [Join],
{joins, _pipe}
end,
erlang:element(7, Update),
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)}.
-file("src/cake/update.gleam", 643).
?DOC(
" Adds `Join`s to the `Update` query.\n"
"\n"
" NOTICE: On 🐘PostgreSQL and 🪶SQLite `Joins` are only allowed if the `FROM`\n"
" clause is set as well.\n"
).
-spec joins(
cake@internal@write_query:update(GLK),
list(cake@internal@read_query:join())
) -> cake@internal@write_query:update(GLK).
joins(Update, Joins) ->
case {Joins, erlang:element(6, Update)} of
{[], _} ->
Update;
{_, {joins, Existing_joins}} ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
begin
_pipe = Existing_joins,
_pipe@1 = lists:append(_pipe, Joins),
{joins, _pipe@1}
end,
erlang:element(7, Update),
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)};
{_, no_joins} ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
begin
_pipe@2 = Joins,
{joins, _pipe@2}
end,
erlang:element(7, Update),
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)}
end.
-file("src/cake/update.gleam", 657).
?DOC(
" Replaces any `Join`s of the `Update` query with the given `Join`s.\n"
"\n"
" NOTICE: On 🐘PostgreSQL and 🪶SQLite `Joins` are only allowed if the `FROM`\n"
" clause is set as well.\n"
).
-spec replace_joins(
cake@internal@write_query:update(GLO),
list(cake@internal@read_query:join())
) -> cake@internal@write_query:update(GLO).
replace_joins(Update, Joins) ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
begin
_pipe = Joins,
{joins, _pipe}
end,
erlang:element(7, Update),
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)}.
-file("src/cake/update.gleam", 666).
?DOC(" Removes any `Joins` from the `Update` query.\n").
-spec no_join(cake@internal@write_query:update(GLS)) -> cake@internal@write_query:update(GLS).
no_join(Update) ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
no_joins,
erlang:element(7, Update),
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)}.
-file("src/cake/update.gleam", 672).
?DOC(" Gets the `Joins` of the `Update` query.\n").
-spec get_joins(cake@internal@write_query:update(any())) -> cake@internal@read_query:joins().
get_joins(Update) ->
erlang:element(6, Update).
-file("src/cake/update.gleam", 687).
?DOC(
" Sets an `AndWhere` or appends into an existing `AndWhere`.\n"
"\n"
" - If the outermost `Where` is an `AndWhere`, the new `Where` is appended\n"
" to the list within `AndWhere`.\n"
" - If the query does not have a `Where` clause, the given `Where` is set\n"
" instead.\n"
" - If the outermost `Where` is any other kind of `Where`, this and the\n"
" current outermost `Where` are wrapped in an `AndWhere`.\n"
).
-spec where(
cake@internal@write_query:update(GLX),
cake@internal@read_query:where()
) -> cake@internal@write_query:update(GLX).
where(Update, Where) ->
case erlang:element(7, Update) of
no_where ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
erlang:element(6, Update),
Where,
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)};
{and_where, Conditions} ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
erlang:element(6, Update),
begin
_pipe = Conditions,
_pipe@1 = lists:append(_pipe, [Where]),
{and_where, _pipe@1}
end,
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)};
_ ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
erlang:element(6, Update),
begin
_pipe@2 = [erlang:element(7, Update), Where],
{and_where, _pipe@2}
end,
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)}
end.
-file("src/cake/update.gleam", 705).
?DOC(
" Sets an `OrWhere` or appends into an existing `OrWhere`.\n"
"\n"
" - If the outermost `Where` is an `OrWhere`, the new `Where` is appended\n"
" to the list within `OrWhere`.\n"
" - If the query does not have a `Where` clause, the given `Where` is set\n"
" instead.\n"
" - If the outermost `Where` is any other kind of `Where`, this and the\n"
" current outermost `Where` are wrapped in an `OrWhere`.\n"
).
-spec or_where(
cake@internal@write_query:update(GMA),
cake@internal@read_query:where()
) -> cake@internal@write_query:update(GMA).
or_where(Update, Where) ->
case erlang:element(7, Update) of
no_where ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
erlang:element(6, Update),
Where,
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)};
{or_where, Conditions} ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
erlang:element(6, Update),
begin
_pipe = Conditions,
_pipe@1 = lists:append(_pipe, [Where]),
{or_where, _pipe@1}
end,
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)};
_ ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
erlang:element(6, Update),
begin
_pipe@2 = [erlang:element(7, Update), Where],
{or_where, _pipe@2}
end,
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)}
end.
-file("src/cake/update.gleam", 730).
?DOC(
" Sets an `XorWhere` or appends into an existing `XorWhere`.\n"
"\n"
" - If the outermost `Where` is an `XorWhere`, the new `Where` is appended\n"
" to the list within `XorWhere`.\n"
" - If the query does not have a `Where` clause, the given `Where` is set\n"
" instead.\n"
" - If the outermost `Where` is any other kind of `Where`, this and the\n"
" current outermost `Where` are wrapped in an `XorWhere`.\n"
"\n"
" NOTICE: *Cake* implements this using a custom `OR / AND / NOT` expansion\n"
" on all four adapters (🐘PostgreSQL, 🪶SQLite, 🦭MariaDB, 🐬MySQL) —\n"
" native `XOR` is **not** used on any adapter.\n"
"\n"
" For odd-parity XOR (which on 🦭MariaDB / 🐬MySQL delegates to its native\n"
" `XOR`) use `where.xor_parity` instead.\n"
).
-spec xor_where(
cake@internal@write_query:update(GMD),
cake@internal@read_query:where()
) -> cake@internal@write_query:update(GMD).
xor_where(Update, Where) ->
case erlang:element(7, Update) of
no_where ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
erlang:element(6, Update),
Where,
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)};
{xor_where, Conditions} ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
erlang:element(6, Update),
begin
_pipe = Conditions,
_pipe@1 = lists:append(_pipe, [Where]),
{xor_where, _pipe@1}
end,
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)};
_ ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
erlang:element(6, Update),
begin
_pipe@2 = [erlang:element(7, Update), Where],
{xor_where, _pipe@2}
end,
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)}
end.
-file("src/cake/update.gleam", 750).
?DOC(
" Sets a `NotWhere` or appends into an existing `AndWhere`.\n"
"\n"
" - Wraps the given `Where` in a `NotWhere`, then applies it with `AND`\n"
" semantics:\n"
" - If the query does not have a `Where` clause, the given `Where` is set\n"
" as a `NotWhere`.\n"
" - If the outermost `Where` is an `AndWhere`, the new `NotWhere` is appended\n"
" to the list within `AndWhere`.\n"
" - If the outermost `Where` is any other kind of `Where`, this and the\n"
" current outermost `Where` are wrapped in an `AndWhere`.\n"
).
-spec not_where(
cake@internal@write_query:update(GMG),
cake@internal@read_query:where()
) -> cake@internal@write_query:update(GMG).
not_where(Update, Where) ->
case erlang:element(7, Update) of
no_where ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
erlang:element(6, Update),
{not_where, Where},
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)};
{and_where, Conditions} ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
erlang:element(6, Update),
begin
_pipe = Conditions,
_pipe@1 = lists:append(_pipe, [{not_where, Where}]),
{and_where, _pipe@1}
end,
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)};
_ ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
erlang:element(6, Update),
begin
_pipe@2 = [erlang:element(7, Update), {not_where, Where}],
{and_where, _pipe@2}
end,
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)}
end.
-file("src/cake/update.gleam", 770).
?DOC(" Replaces the `Where` in the `Update` query.\n").
-spec replace_where(
cake@internal@write_query:update(GMJ),
cake@internal@read_query:where()
) -> cake@internal@write_query:update(GMJ).
replace_where(Update, Where) ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
erlang:element(6, Update),
Where,
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)}.
-file("src/cake/update.gleam", 779).
?DOC(" Removes the `Where` from the `Update` query.\n").
-spec no_where(cake@internal@write_query:update(GMM)) -> cake@internal@write_query:update(GMM).
no_where(Update) ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
erlang:element(6, Update),
no_where,
erlang:element(8, Update),
erlang:element(9, Update),
erlang:element(10, Update)}.
-file("src/cake/update.gleam", 785).
?DOC(" Gets the `Where` of the `Update` query.\n").
-spec get_where(cake@internal@write_query:update(any())) -> cake@internal@read_query:where().
get_where(Update) ->
erlang:element(7, Update).
-file("src/cake/update.gleam", 794).
?DOC(
" NOTICE: 🦭MariaDB and 🐬MySQL do not support `RETURNING` in `UPDATE`\n"
" queries; they do support it in `INSERT` (and `REPLACE`) queries, however.\n"
).
-spec returning(cake@internal@write_query:update(GMR), list(binary())) -> cake@internal@write_query:update(GMR).
returning(Update, Returning) ->
case Returning of
[] ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
erlang:element(6, Update),
erlang:element(7, Update),
no_returning,
erlang:element(9, Update),
erlang:element(10, Update)};
_ ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
erlang:element(6, Update),
erlang:element(7, Update),
begin
_pipe = Returning,
{returning, _pipe}
end,
erlang:element(9, Update),
erlang:element(10, Update)}
end.
-file("src/cake/update.gleam", 807).
?DOC(
" NOTICE: 🦭MariaDB and 🐬MySQL do not support `RETURNING` in `UPDATE`\n"
" queries; they do support it in `INSERT` (and `REPLACE`) queries, however.\n"
).
-spec no_returning(cake@internal@write_query:update(GMV)) -> cake@internal@write_query:update(GMV).
no_returning(Update) ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
erlang:element(6, Update),
erlang:element(7, Update),
no_returning,
erlang:element(9, Update),
erlang:element(10, Update)}.
-file("src/cake/update.gleam", 815).
?DOC(" Sets an `Epilog` or appends into an existing `Epilog`.\n").
-spec epilog(cake@internal@write_query:update(GMY), binary()) -> cake@internal@write_query:update(GMY).
epilog(Update, Epilog) ->
Epilog@1 = begin
_pipe = Epilog,
gleam@string:trim(_pipe)
end,
case Epilog@1 of
<<""/utf8>> ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
erlang:element(6, Update),
erlang:element(7, Update),
erlang:element(8, Update),
no_epilog,
erlang:element(10, Update)};
_ ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
erlang:element(6, Update),
erlang:element(7, Update),
erlang:element(8, Update),
begin
_pipe@1 = (<<" "/utf8, Epilog@1/binary>>),
{epilog, _pipe@1}
end,
erlang:element(10, Update)}
end.
-file("src/cake/update.gleam", 825).
?DOC(" Removes the `Epilog` from the `Update` query.\n").
-spec no_epilog(cake@internal@write_query:update(GNB)) -> cake@internal@write_query:update(GNB).
no_epilog(Update) ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
erlang:element(6, Update),
erlang:element(7, Update),
erlang:element(8, Update),
no_epilog,
erlang:element(10, Update)}.
-file("src/cake/update.gleam", 831).
?DOC(" Gets the `Epilog` of the `Update` query.\n").
-spec get_epilog(cake@internal@write_query:update(any())) -> cake@internal@read_query:epilog().
get_epilog(Update) ->
erlang:element(9, Update).
-file("src/cake/update.gleam", 839).
?DOC(" Sets a `Comment` or appends into an existing `Comment`.\n").
-spec comment(cake@internal@write_query:update(GNG), binary()) -> cake@internal@write_query:update(GNG).
comment(Update, Comment) ->
Comment@1 = begin
_pipe = Comment,
gleam@string:trim(_pipe)
end,
case Comment@1 of
<<""/utf8>> ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
erlang:element(6, Update),
erlang:element(7, Update),
erlang:element(8, Update),
erlang:element(9, Update),
no_comment};
_ ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
erlang:element(6, Update),
erlang:element(7, Update),
erlang:element(8, Update),
erlang:element(9, Update),
begin
_pipe@1 = (<<" "/utf8, Comment@1/binary>>),
{comment, _pipe@1}
end}
end.
-file("src/cake/update.gleam", 849).
?DOC(" Removes the `Comment` from the `Update` query.\n").
-spec no_comment(cake@internal@write_query:update(GNJ)) -> cake@internal@write_query:update(GNJ).
no_comment(Update) ->
{update,
erlang:element(2, Update),
erlang:element(3, Update),
erlang:element(4, Update),
erlang:element(5, Update),
erlang:element(6, Update),
erlang:element(7, Update),
erlang:element(8, Update),
erlang:element(9, Update),
no_comment}.
-file("src/cake/update.gleam", 855).
?DOC(" Gets the `Comment` of the `Update` query.\n").
-spec get_comment(cake@internal@write_query:update(any())) -> cake@internal@read_query:comment().
get_comment(Update) ->
erlang:element(10, Update).