-module(cake@param).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/cake/param.gleam").
-export([bool/1, float/1, int/1, string/1, null/0, date/1]).
-export_type([param/0]).
-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 `Param` is a value that can be used in a query.\n"
"\n"
" `Param` is the boxed value type used in prepared statements. Every piece of\n"
" user-supplied data that enters a query should be wrapped in a `Param` so the\n"
" driver can safely encode and transmit it separately from the SQL string.\n"
"\n"
" ## Aliases\n"
"\n"
" ```gleam\n"
" import cake/param as p\n"
" ```\n"
"\n"
" ---\n"
"\n"
" ## Concept\n"
"\n"
" A `Param` carries a single typed value. It is never executed directly — it is\n"
" bound to a placeholder (`?`) at query time. This separation is what makes Cake\n"
" queries safe from SQL injection.\n"
"\n"
" ```mermaid\n"
" flowchart LR\n"
" A[Gleam value] --> B[p.string, p.int, ...]\n"
" B --> C[Param]\n"
" C --> D[prepared statement]\n"
" D --> E[placeholder ?]\n"
" E --> F[driver encodes & binds]\n"
" F --> G[SQL + params sent to DB]\n"
" ```\n"
"\n"
" ---\n"
"\n"
" ## Param Constructors\n"
"\n"
" Each constructor wraps a Gleam value into the corresponding `Param` variant.\n"
"\n"
" | Function | Gleam type | SQL type | Param variant |\n"
" | ---------- | ---------- | ---------- | ---------- |\n"
" | `string(value)` | `String` | `TEXT` / `VARCHAR` | `StringParam` |\n"
" | `int(value)` | `Int` | Integer | `IntParam` |\n"
" | `float(value)` | `Float` | Float / Double | `FloatParam` |\n"
" | `bool(value)` | `Bool` | Boolean | `BoolParam` |\n"
" | `true()` | — | `TRUE` | `BoolParam(True)` |\n"
" | `false()` | — | `FALSE` | `BoolParam(False)` |\n"
" | `null()` | — | `NULL` | `NullParam` |\n"
" | `date(value)` | `calendar.Date` | `DATE` | `DateParam` |\n"
"\n"
" ### `string(value: String) -> Param`\n"
"\n"
" ```gleam\n"
" p.string(\"hello world\")\n"
" ```\n"
"\n"
" ### `int(value: Int) -> Param`\n"
"\n"
" ```gleam\n"
" p.int(42)\n"
" ```\n"
"\n"
" ### `float(value: Float) -> Param`\n"
"\n"
" ```gleam\n"
" p.float(3.14)\n"
" ```\n"
"\n"
" ### `bool(value: Bool) -> Param`\n"
"\n"
" ```gleam\n"
" p.bool(True)\n"
" ```\n"
"\n"
" ### `true() -> Param`\n"
"\n"
" Convenience for `p.bool(True)`.\n"
"\n"
" ### `false() -> Param`\n"
"\n"
" Convenience for `p.bool(False)`.\n"
"\n"
" ### `null() -> Param`\n"
"\n"
" Represents an SQL `NULL`. Use when a column value is unknown or intentionally absent.\n"
"\n"
" ```gleam\n"
" p.null()\n"
" ```\n"
"\n"
" ### `date(value: calendar.Date) -> Param`\n"
"\n"
" Wraps a Gleam `calendar.Date` into a `Param` suitable for `DATE` columns.\n"
"\n"
" ```gleam\n"
" import gleam/time/calendar\n"
"\n"
" p.date(calendar.from_iso_date(\"2025-01-15\"))\n"
" ```\n"
"\n"
" ---\n"
"\n"
" ## Param Variants\n"
"\n"
" The `Param` type has the following constructors:\n"
"\n"
" | Constructor | Description |\n"
"\n"
" | Constructor | Description |\n"
" | -------- | -------- |\n"
" | `StringParam(value)` | UTF-8 string |\n"
" | `IntParam(value)` | Integer |\n"
" | `FloatParam(value)` | Float |\n"
" | `BoolParam(value)` | Boolean |\n"
" | `NullParam` | SQL NULL |\n"
" | `DateParam(value)` | `calendar.Date` |\n"
"\n"
" ---\n"
"\n"
" ## Using Params in Queries\n"
"\n"
" Params are typically created inside builder functions (e.g. `i.string()`,\n"
" `w.col()`) rather than imported directly, but you can use `cake/param`\n"
" convenience functions anywhere a `Param` is needed.\n"
"\n"
" ### In WHERE conditions\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(\"name\")\n"
" |> s.where(w.and([\n"
" w.eq(w.col(\"age\"), w.int(p.int(18))),\n"
" w.eq(w.col(\"role\"), w.string(p.string(\"admin\"))),\n"
" ]))\n"
" |> s.to_query\n"
" ```\n"
"\n"
" ### In INSERT values\n"
"\n"
" ```gleam\n"
" import cake/insert as i\n"
"\n"
" i.from_values(\"users\", [\"name\", \"age\"], [\n"
" i.row([\n"
" i.string(p.string(\"Alice\")),\n"
" i.int(p.int(30)),\n"
" ]),\n"
" ])\n"
" ```\n"
"\n"
" ### In fragments\n"
"\n"
" Params created via `cake/param` can be passed to `f.prepared()` in the same\n"
" way as the convenience constructors in `cake/fragment`.\n"
"\n"
" ---\n"
"\n"
" ## Full Example\n"
"\n"
" ```gleam\n"
" import cake/insert as i\n"
" import cake/param as p\n"
" import cake/where as w\n"
" import gleam/time/calendar\n"
"\n"
" type User {\n"
" User(name: String, age: Int, active: Bool, registered: calendar.Date)\n"
" }\n"
"\n"
" let user = User(\"Alice\", 30, True, calendar.from_iso_date(\"2025-01-15\"))\n"
"\n"
" i.from_values(\"users\", [\"name\", \"age\", \"active\", \"registered\"], [\n"
" i.row([\n"
" i.string(p.string(user.name)),\n"
" i.int(p.int(user.age)),\n"
" i.bool(p.bool(user.active)),\n"
" i.date(p.date(user.registered)),\n"
" ]),\n"
" ])\n"
" |> i.to_query\n"
" // INSERT INTO users (name, age, active, registered) VALUES ($1, $2, $3, $4)\n"
" ```\n"
"\n"
"\n"
" \n"
" \n"
" \n"
" \n"
" \n"
"\n"
).
-type param() :: {string_param, binary()} |
{int_param, integer()} |
{float_param, float()} |
null_param |
{bool_param, boolean()} |
{date_param, gleam@time@calendar:date()}.
-file("src/cake/param.gleam", 254).
?DOC(" Create a new `Param` with a `Bool` value.\n").
-spec bool(boolean()) -> param().
bool(Value) ->
_pipe = Value,
{bool_param, _pipe}.
-file("src/cake/param.gleam", 260).
?DOC(" Create a new `Param` with a `Float` value.\n").
-spec float(float()) -> param().
float(Value) ->
_pipe = Value,
{float_param, _pipe}.
-file("src/cake/param.gleam", 266).
?DOC(" Create a new `Param` with an `Int` value.\n").
-spec int(integer()) -> param().
int(Value) ->
_pipe = Value,
{int_param, _pipe}.
-file("src/cake/param.gleam", 272).
?DOC(" Create a new `Param` with a `String` value.\n").
-spec string(binary()) -> param().
string(Value) ->
_pipe = Value,
{string_param, _pipe}.
-file("src/cake/param.gleam", 278).
?DOC(" Create a new `Param` with an SQL `NULL` value.\n").
-spec null() -> param().
null() ->
null_param.
-file("src/cake/param.gleam", 284).
?DOC(" Create a new `Param` with a `calendar.Date` value.\n").
-spec date(gleam@time@calendar:date()) -> param().
date(Value) ->
_pipe = Value,
{date_param, _pipe}.