Packages

A native Gleam SQLite driver

Current section

Files

Jump to
glite src glite.erl
Raw

src/glite.erl

-module(glite).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/glite.gleam").
-export([connect/1, disconnect/1, exec/3, exec_many/3, 'query'/3, last_insert_rowid/1, int/1, float/1, text/1, blob/1, bool/1, null/0, nullable/2, transaction/2, query_with/4, query_one/4]).
-export_type([response/1, connection/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.
-type response(GIA) :: {response, list(GIA), integer()}.
-opaque connection() :: {connection,
gleam@erlang@process:subject(glite@internal@connection_actor:message()),
glite@config:config()}.
-file("src/glite.gleam", 52).
?DOC(
" Open a SQLite database and return a connection handle.\n"
" The connection is managed by an OTP actor process.\n"
).
-spec connect(glite@config:config()) -> {ok, connection()} |
{error, glite@error:error()}.
connect(Config) ->
case glite@internal@connection_actor:start(Config) of
{ok, Started} ->
{ok, {connection, erlang:element(3, Started), Config}};
{error, init_timeout} ->
{error,
{connection_error,
<<"Connection initialization timed out"/utf8>>}};
{error, {init_failed, Reason}} ->
{error, {connection_error, Reason}};
{error, {init_exited, _}} ->
{error,
{connection_error,
<<"Connection process exited during init"/utf8>>}}
end.
-file("src/glite.gleam", 64).
?DOC(" Close the database connection and stop the actor.\n").
-spec disconnect(connection()) -> nil.
disconnect(Conn) ->
gleam@erlang@process:call(
erlang:element(2, Conn),
erlang:element(3, erlang:element(3, Conn)),
fun(Reply) -> {disconnect, Reply} end
).
-file("src/glite.gleam", 76).
?DOC(
" Execute a statement that does not return rows (CREATE, INSERT, UPDATE, DELETE).\n"
" Returns the number of rows affected.\n"
).
-spec exec(connection(), binary(), list(glite@value:value())) -> {ok, integer()} |
{error, glite@error:error()}.
exec(Conn, Sql, Params) ->
gleam@erlang@process:call(
erlang:element(2, Conn),
erlang:element(3, erlang:element(3, Conn)),
fun(Reply) -> {exec, Sql, Params, Reply} end
).
-file("src/glite.gleam", 89).
?DOC(
" Execute a statement many times with different parameter sets.\n"
" Prepares once, then binds+steps for each param set efficiently.\n"
" Returns the total number of rows affected.\n"
).
-spec exec_many(connection(), binary(), list(list(glite@value:value()))) -> {ok,
integer()} |
{error, glite@error:error()}.
exec_many(Conn, Sql, Params_list) ->
gleam@erlang@process:call(
erlang:element(2, Conn),
erlang:element(3, erlang:element(3, Conn)),
fun(Reply) -> {exec_many, Sql, Params_list, Reply} end
).
-file("src/glite.gleam", 100).
?DOC(" Execute a query and return raw results (column names + rows of Values).\n").
-spec 'query'(connection(), binary(), list(glite@value:value())) -> {ok,
glite@connection:query_result()} |
{error, glite@error:error()}.
'query'(Conn, Sql, Params) ->
gleam@erlang@process:call(
erlang:element(2, Conn),
erlang:element(3, erlang:element(3, Conn)),
fun(Reply) -> {'query', Sql, Params, Reply} end
).
-file("src/glite.gleam", 170).
?DOC(" Get the last insert rowid.\n").
-spec last_insert_rowid(connection()) -> integer().
last_insert_rowid(Conn) ->
gleam@erlang@process:call(
erlang:element(2, Conn),
erlang:element(3, erlang:element(3, Conn)),
fun(Reply) -> {last_insert_rowid, Reply} end
).
-file("src/glite.gleam", 181).
?DOC(" Create an integer parameter.\n").
-spec int(integer()) -> glite@value:value().
int(Val) ->
{integer, Val}.
-file("src/glite.gleam", 186).
?DOC(" Create a float parameter.\n").
-spec float(float()) -> glite@value:value().
float(Val) ->
{real, Val}.
-file("src/glite.gleam", 191).
?DOC(" Create a text/string parameter.\n").
-spec text(binary()) -> glite@value:value().
text(Val) ->
{text, Val}.
-file("src/glite.gleam", 196).
?DOC(" Create a blob (binary data) parameter.\n").
-spec blob(bitstring()) -> glite@value:value().
blob(Val) ->
{blob, Val}.
-file("src/glite.gleam", 201).
?DOC(" Create a boolean parameter (stored as Integer 0/1).\n").
-spec bool(boolean()) -> glite@value:value().
bool(Val) ->
case Val of
true ->
{integer, 1};
false ->
{integer, 0}
end.
-file("src/glite.gleam", 209).
?DOC(" Create a NULL parameter.\n").
-spec null() -> glite@value:value().
null() ->
null.
-file("src/glite.gleam", 214).
?DOC(" Create a nullable parameter from an Option value.\n").
-spec nullable(gleam@option:option(GJD), fun((GJD) -> glite@value:value())) -> glite@value:value().
nullable(Val, To_param) ->
case Val of
{some, V} ->
To_param(V);
none ->
null
end.
-file("src/glite.gleam", 225).
-spec exec_sql(connection(), binary()) -> {ok, nil} |
{error, glite@error:error()}.
exec_sql(Conn, Sql) ->
gleam@erlang@process:call(
erlang:element(2, Conn),
erlang:element(3, erlang:element(3, Conn)),
fun(Reply) -> {exec_sql, Sql, Reply} end
).
-file("src/glite.gleam", 146).
?DOC(
" Execute a function within a transaction.\n"
" Automatically BEGINs, and COMMITs on Ok or ROLLBACKs on Error.\n"
).
-spec transaction(
connection(),
fun((connection()) -> {ok, GIY} | {error, glite@error:error()})
) -> {ok, GIY} | {error, glite@error:error()}.
transaction(Conn, F) ->
case exec_sql(Conn, <<"BEGIN"/utf8>>) of
{error, E} ->
{error, E};
{ok, _} ->
case F(Conn) of
{ok, Val} ->
case exec_sql(Conn, <<"COMMIT"/utf8>>) of
{ok, _} ->
{ok, Val};
{error, E@1} ->
{error, E@1}
end;
{error, E@2} ->
_ = exec_sql(Conn, <<"ROLLBACK"/utf8>>),
{error, E@2}
end
end.
-file("src/glite.gleam", 231).
-spec decode_rows(
list(list(glite@value:value())),
glite@decode:row_decoder(GJJ),
list(GJJ)
) -> {ok, list(GJJ)} | {error, glite@error:error()}.
decode_rows(Rows, Decoder, Acc) ->
case Rows of
[] ->
{ok, lists:reverse(Acc)};
[Row | Rest] ->
case glite@decode:run(Decoder, Row) of
{ok, Val} ->
decode_rows(Rest, Decoder, [Val | Acc]);
{error, E} ->
{error, E}
end
end.
-file("src/glite.gleam", 111).
?DOC(" Execute a query and decode each row using the provided decoder.\n").
-spec query_with(
connection(),
binary(),
list(glite@value:value()),
glite@decode:row_decoder(GIO)
) -> {ok, response(GIO)} | {error, glite@error:error()}.
query_with(Conn, Sql, Params, Decoder) ->
case 'query'(Conn, Sql, Params) of
{ok, Result} ->
case decode_rows(erlang:element(3, Result), Decoder, []) of
{ok, Decoded} ->
{ok, {response, Decoded, erlang:length(Decoded)}};
{error, E} ->
{error, E}
end;
{error, E@1} ->
{error, E@1}
end.
-file("src/glite.gleam", 128).
?DOC(" Execute a query and return the first decoded row, or error if no rows.\n").
-spec query_one(
connection(),
binary(),
list(glite@value:value()),
glite@decode:row_decoder(GIU)
) -> {ok, GIU} | {error, glite@error:error()}.
query_one(Conn, Sql, Params, Decoder) ->
case query_with(Conn, Sql, Params, Decoder) of
{ok, Response} ->
case erlang:element(2, Response) of
[First | _] ->
{ok, First};
[] ->
{error,
{decode_error,
<<"Expected at least one row, got none"/utf8>>}}
end;
{error, E} ->
{error, E}
end.