aboutsummaryrefslogtreecommitdiff
path: root/apps/dreki/src/store/dreki_mnesia_store.erl
diff options
context:
space:
mode:
Diffstat (limited to 'apps/dreki/src/store/dreki_mnesia_store.erl')
-rw-r--r--apps/dreki/src/store/dreki_mnesia_store.erl94
1 files changed, 94 insertions, 0 deletions
diff --git a/apps/dreki/src/store/dreki_mnesia_store.erl b/apps/dreki/src/store/dreki_mnesia_store.erl
new file mode 100644
index 0000000..aceae09
--- /dev/null
+++ b/apps/dreki/src/store/dreki_mnesia_store.erl
@@ -0,0 +1,94 @@
+-module(dreki_mnesia_store).
+-include("dreki.hrl").
+-include("dreki_otel.hrl").
+-include_lib("stdlib/include/ms_transform.hrl").
+-include_lib("kernel/include/logger.hrl").
+-behaviour(dreki_store_backend).
+
+-export([start/0, start/5, checkout/1, checkin/1, stop/0, stop/1]).
+-export([valid_store/5]).
+-export([list/1, count/1, exists/2, get/2, create/2, update/2, delete/2]).
+
+start() ->
+ ok.
+
+valid_store(_NS, _Loc, _Name, _NSMod, _Args) ->
+ ok.
+
+start(Namespace, NsMod, Name, _XUrn, Args) ->
+ TabName = binary_to_atom(iolist_to_binary(["dreki_mnesia_store", "-", Namespace, "-", Name])),
+ case lists:member(TabName, mnesia:system_info(tables)) of
+ true ->
+ {ok, TabName};
+ false ->
+ DefaultOptions = [{rocksdb_copies, [node()]}],
+ Options0 = maps:get(mnesia_table_options, Args, DefaultOptions),
+ Options = [{attributes, NsMod:record_attributes()}, {record_name, NsMod:record_name()} | Options0],
+ {atomic, ok} = mnesia:create_table(TabName, Options),
+ ?LOG_NOTICE(#{message => "Created mnesia table for store", mnesia_table => TabName, store_namespace => Namespace, store_name => Name}),
+ {ok, TabName}
+ end.
+
+checkout(TabName) ->
+ {ok, TabName}.
+
+checkin(_) ->
+ ok.
+
+stop() ->
+ ok.
+
+stop(_) ->
+ ok.
+
+list(TabName) ->
+ transaction(fun () ->
+ [get(TabName, Id) || Id <- iter_all(mnesia:first(TabName), TabName)]
+ end).
+
+count(TabName) ->
+ mnesia:table_info(TabName, size).
+
+get(TabName, Id) ->
+ transaction(fun() ->
+ case mnesia:read(TabName, Id) of
+ [Tuple] ->
+ Tuple;
+ [] ->
+ not_found
+ end
+ end).
+
+exists(TabName, Id) ->
+ case get(TabName, Id) of
+ not_found ->
+ false;
+ _ ->
+ true
+ end.
+
+create(Table, Tuple) ->
+ transaction(fun() ->
+ mnesia:write(Table, Tuple, write),
+ get(Table, element(2, Tuple))
+ end).
+
+update(Table, Tuple) ->
+ create(Table, Tuple).
+
+delete(TabName, Id) ->
+ transaction(fun() ->
+ mnesia:delete(TabName, Id, write)
+ end).
+
+transaction(Fun) ->
+ ?with_span(?FUN_NAME, #{}, fun(_) -> {atomic, Result} = mnesia:transaction(Fun), Result end).
+
+iter_all(Id, TabName) ->
+ ?with_span(?FUN_NAME, #{}, fun(_) -> iter_all(Id, TabName, []) end).
+
+iter_all('$end_of_table', _, Acc) ->
+ Acc;
+iter_all(Id, TabName, Acc) ->
+ [Tuple] = mnesia:read(TabName, Id),
+ iter_all(mnesia:next(TabName, Id), TabName, [Tuple | Acc]).