-module(glesia).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/glesia.gleam").
-export([create_schema/1, create_local_schema/0, delete_schema/1, delete_local_schema/0, set_dir/1, start/0, stop/0, create_table/4, create_ram_table/2, dirty_write/1, dirty_read/2, dirty_read_decoded/3, dirty_delete/2, insert_new/3, transaction/1]).
-export_type([mnesia_error/0, storage_type/0, table_type/0, schema_result/0, simple_result/0, table_create_result/0, read_result/0, insert_new_result/0, transaction_result/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(
" Safe-ish Gleam bindings for Erlang Mnesia.\n"
"\n"
" Glesia wraps the common Mnesia lifecycle and data operations while keeping\n"
" the dynamic BEAM boundary explicit. Table names and attributes are atoms;\n"
" records cross the FFI boundary as `Dynamic` values and can be decoded by\n"
" callers with normal Gleam decoders.\n"
).
-type mnesia_error() :: already_exists |
not_found |
timeout |
{bad_type, binary()} |
{abort, binary()} |
{unknown, binary()}.
-type storage_type() :: ram_copies | disc_copies | disc_only_copies.
-type table_type() :: set | ordered_set | bag.
-type schema_result() :: schema_ok | {schema_error, gleam@dynamic:dynamic_()}.
-type simple_result() :: simple_ok | {simple_error, gleam@dynamic:dynamic_()}.
-type table_create_result() :: table_create_ok |
table_create_already_exists |
{table_create_error, gleam@dynamic:dynamic_()}.
-type read_result() :: {read_ok, list(gleam@dynamic:dynamic_())} |
{read_error, gleam@dynamic:dynamic_()}.
-type insert_new_result() :: insert_new_inserted |
insert_new_exists |
{insert_new_error, gleam@dynamic:dynamic_()}.
-type transaction_result() :: {transaction_ok, gleam@dynamic:dynamic_()} |
{transaction_abort, gleam@dynamic:dynamic_()}.
-file("src/glesia.gleam", 255).
-spec classify(gleam@dynamic:dynamic_()) -> mnesia_error().
classify(Reason) ->
Inspected = gleam@string:inspect(Reason),
case Inspected of
<<"already_exists"/utf8>> ->
already_exists;
<<"not_found"/utf8>> ->
not_found;
<<"timeout"/utf8>> ->
timeout;
_ ->
{unknown, Inspected}
end.
-file("src/glesia.gleam", 106).
-spec create_schema(list(gleam@erlang@atom:atom_())) -> {ok, nil} |
{error, mnesia_error()}.
create_schema(Nodes) ->
case glesia_ffi:create_schema(Nodes) of
schema_ok ->
{ok, nil};
{schema_error, Reason} ->
{error, classify(Reason)}
end.
-file("src/glesia.gleam", 113).
-spec create_local_schema() -> {ok, nil} | {error, mnesia_error()}.
create_local_schema() ->
create_schema([erlang:node()]).
-file("src/glesia.gleam", 117).
-spec delete_schema(list(gleam@erlang@atom:atom_())) -> {ok, nil} |
{error, mnesia_error()}.
delete_schema(Nodes) ->
case glesia_ffi:delete_schema(Nodes) of
schema_ok ->
{ok, nil};
{schema_error, Reason} ->
{error, classify(Reason)}
end.
-file("src/glesia.gleam", 124).
-spec delete_local_schema() -> {ok, nil} | {error, mnesia_error()}.
delete_local_schema() ->
delete_schema([erlang:node()]).
-file("src/glesia.gleam", 128).
-spec set_dir(binary()) -> {ok, nil} | {error, mnesia_error()}.
set_dir(Path) ->
case glesia_ffi:set_dir(Path) of
simple_ok ->
{ok, nil};
{simple_error, Reason} ->
{error, classify(Reason)}
end.
-file("src/glesia.gleam", 135).
-spec start() -> {ok, nil} | {error, mnesia_error()}.
start() ->
case glesia_ffi:start() of
simple_ok ->
{ok, nil};
{simple_error, Reason} ->
{error, classify(Reason)}
end.
-file("src/glesia.gleam", 142).
-spec stop() -> {ok, nil} | {error, mnesia_error()}.
stop() ->
case glesia_ffi:stop() of
simple_ok ->
{ok, nil};
{simple_error, Reason} ->
{error, classify(Reason)}
end.
-file("src/glesia.gleam", 247).
-spec table_type_to_string(table_type()) -> binary().
table_type_to_string(Table_type) ->
case Table_type of
set ->
<<"set"/utf8>>;
ordered_set ->
<<"ordered_set"/utf8>>;
bag ->
<<"bag"/utf8>>
end.
-file("src/glesia.gleam", 239).
-spec storage_type_to_string(storage_type()) -> binary().
storage_type_to_string(Storage_type) ->
case Storage_type of
ram_copies ->
<<"ram_copies"/utf8>>;
disc_copies ->
<<"disc_copies"/utf8>>;
disc_only_copies ->
<<"disc_only_copies"/utf8>>
end.
-file("src/glesia.gleam", 149).
-spec create_table(
gleam@erlang@atom:atom_(),
list(gleam@erlang@atom:atom_()),
storage_type(),
table_type()
) -> {ok, nil} | {error, mnesia_error()}.
create_table(Table, Attributes, Storage_type, Table_type) ->
case glesia_ffi:create_table(
Table,
Attributes,
storage_type_to_string(Storage_type),
table_type_to_string(Table_type)
) of
table_create_ok ->
{ok, nil};
table_create_already_exists ->
{error, already_exists};
{table_create_error, Reason} ->
{error, classify(Reason)}
end.
-file("src/glesia.gleam", 169).
-spec create_ram_table(
gleam@erlang@atom:atom_(),
list(gleam@erlang@atom:atom_())
) -> {ok, nil} | {error, mnesia_error()}.
create_ram_table(Table, Attributes) ->
create_table(Table, Attributes, ram_copies, set).
-file("src/glesia.gleam", 176).
-spec dirty_write(gleam@dynamic:dynamic_()) -> {ok, nil} |
{error, mnesia_error()}.
dirty_write(Record) ->
case glesia_ffi:dirty_write(Record) of
simple_ok ->
{ok, nil};
{simple_error, Reason} ->
{error, classify(Reason)}
end.
-file("src/glesia.gleam", 183).
-spec dirty_read(gleam@erlang@atom:atom_(), gleam@dynamic:dynamic_()) -> {ok,
list(gleam@dynamic:dynamic_())} |
{error, mnesia_error()}.
dirty_read(Table, Key) ->
case glesia_ffi:dirty_read(Table, Key) of
{read_ok, Records} ->
{ok, Records};
{read_error, Reason} ->
{error, classify(Reason)}
end.
-file("src/glesia.gleam", 193).
-spec dirty_read_decoded(
gleam@erlang@atom:atom_(),
gleam@dynamic:dynamic_(),
gleam@dynamic@decode:decoder(EZT)
) -> {ok, list(EZT)} | {error, mnesia_error()}.
dirty_read_decoded(Table, Key, Decoder) ->
_pipe = dirty_read(Table, Key),
gleam@result:'try'(_pipe, fun(Records) -> _pipe@1 = Records,
gleam@list:try_map(
_pipe@1,
fun(Record) ->
_pipe@2 = gleam@dynamic@decode:run(Record, Decoder),
gleam@result:map_error(
_pipe@2,
fun(Error) ->
{bad_type, gleam@string:inspect(Error)}
end
)
end
) end).
-file("src/glesia.gleam", 208).
-spec dirty_delete(gleam@erlang@atom:atom_(), gleam@dynamic:dynamic_()) -> {ok,
nil} |
{error, mnesia_error()}.
dirty_delete(Table, Key) ->
case glesia_ffi:dirty_delete(Table, Key) of
simple_ok ->
{ok, nil};
{simple_error, Reason} ->
{error, classify(Reason)}
end.
-file("src/glesia.gleam", 220).
?DOC(
" Atomically write a record only when no record exists for the given key.\n"
"\n"
" This uses a transactional Mnesia read with a write lock, then writes the\n"
" record inside the same transaction. It returns `Ok(True)` when inserted and\n"
" `Ok(False)` when the key already exists.\n"
).
-spec insert_new(
gleam@erlang@atom:atom_(),
gleam@dynamic:dynamic_(),
gleam@dynamic:dynamic_()
) -> {ok, boolean()} | {error, mnesia_error()}.
insert_new(Table, Key, Record) ->
case glesia_ffi:insert_new(Table, Key, Record) of
insert_new_inserted ->
{ok, true};
insert_new_exists ->
{ok, false};
{insert_new_error, Reason} ->
{error, classify(Reason)}
end.
-file("src/glesia.gleam", 232).
-spec transaction(fun(() -> any())) -> {ok, gleam@dynamic:dynamic_()} |
{error, mnesia_error()}.
transaction(Fun) ->
case glesia_ffi:transaction(Fun) of
{transaction_ok, Value} ->
{ok, Value};
{transaction_abort, Reason} ->
{error, {abort, gleam@string:inspect(Reason)}}
end.