Current section

Files

Jump to
cake src cake.erl
Raw

src/cake.erl

-module(cake).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/cake.gleam").
-export([to_read_query/1, to_write_query/1, write_query_to_prepared_statement/2, read_query_to_prepared_statement/2, to_prepared_statement/2, get_sql/1, get_params/1, main/0]).
-export_type([cake_query/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(
" *Cake* is an SQL query building library for RDBMS:\n"
"\n"
" - 🐘PostgreSQL\n"
" - πŸͺΆSQLite\n"
" - 🦭MariaDB\n"
" - 🐬MySQL\n"
"\n"
" For examples see the tests.\n"
"\n"
" ## Summary\n"
"\n"
" Cake is a composable SQL query-building library for [Gleam](https://gleam.run). It targets four major RDBMS dialects β€” 🐘 PostgreSQL, πŸͺΆ SQLite, 🦭 MariaDB, and 🐬 MySQL β€” and produces **prepared statements** (parameterised SQL + typed parameter lists) that are safe from SQL injection. Cake does _not_ execute queries or decode result rows; it hands a `PreparedStatement` to a dialect adapter library that does so.\n"
"\n"
" ---\n"
"\n"
" ## Module Overview\n"
"\n"
" | Module | Alias | Purpose |\n"
" | ------------------------------ | ----- | --------------------------------- |\n"
" | [`cake/select`](api/select.md) | `s` | `SELECT` queries |\n"
" | [`cake/insert`](api/insert.md) | `i` | `INSERT` queries |\n"
" | [`cake/update`](api/update.md) | `u` | `UPDATE` queries |\n"
" | [`cake/delete`](api/delete.md) | `d` | `DELETE` queries |\n"
" | [`cake/combined`](api/combined.md) | `c` | `UNION` / `EXCEPT` / `INTERSECT` |\n"
" | [`cake/where`](api/where.md) | `w` | `WHERE` / `HAVING` conditions |\n"
" | [`cake/join`](api/join.md) | `j` | `JOIN` clauses |\n"
" | [`cake/fragment`](api/fragment.md) | `f` | Raw SQL fragments (safe & unsafe) |\n"
" | [`cake/param`](api/param.md) | `p` | Typed parameter values |\n"
"\n"
" Dialect helpers live under `cake/dialect/`:\n"
"\n"
" | Module | Dialect |\n"
" | ------------------------------- | ------------- |\n"
" | `cake/dialect/postgres_dialect` | 🐘 PostgreSQL |\n"
" | `cake/dialect/sqlite_dialect` | πŸͺΆ SQLite |\n"
" | `cake/dialect/maria_dialect` | 🦭 MariaDB |\n"
" | `cake/dialect/mysql_dialect` | 🐬 MySQL |\n"
"\n"
" ---\n"
"\n"
" ## Recommended Imports\n"
"\n"
" ```gleam\n"
" import cake\n"
" import cake/select as s\n"
" import cake/insert as i\n"
" import cake/update as u\n"
" import cake/delete as d\n"
" import cake/combined as c\n"
" import cake/where as w\n"
" import cake/join as j\n"
" import cake/fragment as f\n"
" import cake/param as p\n"
" ```\n"
"\n"
" ## Query Flow\n"
"\n"
" Every query is built using a pipeline of builder functions that accumulate\n"
" clauses, then converted to a `ReadQuery` or `WriteQuery` for execution via\n"
" your chosen adapter.\n"
"\n"
" ```mermaid\n"
" flowchart TD\n"
" A[new] --> B[add clauses]\n"
" B --> C[to_query]\n"
" C --> D{query type}\n"
" D -->|ReadQuery| E[adapter: run_read_query]\n"
" D -->|WriteQuery| F[adapter: run_write_query]\n"
" E --> G[decode results]\n"
" F --> H[inspect returning / rows affected]\n"
" ```\n"
"\n"
" ## Quick Example\n"
"\n"
" ```gleam\n"
" import cake/select as s\n"
" import cake/where as w\n"
"\n"
" s.new()\n"
" |> s.from_table(\"users\")\n"
" |> s.col(\"id\")\n"
" |> s.col(\"name\")\n"
" |> s.where(w.eq(w.col(\"active\"), w.bool(True)))\n"
" |> s.order_by_asc(\"name\")\n"
" |> s.limit(10)\n"
" |> s.to_query\n"
" ```\n"
"\n"
" Generates:\n"
"\n"
" ```sql\n"
" SELECT id, name FROM users WHERE active = $1 ORDER BY name ASC LIMIT 10\n"
" ```\n"
"\n"
" ---\n"
"\n"
" ## How It Works\n"
"\n"
" ```\n"
" Build query β†’ call to_query() β†’ call to_prepared_statement() β†’ pass to adapter\n"
" ```\n"
"\n"
" 1. **Build** – use one of the query-builder modules (`select`, `insert`, `update`, `delete`, `combined`) to assemble a typed query value.\n"
" 2. **Compile** – call `cake.to_prepared_statement(query, dialect)` (or the dialect-specific helper) to get a `PreparedStatement`.\n"
" 3. **Execute** – extract `cake.get_sql(ps)` and `cake.get_params(ps)` and pass them to the appropriate adapter.\n"
"\n"
" ---\n"
"\n"
" ## `cake` β€” Core\n"
"\n"
" Key types re-exported for adapter use:\n"
"\n"
" | Type | Description |\n"
" | ------------------- | --------------------------------------------- |\n"
" | `CakeQuery(a)` | Union of `CakeReadQuery` and `CakeWriteQuery` |\n"
" | `ReadQuery` | Any read query (SELECT, combined) |\n"
" | `WriteQuery(a)` | Any write query (INSERT, UPDATE, DELETE) |\n"
" | `PreparedStatement` | Compiled SQL string + parameter list |\n"
" | `Dialect` | Target database dialect |\n"
" | `Param` | Typed query parameter |\n"
"\n"
" Key functions:\n"
"\n"
" | Function | Description |\n"
" | --------------------------------------------------- | ---------------------------------------------------- |\n"
" | `to_read_query(query)` | Wrap a `ReadQuery` as a `CakeQuery` |\n"
" | `to_write_query(query)` | Wrap a `WriteQuery` as a `CakeQuery` |\n"
" | `to_prepared_statement(query, dialect)` | Compile a `CakeQuery` to a `PreparedStatement` |\n"
" | `read_query_to_prepared_statement(query, dialect)` | Compile a `ReadQuery` directly |\n"
" | `write_query_to_prepared_statement(query, dialect)` | Compile a `WriteQuery` directly |\n"
" | `get_sql(ps)` | Extract the SQL string from a `PreparedStatement` |\n"
" | `get_params(ps)` | Extract the `List(Param)` from a `PreparedStatement` |\n"
"\n"
" ---\n"
"\n"
" ## `cake/select` β€” SELECT Queries\n"
"\n"
" Build `SELECT` statements. All builder functions return a new `Select`, making them pipeable.\n"
"\n"
" ### Constructors\n"
"\n"
" | Function | Description |\n"
" | ------------------ | ---------------------- |\n"
" | `new()` | Empty select query |\n"
" | `to_query(select)` | Convert to `ReadQuery` |\n"
"\n"
" ### Column selection\n"
"\n"
" | Function | Description |\n"
" | ---------------------------------------------------------------------------- | ------------------------------------- |\n"
" | `col(name)` | Reference a column by name |\n"
" | `alias(value, alias)` | Alias a select value |\n"
" | `bool/float/int/string/date/null/fragment(...)` | Literal select values |\n"
" | `select_col(query, col)` | Append a single column |\n"
" | `select(query, value)` | Append a `SelectValue` |\n"
" | `selects(query, values)` | Append multiple `SelectValue`s |\n"
" | `replace_select_col/replace_select/replace_select_cols/replace_selects(...)` | Replace current selection |\n"
" | `all(query)` / `distinct(query)` | Set `SELECT ALL` or `SELECT DISTINCT` |\n"
"\n"
" ### FROM clause\n"
"\n"
" | Function | Description |\n"
" | ------------------------------------ | -------------------------- |\n"
" | `from_table(query, name)` | `FROM table_name` |\n"
" | `from_query(query, subquery, alias)` | `FROM (subquery) AS alias` |\n"
" | `no_from(query)` | Remove FROM clause |\n"
"\n"
" ### Filtering\n"
"\n"
" | Function | Description |\n"
" | --------------------------------- | ------------------------ |\n"
" | `where(query, condition)` | Append to `AND WHERE` |\n"
" | `or_where(query, condition)` | Append to `OR WHERE` |\n"
" | `xor_where(query, condition)` | Append to `XOR WHERE` |\n"
" | `not_where(query, condition)` | Append negated condition |\n"
" | `replace_where(query, condition)` | Replace entire WHERE |\n"
" | `no_where(query)` | Remove WHERE clause |\n"
"\n"
" ### Aggregation\n"
"\n"
" | Function | Description |\n"
" | ------------------------------------------------- | ------------------------ |\n"
" | `group_by(query, col)` / `group_bys(query, cols)` | Add `GROUP BY` columns |\n"
" | `having(query, condition)` | Append to `AND HAVING` |\n"
" | `or_having / xor_having / not_having(...)` | Other HAVING combinators |\n"
" | `replace_having / no_having(...)` | Replace or remove HAVING |\n"
"\n"
" ### Joins\n"
"\n"
" | Function | Description |\n"
" | --------------------------------------------- | ----------------------- |\n"
" | `join(query, join)` | Append a join |\n"
" | `joins(query, joins)` | Append multiple joins |\n"
" | `replace_join / replace_joins / no_join(...)` | Replace or remove joins |\n"
"\n"
" ### Ordering, paging, extras\n"
"\n"
" | Function | Description |\n"
" | --------------------------------------------------------------------- | --------------------------------- |\n"
" | `order_by_asc / order_by_desc(query, col)` | Append ascending/descending order |\n"
" | `order_by_asc_nulls_first/last / order_by_desc_nulls_first/last(...)` | Order with NULL placement |\n"
" | `replace_order_by_* / no_order_by(...)` | Replace or remove ORDER BY |\n"
" | `limit(query, n)` / `no_limit(query)` | Set or clear LIMIT |\n"
" | `offset(query, n)` / `no_offset(query)` | Set or clear OFFSET |\n"
" | `epilog(query, sql)` / `no_epilog(query)` | Append raw SQL after the query |\n"
" | `comment(query, text)` / `no_comment(query)` | Attach an SQL comment |\n"
"\n"
" ---\n"
"\n"
" ## `cake/insert` β€” INSERT Queries\n"
"\n"
" ### Constructors\n"
"\n"
" | Function | Description |\n"
" | ------------------------------------------------ | ---------------------------------- |\n"
" | `new()` | Empty insert query |\n"
" | `from_records(table, columns, records, encoder)` | Build from a list of Gleam records |\n"
" | `from_values(table, columns, rows)` | Build from a list of `InsertRow`s |\n"
" | `to_query(insert)` | Convert to `WriteQuery` |\n"
"\n"
" ### Row / value helpers\n"
"\n"
" | Function | Description |\n"
" | ----------------------------------------------- | --------------------------- |\n"
" | `row(values)` | Create an `InsertRow` |\n"
" | `bool/float/int/string/null/date/fragment(...)` | Create typed `InsertValue`s |\n"
"\n"
" ### Configuration\n"
"\n"
" | Function | Description |\n"
" | --------------------------------------------------- | ---------------------------------------- |\n"
" | `table(insert, name)` | Set the target table |\n"
" | `columns(insert, cols)` | Set column names |\n"
" | `source_records / source_values(...)` | Change the data source |\n"
" | `modifier(insert, keyword)` / `no_modifier(insert)` | Set a query modifier (e.g. `OR REPLACE`) |\n"
"\n"
" ### Conflict handling (upsert)\n"
"\n"
" | Function | Description |\n"
" | ------------------------------------------------------------------ | ---------------------------------------- |\n"
" | `on_conflict_error(insert)` | Error on conflict (default) |\n"
" | `on_columns_conflict_ignore(insert, cols, where)` | Ignore on column conflict (🐘 / πŸͺΆ) |\n"
" | `on_constraint_conflict_ignore(insert, constraint, where)` | Ignore on named constraint conflict (🐘) |\n"
" | `on_columns_conflict_update(insert, cols, where, update)` | Upsert by columns (🐘 / πŸͺΆ) |\n"
" | `on_constraint_conflict_update(insert, constraint, where, update)` | Upsert by constraint (🐘) |\n"
" | `on_duplicate_key_update(insert, update)` | `ON DUPLICATE KEY UPDATE` (🦭 / 🐬) |\n"
"\n"
" ### Returning / extras\n"
"\n"
" | Function | Description |\n"
" | -------------------------------------------------- | ---------------------------- |\n"
" | `returning(insert, cols)` / `no_returning(insert)` | `RETURNING` clause (🐘 / πŸͺΆ) |\n"
" | `epilog / no_epilog / comment / no_comment(...)` | Raw SQL epilog and comment |\n"
"\n"
" ---\n"
"\n"
" ## `cake/update` β€” UPDATE Queries\n"
"\n"
" ### Constructor\n"
"\n"
" | Function | Description |\n"
" | ------------------ | ----------------------- |\n"
" | `new()` | Empty update query |\n"
" | `to_query(update)` | Convert to `WriteQuery` |\n"
"\n"
" ### SET clause\n"
"\n"
" | Function | Description |\n"
" | ------------------------------------------------------------------------ | ------------------------------------------ |\n"
" | `set_bool/set_float/set_int/set_string/set_null/set_date(column, value)` | Typed column assignments |\n"
" | `set_true / set_false(column)` | Boolean shorthand |\n"
" | `set_expression(column, expr)` | Raw SQL expression assignment |\n"
" | `set_sub_query(column, query)` | Sub-query assignment |\n"
" | `set_fragment(column, fragment)` | Fragment assignment with parameter binding |\n"
" | `sets_expression / sets_sub_query(columns, ...)` | Multi-column assignment |\n"
" | `set(update, set)` / `sets(update, sets)` | Append one or more `UpdateSet`s |\n"
" | `set_replace / sets_replace(...)` | Replace all SET items |\n"
"\n"
" ### FROM, JOIN, WHERE, RETURNING, extras\n"
"\n"
" Same API shape as `cake/select` β€” `from_table`, `from_sub_query`, `no_from`, `join`, `where`, `or_where`, `xor_where`, `not_where`, `replace_where`, `no_where`, `returning`, `no_returning`, `epilog`, `comment`, etc.\n"
"\n"
" > **Note:** `RETURNING` is not supported on 🦭 MariaDB or 🐬 MySQL for `UPDATE`.\n"
"\n"
" ---\n"
"\n"
" ## `cake/delete` β€” DELETE Queries\n"
"\n"
" ### Constructor\n"
"\n"
" | Function | Description |\n"
" | ------------------ | ----------------------- |\n"
" | `new()` | Empty delete query |\n"
" | `to_query(delete)` | Convert to `WriteQuery` |\n"
"\n"
" ### Configuration\n"
"\n"
" | Function | Description |\n"
" | --------------------------------------------------------------- | ----------------------------------------------------- |\n"
" | `table(delete, name)` | Set the table to delete from |\n"
" | `modifier(delete, keyword)` / `no_modifier(delete)` | Optional modifier |\n"
" | `using_table / using_sub_query(...)` | `USING` clause for multi-table deletes (🐘 / 🦭 / 🐬) |\n"
" | `replace_using_table / replace_using_sub_query / no_using(...)` | Replace or remove USING |\n"
"\n"
" ### JOIN, WHERE, RETURNING, extras\n"
"\n"
" Same API shape as `cake/update` β€” `join`, `where`, `or_where`, `xor_where`, `not_where`, `replace_where`, `no_where`, `returning`, `no_returning`, `epilog`, `comment`, etc.\n"
"\n"
" > **Note:** πŸͺΆ SQLite does not support `USING`. `RETURNING` is not supported on 🦭 MariaDB or 🐬 MySQL for `DELETE`.\n"
"\n"
" ---\n"
"\n"
" ## `cake/combined` β€” UNION / EXCEPT / INTERSECT\n"
"\n"
" Combines two or more `Select` queries.\n"
"\n"
" | Function | Description |\n"
" | ---------------------------------------------------- | ------------------------------- |\n"
" | `union(a, b)` / `unions(a, b, rest)` | `UNION` (distinct) |\n"
" | `union_all(a, b)` / `unions_all(a, b, rest)` | `UNION ALL` |\n"
" | `except(a, b)` / `excepts(a, b, rest)` | `EXCEPT` (distinct) |\n"
" | `except_all(a, b)` / `excepts_all(a, b, rest)` | `EXCEPT ALL` (not πŸͺΆ SQLite) |\n"
" | `intersect(a, b)` / `intersects(a, b, rest)` | `INTERSECT` (distinct) |\n"
" | `intersect_all(a, b)` / `intersects_all(a, b, rest)` | `INTERSECT ALL` (not πŸͺΆ SQLite) |\n"
" | `to_query(combined)` | Convert to `ReadQuery` |\n"
"\n"
" Supports `limit`, `offset`, `order_by_*`, `epilog`, and `comment` with the same API as `cake/select`.\n"
"\n"
" ---\n"
"\n"
" ## `cake/where` β€” WHERE / HAVING Conditions\n"
"\n"
" Used to build `WHERE` clauses (and `HAVING` clauses, which share the same type).\n"
"\n"
" ### Value constructors\n"
"\n"
" | Function | Description |\n"
" | ---------------------------------------- | ---------------------- |\n"
" | `col(name)` | Reference a column |\n"
" | `bool/float/int/string/null/date(value)` | Typed literal values |\n"
" | `true()` / `false()` | Boolean shortcuts |\n"
" | `sub_query(query)` | Scalar sub-query value |\n"
" | `fragment_value(fragment)` | Fragment value |\n"
"\n"
" ### Logical combinators\n"
"\n"
" | Function | Description |\n"
" | -------------------- | ----------------------------------------------- |\n"
" | `and(wheres)` | `AND` of a list of conditions |\n"
" | `or(wheres)` | `OR` of a list of conditions |\n"
" | `xor(wheres)` | Strict `XOR` β€” exactly one true |\n"
" | `xor_parity(wheres)` | Odd-parity `XOR` β€” uses native `XOR` on 🦭 / 🐬 |\n"
" | `not(where)` | Negate a condition |\n"
" | `none()` | No condition (`NoWhere`) |\n"
"\n"
" ### Comparisons\n"
"\n"
" `eq`, `neq`, `lt`, `lte`, `gt`, `gte` β€” compare two `WhereValue`s.\n"
"\n"
" `eq_any_query`, `lt_any_query`, `lte_any_query`, `gt_any_query`, `gte_any_query`, `neq_any_query` β€” compare against `ANY` result of a sub-query (not πŸͺΆ SQLite).\n"
"\n"
" `eq_all_query`, `lt_all_query`, `lte_all_query`, `gt_all_query`, `gte_all_query`, `neq_all_query` β€” compare against `ALL` results of a sub-query (not πŸͺΆ SQLite).\n"
"\n"
" ### Other predicates\n"
"\n"
" | Function | Description |\n"
" | -------------------------------------------------------- | -------------------------------- |\n"
" | `is_null / is_not_null(value)` | NULL checks |\n"
" | `is_bool / is_not_bool / is_true / is_false(value, ...)` | Boolean checks |\n"
" | `in(value, values)` | `IN (...)` with a list of values |\n"
" | `in_query(value, query)` | `IN (subquery)` |\n"
" | `exists_in_query(query)` | `EXISTS (subquery)` |\n"
" | `between(a, b, c)` | `BETWEEN b AND c` |\n"
" | `like(value, pattern)` | `LIKE` pattern match |\n"
" | `ilike(value, pattern)` | Case-insensitive `LIKE` |\n"
" | `similar_to(value, pattern, escape)` | `SIMILAR TO` (not πŸͺΆ SQLite) |\n"
" | `fragment(fragment)` | Raw SQL condition |\n"
"\n"
" ---\n"
"\n"
" ## `cake/join` β€” JOIN Clauses\n"
"\n"
" ### Join target constructors\n"
"\n"
" | Function | Description |\n"
" | ------------------ | -------------------- |\n"
" | `table(name)` | Join a table by name |\n"
" | `sub_query(query)` | Join a sub-query |\n"
"\n"
" ### Join kind constructors\n"
"\n"
" | Function | Description |\n"
" | ---------------------------- | ------------------------------------------------- |\n"
" | `inner(with, on, alias)` | `INNER JOIN` |\n"
" | `left(with, on, alias)` | `LEFT JOIN` |\n"
" | `right(with, on, alias)` | `RIGHT JOIN` |\n"
" | `full(with, on, alias)` | `FULL JOIN` |\n"
" | `cross(with, alias)` | `CROSS JOIN` |\n"
" | `inner_lateral(with, alias)` | `INNER JOIN LATERAL ... ON TRUE` (🐘 / recent 🐬) |\n"
" | `left_lateral(with, alias)` | `LEFT JOIN LATERAL ... ON TRUE` (🐘 / recent 🐬) |\n"
" | `cross_lateral(with, alias)` | `CROSS JOIN LATERAL` (🐘 / recent 🐬) |\n"
"\n"
" ---\n"
"\n"
" ## `cake/fragment` β€” Raw SQL Fragments\n"
"\n"
" Fragments allow injecting custom SQL into a query while keeping parameter binding safe.\n"
"\n"
" | Function / Constant | Description |\n"
" | --------------------------------------------------- | -------------------------------------------------------------------- |\n"
" | `placeholder` | The placeholder grapheme used in prepared fragments (`?` by default) |\n"
" | `prepared(sql, params)` | Create a fragment with bound parameters β€” **safe for user input** |\n"
" | `literal(sql)` | Create a fragment from a raw string β€” **never use with user input** |\n"
" | `bool/float/int/string/null/date/true/false(value)` | Convenience `Param` constructors mirroring `cake/param` |\n"
"\n"
" ---\n"
"\n"
" ## `cake/param` β€” Typed Parameters\n"
"\n"
" `Param` is the boxed value type used in prepared statements.\n"
"\n"
" | Constructor / Function | Description |\n"
" | -------------------------------------- | --------------- |\n"
" | `StringParam(value)` / `string(value)` | UTF-8 string |\n"
" | `IntParam(value)` / `int(value)` | Integer |\n"
" | `FloatParam(value)` / `float(value)` | Float |\n"
" | `BoolParam(value)` / `bool(value)` | Boolean |\n"
" | `NullParam` / `null()` | SQL NULL |\n"
" | `DateParam(value)` / `date(value)` | `calendar.Date` |\n"
"\n"
" ---\n"
"\n"
" ## Dialect Compatibility Summary\n"
"\n"
" | Feature | 🐘 PostgreSQL | πŸͺΆ SQLite | 🦭 MariaDB | 🐬 MySQL |\n"
" | -------------------------------------- | ------------- | --------- | ---------- | ----------- |\n"
" | `ANY` / `ALL` sub-query | βœ… | ❌ | βœ… | βœ… |\n"
" | `SIMILAR TO` | βœ… | ❌ | βœ… | βœ… |\n"
" | `EXCEPT ALL` / `INTERSECT ALL` | βœ… | ❌ | βœ… | βœ… |\n"
" | `ON CONFLICT ... DO UPDATE` | βœ… | βœ… | ❌ | ❌ |\n"
" | `ON DUPLICATE KEY UPDATE` | ❌ | ❌ | βœ… | βœ… |\n"
" | `RETURNING` (INSERT / UPDATE / DELETE) | βœ… | βœ… | ❌ | ❌ |\n"
" | `USING` in DELETE | βœ… | ❌ | βœ… | βœ… |\n"
" | `LATERAL` joins | βœ… | ❌ | ❌ | βœ… (recent) |\n"
" | `NULLS FIRST` / `NULLS LAST` | βœ… | βœ… | ❌ | ❌ |\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"
).
-type cake_query(ENS) :: {cake_read_query,
cake@internal@read_query:read_query()} |
{cake_write_query, cake@internal@write_query:write_query(ENS)}.
-file("src/cake.gleam", 505).
?DOC(
" Create a Cake read query from a read query.\n"
"\n"
" Also see `cake/dialect/*` for dialect specific implementations of this.\n"
).
-spec to_read_query(cake@internal@read_query:read_query()) -> cake_query(any()).
to_read_query(Query) ->
_pipe = Query,
{cake_read_query, _pipe}.
-file("src/cake.gleam", 513).
?DOC(
" Create a Cake write query from a write query.\n"
"\n"
" Also see `cake/dialect/*` for dialect specific implementations of this.\n"
).
-spec to_write_query(cake@internal@write_query:write_query(ENX)) -> cake_query(ENX).
to_write_query(Query) ->
_pipe = Query,
{cake_write_query, _pipe}.
-file("src/cake.gleam", 548).
?DOC(" Create a prepared statement from a write query.\n").
-spec write_query_to_prepared_statement(
cake@internal@write_query:write_query(any()),
cake@internal@dialect:dialect()
) -> cake@internal@prepared_statement:prepared_statement().
write_query_to_prepared_statement(Query, Dialect) ->
_pipe = Dialect,
_pipe@1 = cake@internal@dialect:placeholder_base(_pipe),
cake@internal@write_query:to_prepared_statement(Query, _pipe@1, Dialect).
-file("src/cake.gleam", 537).
?DOC(" Create a prepared statement from a read query.\n").
-spec read_query_to_prepared_statement(
cake@internal@read_query:read_query(),
cake@internal@dialect:dialect()
) -> cake@internal@prepared_statement:prepared_statement().
read_query_to_prepared_statement(Query, Dialect) ->
_pipe = Dialect,
_pipe@1 = cake@internal@dialect:placeholder_base(_pipe),
cake@internal@read_query:to_prepared_statement(Query, _pipe@1, Dialect).
-file("src/cake.gleam", 521).
?DOC(
" Create a prepared statement from a Cake query.\n"
"\n"
" Also see `cake/dialect/*` for dialect specific implementations of this.\n"
).
-spec to_prepared_statement(cake_query(any()), cake@internal@dialect:dialect()) -> cake@internal@prepared_statement:prepared_statement().
to_prepared_statement(Query, Dialect) ->
case Query of
{cake_read_query, Query@1} ->
_pipe = Query@1,
read_query_to_prepared_statement(_pipe, Dialect);
{cake_write_query, Query@2} ->
_pipe@1 = Query@2,
write_query_to_prepared_statement(_pipe@1, Dialect)
end.
-file("src/cake.gleam", 559).
?DOC(" Get the SQL of the prepared statement.\n").
-spec get_sql(cake@internal@prepared_statement:prepared_statement()) -> binary().
get_sql(Prepared_statement) ->
_pipe = Prepared_statement,
cake@internal@prepared_statement:get_sql(_pipe).
-file("src/cake.gleam", 567).
?DOC(" Get the parameters of the prepared statement.\n").
-spec get_params(cake@internal@prepared_statement:prepared_statement()) -> list(cake@param:param()).
get_params(Prepared_statement) ->
_pipe = Prepared_statement,
cake@internal@prepared_statement:get_params(_pipe).
-file("src/cake.gleam", 575).
?DOC(" As a library *Cake* cannot be invoked directly in a meaningful way.\n").
-spec main() -> nil.
main() ->
_pipe = (<<<<<<"\n"/utf8,
"cake is a query building library and cannot be invoked directly."/utf8>>/binary,
"\n"/utf8>>/binary,
"For demos see the tests."/utf8>>),
gleam_stdlib:println(_pipe).