Packages
cake
4.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
Current section
Files
Jump to
Current section
Files
src/cake@insert.erl
-module(cake@insert).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/cake/insert.gleam").
-export([to_query/1, row/1, bool/1, float/1, int/1, string/1, null/0, date/1, fragment/1, new/0, from_records/4, from_values/3, table/2, get_table/1, modifier/2, no_modifier/1, get_modifier/1, source_records/3, source_values/2, get_source/1, columns/2, get_columns/1, on_conflict_error/1, on_columns_conflict_ignore/3, on_constraint_conflict_ignore/3, on_columns_conflict_update/4, on_constraint_conflict_update/4, get_on_conflict/1, on_duplicate_key_update/2, 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 `INSERT` queries.\n"
"\n"
" ## Aliases\n"
"\n"
" ```gleam\n"
" import cake/insert as i\n"
" import cake/where as w\n"
" import cake/fragment as f\n"
" ```\n"
"\n"
" ---\n"
"\n"
" ## Query Lifecycle\n"
"\n"
" ```mermaid\n"
" flowchart LR\n"
" A[i.from_records / i.from_values / i.new] --> B[configure table & columns]\n"
" B --> C[on_conflict strategy]\n"
" C --> D[returning]\n"
" D --> E[i.to_query]\n"
" ```\n"
"\n"
" ---\n"
"\n"
" ## Constructors\n"
"\n"
" There are three ways to start building an `INSERT` query.\n"
"\n"
" ### `from_records(table_name, columns, records, encoder) -> Insert(a)`\n"
"\n"
" The idiomatic way. Supply a list of typed Gleam records and an encoder function\n"
" that maps each record to an `InsertRow`.\n"
"\n"
" ```gleam\n"
" type User {\n"
" User(name: String, age: Int)\n"
" }\n"
"\n"
" fn encode_user(u: User) -> i.InsertRow {\n"
" i.row([i.string(u.name), i.int(u.age)])\n"
" }\n"
"\n"
" [User(\"Alice\", 30), User(\"Bob\", 25)]\n"
" |> i.from_records(\n"
" table_name: \"users\",\n"
" columns: [\"name\", \"age\"],\n"
" encoder: encode_user,\n"
" )\n"
" |> i.to_query\n"
" // INSERT INTO users (name, age) VALUES ($1, $2), ($3, $4)\n"
" ```\n"
"\n"
" ### `from_values(table_name, columns, values) -> Insert(a)`\n"
"\n"
" Supply pre-built `InsertRow` values directly.\n"
"\n"
" ```gleam\n"
" [\n"
" i.row([i.string(\"Alice\"), i.int(30)]),\n"
" i.row([i.string(\"Bob\"), i.int(25)]),\n"
" ]\n"
" |> i.from_values(table_name: \"users\", columns: [\"name\", \"age\"])\n"
" |> i.to_query\n"
" ```\n"
"\n"
" ### `new() -> Insert(a)`\n"
"\n"
" Creates a completely empty `Insert`. Useful when building the query\n"
" incrementally.\n"
"\n"
" ```gleam\n"
" i.new()\n"
" |> i.table(\"users\")\n"
" |> i.columns([\"name\", \"age\"])\n"
" |> i.source_values([i.row([i.string(\"Alice\"), i.int(30)])])\n"
" |> i.to_query\n"
" ```\n"
"\n"
" ### `to_query(insert: Insert(a)) -> WriteQuery(a)`\n"
"\n"
" Converts an `Insert` into a `WriteQuery` for execution.\n"
"\n"
" ---\n"
"\n"
" ## Row and Value Constructors\n"
"\n"
" ### `row(values: List(InsertValue)) -> InsertRow`\n"
"\n"
" Wraps a list of `InsertValue`s into a single `InsertRow`.\n"
"\n"
" ```gleam\n"
" i.row([i.string(\"Alice\"), i.int(30), i.bool(True)])\n"
" ```\n"
"\n"
" ### Value constructors\n"
"\n"
" | Function | SQL type |\n"
"\n"
" | Function | SQL type |\n"
" | ---------- | ---------------- |\n"
" | `bool(value)` | Boolean param |\n"
" | `float(value)` | Float param |\n"
" | `int(value)` | Integer param |\n"
" | `string(value)` | String param |\n"
" | `null()` | NULL |\n"
" | `date(value)` | Date param |\n"
" | `fragment(value)` | Raw SQL fragment |\n"
"\n"
" ```gleam\n"
" // Inserting a UUID via a database cast\n"
" import cake/fragment as f\n"
"\n"
" i.fragment(f.prepared(\"?::uuid\", [f.string(\"0000-0000-4000-a000-a00000000000\")]))\n"
" ```\n"
"\n"
" ---\n"
"\n"
" ## Setting the Table\n"
"\n"
" When using `new()` you can configure (or override) the target table:\n"
"\n"
" ```gleam\n"
" i.new() |> i.table(\"users\")\n"
" ```\n"
"\n"
" ---\n"
"\n"
" ## Configuring the Source\n"
"\n"
" ### `source_records(insert, records, encoder) -> Insert(a)`\n"
"\n"
" Attach a list of records and an encoder to an existing `Insert`.\n"
"\n"
" ### `source_values(insert, rows) -> Insert(a)`\n"
"\n"
" Attach raw `InsertRow` values to an existing `Insert`.\n"
"\n"
" ### `columns(insert, columns) -> Insert(a)`\n"
"\n"
" Set the column list. The number of columns **must** match the number of values\n"
" in each `InsertRow`.\n"
"\n"
" ---\n"
"\n"
" ## Conflict Strategies\n"
"\n"
" ```mermaid\n"
" flowchart TD\n"
" A[Insert] --> B{on conflict}\n"
" B -->|error| C[InsertConflictError\\ndefault - raise error]\n"
" B -->|ignore columns| D[on_columns_conflict_ignore\\nPG + SQLite]\n"
" B -->|ignore constraint| E[on_constraint_conflict_ignore\\nPG + SQLite]\n"
" B -->|upsert columns| F[on_columns_conflict_update\\nPG + SQLite]\n"
" B -->|upsert constraint| G[on_constraint_conflict_update\\nPG only]\n"
" B -->|duplicate key| H[on_duplicate_key_update\\nMySQL + MariaDB]\n"
" ```\n"
"\n"
" ### `on_conflict_error(insert) -> Insert(a)`\n"
"\n"
" The default. Any uniqueness/constraint violation raises an error.\n"
"\n"
" ### `on_columns_conflict_ignore(insert, columns, where) -> Insert(a)`\n"
"\n"
" Silently skip conflicting rows when the conflict is on the given columns.\n"
"\n"
" > Supported by 🐘 PostgreSQL and 🪶 SQLite.\n"
"\n"
" ```gleam\n"
" i.from_values(\"users\", [\"email\"], [i.row([i.string(\"a@b.com\")])])\n"
" |> i.on_columns_conflict_ignore(\n"
" columns: [\"email\"],\n"
" where: w.none(),\n"
" )\n"
" // INSERT INTO users (email) VALUES ($1) ON CONFLICT (email) DO NOTHING\n"
" ```\n"
"\n"
" ### `on_constraint_conflict_ignore(insert, constraint, where) -> Insert(a)`\n"
"\n"
" Same as above but identifies the conflict target by constraint name.\n"
"\n"
" > Supported by 🐘 PostgreSQL and 🪶 SQLite.\n"
"\n"
" ### `on_columns_conflict_update(insert, columns, where, update) -> Insert(a)`\n"
"\n"
" **Upsert** — insert or update on conflict (PostgreSQL / SQLite style).\n"
"\n"
" Use `excluded.column` in your `Update` expressions to reference the values\n"
" that were being inserted.\n"
"\n"
" > Supported by 🐘 PostgreSQL ✅ and 🪶 SQLite ✅.\n"
" > Not supported by 🦭 MariaDB or 🐬 MySQL — use `on_duplicate_key_update` instead.\n"
"\n"
" ```gleam\n"
" import cake/update as u\n"
"\n"
" i.from_values(\"scores\", [\"username\", \"score\"], [\n"
" i.row([i.string(\"alice\"), i.int(100)]),\n"
" ])\n"
" |> i.on_columns_conflict_update(\n"
" columns: [\"username\"],\n"
" where: w.none(),\n"
" update: u.new()\n"
" |> u.set(u.set_expression(\"score\", \"excluded.score\")),\n"
" )\n"
" // INSERT INTO scores (username, score) VALUES ($1, $2)\n"
" // ON CONFLICT (username) DO UPDATE SET score = excluded.score\n"
" ```\n"
"\n"
" ### `on_constraint_conflict_update(insert, constraint, where, update) -> Insert(a)`\n"
"\n"
" Same as above but targets a named constraint.\n"
"\n"
" > Supported by 🐘 PostgreSQL only.\n"
"\n"
" ### `on_duplicate_key_update(insert, update) -> Insert(a)`\n"
"\n"
" **MySQL / MariaDB upsert** using `ON DUPLICATE KEY UPDATE` syntax.\n"
"\n"
" Use `VALUES(column)` (not `excluded.column`) in your `Update` expressions.\n"
"\n"
" > Supported by 🦭 MariaDB ✅ and 🐬 MySQL ✅ only.\n"
"\n"
" ```gleam\n"
" i.from_values(\"scores\", [\"username\", \"score\"], [\n"
" i.row([i.string(\"alice\"), i.int(100)]),\n"
" ])\n"
" |> i.on_duplicate_key_update(\n"
" update: u.new()\n"
" |> u.set(u.set_expression(\"score\", \"VALUES(score) + scores.score\")),\n"
" )\n"
" // INSERT INTO scores (username, score) VALUES (?, ?)\n"
" // ON DUPLICATE KEY UPDATE score = VALUES(score) + scores.score\n"
" ```\n"
"\n"
" ---\n"
"\n"
" ## RETURNING\n"
"\n"
" Fetch column values from the inserted rows (🐘 PostgreSQL and 🪶 SQLite).\n"
"\n"
" > 🦭 MariaDB and 🐬 MySQL do not support `RETURNING` in `INSERT` queries.\n"
"\n"
" ```gleam\n"
" i.from_values(\"users\", [\"name\"], [i.row([i.string(\"Alice\")])])\n"
" |> i.returning([\"id\", \"name\"])\n"
" // INSERT INTO users (name) VALUES ($1) RETURNING id, name\n"
" ```\n"
"\n"
" | Function | Effect |\n"
"\n"
" | Function | Effect |\n"
" | ------ | ------ |\n"
" | `returning(insert, cols)` | Return the listed columns |\n"
" | `no_returning(insert)` | Remove RETURNING clause |\n"
"\n"
" ---\n"
"\n"
" ## Modifier\n"
"\n"
" A raw string modifier inserted after `INSERT` (e.g. `OR IGNORE` for SQLite).\n"
"\n"
" ```gleam\n"
" i.new() |> i.modifier(\"OR IGNORE\")\n"
" // INSERT OR IGNORE INTO ...\n"
" ```\n"
"\n"
" ---\n"
"\n"
" ## Epilog and Comment\n"
"\n"
" ```gleam\n"
" i.new()\n"
" |> i.from_values(\"logs\", [\"msg\"], [i.row([i.string(\"hello\")])])\n"
" |> i.epilog(\"RETURNING id\")\n"
" |> i.comment(\"audit log insert\")\n"
" ```\n"
"\n"
" ---\n"
"\n"
" ## Full Example\n"
"\n"
" ```gleam\n"
" import cake/insert as i\n"
" import cake/update as u\n"
" import cake/where as w\n"
"\n"
" type Product { Product(sku: String, price: Float) }\n"
"\n"
" fn encode_product(p: Product) -> i.InsertRow {\n"
" i.row([i.string(p.sku), i.float(p.price)])\n"
" }\n"
"\n"
" [Product(\"ABC-1\", 9.99), Product(\"ABC-2\", 14.99)]\n"
" |> i.from_records(\n"
" table_name: \"products\",\n"
" columns: [\"sku\", \"price\"],\n"
" encoder: encode_product,\n"
" )\n"
" |> i.on_columns_conflict_update(\n"
" columns: [\"sku\"],\n"
" where: w.none(),\n"
" update: u.new() |> u.set(u.set_expression(\"price\", \"excluded.price\")),\n"
" )\n"
" |> i.returning([\"id\", \"sku\"])\n"
" |> i.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/insert.gleam", 397).
?DOC(" Creates a `WriteQuery` from an `Insert` query.\n").
-spec to_query(cake@internal@write_query:insert(FPK)) -> cake@internal@write_query:write_query(FPK).
to_query(Insert) ->
_pipe = Insert,
{insert_query, _pipe}.
-file("src/cake/insert.gleam", 405).
?DOC(" Create an `InsertRow` from a list of `InsertValue`s.\n").
-spec row(list(cake@internal@write_query:insert_value())) -> cake@internal@write_query:insert_row().
row(Values) ->
_pipe = Values,
{insert_row, _pipe}.
-file("src/cake/insert.gleam", 411).
?DOC(" Create an `InsertValue` from a column `String` and a `Bool` value.\n").
-spec bool(boolean()) -> cake@internal@write_query:insert_value().
bool(Value) ->
_pipe = Value,
_pipe@1 = {bool_param, _pipe},
{insert_param, _pipe@1}.
-file("src/cake/insert.gleam", 417).
?DOC(" Create an `InsertValue` from a column `String` and a `Float` value.\n").
-spec float(float()) -> cake@internal@write_query:insert_value().
float(Value) ->
_pipe = Value,
_pipe@1 = {float_param, _pipe},
{insert_param, _pipe@1}.
-file("src/cake/insert.gleam", 423).
?DOC(" Create an `InsertValue` from a column `String` and an `Int` value.\n").
-spec int(integer()) -> cake@internal@write_query:insert_value().
int(Value) ->
_pipe = Value,
_pipe@1 = {int_param, _pipe},
{insert_param, _pipe@1}.
-file("src/cake/insert.gleam", 429).
?DOC(" Create an `InsertValue` from a column `String` and a `String` value.\n").
-spec string(binary()) -> cake@internal@write_query:insert_value().
string(Value) ->
_pipe = Value,
_pipe@1 = {string_param, _pipe},
{insert_param, _pipe@1}.
-file("src/cake/insert.gleam", 435).
?DOC(" Create a NULL `InsertValue`.\n").
-spec null() -> cake@internal@write_query:insert_value().
null() ->
_pipe = null_param,
{insert_param, _pipe}.
-file("src/cake/insert.gleam", 441).
?DOC(" Create an `InsertValue` from a `calendar.Date`.\n").
-spec date(gleam@time@calendar:date()) -> cake@internal@write_query:insert_value().
date(Value) ->
_pipe = Value,
_pipe@1 = {date_param, _pipe},
{insert_param, _pipe@1}.
-file("src/cake/insert.gleam", 456).
?DOC(
" Create an `InsertValue` from a `Fragment`.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" import cake/fragment as f\n"
" import cake/insert as i\n"
"\n"
" i.fragment(f.prepared(\"$::uuid\", [f.string(\"0000000000-0000-4000-a000-a00000000000\")]))\n"
" ```\n"
).
-spec fragment(cake@internal@read_query:fragment()) -> cake@internal@write_query:insert_value().
fragment(Value) ->
{insert_fragment, Value}.
-file("src/cake/insert.gleam", 464).
?DOC(" Create an empty `INSERT` query.\n").
-spec new() -> cake@internal@write_query:insert(any()).
new() ->
{insert,
no_insert_into_table,
no_insert_columns,
no_insert_modifier,
no_insert_source,
insert_conflict_error,
no_returning,
no_epilog,
no_comment}.
-file("src/cake/insert.gleam", 481).
?DOC(
" Create an `INSERT` query from a list of gleam records.\n"
"\n"
" The `encoder` function is used to convert each record into an `InsertRow`.\n"
).
-spec from_records(
binary(),
list(binary()),
list(FPR),
fun((FPR) -> cake@internal@write_query:insert_row())
) -> cake@internal@write_query:insert(FPR).
from_records(Table_name, Columns, Records, Encoder) ->
{insert,
begin
_pipe = Table_name,
{insert_into_table, _pipe}
end,
begin
_pipe@1 = Columns,
{insert_columns, _pipe@1}
end,
no_insert_modifier,
begin
_pipe@2 = Records,
{insert_source_records, _pipe@2, Encoder}
end,
insert_conflict_error,
no_returning,
no_epilog,
no_comment}.
-file("src/cake/insert.gleam", 501).
?DOC(" Create an `INSERT` query from a list of `InsertRow`s.\n").
-spec from_values(
binary(),
list(binary()),
list(cake@internal@write_query:insert_row())
) -> cake@internal@write_query:insert(any()).
from_values(Table_name, Columns, Values) ->
{insert,
begin
_pipe = Table_name,
{insert_into_table, _pipe}
end,
begin
_pipe@1 = Columns,
{insert_columns, _pipe@1}
end,
no_insert_modifier,
begin
_pipe@2 = Values,
{insert_source_rows, _pipe@2}
end,
insert_conflict_error,
no_returning,
no_epilog,
no_comment}.
-file("src/cake/insert.gleam", 522).
?DOC(" Specify the table to insert into.\n").
-spec table(cake@internal@write_query:insert(FPY), binary()) -> cake@internal@write_query:insert(FPY).
table(Insert, Table_name) ->
{insert,
begin
_pipe = Table_name,
{insert_into_table, _pipe}
end,
erlang:element(3, Insert),
erlang:element(4, Insert),
erlang:element(5, Insert),
erlang:element(6, Insert),
erlang:element(7, Insert),
erlang:element(8, Insert),
erlang:element(9, Insert)}.
-file("src/cake/insert.gleam", 531).
?DOC(" Get the table name to insert into from an `Insert` query.\n").
-spec get_table(cake@internal@write_query:insert(any())) -> cake@internal@write_query:insert_into_table().
get_table(Insert) ->
erlang:element(2, Insert).
-file("src/cake/insert.gleam", 539).
?DOC(" Specify a modifier for the `INSERT` query.\n").
-spec modifier(cake@internal@write_query:insert(FQD), binary()) -> cake@internal@write_query:insert(FQD).
modifier(Insert, Modifier) ->
Modifier@1 = begin
_pipe = Modifier,
gleam@string:trim(_pipe)
end,
case Modifier@1 of
<<""/utf8>> ->
{insert,
erlang:element(2, Insert),
erlang:element(3, Insert),
no_insert_modifier,
erlang:element(5, Insert),
erlang:element(6, Insert),
erlang:element(7, Insert),
erlang:element(8, Insert),
erlang:element(9, Insert)};
_ ->
{insert,
erlang:element(2, Insert),
erlang:element(3, Insert),
begin
_pipe@1 = Modifier@1,
{insert_modifier, _pipe@1}
end,
erlang:element(5, Insert),
erlang:element(6, Insert),
erlang:element(7, Insert),
erlang:element(8, Insert),
erlang:element(9, Insert)}
end.
-file("src/cake/insert.gleam", 552).
?DOC(" Specify that no modifier should be used for the given `INSERT` query.\n").
-spec no_modifier(cake@internal@write_query:insert(FQG)) -> cake@internal@write_query:insert(FQG).
no_modifier(Insert) ->
{insert,
erlang:element(2, Insert),
erlang:element(3, Insert),
no_insert_modifier,
erlang:element(5, Insert),
erlang:element(6, Insert),
erlang:element(7, Insert),
erlang:element(8, Insert),
erlang:element(9, Insert)}.
-file("src/cake/insert.gleam", 558).
?DOC(" Get the modifier from an `Insert` query.\n").
-spec get_modifier(cake@internal@write_query:insert(any())) -> binary().
get_modifier(Insert) ->
case erlang:element(4, Insert) of
no_insert_modifier ->
<<""/utf8>>;
{insert_modifier, Keyword} ->
Keyword
end.
-file("src/cake/insert.gleam", 569).
?DOC(" Specify the source records to insert.\n").
-spec source_records(
cake@internal@write_query:insert(FQL),
list(FQL),
fun((FQL) -> cake@internal@write_query:insert_row())
) -> cake@internal@write_query:insert(FQL).
source_records(Insert, Records, Encoder) ->
{insert,
erlang:element(2, Insert),
erlang:element(3, Insert),
erlang:element(4, Insert),
begin
_pipe = Records,
{insert_source_records, _pipe, Encoder}
end,
erlang:element(6, Insert),
erlang:element(7, Insert),
erlang:element(8, Insert),
erlang:element(9, Insert)}.
-file("src/cake/insert.gleam", 579).
?DOC(" Specify the source values to insert.\n").
-spec source_values(
cake@internal@write_query:insert(FQP),
list(cake@internal@write_query:insert_row())
) -> cake@internal@write_query:insert(FQP).
source_values(Insert, Rows) ->
{insert,
erlang:element(2, Insert),
erlang:element(3, Insert),
erlang:element(4, Insert),
begin
_pipe = Rows,
{insert_source_rows, _pipe}
end,
erlang:element(6, Insert),
erlang:element(7, Insert),
erlang:element(8, Insert),
erlang:element(9, Insert)}.
-file("src/cake/insert.gleam", 589).
?DOC(
" Get the source from an `Insert` query which is either a list of records,\n"
" accompanied by an encoder function or a list of `InsertRow`s.\n"
).
-spec get_source(cake@internal@write_query:insert(FQT)) -> cake@internal@write_query:insert_source(FQT).
get_source(Insert) ->
erlang:element(5, Insert).
-file("src/cake/insert.gleam", 600).
?DOC(
" Specify the columns to insert into.\n"
"\n"
" NOTICE: You have to specify the columns and ensure their names are\n"
" correct, as well as their count which must be equal to the count of\n"
" `InsertRows` the encoder function returns or is given as source\n"
" values.\n"
).
-spec columns(cake@internal@write_query:insert(FQW), list(binary())) -> cake@internal@write_query:insert(FQW).
columns(Insert, Columns) ->
{insert,
erlang:element(2, Insert),
begin
_pipe = Columns,
{insert_columns, _pipe}
end,
erlang:element(4, Insert),
erlang:element(5, Insert),
erlang:element(6, Insert),
erlang:element(7, Insert),
erlang:element(8, Insert),
erlang:element(9, Insert)}.
-file("src/cake/insert.gleam", 609).
?DOC(" Get the columns to insert into from an `Insert` query.\n").
-spec get_columns(cake@internal@write_query:insert(any())) -> cake@internal@write_query:insert_columns().
get_columns(Insert) ->
erlang:element(3, Insert).
-file("src/cake/insert.gleam", 619).
?DOC(
" This specifies that any conflicts result in the query to fail\n"
"\n"
" This is the default behaviour.\n"
).
-spec on_conflict_error(cake@internal@write_query:insert(FRC)) -> cake@internal@write_query:insert(FRC).
on_conflict_error(Insert) ->
{insert,
erlang:element(2, Insert),
erlang:element(3, Insert),
erlang:element(4, Insert),
erlang:element(5, Insert),
insert_conflict_error,
erlang:element(7, Insert),
erlang:element(8, Insert),
erlang:element(9, Insert)}.
-file("src/cake/insert.gleam", 628).
?DOC(
" This specifies that specific conflicts do not result in an error but instead\n"
" are just ignored and not inserted.\n"
"\n"
" Conflict Target: Columns\n"
).
-spec on_columns_conflict_ignore(
cake@internal@write_query:insert(FRF),
list(binary()),
cake@internal@read_query:where()
) -> cake@internal@write_query:insert(FRF).
on_columns_conflict_ignore(Insert, Columns, Where) ->
{insert,
erlang:element(2, Insert),
erlang:element(3, Insert),
erlang:element(4, Insert),
erlang:element(5, Insert),
{insert_conflict_ignore,
begin
_pipe = Columns,
{insert_conflict_target, _pipe}
end,
Where},
erlang:element(7, Insert),
erlang:element(8, Insert),
erlang:element(9, Insert)}.
-file("src/cake/insert.gleam", 647).
?DOC(
" This specifies that specific conflicts do not result in an error but instead\n"
" are just ignored and not inserted.\n"
"\n"
" Conflict Target: Constraint\n"
).
-spec on_constraint_conflict_ignore(
cake@internal@write_query:insert(FRJ),
binary(),
cake@internal@read_query:where()
) -> cake@internal@write_query:insert(FRJ).
on_constraint_conflict_ignore(Insert, Constraint, Where) ->
{insert,
erlang:element(2, Insert),
erlang:element(3, Insert),
erlang:element(4, Insert),
erlang:element(5, Insert),
{insert_conflict_ignore,
begin
_pipe = Constraint,
{insert_conflict_target_constraint, _pipe}
end,
Where},
erlang:element(7, Insert),
erlang:element(8, Insert),
erlang:element(9, Insert)}.
-file("src/cake/insert.gleam", 683).
?DOC(
" Inserts or updates on conflict, also called ´UPSERT´.\n"
"\n"
" This function generates PostgreSQL/SQLite-specific upsert queries using\n"
" `ON CONFLICT ... DO UPDATE` syntax.\n"
"\n"
" **For MySQL/MariaDB, use `on_duplicate_key_update()` instead.**\n"
"\n"
" Conflict Target: Columns\n"
"\n"
" ## Important\n"
"\n"
" - Use `excluded.column` in UPDATE expressions to reference insert values\n"
" - Explicitly specify which columns to check for conflicts\n"
" - Supports optional WHERE clause for conditional updates\n"
"\n"
" ## Database Support\n"
"\n"
" - **🐘PostgreSQL**: ✅ Fully supported\n"
" - **🪶SQLite**: ✅ Fully supported\n"
" - **🦭MariaDB**: ❌ Not supported - use `on_duplicate_key_update()`\n"
" - **🐬MySQL**: ❌ Not supported - use `on_duplicate_key_update()`\n"
).
-spec on_columns_conflict_update(
cake@internal@write_query:insert(FRM),
list(binary()),
cake@internal@read_query:where(),
cake@internal@write_query:update(FRM)
) -> cake@internal@write_query:insert(FRM).
on_columns_conflict_update(Insert, Columns, Where, Update) ->
{insert,
erlang:element(2, Insert),
erlang:element(3, Insert),
erlang:element(4, Insert),
erlang:element(5, Insert),
{insert_conflict_update,
begin
_pipe = Columns,
{insert_conflict_target, _pipe}
end,
Where,
Update},
erlang:element(7, Insert),
erlang:element(8, Insert),
erlang:element(9, Insert)}.
-file("src/cake/insert.gleam", 716).
?DOC(
" Inserts or updates on conflict, also called ´UPSERT´.\n"
"\n"
" This function generates PostgreSQL-specific upsert queries using\n"
" `ON CONFLICT ON CONSTRAINT ... DO UPDATE` syntax.\n"
"\n"
" **For MySQL/MariaDB, use `on_duplicate_key_update()` instead.**\n"
" **For SQLite, use `on_columns_conflict_update()` instead.**\n"
"\n"
" Conflict Target: Named Constraint\n"
"\n"
" ## Database Support\n"
"\n"
" - **🐘PostgreSQL**: ✅ Fully supported\n"
" - **🪶SQLite**: ❌ Not supported - use `on_columns_conflict_update()`\n"
" - **🦭MariaDB**: ❌ Not supported - use `on_duplicate_key_update()`\n"
" - **🐬MySQL**: ❌ Not supported - use `on_duplicate_key_update()`\n"
).
-spec on_constraint_conflict_update(
cake@internal@write_query:insert(FRR),
binary(),
cake@internal@read_query:where(),
cake@internal@write_query:update(FRR)
) -> cake@internal@write_query:insert(FRR).
on_constraint_conflict_update(Insert, Constraint, Where, Update) ->
{insert,
erlang:element(2, Insert),
erlang:element(3, Insert),
erlang:element(4, Insert),
erlang:element(5, Insert),
{insert_conflict_update,
begin
_pipe = Constraint,
{insert_conflict_target_constraint, _pipe}
end,
Where,
Update},
erlang:element(7, Insert),
erlang:element(8, Insert),
erlang:element(9, Insert)}.
-file("src/cake/insert.gleam", 734).
?DOC(" Get the conflict strategy from an `Insert` query.\n").
-spec get_on_conflict(cake@internal@write_query:insert(FRV)) -> cake@internal@write_query:insert_conflict_strategy(FRV).
get_on_conflict(Insert) ->
erlang:element(6, Insert).
-file("src/cake/insert.gleam", 781).
?DOC(
" MySQL/MariaDB upsert using `ON DUPLICATE KEY UPDATE` syntax.\n"
"\n"
" This function generates MySQL/MariaDB-specific upsert queries.\n"
" **Only use this when targeting MySQL or MariaDB databases.**\n"
"\n"
" For PostgreSQL/SQLite, use `on_columns_conflict_update()` or\n"
" `on_constraint_conflict_update()` instead.\n"
"\n"
" ## Important\n"
"\n"
" - Use `VALUES(column)` (not `excluded.column`) in your UPDATE expressions\n"
" - Updates occur on the **first** matched unique/primary key constraint\n"
" - No explicit conflict target - relies on existing indexes\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" import cake/insert as i\n"
" import cake/update as u\n"
"\n"
" [[i.string(\"user1\"), i.int(100)] |> i.row]\n"
" |> i.from_values(table_name: \"scores\", columns: [\"username\", \"score\"])\n"
" |> i.on_duplicate_key_update(\n"
" update: u.new()\n"
" |> u.set(\"score\" |> u.set_expression(\"VALUES(score) + scores.score\")),\n"
" )\n"
" ```\n"
"\n"
" Generates:\n"
" ```sql\n"
" INSERT INTO scores (username, score) VALUES (?, ?)\n"
" ON DUPLICATE KEY UPDATE score = VALUES(score) + scores.score\n"
" ```\n"
"\n"
" ## Database Support\n"
"\n"
" - **🦭MariaDB**: ✅ Supported\n"
" - **🐬MySQL**: ✅ Supported\n"
" - **🐘PostgreSQL**: ❌ Not supported - use `on_columns_conflict_update()`\n"
" - **🪶SQLite**: ❌ Not supported - use `on_columns_conflict_update()`\n"
).
-spec on_duplicate_key_update(
cake@internal@write_query:insert(FRY),
cake@internal@write_query:update(FRY)
) -> cake@internal@write_query:insert(FRY).
on_duplicate_key_update(Insert, Update) ->
{insert,
erlang:element(2, Insert),
erlang:element(3, Insert),
erlang:element(4, Insert),
erlang:element(5, Insert),
{insert_duplicate_key_update, Update},
erlang:element(7, Insert),
erlang:element(8, Insert),
erlang:element(9, Insert)}.
-file("src/cake/insert.gleam", 792).
?DOC(" Specify the columns to return after the `INSERT` query.\n").
-spec returning(cake@internal@write_query:insert(FSC), list(binary())) -> cake@internal@write_query:insert(FSC).
returning(Insert, Returning) ->
case Returning of
[] ->
{insert,
erlang:element(2, Insert),
erlang:element(3, Insert),
erlang:element(4, Insert),
erlang:element(5, Insert),
erlang:element(6, Insert),
no_returning,
erlang:element(8, Insert),
erlang:element(9, Insert)};
_ ->
{insert,
erlang:element(2, Insert),
erlang:element(3, Insert),
erlang:element(4, Insert),
erlang:element(5, Insert),
erlang:element(6, Insert),
begin
_pipe = Returning,
{returning, _pipe}
end,
erlang:element(8, Insert),
erlang:element(9, Insert)}
end.
-file("src/cake/insert.gleam", 804).
?DOC(" Specify that no columns should be returned after the `INSERT` query.\n").
-spec no_returning(cake@internal@write_query:insert(FSG)) -> cake@internal@write_query:insert(FSG).
no_returning(Insert) ->
{insert,
erlang:element(2, Insert),
erlang:element(3, Insert),
erlang:element(4, Insert),
erlang:element(5, Insert),
erlang:element(6, Insert),
no_returning,
erlang:element(8, Insert),
erlang:element(9, Insert)}.
-file("src/cake/insert.gleam", 812).
?DOC(" Specify an epilog for the `INSERT` query.\n").
-spec epilog(cake@internal@write_query:insert(FSJ), binary()) -> cake@internal@write_query:insert(FSJ).
epilog(Insert, Epilog) ->
Epilog@1 = begin
_pipe = Epilog,
gleam@string:trim(_pipe)
end,
case Epilog@1 of
<<""/utf8>> ->
{insert,
erlang:element(2, Insert),
erlang:element(3, Insert),
erlang:element(4, Insert),
erlang:element(5, Insert),
erlang:element(6, Insert),
erlang:element(7, Insert),
no_epilog,
erlang:element(9, Insert)};
_ ->
{insert,
erlang:element(2, Insert),
erlang:element(3, Insert),
erlang:element(4, Insert),
erlang:element(5, Insert),
erlang:element(6, Insert),
erlang:element(7, Insert),
begin
_pipe@1 = (<<" "/utf8, Epilog@1/binary>>),
{epilog, _pipe@1}
end,
erlang:element(9, Insert)}
end.
-file("src/cake/insert.gleam", 822).
?DOC(" Specify that no epilog should be added to the `INSERT` query.\n").
-spec no_epilog(cake@internal@write_query:insert(FSM)) -> cake@internal@write_query:insert(FSM).
no_epilog(Insert) ->
{insert,
erlang:element(2, Insert),
erlang:element(3, Insert),
erlang:element(4, Insert),
erlang:element(5, Insert),
erlang:element(6, Insert),
erlang:element(7, Insert),
no_epilog,
erlang:element(9, Insert)}.
-file("src/cake/insert.gleam", 828).
?DOC(" Get the epilog from an `INSERT` query.\n").
-spec get_epilog(cake@internal@write_query:insert(any())) -> cake@internal@read_query:epilog().
get_epilog(Insert) ->
erlang:element(8, Insert).
-file("src/cake/insert.gleam", 836).
?DOC(" Specify a comment for the `INSERT` query.\n").
-spec comment(cake@internal@write_query:insert(FSR), binary()) -> cake@internal@write_query:insert(FSR).
comment(Insert, Comment) ->
Comment@1 = begin
_pipe = Comment,
gleam@string:trim(_pipe)
end,
case Comment@1 of
<<""/utf8>> ->
{insert,
erlang:element(2, Insert),
erlang:element(3, Insert),
erlang:element(4, Insert),
erlang:element(5, Insert),
erlang:element(6, Insert),
erlang:element(7, Insert),
erlang:element(8, Insert),
no_comment};
_ ->
{insert,
erlang:element(2, Insert),
erlang:element(3, Insert),
erlang:element(4, Insert),
erlang:element(5, Insert),
erlang:element(6, Insert),
erlang:element(7, Insert),
erlang:element(8, Insert),
begin
_pipe@1 = (<<" "/utf8, Comment@1/binary>>),
{comment, _pipe@1}
end}
end.
-file("src/cake/insert.gleam", 846).
?DOC(" Specify that no comment should be added to the `INSERT` query.\n").
-spec no_comment(cake@internal@write_query:insert(FSU)) -> cake@internal@write_query:insert(FSU).
no_comment(Insert) ->
{insert,
erlang:element(2, Insert),
erlang:element(3, Insert),
erlang:element(4, Insert),
erlang:element(5, Insert),
erlang:element(6, Insert),
erlang:element(7, Insert),
erlang:element(8, Insert),
no_comment}.
-file("src/cake/insert.gleam", 852).
?DOC(" Get the comment from an `INSERT` query.\n").
-spec get_comment(cake@internal@write_query:insert(any())) -> cake@internal@read_query:comment().
get_comment(Insert) ->
erlang:element(9, Insert).