Makefile View File
| 62 | @echo "Cleaning old data..." |
| 63 | @rm -rf Mnesia.* |
| 64 | @echo "Starting server..." |
| 307 | @docker exec $$(docker ps -qf "name=eventhub_eventhub" | head -n 1) /app/bin/eventhub eval 'nodes().' |
| 308 | @echo "Список узлов Mnesia:" |
| 309 | @docker exec $$(docker ps -qf "name=eventhub_eventhub" | head -n 1) /app/bin/eventhub eval 'mnesia:table_info(user, disc_copies).' |
docker/grafana/dashboards/eventhub-erlang.json View File
| 604 | "panels": [], |
| 605 | "title": "Mnesia", |
| 606 | "type": "row" |
| 708 | { |
| 709 | "expr": "rate(erlang_mnesia_committed_transactions{instance=~\"$instance\"}[1m])", |
| 710 | "legendFormat": "Committed Tx Rate - {{instance}}", |
| 713 | { |
| 714 | "expr": "rate(erlang_mnesia_failed_transactions{instance=~\"$instance\"}[1m])", |
| 715 | "legendFormat": "Failed Tx Rate - {{instance}}", |
| 791 | { |
| 792 | "expr": "erlang_mnesia_held_locks{instance=~\"$instance\"}", |
| 793 | "legendFormat": "Held Locks - {{instance}}", |
| 796 | { |
| 797 | "expr": "erlang_mnesia_lock_queue{instance=~\"$instance\"}", |
| 798 | "legendFormat": "Lock Queue - {{instance}}", |
| 801 | { |
| 802 | "expr": "erlang_mnesia_transaction_participants{instance=~\"$instance\"}", |
| 803 | "legendFormat": "Participants - {{instance}}", |
| 806 | { |
| 807 | "expr": "erlang_mnesia_transaction_coordinators{instance=~\"$instance\"}", |
| 808 | "legendFormat": "Coordinators - {{instance}}", |
src/archive/archive_controller.erl View File
| 10 | try |
| 11 | rpc:call(ArchiveNode, mnesia, create_schema, [[ArchiveNode]]), |
| 12 | rpc:call(ArchiveNode, mnesia, start, []), |
| 13 | rpc:call(ArchiveNode, code, ensure_loaded, [archive_fetcher]), |
| 65 | end, |
| 66 | rpc:call(Node, mnesia, create_table, [Tab, Opts]). |
| 67 | |
| 71 | Records = fetch_records(Tab, Day), |
| 72 | rpc:call(ArchiveNode, mnesia, transaction, [ |
| 73 | fun() -> [mnesia:write(Rec) || Rec <- Records] end |
| 74 | ]), |
| 75 | mnesia:transaction(fun() -> |
| 76 | [mnesia:delete({Tab, element(2, Rec)}) || Rec <- Records] |
| 77 | end) |
| 82 | End = list_to_binary(Day ++ " 23:59:59"), |
| 83 | mnesia:dirty_select(event, [{#event{start_time = '$1', _ = '_'}, |
| 84 | [{'>=','$1', Start},{'=<','$1', End}], |
| 86 | fetch_records(booking, Day) -> |
| 87 | mnesia:dirty_select(booking, [{#booking{created_at = '$1', _ = '_'}, |
| 88 | [{'>=','$1', Day},{'=<','$1', Day ++ " 23:59:59"}], |
| 90 | fetch_records(review, Day) -> |
| 91 | mnesia:dirty_select(review, [{#review{created_at = '$1', _ = '_'}, |
| 92 | [{'>=','$1', Day},{'=<','$1', Day ++ " 23:59:59"}], |
| 94 | fetch_records(report, Day) -> |
| 95 | mnesia:dirty_select(report, [{#report{created_at = '$1', _ = '_'}, |
| 96 | [{'>=','$1', Day},{'=<','$1', Day ++ " 23:59:59"}], |
src/archive/archive_fetcher.erl View File
src/archive/archive_manager.erl View File
src/config/sys.config View File
src/core/core_admin.erl View File
| 23 | }, |
| 24 | mnesia:dirty_write(Admin), |
| 25 | {ok, Admin} |
| 30 | F = fun() -> |
| 31 | case mnesia:read(admin, AdminId) of |
| 32 | [] -> {error, not_found}; |
| 34 | UpdatedAdmin = apply_updates(Admin, Updates), |
| 35 | mnesia:write(UpdatedAdmin), |
| 36 | {ok, UpdatedAdmin} |
| 38 | end, |
| 39 | case mnesia:transaction(F) of |
| 40 | {atomic, Result} -> Result; |
| 45 | Match = #admin{email = Email, _ = '_'}, |
| 46 | case mnesia:dirty_match_object(Match) of |
| 47 | [Admin] -> {ok, Admin}; |
| 51 | get_by_id(Id) -> |
| 52 | case mnesia:dirty_read({admin, Id}) of |
| 53 | [Admin] -> {ok, Admin}; |
| 57 | list_all() -> |
| 58 | mnesia:dirty_match_object(#admin{_ = '_'}). |
| 59 | |
| 63 | Updated = Admin#admin{role = NewRole, updated_at = calendar:universal_time()}, |
| 64 | mnesia:dirty_write(Updated), |
| 65 | {ok, Updated}; |
| 72 | Updated = Admin#admin{last_login = calendar:universal_time()}, |
| 73 | mnesia:dirty_write(Updated), |
| 74 | {ok, Updated}; |
| 87 | Updated = Admin#admin{status = Status, updated_at = calendar:universal_time()}, |
| 88 | mnesia:dirty_write(Updated), |
| 89 | {ok, Updated}; |
| 97 | {ok, _Admin} -> |
| 98 | mnesia:dirty_delete(admin, AdminId), |
| 99 | {ok, deleted}; |
src/core/core_admin_audit.erl View File
src/core/core_admin_session.erl View File
src/core/core_banned_words.erl View File
| 9 | list_banned_words() -> |
| 10 | mnesia:dirty_match_object(#banned_word{_ = '_'}). |
| 11 | |
| 15 | BW = #banned_word{id = Id, word = Word, added_by = AddedBy, added_at = Now}, |
| 16 | case mnesia:transaction(fun() -> |
| 17 | case mnesia:match_object(#banned_word{word = Word, _ = '_'}) of |
| 18 | [] -> mnesia:write(BW), {ok, BW}; |
| 19 | _ -> mnesia:abort(already_exists) |
| 20 | end |
| 27 | remove_banned_word(Word) -> |
| 28 | case mnesia:transaction(fun() -> |
| 29 | case mnesia:match_object(#banned_word{word = Word, _ = '_'}) of |
| 30 | [Rec] -> mnesia:delete_object(Rec), {ok, deleted}; |
| 31 | [] -> mnesia:abort(not_found) |
| 32 | end |
| 38 | update_banned_word(OldWord, NewWord) -> |
| 39 | case mnesia:transaction(fun() -> |
| 40 | case mnesia:match_object(#banned_word{word = OldWord, _ = '_'}) of |
| 41 | [Rec] -> |
| 42 | Updated = Rec#banned_word{word = NewWord}, |
| 43 | mnesia:write(Updated), |
| 44 | {ok, Updated}; |
| 45 | [] -> |
| 46 | mnesia:abort(not_found) |
| 47 | end |
src/core/core_booking.erl View File
| 21 | F = fun() -> |
| 22 | mnesia:write(Booking), |
| 23 | {ok, Booking} |
| 25 | |
| 26 | case mnesia:transaction(F) of |
| 27 | {atomic, Result} -> Result; |
| 32 | get_by_id(Id) -> |
| 33 | case mnesia:dirty_read(booking, Id) of |
| 34 | [] -> {error, not_found}; |
| 40 | Match = #booking{event_id = EventId, user_id = UserId, _ = '_'}, |
| 41 | case mnesia:dirty_match_object(Match) of |
| 42 | [] -> {error, not_found}; |
| 48 | Match = #booking{event_id = EventId, _ = '_'}, |
| 49 | Bookings = mnesia:dirty_match_object(Match), |
| 50 | {ok, Bookings}. |
| 54 | Match = #booking{user_id = UserId, _ = '_'}, |
| 55 | Bookings = mnesia:dirty_match_object(Match), |
| 56 | {ok, Bookings}. |
| 60 | F = fun() -> |
| 61 | case mnesia:read(booking, Id) of |
| 62 | [] -> |
| 72 | }, |
| 73 | mnesia:write(Updated), |
| 74 | {ok, Updated} |
| 77 | |
| 78 | case mnesia:transaction(F) of |
| 79 | {atomic, Result} -> Result; |
| 85 | F = fun() -> |
| 86 | case mnesia:read(booking, Id) of |
| 87 | [] -> |
| 89 | [Booking] -> |
| 90 | mnesia:delete_object(Booking), |
| 91 | {ok, deleted} |
| 94 | |
| 95 | case mnesia:transaction(F) of |
| 96 | {atomic, Result} -> Result; |
| 99 | |
| 100 | count_bookings() -> mnesia:table_info(booking, size). |
src/core/core_calendar.erl View File
| 23 | }, |
| 24 | F = fun() -> mnesia:write(Calendar), {ok, Calendar} end, |
| 25 | case mnesia:transaction(F) of |
| 26 | {atomic, Result} -> Result; |
| 46 | }, |
| 47 | F = fun() -> mnesia:write(Calendar), {ok, Calendar} end, |
| 48 | case mnesia:transaction(F) of |
| 49 | {atomic, Result} -> Result; |
| 54 | get_by_id(Id) -> |
| 55 | case mnesia:dirty_read(calendar, Id) of |
| 56 | [] -> {error, not_found}; |
| 62 | Match = #calendar{owner_id = OwnerId, status = active, _ = '_'}, |
| 63 | Calendars = mnesia:dirty_match_object(Match), |
| 64 | {ok, Calendars}. |
| 68 | F = fun() -> |
| 69 | case mnesia:read(calendar, Id) of |
| 70 | [] -> {error, not_found}; |
| 72 | UpdatedCalendar = apply_updates(Calendar, Updates), |
| 73 | mnesia:write(UpdatedCalendar), |
| 74 | {ok, UpdatedCalendar} |
| 76 | end, |
| 77 | case mnesia:transaction(F) of |
| 78 | {atomic, Result} -> Result; |
| 86 | count_calendars() -> |
| 87 | mnesia:table_info(calendar, size). |
src/core/core_event.erl View File
| 36 | F = fun() -> |
| 37 | mnesia:write(Event), |
| 38 | {ok, Event} |
| 40 | |
| 41 | case mnesia:transaction(F) of |
| 42 | {atomic, Result} -> Result; |
| 72 | F = fun() -> |
| 73 | mnesia:write(Event), |
| 74 | {ok, Event} |
| 76 | |
| 77 | case mnesia:transaction(F) of |
| 78 | {atomic, Result} -> Result; |
| 83 | materialize_occurrence(MasterId, OccurrenceStart, SpecialistId) -> |
| 84 | case mnesia:dirty_read(event, MasterId) of |
| 85 | [] -> |
| 88 | % Проверяем, не существует ли уже материализованное вхождение |
| 89 | Existing = mnesia:dirty_match_object( |
| 90 | #event{master_id = MasterId, start_time = OccurrenceStart, is_instance = true, _ = '_'} |
| 120 | F = fun() -> |
| 121 | mnesia:write(Instance), |
| 122 | {ok, Instance} |
| 124 | |
| 125 | case mnesia:transaction(F) of |
| 126 | {atomic, Result} -> Result; |
| 138 | get_by_id(Id) -> |
| 139 | case mnesia:dirty_read(event, Id) of |
| 140 | [] -> {error, not_found}; |
| 146 | Match = #event{calendar_id = CalendarId, status = active, is_instance = false, _ = '_'}, |
| 147 | Events = mnesia:dirty_match_object(Match), |
| 148 | {ok, Events}. |
| 152 | F = fun() -> |
| 153 | case mnesia:read(event, Id) of |
| 154 | [] -> |
| 157 | UpdatedEvent = apply_updates(Event, Updates), |
| 158 | mnesia:write(UpdatedEvent), |
| 159 | {ok, UpdatedEvent} |
| 162 | |
| 163 | case mnesia:transaction(F) of |
| 164 | {atomic, Result} -> Result; |
| 172 | count_events() -> |
| 173 | mnesia:table_info(event, size). |
| 174 | |
| 176 | Match = #event{status = active, is_instance = false, _ = '_'}, |
| 177 | mnesia:dirty_match_object(Match). |
| 178 | |
| 179 | count_events_by_date(From, To) -> |
| 180 | All = mnesia:dirty_match_object(#event{_ = '_'}), |
| 181 | Filtered = lists:filter(fun(E) -> |
src/core/core_report.erl View File
| 26 | F = fun() -> |
| 27 | mnesia:write(Report), |
| 28 | {ok, Report} |
| 30 | |
| 31 | case mnesia:transaction(F) of |
| 32 | {atomic, Result} -> Result; |
| 37 | get_by_id(Id) -> |
| 38 | case mnesia:dirty_read(report, Id) of |
| 39 | [] -> {error, not_found}; |
| 45 | Match = #report{target_type = TargetType, target_id = TargetId, _ = '_'}, |
| 46 | Reports = mnesia:dirty_match_object(Match), |
| 47 | {ok, Reports}. |
| 51 | Match = #report{reporter_id = ReporterId, _ = '_'}, |
| 52 | Reports = mnesia:dirty_match_object(Match), |
| 53 | {ok, Reports}. |
| 57 | Match = #report{_ = '_'}, |
| 58 | Reports = mnesia:dirty_match_object(Match), |
| 59 | {ok, Reports}. |
| 63 | F = fun() -> |
| 64 | case mnesia:read(report, Id) of |
| 65 | [] -> |
| 72 | }, |
| 73 | mnesia:write(Updated), |
| 74 | {ok, Updated} |
| 77 | |
| 78 | case mnesia:transaction(F) of |
| 79 | {atomic, Result} -> Result; |
| 85 | Match = #report{target_type = TargetType, target_id = TargetId, status = pending, _ = '_'}, |
| 86 | Reports = mnesia:dirty_match_object(Match), |
| 87 | length(Reports). |
| 90 | Match = #report{status = Status, _ = '_'}, |
| 91 | length(mnesia:dirty_match_object(Match)). |
| 92 | |
| 94 | Match = #report{resolved_by = AdminId, status = Status, _ = '_'}, |
| 95 | length(mnesia:dirty_match_object(Match)). |
| 96 | |
| 98 | Match = #report{resolved_by = AdminId, status = Status, _ = '_'}, |
| 99 | length(mnesia:dirty_match_object(Match)). |
| 100 | |
| 102 | Match = #report{status = Status, _ = '_'}, |
| 103 | Reports = mnesia:dirty_match_object(Match), |
| 104 | Resolved = lists:filter(fun(R) -> R#report.resolved_at =/= undefined end, Reports), |
| 117 | {ok, _} -> |
| 118 | mnesia:dirty_delete(report, Id), |
| 119 | {ok, deleted}; |
| 128 | UpdatedReport = apply_updates(Report, Updates), |
| 129 | mnesia:dirty_write(UpdatedReport), |
| 130 | {ok, UpdatedReport}; |
src/core/core_review.erl View File
| 24 | F = fun() -> |
| 25 | mnesia:write(Review), |
| 26 | {ok, Review} |
| 28 | |
| 29 | case mnesia:transaction(F) of |
| 30 | {atomic, Result} -> Result; |
| 35 | get_by_id(Id) -> |
| 36 | case mnesia:dirty_read(review, Id) of |
| 37 | [] -> {error, not_found}; |
| 43 | Match = #review{target_type = TargetType, target_id = TargetId, status = visible, _ = '_'}, |
| 44 | Reviews = mnesia:dirty_match_object(Match), |
| 45 | {ok, lists:sort(fun(A, B) -> A#review.created_at >= B#review.created_at end, Reviews)}. |
| 49 | Match = #review{user_id = UserId, _ = '_'}, |
| 50 | Reviews = mnesia:dirty_match_object(Match), |
| 51 | {ok, Reviews}. |
| 55 | F = fun() -> |
| 56 | case mnesia:read(review, Id) of |
| 57 | [] -> |
| 60 | UpdatedReview = apply_updates(Review, Updates), |
| 61 | mnesia:write(UpdatedReview), |
| 62 | {ok, UpdatedReview} |
| 65 | |
| 66 | case mnesia:transaction(F) of |
| 67 | {atomic, Result} -> Result; |
| 73 | F = fun() -> |
| 74 | case mnesia:read(review, Id) of |
| 75 | [] -> |
| 77 | [Review] -> |
| 78 | mnesia:delete_object(Review), |
| 79 | {ok, deleted} |
| 82 | |
| 83 | case mnesia:transaction(F) of |
| 84 | {atomic, Result} -> Result; |
| 97 | Match = #review{target_type = TargetType, target_id = TargetId, status = visible, _ = '_'}, |
| 98 | Reviews = mnesia:dirty_match_object(Match), |
| 99 | |
| 109 | Match = #review{user_id = UserId, target_type = TargetType, target_id = TargetId, _ = '_'}, |
| 110 | case mnesia:dirty_match_object(Match) of |
| 111 | [] -> false; |
| 114 | |
| 115 | count_reviews() -> mnesia:table_info(review, size). |
| 116 | |
| 117 | list_all() -> mnesia:dirty_match_object(#review{_ = '_'}). |
src/core/core_session.erl View File
| 13 | }, |
| 14 | mnesia:dirty_write(Session), |
| 15 | ok. |
| 18 | validate(Token) -> |
| 19 | case mnesia:dirty_read({session, Token}) of |
| 20 | [Session] -> |
| 23 | % Получаем пользователя по ID из сессии |
| 24 | case mnesia:dirty_read({user, Session#session.user_id}) of |
| 25 | [User] -> |
| 30 | false -> |
| 31 | mnesia:dirty_delete({session, Token}), |
| 32 | {error, expired} |
| 39 | delete(Token) -> |
| 40 | mnesia:dirty_delete({session, Token}), |
| 41 | ok. |
src/core/core_subscription.erl View File
| 45 | F = fun() -> |
| 46 | mnesia:write(Subscription), |
| 47 | {ok, Subscription} |
| 49 | |
| 50 | case mnesia:transaction(F) of |
| 51 | {atomic, Result} -> Result; |
| 56 | get_by_id(Id) -> |
| 57 | case mnesia:dirty_read(subscription, Id) of |
| 58 | [] -> {error, not_found}; |
| 64 | Match = #subscription{user_id = UserId, status = active, _ = '_'}, |
| 65 | case mnesia:dirty_match_object(Match) of |
| 66 | [] -> {error, not_found}; |
| 72 | Match = #subscription{user_id = UserId, _ = '_'}, |
| 73 | Subscriptions = mnesia:dirty_match_object(Match), |
| 74 | {ok, lists:sort(fun(A, B) -> A#subscription.created_at >= B#subscription.created_at end, Subscriptions)}. |
| 78 | Match = #subscription{_ = '_'}, |
| 79 | Subscriptions = mnesia:dirty_match_object(Match), |
| 80 | {ok, Subscriptions}. |
| 84 | F = fun() -> |
| 85 | case mnesia:read(subscription, Id) of |
| 86 | [] -> |
| 92 | }, |
| 93 | mnesia:write(Updated), |
| 94 | {ok, Updated} |
| 97 | |
| 98 | case mnesia:transaction(F) of |
| 99 | {atomic, Result} -> Result; |
| 106 | Match = #subscription{status = active, _ = '_'}, |
| 107 | ActiveSubscriptions = mnesia:dirty_match_object(Match), |
| 108 | |
| 125 | Match = #calendar{owner_id = UserId, type = commercial, _ = '_'}, |
| 126 | Calendars = mnesia:dirty_match_object(Match), |
| 127 | lists:foreach(fun(Cal) -> |
| 171 | Updated = apply_updates(Sub, Updates), |
| 172 | mnesia:dirty_write(Updated), |
| 173 | {ok, Updated}; |
| 179 | {ok, _Sub} -> |
| 180 | mnesia:dirty_delete({subscription, Id}), |
| 181 | {ok, deleted}; |
| 240 | |
| 241 | count_subscription() -> mnesia:table_info(subscription, size). |