Current section
Files
Jump to
Current section
Files
src/based@sql.erl
-module(based@sql).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/based/sql.gleam").
-export(['query'/1, params/2, table/1, table_as/2, column/1, count/1, sum/1, avg/1, max/1, min/1, column_for/2, column_as/2, adapter/0, on_placeholder/2, on_value/2, on_identifier/2, on_null/2, on_int/2, on_text/2, value/3, rows/1, list/1, inner_join/3, left_join/3, right_join/3, full_join/3, asc/1, desc/1, eq/3, not_eq/3, gt/3, lt/3, gt_eq/3, lt_eq/3, between/4, like/3, not_like/3, in/3, is_null/1, is_not_null/1, is_true/1, is_false/1, 'or'/2, 'and'/2, 'not'/1, exists/1, raw/1, from/1, select/2, insert/1, update/2, delete/1, from_subquery/2, where/2, returning/2, order_by/2, group_by/2, limit/2, offset/2, distinct/1, having/2, for_update/1, values/2, on_conflict/4, set/3, cte/2, cte_columns/2, with/2, recursive/1, union/1, union_all/1, to_query/2, to_string/2]).
-export_type(['query'/1, table/0, aggregate/0, column/0, adapter/1, rows/2, operand/1, condition/1, join/1, order/0, conflict_action/0, on_conflict/1, kind/2, select/0, insert/0, update/0, delete/0, subquery/0, union/0, union_all/0, union_type/0, from/2, table_or_subquery/1, select_query/1, insert_query/1, update_query/1, delete_query/1, union_query/1, builder/2, cte/1, set/1, sql_builder/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 type-safe SQL query builder for Gleam.\n"
"\n"
" Queries are built using a pipeline API that starts with a table source and\n"
" chains modifiers to construct SELECT, INSERT, UPDATE, and DELETE statements.\n"
" Phantom types ensure that only valid modifiers can be applied to each query\n"
" kind at compile time.\n"
"\n"
" ## Quick example\n"
"\n"
" ```gleam\n"
" import based/sql\n"
"\n"
" let adapter = sql.adapter()\n"
"\n"
" let query =\n"
" sql.from(sql.table(\"users\"))\n"
" |> sql.select([sql.column(\"name\"), sql.column(\"email\")])\n"
" |> sql.where([sql.column(\"active\") |> sql.is_true()])\n"
" |> sql.order_by([sql.asc(sql.column(\"name\"))])\n"
" |> sql.limit(10)\n"
" |> sql.to_query(adapter)\n"
"\n"
" query.sql\n"
" // -> \"SELECT name, email FROM users WHERE active IS TRUE ORDER BY name ASC LIMIT 10\"\n"
"\n"
" query.values\n"
" // -> []\n"
" ```\n"
"\n"
" ## Custom adapters\n"
"\n"
" Use `adapter()` with builder functions to configure how queries are\n"
" rendered for a specific database backend. This controls placeholder style,\n"
" identifier quoting, and value type mapping.\n"
"\n"
" ```gleam\n"
" let mysql_adapter =\n"
" sql.adapter()\n"
" |> sql.on_null(fn() { mysql.null })\n"
" |> sql.on_int(fn(i) { mysql.int(i) })\n"
" |> sql.on_text(fn(s) { mysql.text(s) })\n"
" |> sql.on_placeholder(fn(_) { \"?\" })\n"
" |> sql.on_value(mysql_value_to_string)\n"
" |> sql.on_identifier(fn(name) { \"`\" <> name <> \"`\" })\n"
" ```\n"
"\n"
" ## Phantom types\n"
"\n"
" The `Builder(kind, v)` type uses phantom types to restrict which modifier\n"
" functions can be called. For example, `join` only accepts `Builder(Select, v)`,\n"
" and `set` only accepts `Builder(Update, v)`. This helps callers avoid\n"
" building invalid SQL queries. It is possible to call functions that do\n"
" not modify the provided `Builder`. Passing `Builder(Insert, v)`\n"
" to `sql.where` will not modify the query builder.\n"
"\n"
).
-type 'query'(DKX) :: {'query', binary(), list(DKX)}.
-opaque table() :: {table, binary(), gleam@option:option(binary())}.
-type aggregate() :: count | sum | avg | max | min.
-opaque column() :: {column,
gleam@option:option(table()),
binary(),
gleam@option:option(binary()),
gleam@option:option(aggregate())} |
{all, gleam@option:option(table())}.
-opaque adapter(DKY) :: {adapter,
fun((integer()) -> binary()),
fun((DKY) -> binary()),
fun((binary()) -> binary()),
fun(() -> DKY),
fun((integer()) -> DKY),
fun((binary()) -> DKY)}.
-opaque rows(DKZ, DLA) :: {rows,
list(binary()),
list(fun((DKZ) -> DLA)),
list(DKZ)}.
-type operand(DLB) :: {column_ref, column()} |
{value_ref, DLB} |
null_ref |
{sub_query, builder(select(), DLB)} |
{any_query, builder(select(), DLB)} |
{all_query, builder(select(), DLB)}.
-opaque condition(DLC) :: {equal, operand(DLC), operand(DLC)} |
{not_equal, operand(DLC), operand(DLC)} |
{greater_than, operand(DLC), operand(DLC)} |
{less_than, operand(DLC), operand(DLC)} |
{greater_than_or_equal, operand(DLC), operand(DLC)} |
{less_than_or_equal, operand(DLC), operand(DLC)} |
{between, operand(DLC), operand(DLC), operand(DLC)} |
{like, operand(DLC), operand(DLC)} |
{not_like, operand(DLC), operand(DLC)} |
{in, operand(DLC), list(operand(DLC))} |
{is_null, operand(DLC)} |
{is_not_null, operand(DLC)} |
{is_true, operand(DLC)} |
{is_false, operand(DLC)} |
{'and', condition(DLC), condition(DLC)} |
{'or', condition(DLC), condition(DLC)} |
{'not', condition(DLC)} |
{exists, builder(select(), DLC)} |
{raw, binary()}.
-type join(DLD) :: {inner_join, table(), list(condition(DLD))} |
{left_join, table(), list(condition(DLD))} |
{right_join, table(), list(condition(DLD))} |
{full_join, table(), list(condition(DLD))}.
-opaque order() :: {asc, column()} | {desc, column()}.
-type conflict_action() :: do_nothing | {do_update, list({binary(), binary()})}.
-type on_conflict(DLE) :: {on_conflict,
binary(),
conflict_action(),
list(condition(DLE))}.
-opaque kind(DLF, DLG) :: {kind, fun((DLF) -> operand(DLG))}.
-type select() :: any().
-type insert() :: any().
-type update() :: any().
-type delete() :: any().
-type subquery() :: any().
-type union() :: any().
-type union_all() :: any().
-type union_type() :: union | union_all.
-opaque from(DLH, DLI) :: {from_table, table()} |
{from_sub_query, builder(select(), DLI), binary()} |
{gleam_phantom, DLH}.
-type table_or_subquery(DLJ) :: {select_from_table, table()} |
{select_from_sub_query, builder(select(), DLJ), binary()}.
-type select_query(DLK) :: {select_query,
list(column()),
table_or_subquery(DLK),
list(list(condition(DLK))),
list(join(DLK)),
list(order()),
gleam@option:option(integer()),
gleam@option:option(integer()),
list(column()),
boolean(),
list(list(condition(DLK))),
boolean()}.
-type insert_query(DLL) :: {insert_query,
table(),
list(binary()),
list(list(DLL)),
list(column()),
gleam@option:option(on_conflict(DLL))}.
-type update_query(DLM) :: {update_query,
table(),
list(set(DLM)),
list(list(condition(DLM))),
list(column()),
list(order()),
gleam@option:option(integer()),
gleam@option:option(integer())}.
-type delete_query(DLN) :: {delete_query,
table(),
list(list(condition(DLN))),
list(column())}.
-type union_query(DLO) :: {union_query,
list(builder(select(), DLO)),
union_type()}.
-opaque builder(DLP, DLQ) :: {select_builder,
select_query(DLQ),
list(cte(DLQ)),
boolean()} |
{insert_builder, insert_query(DLQ), list(cte(DLQ)), boolean()} |
{update_builder, update_query(DLQ), list(cte(DLQ)), boolean()} |
{delete_builder, delete_query(DLQ), list(cte(DLQ)), boolean()} |
{union_builder, union_query(DLQ), list(cte(DLQ)), boolean()} |
{gleam_phantom, DLP}.
-opaque cte(DLR) :: {cte,
binary(),
list(binary()),
fun((adapter(DLR)) -> sql_builder(DLR))}.
-opaque set(DLS) :: {set, binary(), operand(DLS)}.
-type sql_builder(DLT) :: {sql_builder, binary(), list(list(DLT))}.
-file("src/based/sql.gleam", 81).
?DOC(" Creates a `Query` from a raw SQL string with no parameters.\n").
-spec 'query'(binary()) -> 'query'(any()).
'query'(Sql) ->
{'query', Sql, []}.
-file("src/based/sql.gleam", 86).
?DOC(" Sets the parameter values on a `Query`.\n").
-spec params('query'(DLW), list(DLW)) -> 'query'(DLW).
params(Query, Values) ->
{'query', erlang:element(2, Query), Values}.
-file("src/based/sql.gleam", 96).
?DOC(" Creates a table reference.\n").
-spec table(binary()) -> table().
table(Name) ->
{table, Name, none}.
-file("src/based/sql.gleam", 101).
?DOC(" Sets an alias on a table.\n").
-spec table_as(table(), binary()) -> table().
table_as(Table, Alias) ->
{table, erlang:element(2, Table), {some, Alias}}.
-file("src/based/sql.gleam", 126).
?DOC(" Creates a plain column reference.\n").
-spec column(binary()) -> column().
column(Name) ->
{column, none, Name, none, none}.
-file("src/based/sql.gleam", 131).
?DOC(" Creates a column wrapped in `COUNT(...)`.\n").
-spec count(binary()) -> column().
count(Name) ->
{column, none, Name, none, {some, count}}.
-file("src/based/sql.gleam", 136).
?DOC(" Creates a column wrapped in `SUM(...)`.\n").
-spec sum(binary()) -> column().
sum(Name) ->
{column, none, Name, none, {some, sum}}.
-file("src/based/sql.gleam", 141).
?DOC(" Creates a column wrapped in `AVG(...)`.\n").
-spec avg(binary()) -> column().
avg(Name) ->
{column, none, Name, none, {some, avg}}.
-file("src/based/sql.gleam", 146).
?DOC(" Creates a column wrapped in `MAX(...)`.\n").
-spec max(binary()) -> column().
max(Name) ->
{column, none, Name, none, {some, max}}.
-file("src/based/sql.gleam", 151).
?DOC(" Creates a column wrapped in `MIN(...)`.\n").
-spec min(binary()) -> column().
min(Name) ->
{column, none, Name, none, {some, min}}.
-file("src/based/sql.gleam", 156).
?DOC(" Qualifies a column with a table name.\n").
-spec column_for(column(), table()) -> column().
column_for(Column, Table) ->
case Column of
{column, _, _, _, _} ->
{column,
{some, Table},
erlang:element(3, Column),
erlang:element(4, Column),
erlang:element(5, Column)};
{all, _} ->
{all, {some, Table}}
end.
-file("src/based/sql.gleam", 164).
?DOC(" Sets an alias on a column. No-ops on `star`.\n").
-spec column_as(column(), binary()) -> column().
column_as(Column, Alias) ->
case Column of
{column, _, _, _, _} ->
{column,
erlang:element(2, Column),
erlang:element(3, Column),
{some, Alias},
erlang:element(5, Column)};
{all, _} ->
Column
end.
-file("src/based/sql.gleam", 198).
?DOC(
" Creates a new adapter with unconfigured value handlers.\n"
"\n"
" Defaults to `\"?\"` placeholders and does not quote identifiers.\n"
" The `on_value`, `on_null`, `on_int`, and `on_text` handlers\n"
" will panic if left unconfigured.\n"
"\n"
" Configure the returned adapter using the `on_*` builder functions\n"
" before passing it to `to_query` or `to_string`.\n"
).
-spec adapter() -> adapter(any()).
adapter() ->
{adapter,
fun(_) -> <<"?"/utf8>> end,
fun(_) -> erlang:error(#{gleam_error => panic,
message => <<"sql.Adapter not configured (on_value)"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"based/sql"/utf8>>,
function => <<"adapter"/utf8>>,
line => 201}) end,
fun gleam@function:identity/1,
fun() -> erlang:error(#{gleam_error => panic,
message => <<"sql.Adapter not configured (on_null)"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"based/sql"/utf8>>,
function => <<"adapter"/utf8>>,
line => 203}) end,
fun(_) -> erlang:error(#{gleam_error => panic,
message => <<"sql.Adapter not configured (on_int)"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"based/sql"/utf8>>,
function => <<"adapter"/utf8>>,
line => 204}) end,
fun(_) -> erlang:error(#{gleam_error => panic,
message => <<"sql.Adapter not configured (on_text)"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"based/sql"/utf8>>,
function => <<"adapter"/utf8>>,
line => 205}) end}.
-file("src/based/sql.gleam", 210).
?DOC(" Sets the placeholder format function.\n").
-spec on_placeholder(adapter(DMC), fun((integer()) -> binary())) -> adapter(DMC).
on_placeholder(Adapter, Handle_placeholder) ->
{adapter,
Handle_placeholder,
erlang:element(3, Adapter),
erlang:element(4, Adapter),
erlang:element(5, Adapter),
erlang:element(6, Adapter),
erlang:element(7, Adapter)}.
-file("src/based/sql.gleam", 218).
?DOC(" Sets the function used to render a value as a literal SQL string.\n").
-spec on_value(adapter(DMF), fun((DMF) -> binary())) -> adapter(DMF).
on_value(Adapter, Handle_value) ->
{adapter,
erlang:element(2, Adapter),
Handle_value,
erlang:element(4, Adapter),
erlang:element(5, Adapter),
erlang:element(6, Adapter),
erlang:element(7, Adapter)}.
-file("src/based/sql.gleam", 226).
?DOC(" Sets the identifier quoting function.\n").
-spec on_identifier(adapter(DMI), fun((binary()) -> binary())) -> adapter(DMI).
on_identifier(Adapter, Handle_identifier) ->
{adapter,
erlang:element(2, Adapter),
erlang:element(3, Adapter),
Handle_identifier,
erlang:element(5, Adapter),
erlang:element(6, Adapter),
erlang:element(7, Adapter)}.
-file("src/based/sql.gleam", 234).
?DOC(" Sets the function that produces the null representation for type `v`.\n").
-spec on_null(adapter(DML), fun(() -> DML)) -> adapter(DML).
on_null(Adapter, Handle_null) ->
{adapter,
erlang:element(2, Adapter),
erlang:element(3, Adapter),
erlang:element(4, Adapter),
Handle_null,
erlang:element(6, Adapter),
erlang:element(7, Adapter)}.
-file("src/based/sql.gleam", 242).
?DOC(
" Sets the function that wraps an `Int` into the value type `v`.\n"
"\n"
" Adapter packages use this to convert Gleam `Int` values into\n"
" their value type `v`.\n"
).
-spec on_int(adapter(DMO), fun((integer()) -> DMO)) -> adapter(DMO).
on_int(Adapter, Handle_int) ->
{adapter,
erlang:element(2, Adapter),
erlang:element(3, Adapter),
erlang:element(4, Adapter),
erlang:element(5, Adapter),
Handle_int,
erlang:element(7, Adapter)}.
-file("src/based/sql.gleam", 250).
?DOC(
" Sets the function that wraps a `String` into the value type `v`.\n"
"\n"
" Adapter packages use this to convert Gleam `String` values into\n"
" their value type `v`.\n"
).
-spec on_text(adapter(DMR), fun((binary()) -> DMR)) -> adapter(DMR).
on_text(Adapter, Handle_text) ->
{adapter,
erlang:element(2, Adapter),
erlang:element(3, Adapter),
erlang:element(4, Adapter),
erlang:element(5, Adapter),
erlang:element(6, Adapter),
Handle_text}.
-file("src/based/sql.gleam", 278).
?DOC(" Adds a column to the rows being inserted, with a function to extract the SQL value.\n").
-spec value(rows(DMU, DMV), binary(), fun((DMU) -> DMV)) -> rows(DMU, DMV).
value(Rows, Column, Extract) ->
{rows,
[Column | erlang:element(2, Rows)],
[Extract | erlang:element(3, Rows)],
erlang:element(4, Rows)}.
-file("src/based/sql.gleam", 292).
?DOC(
" Creates a new `Rows` with the given values. Pipe through `value` to add\n"
" columns and extractors.\n"
).
-spec rows(list(DNA)) -> rows(DNA, any()).
rows(Values) ->
{rows, [], [], Values}.
-file("src/based/sql.gleam", 903).
?DOC(
" Creates a kind that maps an arbitrary type to a value using a conversion\n"
" function. Useful for `in` clauses with custom types.\n"
).
-spec list(fun((DVH) -> DVI)) -> kind(DVH, DVI).
list(Map) ->
{kind, fun(X) -> {value_ref, Map(X)} end}.
-file("src/based/sql.gleam", 375).
-spec prepend_join(builder(select(), DOH), join(DOH)) -> builder(select(), DOH).
prepend_join(Builder, J) ->
case Builder of
{select_builder, Query, Ctes, Recursive} ->
Joins = gleam@list:prepend(erlang:element(5, Query), J),
_pipe = {select_query,
erlang:element(2, Query),
erlang:element(3, Query),
erlang:element(4, Query),
Joins,
erlang:element(6, Query),
erlang:element(7, Query),
erlang:element(8, Query),
erlang:element(9, Query),
erlang:element(10, Query),
erlang:element(11, Query),
erlang:element(12, Query)},
{select_builder, _pipe, Ctes, Recursive};
_ ->
Builder
end.
-file("src/based/sql.gleam", 340).
?DOC(" Adds an `INNER JOIN` clause to a SELECT query.\n").
-spec inner_join(builder(select(), DNF), table(), list(condition(DNF))) -> builder(select(), DNF).
inner_join(Builder, Table, On) ->
prepend_join(Builder, {inner_join, Table, On}).
-file("src/based/sql.gleam", 349).
?DOC(" Adds a `LEFT JOIN` clause to a SELECT query.\n").
-spec left_join(builder(select(), DNM), table(), list(condition(DNM))) -> builder(select(), DNM).
left_join(Builder, Table, On) ->
prepend_join(Builder, {left_join, Table, On}).
-file("src/based/sql.gleam", 358).
?DOC(" Adds a `RIGHT JOIN` clause to a SELECT query.\n").
-spec right_join(builder(select(), DNT), table(), list(condition(DNT))) -> builder(select(), DNT).
right_join(Builder, Table, On) ->
prepend_join(Builder, {right_join, Table, On}).
-file("src/based/sql.gleam", 367).
?DOC(" Adds a `FULL JOIN` clause to a SELECT query.\n").
-spec full_join(builder(select(), DOA), table(), list(condition(DOA))) -> builder(select(), DOA).
full_join(Builder, Table, On) ->
prepend_join(Builder, {full_join, Table, On}).
-file("src/based/sql.gleam", 394).
?DOC(" Returns an ascending `Order` for the column.\n").
-spec asc(column()) -> order().
asc(Column) ->
{asc, Column}.
-file("src/based/sql.gleam", 399).
?DOC(" Returns a descending `Order` for the column.\n").
-spec desc(column()) -> order().
desc(Column) ->
{desc, Column}.
-file("src/based/sql.gleam", 538).
?DOC(" Creates an equality condition.\n").
-spec eq(column(), DON, kind(DON, DOO)) -> condition(DOO).
eq(Column, Input, Kind) ->
{equal, {column_ref, Column}, (erlang:element(2, Kind))(Input)}.
-file("src/based/sql.gleam", 543).
?DOC(" Creates an inequality condition.\n").
-spec not_eq(column(), DOS, kind(DOS, DOT)) -> condition(DOT).
not_eq(Column, Input, Kind) ->
{not_equal, {column_ref, Column}, (erlang:element(2, Kind))(Input)}.
-file("src/based/sql.gleam", 548).
?DOC(" Creates a greater-than condition.\n").
-spec gt(column(), DOX, kind(DOX, DOY)) -> condition(DOY).
gt(Column, Input, Kind) ->
{greater_than, {column_ref, Column}, (erlang:element(2, Kind))(Input)}.
-file("src/based/sql.gleam", 553).
?DOC(" Creates a less-than condition.\n").
-spec lt(column(), DPC, kind(DPC, DPD)) -> condition(DPD).
lt(Column, Input, Kind) ->
{less_than, {column_ref, Column}, (erlang:element(2, Kind))(Input)}.
-file("src/based/sql.gleam", 558).
?DOC(" Creates a greater-than-or-equal condition.\n").
-spec gt_eq(column(), DPH, kind(DPH, DPI)) -> condition(DPI).
gt_eq(Column, Input, Kind) ->
{greater_than_or_equal,
{column_ref, Column},
(erlang:element(2, Kind))(Input)}.
-file("src/based/sql.gleam", 563).
?DOC(" Creates a less-than-or-equal condition.\n").
-spec lt_eq(column(), DPM, kind(DPM, DPN)) -> condition(DPN).
lt_eq(Column, Input, Kind) ->
{less_than_or_equal, {column_ref, Column}, (erlang:element(2, Kind))(Input)}.
-file("src/based/sql.gleam", 568).
?DOC(" Creates a BETWEEN condition.\n").
-spec between(column(), DPR, DPR, kind(DPR, DPS)) -> condition(DPS).
between(Column, Low, High, Kind) ->
{between,
{column_ref, Column},
(erlang:element(2, Kind))(Low),
(erlang:element(2, Kind))(High)}.
-file("src/based/sql.gleam", 578).
?DOC(" Creates a LIKE condition.\n").
-spec like(column(), DPW, kind(DPW, DPX)) -> condition(DPX).
like(Column, Input, Kind) ->
{like, {column_ref, Column}, (erlang:element(2, Kind))(Input)}.
-file("src/based/sql.gleam", 583).
?DOC(" Creates a NOT LIKE condition.\n").
-spec not_like(column(), DQB, kind(DQB, DQC)) -> condition(DQC).
not_like(Column, Input, Kind) ->
{not_like, {column_ref, Column}, (erlang:element(2, Kind))(Input)}.
-file("src/based/sql.gleam", 588).
?DOC(" Creates an IN condition.\n").
-spec in(column(), list(DQG), kind(DQG, DQI)) -> condition(DQI).
in(Column, Values, Kind) ->
{in, {column_ref, Column}, gleam@list:map(Values, erlang:element(2, Kind))}.
-file("src/based/sql.gleam", 593).
?DOC(" Creates an IS NULL condition.\n").
-spec is_null(column()) -> condition(any()).
is_null(Column) ->
{is_null, {column_ref, Column}}.
-file("src/based/sql.gleam", 598).
?DOC(" Creates an IS NOT NULL condition.\n").
-spec is_not_null(column()) -> condition(any()).
is_not_null(Column) ->
{is_not_null, {column_ref, Column}}.
-file("src/based/sql.gleam", 603).
?DOC(" Creates an IS TRUE condition.\n").
-spec is_true(column()) -> condition(any()).
is_true(Column) ->
{is_true, {column_ref, Column}}.
-file("src/based/sql.gleam", 608).
?DOC(" Creates an IS FALSE condition.\n").
-spec is_false(column()) -> condition(any()).
is_false(Column) ->
{is_false, {column_ref, Column}}.
-file("src/based/sql.gleam", 613).
?DOC(" Combines two conditions with OR.\n").
-spec 'or'(condition(DQU), condition(DQU)) -> condition(DQU).
'or'(Left, Right) ->
{'or', Left, Right}.
-file("src/based/sql.gleam", 618).
?DOC(" Combines two conditions with AND.\n").
-spec 'and'(condition(DQY), condition(DQY)) -> condition(DQY).
'and'(Left, Right) ->
{'and', Left, Right}.
-file("src/based/sql.gleam", 623).
?DOC(" Negates a condition.\n").
-spec 'not'(condition(DRC)) -> condition(DRC).
'not'(Condition) ->
{'not', Condition}.
-file("src/based/sql.gleam", 628).
?DOC(" Creates an EXISTS condition.\n").
-spec exists(builder(select(), DRF)) -> condition(DRF).
exists(Builder) ->
{exists, Builder}.
-file("src/based/sql.gleam", 638).
?DOC(
" Creates a raw SQL condition.\n"
"\n"
" **Warning:** The given SQL string is embedded directly in the query\n"
" without any escaping or parameterization. Never pass untrusted user\n"
" input to this function — doing so may expose your application to SQL\n"
" injection attacks.\n"
).
-spec raw(binary()) -> condition(any()).
raw(Sql) ->
{raw, Sql}.
-file("src/based/sql.gleam", 646).
?DOC(
" Starts building a query from a table. This is the entry point for SELECT\n"
" and DELETE queries.\n"
"\n"
" Pass into `select` or `delete` to choose the query kind.\n"
).
-spec from(table()) -> from(table(), any()).
from(Table) ->
{from_table, Table}.
-file("src/based/sql.gleam", 651).
?DOC(" Converts a `From` into a SELECT query with the given columns.\n").
-spec select(from(any(), DRP), list(column())) -> builder(select(), DRP).
select(From, Columns) ->
From@1 = case From of
{from_table, Table} ->
{select_from_table, Table};
{from_sub_query, Builder, Alias} ->
{select_from_sub_query, Builder, Alias}
end,
_pipe = {select_query,
Columns,
From@1,
[],
[],
[],
none,
none,
[],
false,
[],
false},
{select_builder, _pipe, [], false}.
-file("src/based/sql.gleam", 674).
?DOC(" Creates a new INSERT query builder for the given table.\n").
-spec insert(table()) -> builder(insert(), any()).
insert(Tbl) ->
_pipe = {insert_query, Tbl, [], [], [], none},
{insert_builder, _pipe, [], false}.
-file("src/based/sql.gleam", 686).
?DOC(" Creates a new UPDATE query builder for the given table.\n").
-spec update(table(), list(set(DRY))) -> builder(update(), DRY).
update(Tbl, Sets) ->
_pipe = {update_query, Tbl, Sets, [], [], [], none, none},
{update_builder, _pipe, [], false}.
-file("src/based/sql.gleam", 700).
?DOC(" Converts a `From` into a DELETE query.\n").
-spec delete(from(table(), DSD)) -> builder(delete(), DSD).
delete(From) ->
case From of
{from_table, Table} ->
_pipe = {delete_query, Table, [], []},
{delete_builder, _pipe, [], false};
_ ->
erlang:error(#{gleam_error => panic,
message => <<"unreachable: delete requires FromTable"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"based/sql"/utf8>>,
function => <<"delete"/utf8>>,
line => 706})
end.
-file("src/based/sql.gleam", 711).
?DOC(" Creates a `From` that selects from a subquery instead of a table.\n").
-spec from_subquery(builder(select(), DSI), binary()) -> from(subquery(), DSI).
from_subquery(Builder, Alias) ->
{from_sub_query, Builder, Alias}.
-file("src/based/sql.gleam", 721).
?DOC(
" Adds a WHERE condition to the query.\n"
"\n"
" Applies to SELECT, UPDATE, and DELETE queries. No-ops on other builder types.\n"
).
-spec where(builder(DSN, DSO), list(condition(DSO))) -> builder(DSN, DSO).
where(Builder, Conditions) ->
case Builder of
{select_builder, Query, Ctes, Recursive} ->
_pipe = {select_query,
erlang:element(2, Query),
erlang:element(3, Query),
gleam@list:prepend(erlang:element(4, Query), Conditions),
erlang:element(5, Query),
erlang:element(6, Query),
erlang:element(7, Query),
erlang:element(8, Query),
erlang:element(9, Query),
erlang:element(10, Query),
erlang:element(11, Query),
erlang:element(12, Query)},
{select_builder, _pipe, Ctes, Recursive};
{update_builder, Query@1, Ctes@1, Recursive@1} ->
_pipe@1 = {update_query,
erlang:element(2, Query@1),
erlang:element(3, Query@1),
gleam@list:prepend(erlang:element(4, Query@1), Conditions),
erlang:element(5, Query@1),
erlang:element(6, Query@1),
erlang:element(7, Query@1),
erlang:element(8, Query@1)},
{update_builder, _pipe@1, Ctes@1, Recursive@1};
{delete_builder, Query@2, Ctes@2, Recursive@2} ->
_pipe@2 = {delete_query,
erlang:element(2, Query@2),
gleam@list:prepend(erlang:element(3, Query@2), Conditions),
erlang:element(4, Query@2)},
{delete_builder, _pipe@2, Ctes@2, Recursive@2};
_ ->
Builder
end.
-file("src/based/sql.gleam", 740).
?DOC(" Adds a RETURNING clause. Applies to INSERT, UPDATE, and DELETE queries.\n").
-spec returning(builder(DSV, DSW), list(column())) -> builder(DSV, DSW).
returning(Builder, Columns) ->
case Builder of
{insert_builder, Query, Ctes, Recursive} ->
_pipe = {insert_query,
erlang:element(2, Query),
erlang:element(3, Query),
erlang:element(4, Query),
Columns,
erlang:element(6, Query)},
{insert_builder, _pipe, Ctes, Recursive};
{update_builder, Query@1, Ctes@1, Recursive@1} ->
_pipe@1 = {update_query,
erlang:element(2, Query@1),
erlang:element(3, Query@1),
erlang:element(4, Query@1),
Columns,
erlang:element(6, Query@1),
erlang:element(7, Query@1),
erlang:element(8, Query@1)},
{update_builder, _pipe@1, Ctes@1, Recursive@1};
{delete_builder, Query@2, Ctes@2, Recursive@2} ->
_pipe@2 = {delete_query,
erlang:element(2, Query@2),
erlang:element(3, Query@2),
Columns},
{delete_builder, _pipe@2, Ctes@2, Recursive@2};
_ ->
Builder
end.
-file("src/based/sql.gleam", 756).
?DOC(" Sets the ORDER BY clause. Applies to SELECT and UPDATE queries.\n").
-spec order_by(builder(DTC, DTD), list(order())) -> builder(DTC, DTD).
order_by(Builder, Order_by) ->
case Builder of
{select_builder, Query, Ctes, Recursive} ->
_pipe = {select_query,
erlang:element(2, Query),
erlang:element(3, Query),
erlang:element(4, Query),
erlang:element(5, Query),
Order_by,
erlang:element(7, Query),
erlang:element(8, Query),
erlang:element(9, Query),
erlang:element(10, Query),
erlang:element(11, Query),
erlang:element(12, Query)},
{select_builder, _pipe, Ctes, Recursive};
{update_builder, Query@1, Ctes@1, Recursive@1} ->
_pipe@1 = {update_query,
erlang:element(2, Query@1),
erlang:element(3, Query@1),
erlang:element(4, Query@1),
erlang:element(5, Query@1),
Order_by,
erlang:element(7, Query@1),
erlang:element(8, Query@1)},
{update_builder, _pipe@1, Ctes@1, Recursive@1};
_ ->
Builder
end.
-file("src/based/sql.gleam", 769).
?DOC(" Adds a GROUP BY clause to a SELECT query.\n").
-spec group_by(builder(select(), DTJ), list(column())) -> builder(select(), DTJ).
group_by(Builder, Columns) ->
case Builder of
{select_builder, Query, Ctes, Recursive} ->
_pipe = {select_query,
erlang:element(2, Query),
erlang:element(3, Query),
erlang:element(4, Query),
erlang:element(5, Query),
erlang:element(6, Query),
erlang:element(7, Query),
erlang:element(8, Query),
lists:append(erlang:element(9, Query), Columns),
erlang:element(10, Query),
erlang:element(11, Query),
erlang:element(12, Query)},
{select_builder, _pipe, Ctes, Recursive};
_ ->
erlang:error(#{gleam_error => panic,
message => <<"unreachable: group_by called on non-Select builder"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"based/sql"/utf8>>,
function => <<"group_by"/utf8>>,
line => 777})
end.
-file("src/based/sql.gleam", 782).
?DOC(" Adds a LIMIT clause. Applies to SELECT and UPDATE queries.\n").
-spec limit(builder(DTP, DTQ), integer()) -> builder(DTP, DTQ).
limit(Builder, N) ->
case Builder of
{select_builder, Query, Ctes, Recursive} ->
_pipe = {select_query,
erlang:element(2, Query),
erlang:element(3, Query),
erlang:element(4, Query),
erlang:element(5, Query),
erlang:element(6, Query),
{some, N},
erlang:element(8, Query),
erlang:element(9, Query),
erlang:element(10, Query),
erlang:element(11, Query),
erlang:element(12, Query)},
{select_builder, _pipe, Ctes, Recursive};
{update_builder, Query@1, Ctes@1, Recursive@1} ->
_pipe@1 = {update_query,
erlang:element(2, Query@1),
erlang:element(3, Query@1),
erlang:element(4, Query@1),
erlang:element(5, Query@1),
erlang:element(6, Query@1),
{some, N},
erlang:element(8, Query@1)},
{update_builder, _pipe@1, Ctes@1, Recursive@1};
_ ->
Builder
end.
-file("src/based/sql.gleam", 793).
?DOC(" Adds an OFFSET clause. Applies to SELECT and UPDATE queries.\n").
-spec offset(builder(DTV, DTW), integer()) -> builder(DTV, DTW).
offset(Builder, N) ->
case Builder of
{select_builder, Query, Ctes, Recursive} ->
_pipe = {select_query,
erlang:element(2, Query),
erlang:element(3, Query),
erlang:element(4, Query),
erlang:element(5, Query),
erlang:element(6, Query),
erlang:element(7, Query),
{some, N},
erlang:element(9, Query),
erlang:element(10, Query),
erlang:element(11, Query),
erlang:element(12, Query)},
{select_builder, _pipe, Ctes, Recursive};
{update_builder, Query@1, Ctes@1, Recursive@1} ->
_pipe@1 = {update_query,
erlang:element(2, Query@1),
erlang:element(3, Query@1),
erlang:element(4, Query@1),
erlang:element(5, Query@1),
erlang:element(6, Query@1),
erlang:element(7, Query@1),
{some, N}},
{update_builder, _pipe@1, Ctes@1, Recursive@1};
_ ->
Builder
end.
-file("src/based/sql.gleam", 804).
?DOC(" Adds DISTINCT to a SELECT query.\n").
-spec distinct(builder(select(), DUB)) -> builder(select(), DUB).
distinct(Builder) ->
case Builder of
{select_builder, Query, Ctes, Recursive} ->
_pipe = {select_query,
erlang:element(2, Query),
erlang:element(3, Query),
erlang:element(4, Query),
erlang:element(5, Query),
erlang:element(6, Query),
erlang:element(7, Query),
erlang:element(8, Query),
erlang:element(9, Query),
true,
erlang:element(11, Query),
erlang:element(12, Query)},
{select_builder, _pipe, Ctes, Recursive};
_ ->
erlang:error(#{gleam_error => panic,
message => <<"unreachable: distinct called on non-Select builder"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"based/sql"/utf8>>,
function => <<"distinct"/utf8>>,
line => 808})
end.
-file("src/based/sql.gleam", 813).
?DOC(" Adds a HAVING clause to a SELECT query.\n").
-spec having(builder(select(), DUG), list(condition(DUG))) -> builder(select(), DUG).
having(Builder, Conditions) ->
case Builder of
{select_builder, Query, Ctes, Recursive} ->
_pipe = {select_query,
erlang:element(2, Query),
erlang:element(3, Query),
erlang:element(4, Query),
erlang:element(5, Query),
erlang:element(6, Query),
erlang:element(7, Query),
erlang:element(8, Query),
erlang:element(9, Query),
erlang:element(10, Query),
gleam@list:prepend(erlang:element(11, Query), Conditions),
erlang:element(12, Query)},
{select_builder, _pipe, Ctes, Recursive};
_ ->
erlang:error(#{gleam_error => panic,
message => <<"unreachable: having called on non-Select builder"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"based/sql"/utf8>>,
function => <<"having"/utf8>>,
line => 821})
end.
-file("src/based/sql.gleam", 826).
?DOC(" Adds `FOR UPDATE` to a SELECT query for row-level locking.\n").
-spec for_update(builder(select(), DUN)) -> builder(select(), DUN).
for_update(Builder) ->
case Builder of
{select_builder, Query, Ctes, Recursive} ->
_pipe = {select_query,
erlang:element(2, Query),
erlang:element(3, Query),
erlang:element(4, Query),
erlang:element(5, Query),
erlang:element(6, Query),
erlang:element(7, Query),
erlang:element(8, Query),
erlang:element(9, Query),
erlang:element(10, Query),
erlang:element(11, Query),
true},
{select_builder, _pipe, Ctes, Recursive};
_ ->
erlang:error(#{gleam_error => panic,
message => <<"unreachable: for_update called on non-Select builder"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"based/sql"/utf8>>,
function => <<"for_update"/utf8>>,
line => 830})
end.
-file("src/based/sql.gleam", 835).
?DOC(" Sets the rows to be inserted.\n").
-spec values(builder(insert(), DUS), rows(any(), DUS)) -> builder(insert(), DUS).
values(Builder, Rows) ->
Columns = lists:reverse(erlang:element(2, Rows)),
Extractors = lists:reverse(erlang:element(3, Rows)),
Value_rows = begin
_pipe = erlang:element(4, Rows),
gleam@list:map(_pipe, fun(Item) -> _pipe@1 = Extractors,
gleam@list:map(_pipe@1, fun(Extract) -> Extract(Item) end) end)
end,
case Builder of
{insert_builder, Query, Ctes, Recursive} ->
_pipe@2 = {insert_query,
erlang:element(2, Query),
Columns,
Value_rows,
erlang:element(5, Query),
erlang:element(6, Query)},
{insert_builder, _pipe@2, Ctes, Recursive};
_ ->
erlang:error(#{gleam_error => panic,
message => <<"unreachable: values called on non-Insert builder"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"based/sql"/utf8>>,
function => <<"values"/utf8>>,
line => 852})
end.
-file("src/based/sql.gleam", 857).
?DOC(" Adds an ON CONFLICT clause to an INSERT query (upsert).\n").
-spec on_conflict(
builder(insert(), DVA),
binary(),
conflict_action(),
list(condition(DVA))
) -> builder(insert(), DVA).
on_conflict(Builder, Target, Action, Wheres) ->
case Builder of
{insert_builder, Query, Ctes, Recursive} ->
_pipe = {insert_query,
erlang:element(2, Query),
erlang:element(3, Query),
erlang:element(4, Query),
erlang:element(5, Query),
{some, {on_conflict, Target, Action, Wheres}}},
{insert_builder, _pipe, Ctes, Recursive};
_ ->
erlang:error(#{gleam_error => panic,
message => <<"unreachable: on_conflict called on non-Insert builder"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"based/sql"/utf8>>,
function => <<"on_conflict"/utf8>>,
line => 874})
end.
-file("src/based/sql.gleam", 912).
?DOC(" Sets a column to a value in an UPDATE query. Can be called multiple times.\n").
-spec set(binary(), DVL, kind(DVL, DVM)) -> set(DVM).
set(Column, Input, Kind) ->
{set, Column, (erlang:element(2, Kind))(Input)}.
-file("src/based/sql.gleam", 1152).
-spec append_for_update(sql_builder(DYW), boolean()) -> sql_builder(DYW).
append_for_update(Builder, For_update) ->
case For_update of
true ->
_pipe = erlang:element(2, Builder),
_pipe@1 = based@internal@fmt:for_update(_pipe),
{sql_builder, _pipe@1, erlang:element(3, Builder)};
false ->
Builder
end.
-file("src/based/sql.gleam", 1138).
-spec append_offset(sql_builder(DYS), gleam@option:option(integer())) -> sql_builder(DYS).
append_offset(Builder, Offset_val) ->
case Offset_val of
none ->
Builder;
{some, N} ->
_pipe = erlang:element(2, Builder),
_pipe@1 = based@internal@fmt:offset(_pipe, N),
{sql_builder, _pipe@1, erlang:element(3, Builder)}
end.
-file("src/based/sql.gleam", 1127).
-spec append_limit(sql_builder(DYO), gleam@option:option(integer())) -> sql_builder(DYO).
append_limit(Builder, Limit_val) ->
case Limit_val of
none ->
Builder;
{some, N} ->
_pipe = erlang:element(2, Builder),
_pipe@1 = based@internal@fmt:limit(_pipe, N),
{sql_builder, _pipe@1, erlang:element(3, Builder)}
end.
-file("src/based/sql.gleam", 1658).
-spec build_table_ref(table(), adapter(any())) -> binary().
build_table_ref(Tbl, Adapter) ->
case erlang:element(3, Tbl) of
none ->
(erlang:element(4, Adapter))(erlang:element(2, Tbl));
{some, A} ->
(erlang:element(4, Adapter))(A)
end.
-file("src/based/sql.gleam", 1597).
-spec build_column(column(), adapter(any())) -> binary().
build_column(Column, Adapter) ->
case Column of
{all, Table} ->
case Table of
{some, Tbl} ->
<<(build_table_ref(Tbl, Adapter))/binary, ".*"/utf8>>;
none ->
<<"*"/utf8>>
end;
{column, Table@1, Name, Alias, Func} ->
Col_ref = case Name of
<<"*"/utf8>> ->
case Table@1 of
{some, Tbl@1} ->
<<(build_table_ref(Tbl@1, Adapter))/binary,
".*"/utf8>>;
none ->
<<"*"/utf8>>
end;
_ ->
case Table@1 of
{some, Tbl@2} ->
<<<<(build_table_ref(Tbl@2, Adapter))/binary,
"."/utf8>>/binary,
((erlang:element(4, Adapter))(Name))/binary>>;
none ->
(erlang:element(4, Adapter))(Name)
end
end,
Col_ref@1 = case Func of
none ->
Col_ref;
{some, count} ->
based@internal@fmt:count(Col_ref);
{some, sum} ->
based@internal@fmt:sum(Col_ref);
{some, avg} ->
based@internal@fmt:avg(Col_ref);
{some, max} ->
based@internal@fmt:max(Col_ref);
{some, min} ->
based@internal@fmt:min(Col_ref)
end,
case Alias of
none ->
Col_ref@1;
{some, A} ->
based@internal@fmt:alias_as(
Col_ref@1,
(erlang:element(4, Adapter))(A)
)
end
end.
-file("src/based/sql.gleam", 1665).
-spec build_order_by(list(order()), adapter(any())) -> binary().
build_order_by(Orders, Adapter) ->
_pipe = Orders,
_pipe@5 = gleam@list:map(_pipe, fun(O) -> case O of
{asc, Column} ->
_pipe@1 = Column,
_pipe@2 = build_column(_pipe@1, Adapter),
based@internal@fmt:asc(_pipe@2);
{desc, Column@1} ->
_pipe@3 = Column@1,
_pipe@4 = build_column(_pipe@3, Adapter),
based@internal@fmt:desc(_pipe@4)
end end),
gleam@string:join(_pipe@5, <<", "/utf8>>).
-file("src/based/sql.gleam", 1112).
-spec append_order_by(sql_builder(DYJ), list(order()), adapter(DYJ)) -> sql_builder(DYJ).
append_order_by(Builder, Orders, Adapter) ->
case Orders of
[] ->
Builder;
_ ->
_pipe = erlang:element(2, Builder),
_pipe@1 = based@internal@fmt:order_by(
_pipe,
build_order_by(Orders, Adapter)
),
{sql_builder, _pipe@1, erlang:element(3, Builder)}
end.
-file("src/based/sql.gleam", 1641).
-spec build_columns(list(column()), adapter(any())) -> binary().
build_columns(Columns, Adapter) ->
_pipe = Columns,
_pipe@1 = gleam@list:map(_pipe, fun(C) -> build_column(C, Adapter) end),
gleam@string:join(_pipe@1, <<", "/utf8>>).
-file("src/based/sql.gleam", 1097).
-spec append_group_by(sql_builder(DYE), list(column()), adapter(DYE)) -> sql_builder(DYE).
append_group_by(Builder, Group_by, Adapter) ->
case Group_by of
[] ->
Builder;
Cols ->
_pipe = erlang:element(2, Builder),
_pipe@1 = based@internal@fmt:group_by(
_pipe,
build_columns(Cols, Adapter)
),
{sql_builder, _pipe@1, erlang:element(3, Builder)}
end.
-file("src/based/sql.gleam", 1647).
-spec build_table(table(), adapter(any())) -> binary().
build_table(Tbl, Adapter) ->
case erlang:element(3, Tbl) of
none ->
(erlang:element(4, Adapter))(erlang:element(2, Tbl));
{some, A} ->
based@internal@fmt:alias_as(
(erlang:element(4, Adapter))(erlang:element(2, Tbl)),
(erlang:element(4, Adapter))(A)
)
end.
-file("src/based/sql.gleam", 1407).
-spec build_operand(operand(EAX), adapter(EAX)) -> {binary(), list(list(EAX))}.
build_operand(Operand, Adapter) ->
case Operand of
{column_ref, Column} ->
{build_column(Column, Adapter), []};
{value_ref, Value} ->
{<<":param:"/utf8>>, [[Value]]};
null_ref ->
{<<":param:"/utf8>>, [[(erlang:element(5, Adapter))()]]};
{sub_query, Query} ->
{sql_builder, Sql, Vals} = build_single_select(Query, Adapter),
{based@internal@fmt:subquery(Sql), Vals};
{any_query, Query@1} ->
{sql_builder, Sql@1, Vals@1} = build_single_select(Query@1, Adapter),
{based@internal@fmt:any(Sql@1), Vals@1};
{all_query, Query@2} ->
{sql_builder, Sql@2, Vals@2} = build_single_select(Query@2, Adapter),
{based@internal@fmt:all(Sql@2), Vals@2}
end.
-file("src/based/sql.gleam", 1510).
-spec build_binary_condition(
operand(EBH),
fun((binary(), binary()) -> binary()),
operand(EBH),
adapter(EBH)
) -> {binary(), list(list(EBH))}.
build_binary_condition(Left, Op, Right, Adapter) ->
{Ls, Lv} = build_operand(Left, Adapter),
{Rs, Rv} = build_operand(Right, Adapter),
{Op(Ls, Rs), gleam@list:prepend(Lv, lists:append(Rv))}.
-file("src/based/sql.gleam", 1430).
-spec build_condition(condition(EBC), adapter(EBC)) -> {binary(),
list(list(EBC))}.
build_condition(Condition, Adapter) ->
case Condition of
{equal, Left, Right} ->
build_binary_condition(
Left,
fun based@internal@fmt:eq/2,
Right,
Adapter
);
{not_equal, Left@1, Right@1} ->
build_binary_condition(
Left@1,
fun based@internal@fmt:not_eq/2,
Right@1,
Adapter
);
{greater_than, Left@2, Right@2} ->
build_binary_condition(
Left@2,
fun based@internal@fmt:gt/2,
Right@2,
Adapter
);
{less_than, Left@3, Right@3} ->
build_binary_condition(
Left@3,
fun based@internal@fmt:lt/2,
Right@3,
Adapter
);
{greater_than_or_equal, Left@4, Right@4} ->
build_binary_condition(
Left@4,
fun based@internal@fmt:gt_eq/2,
Right@4,
Adapter
);
{less_than_or_equal, Left@5, Right@5} ->
build_binary_condition(
Left@5,
fun based@internal@fmt:lt_eq/2,
Right@5,
Adapter
);
{between, Operand, Low, High} ->
{Os, Ov} = build_operand(Operand, Adapter),
{Ls, Lv} = build_operand(Low, Adapter),
{Hs, Hv} = build_operand(High, Adapter),
{based@internal@fmt:between(Os, Ls, Hs), lists:append([Ov, Lv, Hv])};
{like, Operand@1, Pattern} ->
build_binary_condition(
Operand@1,
fun based@internal@fmt:like/2,
Pattern,
Adapter
);
{not_like, Operand@2, Pattern@1} ->
build_binary_condition(
Operand@2,
fun based@internal@fmt:not_like/2,
Pattern@1,
Adapter
);
{in, Operand@3, Vals} ->
{Os@1, Ov@1} = build_operand(Operand@3, Adapter),
{Val_strings, All_vals} = gleam@list:fold(
Vals,
{[], []},
fun(Acc, V) ->
{Strings, Collected} = Acc,
{Vs, Vv} = build_operand(V, Adapter),
{gleam@list:prepend(Strings, Vs),
lists:append(Collected, Vv)}
end
),
Val_strings@1 = begin
_pipe = Val_strings,
_pipe@1 = lists:reverse(_pipe),
gleam@string:join(_pipe@1, <<", "/utf8>>)
end,
{based@internal@fmt:in_(Os@1, Val_strings@1),
lists:append(Ov@1, All_vals)};
{is_null, Operand@4} ->
{Os@2, Ov@2} = build_operand(Operand@4, Adapter),
{based@internal@fmt:is_null(Os@2), Ov@2};
{is_not_null, Operand@5} ->
{Os@3, Ov@3} = build_operand(Operand@5, Adapter),
{based@internal@fmt:is_not_null(Os@3), Ov@3};
{is_true, Operand@6} ->
{Os@4, Ov@4} = build_operand(Operand@6, Adapter),
{based@internal@fmt:is_true(Os@4), Ov@4};
{is_false, Operand@7} ->
{Os@5, Ov@5} = build_operand(Operand@7, Adapter),
{based@internal@fmt:is_false(Os@5), Ov@5};
{'and', Left@6, Right@6} ->
{Ls@1, Lv@1} = build_condition(Left@6, Adapter),
{Rs, Rv} = build_condition(Right@6, Adapter),
{based@internal@fmt:and_op(Ls@1, Rs), lists:append(Lv@1, Rv)};
{'or', Left@7, Right@7} ->
{Ls@2, Lv@2} = build_condition(Left@7, Adapter),
{Rs@1, Rv@1} = build_condition(Right@7, Adapter),
{based@internal@fmt:or_op(Ls@2, Rs@1), lists:append(Lv@2, Rv@1)};
{'not', Condition@1} ->
{Cs, Cv} = build_condition(Condition@1, Adapter),
{based@internal@fmt:'not'(Cs), Cv};
{exists, Query} ->
{sql_builder, Sql, Vals@1} = build_single_select(Query, Adapter),
{based@internal@fmt:exists(Sql), Vals@1};
{raw, Sql@1} ->
{Sql@1, []}
end.
-file("src/based/sql.gleam", 1053).
-spec append_having(sql_builder(DXR), list(list(condition(DXR))), adapter(DXR)) -> sql_builder(DXR).
append_having(Builder, Having, Adapter) ->
Having@1 = begin
_pipe = Having,
_pipe@1 = lists:reverse(_pipe),
lists:append(_pipe@1)
end,
case Having@1 of
[] ->
Builder;
[Single] ->
{Hs, Hv} = build_condition(Single, Adapter),
_pipe@2 = erlang:element(2, Builder),
_pipe@3 = based@internal@fmt:having(_pipe@2, Hs),
{sql_builder,
_pipe@3,
gleam@list:prepend(erlang:element(3, Builder), lists:append(Hv))};
[First | Rest] ->
{Hs@1, Hv@1} = begin
_pipe@4 = Rest,
_pipe@5 = gleam@list:fold(
_pipe@4,
First,
fun(Field@0, Field@1) -> {'and', Field@0, Field@1} end
),
build_condition(_pipe@5, Adapter)
end,
_pipe@6 = erlang:element(2, Builder),
_pipe@7 = based@internal@fmt:having(_pipe@6, Hs@1),
{sql_builder,
_pipe@7,
gleam@list:prepend(
erlang:element(3, Builder),
lists:append(Hv@1)
)}
end.
-file("src/based/sql.gleam", 1021).
-spec append_where(sql_builder(DXK), list(list(condition(DXK))), adapter(DXK)) -> sql_builder(DXK).
append_where(Builder, Wheres, Adapter) ->
Wheres@1 = begin
_pipe = Wheres,
_pipe@1 = lists:reverse(_pipe),
lists:append(_pipe@1)
end,
case Wheres@1 of
[] ->
Builder;
[Where] ->
{Ws, Wv} = build_condition(Where, Adapter),
_pipe@2 = erlang:element(2, Builder),
_pipe@3 = based@internal@fmt:where(_pipe@2, Ws),
{sql_builder,
_pipe@3,
gleam@list:prepend(erlang:element(3, Builder), lists:append(Wv))};
[First | Rest] ->
{Ws@1, Wv@1} = begin
_pipe@4 = Rest,
_pipe@5 = gleam@list:fold(
_pipe@4,
First,
fun(Field@0, Field@1) -> {'and', Field@0, Field@1} end
),
build_condition(_pipe@5, Adapter)
end,
_pipe@6 = erlang:element(2, Builder),
_pipe@7 = based@internal@fmt:where(_pipe@6, Ws@1),
{sql_builder,
_pipe@7,
gleam@list:prepend(
erlang:element(3, Builder),
lists:append(Wv@1)
)}
end.
-file("src/based/sql.gleam", 1522).
-spec build_join(sql_builder(EBN), join(EBN), adapter(EBN)) -> sql_builder(EBN).
build_join(Builder, Join, Adapter) ->
{Join_fn, Tbl, On_conditions} = case Join of
{inner_join, Table, On} ->
{fun based@internal@fmt:inner_join/2, Table, On};
{left_join, Table@1, On@1} ->
{fun based@internal@fmt:left_join/2, Table@1, On@1};
{right_join, Table@2, On@2} ->
{fun based@internal@fmt:right_join/2, Table@2, On@2};
{full_join, Table@3, On@3} ->
{fun based@internal@fmt:full_join/2, Table@3, On@3}
end,
{On_sql, On_vals} = case On_conditions of
[] ->
{<<""/utf8>>, []};
[Single] ->
build_condition(Single, Adapter);
[First | Rest] ->
_pipe = Rest,
_pipe@1 = gleam@list:fold(
_pipe,
First,
fun(Field@0, Field@1) -> {'and', Field@0, Field@1} end
),
build_condition(_pipe@1, Adapter)
end,
Sql = begin
_pipe@2 = erlang:element(2, Builder),
_pipe@3 = Join_fn(_pipe@2, build_table(Tbl, Adapter)),
based@internal@fmt:on(_pipe@3, On_sql)
end,
{sql_builder,
Sql,
gleam@list:prepend(erlang:element(3, Builder), lists:append(On_vals))}.
-file("src/based/sql.gleam", 1085).
-spec append_joins(sql_builder(DXY), list(join(DXY)), adapter(DXY)) -> sql_builder(DXY).
append_joins(Builder, Joins, Adapter) ->
_pipe = Joins,
_pipe@1 = lists:reverse(_pipe),
gleam@list:fold(
_pipe@1,
Builder,
fun(Builder1, Join) -> build_join(Builder1, Join, Adapter) end
).
-file("src/based/sql.gleam", 1264).
-spec build_select(select_query(DZV), adapter(DZV)) -> sql_builder(DZV).
build_select(Query, Adapter) ->
Select_fn = case erlang:element(10, Query) of
true ->
fun based@internal@fmt:select_distinct/1;
false ->
fun based@internal@fmt:select/1
end,
Select_start = begin
_pipe = erlang:element(2, Query),
_pipe@1 = build_columns(_pipe, Adapter),
Select_fn(_pipe@1)
end,
Builder@1 = case erlang:element(3, Query) of
{select_from_table, Table} ->
_pipe@2 = Table,
_pipe@3 = build_table(_pipe@2, Adapter),
{sql_builder, _pipe@3, []};
{select_from_sub_query, Query@1, Alias} ->
Builder = build_single_select(Query@1, Adapter),
_pipe@4 = erlang:element(2, Builder),
_pipe@5 = based@internal@fmt:enclose(_pipe@4),
_pipe@6 = based@internal@fmt:alias_as(
_pipe@5,
(erlang:element(4, Adapter))(Alias)
),
{sql_builder, _pipe@6, erlang:element(3, Builder)}
end,
_pipe@7 = based@internal@fmt:from(
Select_start,
erlang:element(2, Builder@1)
),
_pipe@8 = {sql_builder, _pipe@7, erlang:element(3, Builder@1)},
_pipe@9 = append_joins(_pipe@8, erlang:element(5, Query), Adapter),
_pipe@10 = append_where(_pipe@9, erlang:element(4, Query), Adapter),
_pipe@11 = append_group_by(_pipe@10, erlang:element(9, Query), Adapter),
_pipe@12 = append_having(_pipe@11, erlang:element(11, Query), Adapter),
_pipe@13 = append_order_by(_pipe@12, erlang:element(6, Query), Adapter),
_pipe@14 = append_limit(_pipe@13, erlang:element(7, Query)),
_pipe@15 = append_offset(_pipe@14, erlang:element(8, Query)),
append_for_update(_pipe@15, erlang:element(12, Query)).
-file("src/based/sql.gleam", 1586).
-spec build_single_select(builder(select(), ECC), adapter(ECC)) -> sql_builder(ECC).
build_single_select(Builder, Adapter) ->
case Builder of
{select_builder, Query, _, _} ->
build_select(Query, Adapter);
_ ->
erlang:error(#{gleam_error => panic,
message => <<"unreachable: build_single_select called with non-Select builder"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"based/sql"/utf8>>,
function => <<"build_single_select"/utf8>>,
line => 1593})
end.
-file("src/based/sql.gleam", 1552).
-spec build_union(union_query(EBS), adapter(EBS)) -> sql_builder(EBS).
build_union(Query, Adapter) ->
Union_fn = case erlang:element(3, Query) of
union ->
fun based@internal@fmt:union/2;
union_all ->
fun based@internal@fmt:union_all/2
end,
{Sql_parts, Values} = begin
_pipe = erlang:element(2, Query),
gleam@list:fold(
_pipe,
{[], []},
fun(Acc, Q) ->
{Parts, Vals} = Acc,
Builder = build_single_select(Q, Adapter),
{gleam@list:prepend(Parts, erlang:element(2, Builder)),
gleam@list:prepend(Vals, erlang:element(3, Builder))}
end
)
end,
Values@1 = begin
_pipe@1 = lists:append(Values),
lists:reverse(_pipe@1)
end,
Sql = case Sql_parts of
[] ->
<<""/utf8>>;
[First | Rest] ->
gleam@list:fold(Rest, First, Union_fn)
end,
{sql_builder, Sql, Values@1}.
-file("src/based/sql.gleam", 1163).
-spec append_returning(sql_builder(DYZ), list(column()), adapter(DYZ)) -> sql_builder(DYZ).
append_returning(Builder, Returning, Adapter) ->
case Returning of
[] ->
Builder;
Cols ->
_pipe = erlang:element(2, Builder),
_pipe@1 = based@internal@fmt:returning(
_pipe,
build_columns(Cols, Adapter)
),
{sql_builder, _pipe@1, erlang:element(3, Builder)}
end.
-file("src/based/sql.gleam", 1398).
-spec build_delete(delete_query(EAT), adapter(EAT)) -> sql_builder(EAT).
build_delete(Query, Adapter) ->
_pipe = erlang:element(2, Query),
_pipe@1 = build_table(_pipe, Adapter),
_pipe@2 = based@internal@fmt:delete(_pipe@1),
_pipe@3 = {sql_builder, _pipe@2, []},
_pipe@4 = append_where(_pipe@3, erlang:element(3, Query), Adapter),
append_returning(_pipe@4, erlang:element(4, Query), Adapter).
-file("src/based/sql.gleam", 1370).
-spec append_sets(sql_builder(EAN), list(set(EAN)), adapter(EAN)) -> sql_builder(EAN).
append_sets(Builder, Sets, Adapter) ->
{Sets_sql, Values@2} = begin
gleam@list:fold(
Sets,
{[], []},
fun(_use0, Set) ->
{Sql, Values} = _use0,
{Set_string, Operand_values} = build_operand(
erlang:element(3, Set),
Adapter
),
Values@1 = gleam@list:prepend(Values, Operand_values),
Sql@1 = begin
_pipe = erlang:element(2, Set),
_pipe@1 = (erlang:element(4, Adapter))(_pipe),
_pipe@2 = based@internal@fmt:eq(_pipe@1, Set_string),
gleam@list:prepend(Sql, _pipe@2)
end,
{Sql@1, Values@1}
end
)
end,
Sets_sql@1 = begin
_pipe@3 = Sets_sql,
_pipe@4 = lists:reverse(_pipe@3),
gleam@string:join(_pipe@4, <<", "/utf8>>)
end,
Values@3 = begin
_pipe@5 = Values@2,
_pipe@6 = lists:reverse(_pipe@5),
_pipe@7 = lists:append(_pipe@6),
lists:append(_pipe@7)
end,
_pipe@8 = erlang:element(2, Builder),
_pipe@9 = based@internal@fmt:set(_pipe@8, Sets_sql@1),
{sql_builder,
_pipe@9,
gleam@list:prepend(erlang:element(3, Builder), Values@3)}.
-file("src/based/sql.gleam", 1357).
-spec build_update(update_query(EAJ), adapter(EAJ)) -> sql_builder(EAJ).
build_update(Query, Adapter) ->
_pipe = erlang:element(2, Query),
_pipe@1 = build_table(_pipe, Adapter),
_pipe@2 = based@internal@fmt:update(_pipe@1),
_pipe@3 = {sql_builder, _pipe@2, []},
_pipe@4 = append_sets(_pipe@3, erlang:element(3, Query), Adapter),
_pipe@5 = append_where(_pipe@4, erlang:element(4, Query), Adapter),
_pipe@6 = append_order_by(_pipe@5, erlang:element(6, Query), Adapter),
_pipe@7 = append_limit(_pipe@6, erlang:element(7, Query)),
_pipe@8 = append_offset(_pipe@7, erlang:element(8, Query)),
append_returning(_pipe@8, erlang:element(5, Query), Adapter).
-file("src/based/sql.gleam", 1328).
-spec append_on_conflict(
sql_builder(EAD),
gleam@option:option(on_conflict(EAD)),
adapter(EAD)
) -> sql_builder(EAD).
append_on_conflict(Builder, On_conflict, Adapter) ->
case On_conflict of
none ->
Builder;
{some, {on_conflict, Target, Action, Conflict_wheres}} ->
Sql = begin
_pipe = erlang:element(2, Builder),
based@internal@fmt:on_conflict(
_pipe,
(erlang:element(4, Adapter))(Target)
)
end,
_pipe@3 = case Action of
do_nothing ->
based@internal@fmt:do_nothing(Sql);
{do_update, Sets} ->
_pipe@1 = Sets,
_pipe@2 = gleam@list:map(
_pipe@1,
fun(Pair) ->
{Col_name, Val_expr} = Pair,
based@internal@fmt:eq(
(erlang:element(4, Adapter))(Col_name),
Val_expr
)
end
),
based@internal@fmt:do_update(Sql, _pipe@2)
end,
_pipe@4 = {sql_builder, _pipe@3, erlang:element(3, Builder)},
append_where(_pipe@4, [Conflict_wheres], Adapter)
end.
-file("src/based/sql.gleam", 1303).
-spec build_insert(insert_query(DZZ), adapter(DZZ)) -> sql_builder(DZZ).
build_insert(Query, Adapter) ->
{Placeholders, Values} = begin
gleam@list:fold(
erlang:element(4, Query),
{[], []},
fun(_use0, Row) ->
{Rows, Vals} = _use0,
Row_placeholders = begin
_pipe = Row,
_pipe@1 = gleam@list:map(
_pipe,
fun(_) -> <<":param:"/utf8>> end
),
_pipe@2 = gleam@string:join(_pipe@1, <<", "/utf8>>),
based@internal@fmt:enclose(_pipe@2)
end,
{gleam@list:prepend(Rows, Row_placeholders),
gleam@list:prepend(Vals, Row)}
end
)
end,
Columns = gleam@list:map(
erlang:element(3, Query),
erlang:element(4, Adapter)
),
Sql = begin
_pipe@3 = erlang:element(2, Query),
_pipe@4 = build_table(_pipe@3, Adapter),
based@internal@fmt:insert(_pipe@4, Columns, Placeholders)
end,
_pipe@5 = {sql_builder, Sql, Values},
_pipe@6 = append_on_conflict(_pipe@5, erlang:element(6, Query), Adapter),
append_returning(_pipe@6, erlang:element(5, Query), Adapter).
-file("src/based/sql.gleam", 1576).
-spec build_inner(builder(any(), EBX), adapter(EBX)) -> sql_builder(EBX).
build_inner(Builder, Adapter) ->
case Builder of
{select_builder, Query, _, _} ->
build_select(Query, Adapter);
{insert_builder, Query@1, _, _} ->
build_insert(Query@1, Adapter);
{update_builder, Query@2, _, _} ->
build_update(Query@2, Adapter);
{delete_builder, Query@3, _, _} ->
build_delete(Query@3, Adapter);
{union_builder, Query@4, _, _} ->
build_union(Query@4, Adapter)
end.
-file("src/based/sql.gleam", 917).
?DOC(" Creates a Common Table Expression (CTE).\n").
-spec cte(binary(), builder(any(), DVR)) -> cte(DVR).
cte(Name, Builder) ->
{cte, Name, [], fun(_capture) -> build_inner(Builder, _capture) end}.
-file("src/based/sql.gleam", 922).
?DOC(" Sets explicit column names on a CTE.\n").
-spec cte_columns(cte(DVV), list(binary())) -> cte(DVV).
cte_columns(C, Cols) ->
{cte, erlang:element(2, C), Cols, erlang:element(4, C)}.
-file("src/based/sql.gleam", 927).
?DOC(" Attaches CTEs to a query as a `WITH` clause.\n").
-spec with(builder(DVZ, DWA), list(cte(DWA))) -> builder(DVZ, DWA).
with(Builder, Ctes) ->
case Builder of
{select_builder, _, _, _} ->
{select_builder,
erlang:element(2, Builder),
Ctes,
erlang:element(4, Builder)};
{insert_builder, _, _, _} ->
{insert_builder,
erlang:element(2, Builder),
Ctes,
erlang:element(4, Builder)};
{update_builder, _, _, _} ->
{update_builder,
erlang:element(2, Builder),
Ctes,
erlang:element(4, Builder)};
{delete_builder, _, _, _} ->
{delete_builder,
erlang:element(2, Builder),
Ctes,
erlang:element(4, Builder)};
{union_builder, _, _, _} ->
{union_builder,
erlang:element(2, Builder),
Ctes,
erlang:element(4, Builder)}
end.
-file("src/based/sql.gleam", 938).
?DOC(" Marks the query's WITH clause as `WITH RECURSIVE`.\n").
-spec recursive(builder(DWH, DWI)) -> builder(DWH, DWI).
recursive(Builder) ->
case Builder of
{select_builder, _, _, _} ->
{select_builder,
erlang:element(2, Builder),
erlang:element(3, Builder),
true};
{insert_builder, _, _, _} ->
{insert_builder,
erlang:element(2, Builder),
erlang:element(3, Builder),
true};
{update_builder, _, _, _} ->
{update_builder,
erlang:element(2, Builder),
erlang:element(3, Builder),
true};
{delete_builder, _, _, _} ->
{delete_builder,
erlang:element(2, Builder),
erlang:element(3, Builder),
true};
{union_builder, _, _, _} ->
{union_builder,
erlang:element(2, Builder),
erlang:element(3, Builder),
true}
end.
-file("src/based/sql.gleam", 949).
?DOC(" Combines SELECT queries with `UNION`.\n").
-spec union(list(builder(select(), DWN))) -> builder(union(), DWN).
union(Selects) ->
{union_builder, {union_query, Selects, union}, [], false}.
-file("src/based/sql.gleam", 958).
?DOC(" Combines SELECT queries with `UNION ALL`.\n").
-spec union_all(list(builder(select(), DWT))) -> builder(union_all(), DWT).
union_all(Selects) ->
{union_builder, {union_query, Selects, union_all}, [], false}.
-file("src/based/sql.gleam", 1001).
-spec placeholders(binary(), fun((integer()) -> binary())) -> binary().
placeholders(St, Mapper) ->
_pipe = gleam@string:split(St, <<":param:"/utf8>>),
_pipe@1 = gleam@list:index_fold(_pipe, [], fun(Acc, St1, Idx) -> case Idx of
0 ->
[St1 | Acc];
Idx@1 ->
Ph = Mapper(Idx@1),
[St1, Ph | Acc]
end end),
_pipe@2 = lists:reverse(_pipe@1),
gleam@string:join(_pipe@2, <<""/utf8>>).
-file("src/based/sql.gleam", 1222).
-spec build_ctes(list(cte(DZQ)), boolean(), adapter(DZQ)) -> sql_builder(DZQ).
build_ctes(Ctes, Recursive, Adapter) ->
case Ctes of
[] ->
{sql_builder, <<""/utf8>>, []};
_ ->
{Cte_parts, All_vals} = begin
gleam@list:fold(
Ctes,
{[], []},
fun(_use0, Cte) ->
{Parts, Vals} = _use0,
Sql_builder = (erlang:element(4, Cte))(Adapter),
Col_part = case erlang:element(3, Cte) of
[] ->
<<""/utf8>>;
Cols ->
based@internal@fmt:enclose(
gleam@string:join(Cols, <<", "/utf8>>)
)
end,
Values = gleam@list:prepend(
Vals,
erlang:element(3, Sql_builder)
),
Parts@1 = begin
_pipe = erlang:element(2, Cte),
_pipe@1 = gleam@string:append(_pipe, Col_part),
_pipe@2 = based@internal@fmt:cte(
_pipe@1,
erlang:element(2, Sql_builder)
),
gleam@list:prepend(Parts, _pipe@2)
end,
{Parts@1, Values}
end
)
end,
Ctes_sql = begin
_pipe@3 = Cte_parts,
_pipe@4 = lists:reverse(_pipe@3),
gleam@string:join(_pipe@4, <<", "/utf8>>)
end,
Prefix = case Recursive of
true ->
based@internal@fmt:with_recursive(Ctes_sql);
false ->
based@internal@fmt:with_cte(Ctes_sql)
end,
{sql_builder, <<Prefix/binary, " "/utf8>>, lists:append(All_vals)}
end.
-file("src/based/sql.gleam", 1208).
-spec apply_ctes(sql_builder(DZK), list(cte(DZK)), boolean(), adapter(DZK)) -> sql_builder(DZK).
apply_ctes(Builder, Ctes, Recursive, Adapter) ->
Cte_builder = build_ctes(Ctes, Recursive, Adapter),
{sql_builder,
<<(erlang:element(2, Cte_builder))/binary,
(based@internal@fmt:terminate(erlang:element(2, Builder)))/binary>>,
lists:append(erlang:element(3, Builder), erlang:element(3, Cte_builder))}.
-file("src/based/sql.gleam", 1178).
-spec build_query(builder(any(), DZF), adapter(DZF)) -> sql_builder(DZF).
build_query(Builder, Adapter) ->
case Builder of
{select_builder, Query, Ctes, Recursive} ->
_pipe = Query,
_pipe@1 = build_select(_pipe, Adapter),
apply_ctes(_pipe@1, Ctes, Recursive, Adapter);
{insert_builder, Query@1, Ctes@1, Recursive@1} ->
_pipe@2 = Query@1,
_pipe@3 = build_insert(_pipe@2, Adapter),
apply_ctes(_pipe@3, Ctes@1, Recursive@1, Adapter);
{update_builder, Query@2, Ctes@2, Recursive@2} ->
_pipe@4 = Query@2,
_pipe@5 = build_update(_pipe@4, Adapter),
apply_ctes(_pipe@5, Ctes@2, Recursive@2, Adapter);
{delete_builder, Query@3, Ctes@3, Recursive@3} ->
_pipe@6 = Query@3,
_pipe@7 = build_delete(_pipe@6, Adapter),
apply_ctes(_pipe@7, Ctes@3, Recursive@3, Adapter);
{union_builder, Query@4, Ctes@4, Recursive@4} ->
_pipe@8 = Query@4,
_pipe@9 = build_union(_pipe@8, Adapter),
apply_ctes(_pipe@9, Ctes@4, Recursive@4, Adapter)
end.
-file("src/based/sql.gleam", 970).
?DOC(
" Serializes a query builder into a `Query(v)` with parameterized placeholders.\n"
"\n"
" Returns a `Query` record with `.sql` containing the SQL string with\n"
" placeholders and `.values` containing the parameter values in order.\n"
).
-spec to_query(builder(any(), DXA), adapter(DXA)) -> 'query'(DXA).
to_query(Builder, Adapter) ->
{sql_builder, Sql, Values} = build_query(Builder, Adapter),
Sql@1 = placeholders(Sql, erlang:element(2, Adapter)),
Values@1 = begin
_pipe = Values,
_pipe@1 = lists:reverse(_pipe),
lists:append(_pipe@1)
end,
{'query', Sql@1, Values@1}.
-file("src/based/sql.gleam", 982).
?DOC(
" Serializes a query builder into a plain SQL string with values inlined.\n"
"\n"
" Values are formatted using the adapter's `on_value` handler. This is useful\n"
" for debugging and logging — use `to_query` for actual database execution.\n"
).
-spec to_string(builder(any(), DXG), adapter(DXG)) -> binary().
to_string(Builder, Adapter) ->
{sql_builder, Sql, Values} = build_query(Builder, Adapter),
Values@1 = begin
_pipe = Values,
_pipe@1 = lists:reverse(_pipe),
lists:append(_pipe@1)
end,
Values_by_idx = begin
_pipe@2 = Values@1,
_pipe@3 = gleam@list:index_map(
_pipe@2,
fun(Val, Idx) -> {Idx + 1, Val} end
),
maps:from_list(_pipe@3)
end,
With = fun(Idx@1) -> _pipe@4 = Values_by_idx,
_pipe@5 = gleam_stdlib:map_get(_pipe@4, Idx@1),
_pipe@6 = gleam@result:map(_pipe@5, erlang:element(3, Adapter)),
gleam@result:unwrap(_pipe@6, <<""/utf8>>) end,
placeholders(Sql, With).