-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}.