Packages

A simple KV store in SQLite

Current section

Files

Jump to
kvite src kvite.erl
Raw

src/kvite.erl

-module(kvite).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-define(FILEPATH, "src/kvite.gleam").
-export([new/0, with_path/2, with_table/2, with_connection/2, sqlight_connection/1, open/1, default/0, get/2, set/3, del/2, keys/1, keys_prefix/2, truncate/1, begin_transaction/1, commit_transaction/1, cancel_transaction/1]).
-export_type([kvite_builder/0, kvite/0, kvite_error/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.
-opaque kvite_builder() :: {kvite_builder,
binary(),
binary(),
gleam@option:option(sqlight:connection())}.
-opaque kvite() :: {kvite, sqlight:connection(), binary()}.
-type kvite_error() :: {sql_error, integer(), binary()}.
-file("src/kvite.gleam", 27).
?DOC(" Create a new KviteBuilder with default values: in-memory SQlite database and a table named \"kv\".\n").
-spec new() -> kvite_builder().
new() ->
{kvite_builder, <<":memory:"/utf8>>, <<"kv"/utf8>>, none}.
-file("src/kvite.gleam", 32).
?DOC(" Set the path to the SQLite database file. Default is `:memory:` for an in-memory database.\n").
-spec with_path(kvite_builder(), binary()) -> kvite_builder().
with_path(Builder, Path) ->
_record = Builder,
{kvite_builder,
Path,
erlang:element(3, _record),
erlang:element(4, _record)}.
-file("src/kvite.gleam", 41).
?DOC(
" Set the name of the table to use. Default is \"kv\".\n"
"\n"
" Note: The table name must be a valid SQLite identifier and cannot contain special characters or spaces.\n"
"\n"
" **WARNING:** Do not use unverified user-input for the table name, as the name is injected as-is into the SQL query.\n"
).
-spec with_table(kvite_builder(), binary()) -> kvite_builder().
with_table(Builder, Table) ->
_record = Builder,
{kvite_builder,
erlang:element(2, _record),
Table,
erlang:element(4, _record)}.
-file("src/kvite.gleam", 49).
?DOC(" Tell Kvite to use an existing connection. If not provided, a new connection will be created when `open` is called on the builder.\n").
-spec with_connection(kvite_builder(), sqlight:connection()) -> kvite_builder().
with_connection(Builder, Conn) ->
_record = Builder,
{kvite_builder,
erlang:element(2, _record),
erlang:element(3, _record),
{some, Conn}}.
-file("src/kvite.gleam", 178).
-spec sqlight_connection(kvite()) -> sqlight:connection().
sqlight_connection(Kv) ->
erlang:element(2, Kv).
-file("src/kvite.gleam", 182).
-spec to_kvite_error(sqlight:error()) -> kvite_error().
to_kvite_error(Err) ->
{sql_error,
sqlight:error_code_to_int(erlang:element(2, Err)),
erlang:element(3, Err)}.
-file("src/kvite.gleam", 57).
?DOC(" Open a Kvite database with the provided builder configuration.\n").
-spec open(kvite_builder()) -> {ok, kvite()} | {error, kvite_error()}.
open(Builder) ->
gleam@result:'try'(case erlang:element(4, Builder) of
{some, Conn} ->
{ok, Conn};
none ->
gleam@result:'try'(
begin
_pipe = sqlight:open(erlang:element(2, Builder)),
gleam@result:map_error(_pipe, fun to_kvite_error/1)
end,
fun(Conn@1) ->
gleam@result:'try'(
begin
_pipe@1 = kvite@raw:apply_pragmas(Conn@1),
gleam@result:map_error(
_pipe@1,
fun to_kvite_error/1
)
end,
fun(_) -> {ok, Conn@1} end
)
end
)
end, fun(Conn@2) ->
gleam@result:'try'(
begin
_pipe@2 = kvite@raw:create_table(
Conn@2,
erlang:element(3, Builder)
),
gleam@result:map_error(_pipe@2, fun to_kvite_error/1)
end,
fun(_) -> {ok, {kvite, Conn@2, erlang:element(3, Builder)}} end
)
end).
-file("src/kvite.gleam", 86).
?DOC(" Create a new Kvite instance with default settings: in-memory database and \"kv\" table.\n").
-spec default() -> {ok, kvite()} | {error, kvite_error()}.
default() ->
_pipe = new(),
open(_pipe).
-file("src/kvite.gleam", 115).
?DOC(" Get the value associated with a key. Returns `Ok(None)` if the key does not exist.\n").
-spec get(kvite(), binary()) -> {ok, gleam@option:option(bitstring())} |
{error, kvite_error()}.
get(Kv, Key) ->
_pipe = kvite@raw:get(erlang:element(2, Kv), erlang:element(3, Kv), Key),
gleam@result:map_error(_pipe, fun to_kvite_error/1).
-file("src/kvite.gleam", 121).
?DOC(" Set the value for a key. If the key already exists, it will be replaced.\n").
-spec set(kvite(), binary(), bitstring()) -> {ok, nil} | {error, kvite_error()}.
set(Kv, Key, Value) ->
_pipe = kvite@raw:set(
erlang:element(2, Kv),
erlang:element(3, Kv),
Key,
Value
),
gleam@result:map_error(_pipe, fun to_kvite_error/1).
-file("src/kvite.gleam", 131).
?DOC(" Delete a key from the database.\n").
-spec del(kvite(), binary()) -> {ok, nil} | {error, kvite_error()}.
del(Kv, Key) ->
_pipe = kvite@raw:del(erlang:element(2, Kv), erlang:element(3, Kv), Key),
gleam@result:map_error(_pipe, fun to_kvite_error/1).
-file("src/kvite.gleam", 137).
?DOC(" Get a list of all keys in the database. Returns an empty list if there are no keys.\n").
-spec keys(kvite()) -> {ok, list(binary())} | {error, kvite_error()}.
keys(Kv) ->
_pipe = kvite@raw:keys(erlang:element(2, Kv), erlang:element(3, Kv), none),
gleam@result:map_error(_pipe, fun to_kvite_error/1).
-file("src/kvite.gleam", 145).
?DOC(
" Get a list of all keys prefixed by `prefix` in the database.\n"
" The list is alphabetically ordered.\n"
" Returns an empty list if there are no keys with the given prefix.\n"
).
-spec keys_prefix(kvite(), binary()) -> {ok, list(binary())} |
{error, kvite_error()}.
keys_prefix(Kv, Prefix) ->
_pipe = kvite@raw:keys(
erlang:element(2, Kv),
erlang:element(3, Kv),
{some, Prefix}
),
gleam@result:map_error(_pipe, fun to_kvite_error/1).
-file("src/kvite.gleam", 154).
?DOC(" Delete all keys and values from the Kvite instance. This operation is irreversible.\n").
-spec truncate(kvite()) -> {ok, nil} | {error, kvite_error()}.
truncate(Kv) ->
_pipe = kvite@raw:truncate(erlang:element(2, Kv), erlang:element(3, Kv)),
gleam@result:map_error(_pipe, fun to_kvite_error/1).
-file("src/kvite.gleam", 161).
?DOC(
" Begin a transaction. All operations after this will be part of the transaction and will only be applied to the\n"
" database when `commit_transaction` is called. Call `cancel_transaction` to discard the changes made during the transaction.\n"
).
-spec begin_transaction(kvite()) -> {ok, nil} | {error, kvite_error()}.
begin_transaction(Kv) ->
_pipe = kvite@raw:begin_transaction(erlang:element(2, Kv)),
gleam@result:map_error(_pipe, fun to_kvite_error/1).
-file("src/kvite.gleam", 167).
?DOC(" Commit the current transaction. All changes made during the transaction will be applied.\n").
-spec commit_transaction(kvite()) -> {ok, nil} | {error, kvite_error()}.
commit_transaction(Kv) ->
_pipe = kvite@raw:commit_transaction(erlang:element(2, Kv)),
gleam@result:map_error(_pipe, fun to_kvite_error/1).
-file("src/kvite.gleam", 173).
?DOC(" Cancel the current transaction. All changes made during the transaction will be discarded.\n").
-spec cancel_transaction(kvite()) -> {ok, nil} | {error, kvite_error()}.
cancel_transaction(Kv) ->
_pipe = kvite@raw:cancel_transaction(erlang:element(2, Kv)),
gleam@result:map_error(_pipe, fun to_kvite_error/1).