Current section
Files
Jump to
Current section
Files
src/cquill@adapter.erl
-module(cquill@adapter).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/cquill/adapter.gleam").
-export([is_not_found/1, is_constraint_violation/1, is_unique_violation/1, is_foreign_key_violation/1, is_connection_error/1, is_recoverable/1, is_query_error/1, format_error/1, format_error_compact/1, from_postgres_error/3, from_mysql_error/2, from_sqlite_error/2, default_capabilities/0, sql_capabilities/0, new/8, name/1, capabilities/1, supports_transactions/1, supports_returning/1, supports_batch_insert/1, supports_upsert/1, supports_json/1, supports_arrays/1, 'query'/3, query_one/3, query_optional/3, mutate/3, insert_returning/3, transaction/3, transaction_with_adapter_errors/3, select_query/2, mutation_query/2, query_with_columns/3, param_int/1, param_float/1, param_string/1, param_bool/1, param_null/0, param_bytes/1, param_custom/2]).
-export_type([compiled_query/0, query_param/0, adapter_capabilities/0, adapter/2]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-type compiled_query() :: {compiled_query,
binary(),
list(query_param()),
integer()}.
-type query_param() :: {param_int, integer()} |
{param_float, float()} |
{param_string, binary()} |
{param_bool, boolean()} |
param_null |
{param_bytes, bitstring()} |
{param_custom, binary(), binary()}.
-type adapter_capabilities() :: {adapter_capabilities,
boolean(),
boolean(),
boolean(),
boolean(),
gleam@option:option(integer()),
boolean(),
boolean()}.
-opaque adapter(LEK, LEL) :: {adapter,
binary(),
adapter_capabilities(),
fun((LEK, compiled_query()) -> {ok, list(LEL)} |
{error, cquill@error:adapter_error()}),
fun((LEK, compiled_query()) -> {ok, integer()} |
{error, cquill@error:adapter_error()}),
fun((LEK, compiled_query()) -> {ok, gleam@option:option(LEL)} |
{error, cquill@error:adapter_error()}),
fun((LEK) -> {ok, LEK} | {error, cquill@error:adapter_error()}),
fun((LEK) -> {ok, nil} | {error, cquill@error:adapter_error()}),
fun((LEK) -> {ok, nil} | {error, cquill@error:adapter_error()})}.
-file("src/cquill/adapter.gleam", 35).
-spec is_not_found(cquill@error:adapter_error()) -> boolean().
is_not_found(Err) ->
cquill@error:is_not_found(Err).
-file("src/cquill/adapter.gleam", 39).
-spec is_constraint_violation(cquill@error:adapter_error()) -> boolean().
is_constraint_violation(Err) ->
cquill@error:is_constraint_violation(Err).
-file("src/cquill/adapter.gleam", 43).
-spec is_unique_violation(cquill@error:adapter_error()) -> boolean().
is_unique_violation(Err) ->
cquill@error:is_unique_violation(Err).
-file("src/cquill/adapter.gleam", 47).
-spec is_foreign_key_violation(cquill@error:adapter_error()) -> boolean().
is_foreign_key_violation(Err) ->
cquill@error:is_foreign_key_violation(Err).
-file("src/cquill/adapter.gleam", 51).
-spec is_connection_error(cquill@error:adapter_error()) -> boolean().
is_connection_error(Err) ->
cquill@error:is_connection_error(Err).
-file("src/cquill/adapter.gleam", 55).
-spec is_recoverable(cquill@error:adapter_error()) -> boolean().
is_recoverable(Err) ->
cquill@error:is_recoverable(Err).
-file("src/cquill/adapter.gleam", 59).
-spec is_query_error(cquill@error:adapter_error()) -> boolean().
is_query_error(Err) ->
cquill@error:is_query_error(Err).
-file("src/cquill/adapter.gleam", 63).
-spec format_error(cquill@error:adapter_error()) -> binary().
format_error(Err) ->
cquill@error:format_error(Err).
-file("src/cquill/adapter.gleam", 67).
-spec format_error_compact(cquill@error:adapter_error()) -> binary().
format_error_compact(Err) ->
cquill@error:format_error_compact(Err).
-file("src/cquill/adapter.gleam", 72).
-spec from_postgres_error(binary(), binary(), binary()) -> cquill@error:adapter_error().
from_postgres_error(Code, Message, Detail) ->
cquill@error:from_postgres_error(Code, Message, Detail).
-file("src/cquill/adapter.gleam", 80).
-spec from_mysql_error(integer(), binary()) -> cquill@error:adapter_error().
from_mysql_error(Code, Message) ->
cquill@error:from_mysql_error(Code, Message).
-file("src/cquill/adapter.gleam", 84).
-spec from_sqlite_error(integer(), binary()) -> cquill@error:adapter_error().
from_sqlite_error(Code, Message) ->
cquill@error:from_sqlite_error(Code, Message).
-file("src/cquill/adapter.gleam", 144).
?DOC(" Default capabilities - minimal feature set all adapters support\n").
-spec default_capabilities() -> adapter_capabilities().
default_capabilities() ->
{adapter_capabilities, false, false, false, false, none, false, false}.
-file("src/cquill/adapter.gleam", 157).
?DOC(" Full SQL database capabilities (Postgres, MySQL, etc.)\n").
-spec sql_capabilities() -> adapter_capabilities().
sql_capabilities() ->
{adapter_capabilities, true, true, true, true, none, true, true}.
-file("src/cquill/adapter.gleam", 211).
?DOC(" Create a new adapter with the given operations.\n").
-spec new(
binary(),
adapter_capabilities(),
fun((LEO, compiled_query()) -> {ok, list(LEP)} |
{error, cquill@error:adapter_error()}),
fun((LEO, compiled_query()) -> {ok, integer()} |
{error, cquill@error:adapter_error()}),
fun((LEO, compiled_query()) -> {ok, gleam@option:option(LEP)} |
{error, cquill@error:adapter_error()}),
fun((LEO) -> {ok, LEO} | {error, cquill@error:adapter_error()}),
fun((LEO) -> {ok, nil} | {error, cquill@error:adapter_error()}),
fun((LEO) -> {ok, nil} | {error, cquill@error:adapter_error()})
) -> adapter(LEO, LEP).
new(
Name,
Capabilities,
Execute_query,
Execute_mutation,
Execute_returning,
Begin_transaction,
Commit_transaction,
Rollback_transaction
) ->
{adapter,
Name,
Capabilities,
Execute_query,
Execute_mutation,
Execute_returning,
Begin_transaction,
Commit_transaction,
Rollback_transaction}.
-file("src/cquill/adapter.gleam", 242).
?DOC(" Get the adapter's name\n").
-spec name(adapter(any(), any())) -> binary().
name(Adapter) ->
{adapter, Name, _, _, _, _, _, _, _} = Adapter,
Name.
-file("src/cquill/adapter.gleam", 248).
?DOC(" Get the adapter's declared capabilities\n").
-spec capabilities(adapter(any(), any())) -> adapter_capabilities().
capabilities(Adapter) ->
{adapter, _, Capabilities, _, _, _, _, _, _} = Adapter,
Capabilities.
-file("src/cquill/adapter.gleam", 254).
?DOC(" Check if adapter supports transactions\n").
-spec supports_transactions(adapter(any(), any())) -> boolean().
supports_transactions(Adapter) ->
erlang:element(2, capabilities(Adapter)).
-file("src/cquill/adapter.gleam", 259).
?DOC(" Check if adapter supports RETURNING clause\n").
-spec supports_returning(adapter(any(), any())) -> boolean().
supports_returning(Adapter) ->
erlang:element(3, capabilities(Adapter)).
-file("src/cquill/adapter.gleam", 264).
?DOC(" Check if adapter supports batch inserts\n").
-spec supports_batch_insert(adapter(any(), any())) -> boolean().
supports_batch_insert(Adapter) ->
erlang:element(4, capabilities(Adapter)).
-file("src/cquill/adapter.gleam", 269).
?DOC(" Check if adapter supports upsert operations\n").
-spec supports_upsert(adapter(any(), any())) -> boolean().
supports_upsert(Adapter) ->
erlang:element(5, capabilities(Adapter)).
-file("src/cquill/adapter.gleam", 274).
?DOC(" Check if adapter supports JSON operations\n").
-spec supports_json(adapter(any(), any())) -> boolean().
supports_json(Adapter) ->
erlang:element(7, capabilities(Adapter)).
-file("src/cquill/adapter.gleam", 279).
?DOC(" Check if adapter supports array types\n").
-spec supports_arrays(adapter(any(), any())) -> boolean().
supports_arrays(Adapter) ->
erlang:element(8, capabilities(Adapter)).
-file("src/cquill/adapter.gleam", 288).
?DOC(" Execute a query and return all rows\n").
-spec 'query'(adapter(LGM, LGN), LGM, compiled_query()) -> {ok, list(LGN)} |
{error, cquill@error:adapter_error()}.
'query'(Adapter, Connection, Compiled) ->
{adapter, _, _, Execute_query, _, _, _, _, _} = Adapter,
Execute_query(Connection, Compiled).
-file("src/cquill/adapter.gleam", 298).
?DOC(" Execute a query and return exactly one row, or error\n").
-spec query_one(adapter(LGT, LGU), LGT, compiled_query()) -> {ok, LGU} |
{error, cquill@error:adapter_error()}.
query_one(Adapter, Connection, Compiled) ->
{adapter, _, _, Execute_query, _, _, _, _, _} = Adapter,
case Execute_query(Connection, Compiled) of
{ok, [Row]} ->
{ok, Row};
{ok, []} ->
{error, not_found};
{ok, Rows} ->
{error, {too_many_rows, 1, erlang:length(Rows)}};
{error, E} ->
{error, E}
end.
-file("src/cquill/adapter.gleam", 313).
?DOC(" Execute a query and return an optional row (None if not found)\n").
-spec query_optional(adapter(LGZ, LHA), LGZ, compiled_query()) -> {ok,
gleam@option:option(LHA)} |
{error, cquill@error:adapter_error()}.
query_optional(Adapter, Connection, Compiled) ->
{adapter, _, _, Execute_query, _, _, _, _, _} = Adapter,
case Execute_query(Connection, Compiled) of
{ok, [Row]} ->
{ok, {some, Row}};
{ok, []} ->
{ok, none};
{ok, Rows} ->
{error, {too_many_rows, 1, erlang:length(Rows)}};
{error, E} ->
{error, E}
end.
-file("src/cquill/adapter.gleam", 328).
?DOC(" Execute a mutation and return affected row count\n").
-spec mutate(adapter(LHG, any()), LHG, compiled_query()) -> {ok, integer()} |
{error, cquill@error:adapter_error()}.
mutate(Adapter, Connection, Compiled) ->
{adapter, _, _, _, Execute_mutation, _, _, _, _} = Adapter,
Execute_mutation(Connection, Compiled).
-file("src/cquill/adapter.gleam", 338).
?DOC(" Execute an INSERT with RETURNING (returns NotSupported if unavailable)\n").
-spec insert_returning(adapter(LHM, LHN), LHM, compiled_query()) -> {ok,
gleam@option:option(LHN)} |
{error, cquill@error:adapter_error()}.
insert_returning(Adapter, Connection, Compiled) ->
{adapter, _, Capabilities, _, _, Execute_returning, _, _, _} = Adapter,
case erlang:element(3, Capabilities) of
true ->
Execute_returning(Connection, Compiled);
false ->
{error, {not_supported, <<"RETURNING clause"/utf8>>}}
end.
-file("src/cquill/adapter.gleam", 353).
?DOC(
" Execute a function within a transaction.\n"
" Returns UserError if the user's operation function fails.\n"
" Returns AdapterTransactionError if the adapter/database fails during the transaction.\n"
).
-spec transaction(
adapter(LHT, any()),
LHT,
fun((LHT) -> {ok, LHX} | {error, LHY})
) -> {ok, LHX} | {error, cquill@error:transaction_error(LHY)}.
transaction(Adapter, Connection, Operation) ->
{adapter,
_,
Capabilities,
_,
_,
_,
Begin_transaction,
Commit_transaction,
Rollback_transaction} = Adapter,
case erlang:element(2, Capabilities) of
false ->
case Operation(Connection) of
{ok, Result} ->
{ok, Result};
{error, E} ->
{error, {user_error, E}}
end;
true ->
case Begin_transaction(Connection) of
{error, Adapter_err} ->
{error,
{begin_failed,
<<"Could not begin transaction: "/utf8,
(cquill@error:format_error(Adapter_err))/binary>>}};
{ok, Tx_conn} ->
case Operation(Tx_conn) of
{ok, Result@1} ->
case Commit_transaction(Tx_conn) of
{ok, _} ->
{ok, Result@1};
{error, Adapter_err@1} ->
{error,
{commit_failed,
<<"Commit failed: "/utf8,
(cquill@error:format_error(
Adapter_err@1
))/binary>>}}
end;
{error, E@1} ->
_ = Rollback_transaction(Tx_conn),
{error, {user_error, E@1}}
end
end
end.
-file("src/cquill/adapter.gleam", 412).
?DOC(
" Execute a function within a transaction with adapter error handling.\n"
" This version allows the operation to return AdapterError, which is wrapped\n"
" in AdapterTransactionError on failure instead of UserError.\n"
).
-spec transaction_with_adapter_errors(
adapter(LIE, any()),
LIE,
fun((LIE) -> {ok, LII} | {error, cquill@error:adapter_error()})
) -> {ok, LII} | {error, cquill@error:transaction_error(nil)}.
transaction_with_adapter_errors(Adapter, Connection, Operation) ->
{adapter,
_,
Capabilities,
_,
_,
_,
Begin_transaction,
Commit_transaction,
Rollback_transaction} = Adapter,
case erlang:element(2, Capabilities) of
false ->
case Operation(Connection) of
{ok, Result} ->
{ok, Result};
{error, Adapter_err} ->
{error, {adapter_transaction_error, Adapter_err}}
end;
true ->
case Begin_transaction(Connection) of
{error, Adapter_err@1} ->
{error,
{begin_failed,
<<"Could not begin transaction: "/utf8,
(cquill@error:format_error(Adapter_err@1))/binary>>}};
{ok, Tx_conn} ->
case Operation(Tx_conn) of
{ok, Result@1} ->
case Commit_transaction(Tx_conn) of
{ok, _} ->
{ok, Result@1};
{error, Adapter_err@2} ->
{error,
{commit_failed,
<<"Commit failed: "/utf8,
(cquill@error:format_error(
Adapter_err@2
))/binary>>}}
end;
{error, Adapter_err@3} ->
_ = Rollback_transaction(Tx_conn),
{error, {adapter_transaction_error, Adapter_err@3}}
end
end
end.
-file("src/cquill/adapter.gleam", 468).
?DOC(" Create a simple SELECT query\n").
-spec select_query(binary(), list(query_param())) -> compiled_query().
select_query(Sql, Params) ->
{compiled_query, Sql, Params, 0}.
-file("src/cquill/adapter.gleam", 473).
?DOC(" Create a mutation query (INSERT/UPDATE/DELETE)\n").
-spec mutation_query(binary(), list(query_param())) -> compiled_query().
mutation_query(Sql, Params) ->
{compiled_query, Sql, Params, 0}.
-file("src/cquill/adapter.gleam", 478).
?DOC(" Create a query with expected column count\n").
-spec query_with_columns(binary(), list(query_param()), integer()) -> compiled_query().
query_with_columns(Sql, Params, Expected_columns) ->
{compiled_query, Sql, Params, Expected_columns}.
-file("src/cquill/adapter.gleam", 491).
?DOC(" Create an integer parameter\n").
-spec param_int(integer()) -> query_param().
param_int(Value) ->
{param_int, Value}.
-file("src/cquill/adapter.gleam", 496).
?DOC(" Create a float parameter\n").
-spec param_float(float()) -> query_param().
param_float(Value) ->
{param_float, Value}.
-file("src/cquill/adapter.gleam", 501).
?DOC(" Create a string parameter\n").
-spec param_string(binary()) -> query_param().
param_string(Value) ->
{param_string, Value}.
-file("src/cquill/adapter.gleam", 506).
?DOC(" Create a boolean parameter\n").
-spec param_bool(boolean()) -> query_param().
param_bool(Value) ->
{param_bool, Value}.
-file("src/cquill/adapter.gleam", 511).
?DOC(" Create a null parameter\n").
-spec param_null() -> query_param().
param_null() ->
param_null.
-file("src/cquill/adapter.gleam", 516).
?DOC(" Create a bytes parameter\n").
-spec param_bytes(bitstring()) -> query_param().
param_bytes(Value) ->
{param_bytes, Value}.
-file("src/cquill/adapter.gleam", 521).
?DOC(" Create a custom type parameter\n").
-spec param_custom(binary(), binary()) -> query_param().
param_custom(Type_name, Value) ->
{param_custom, Type_name, Value}.