This commit is contained in:
2026-04-17 21:36:56 +03:00
commit 7e776ea6e3
11 changed files with 643 additions and 0 deletions

135
src/infra/infra_mnesia.erl Normal file
View File

@@ -0,0 +1,135 @@
-module(infra_mnesia).
-behaviour(gen_server).
-include("records.hrl").
%% API
-export([start_link/0, init_tables/0, wait_for_tables/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
-define(TABLES, [
user, session, calendar, calendar_share, event, recurrence_exception,
booking, review, report, banned_word, ticket, subscription, audit_log
]).
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
init_tables() ->
gen_server:call(?MODULE, init_tables).
wait_for_tables() ->
gen_server:call(?MODULE, wait_for_tables).
init([]) ->
{ok, #{}}.
handle_call(init_tables, _From, State) ->
ok = ensure_schema(),
lists:foreach(fun create_table/1, ?TABLES),
{reply, ok, State};
handle_call(wait_for_tables, _From, State) ->
mnesia:wait_for_tables(?TABLES, 5000),
{reply, ok, State}.
handle_cast(_Msg, State) ->
{noreply, State}.
handle_info(_Info, State) ->
{noreply, State}.
terminate(_Reason, _State) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%% Internal functions
ensure_schema() ->
case mnesia:create_schema([node()]) of
ok ->
ok;
{error, {Node, {already_exists, Node}}} ->
ok;
{error, {already_exists, _Node}} ->
ok;
{error, Reason} ->
error({schema_creation_failed, Reason})
end.
create_table(Table) ->
case mnesia:create_table(Table, table_opts(Table)) of
{atomic, ok} ->
ok;
{aborted, {already_exists, _}} ->
ok;
{aborted, Reason} ->
error({table_creation_failed, Table, Reason})
end.
%% Опции таблиц без индексов (добавим позже)
table_opts(user) ->
[
{attributes, record_info(fields, user)},
{ram_copies, [node()]}
];
table_opts(session) ->
[
{attributes, record_info(fields, session)},
{ram_copies, [node()]}
];
table_opts(calendar) ->
[
{attributes, record_info(fields, calendar)},
{ram_copies, [node()]}
];
table_opts(calendar_share) ->
[
{attributes, record_info(fields, calendar_share)},
{ram_copies, [node()]}
];
table_opts(event) ->
[
{attributes, record_info(fields, event)},
{ram_copies, [node()]}
];
table_opts(recurrence_exception) ->
[
{attributes, record_info(fields, recurrence_exception)},
{ram_copies, [node()]}
];
table_opts(booking) ->
[
{attributes, record_info(fields, booking)},
{ram_copies, [node()]}
];
table_opts(review) ->
[
{attributes, record_info(fields, review)},
{ram_copies, [node()]}
];
table_opts(report) ->
[
{attributes, record_info(fields, report)},
{ram_copies, [node()]}
];
table_opts(banned_word) ->
[
{attributes, record_info(fields, banned_word)},
{ram_copies, [node()]}
];
table_opts(ticket) ->
[
{attributes, record_info(fields, ticket)},
{ram_copies, [node()]}
];
table_opts(subscription) ->
[
{attributes, record_info(fields, subscription)},
{ram_copies, [node()]}
];
table_opts(audit_log) ->
[
{attributes, record_info(fields, audit_log)},
{ram_copies, [node()]}
].