112 lines
4.1 KiB
Erlang
Executable File
112 lines
4.1 KiB
Erlang
Executable File
%%%-------------------------------------------------------------------
|
|
%%% @doc Хранение follow чужих календарей (уникальность calendar_id+user_id).
|
|
%%% @end
|
|
%%%-------------------------------------------------------------------
|
|
-module(core_calendar_follow).
|
|
-include("records.hrl").
|
|
|
|
-export([follow/2, unfollow/2, is_following/2, list_by_user/1,
|
|
list_by_calendar/1, delete_by_calendar/1]).
|
|
|
|
%%%-------------------------------------------------------------------
|
|
%%% @doc Подписаться на календарь. Идемпотентно, если уже follow.
|
|
%%% @end
|
|
%%%-------------------------------------------------------------------
|
|
-spec follow(CalendarId :: binary(), UserId :: binary()) ->
|
|
{ok, #calendar_follow{}} | {error, term()}.
|
|
follow(CalendarId, UserId) ->
|
|
Now = calendar:universal_time(),
|
|
F = fun() ->
|
|
case find(CalendarId, UserId) of
|
|
[#calendar_follow{} = Existing] ->
|
|
{ok, Existing};
|
|
[] ->
|
|
Rec = #calendar_follow{
|
|
id = infra_utils:generate_id(16),
|
|
calendar_id = CalendarId,
|
|
user_id = UserId,
|
|
created_at = Now
|
|
},
|
|
mnesia:write(Rec),
|
|
{ok, Rec}
|
|
end
|
|
end,
|
|
case mnesia:transaction(F) of
|
|
{atomic, Result} -> Result;
|
|
{aborted, Reason} -> {error, Reason}
|
|
end.
|
|
|
|
%%%-------------------------------------------------------------------
|
|
%%% @doc Отписаться. Идемпотентно, если follow нет.
|
|
%%% @end
|
|
%%%-------------------------------------------------------------------
|
|
-spec unfollow(CalendarId :: binary(), UserId :: binary()) -> ok | {error, term()}.
|
|
unfollow(CalendarId, UserId) ->
|
|
F = fun() ->
|
|
case find(CalendarId, UserId) of
|
|
[] ->
|
|
ok;
|
|
[#calendar_follow{id = Id}] ->
|
|
mnesia:delete({calendar_follow, Id}),
|
|
ok
|
|
end
|
|
end,
|
|
case mnesia:transaction(F) of
|
|
{atomic, ok} -> ok;
|
|
{aborted, Reason} -> {error, Reason}
|
|
end.
|
|
|
|
%%%-------------------------------------------------------------------
|
|
%%% @doc Есть ли follow у пользователя.
|
|
%%% @end
|
|
%%%-------------------------------------------------------------------
|
|
-spec is_following(UserId :: binary(), CalendarId :: binary()) -> boolean().
|
|
is_following(UserId, CalendarId) ->
|
|
case mnesia:dirty_match_object(
|
|
#calendar_follow{calendar_id = CalendarId, user_id = UserId, _ = '_'}) of
|
|
[] -> false;
|
|
_ -> true
|
|
end.
|
|
|
|
%%%-------------------------------------------------------------------
|
|
%%% @doc Все follow пользователя.
|
|
%%% @end
|
|
%%%-------------------------------------------------------------------
|
|
-spec list_by_user(UserId :: binary()) -> [#calendar_follow{}].
|
|
list_by_user(UserId) ->
|
|
mnesia:dirty_match_object(#calendar_follow{user_id = UserId, _ = '_'}).
|
|
|
|
%%%-------------------------------------------------------------------
|
|
%%% @doc Все follow календаря.
|
|
%%% @end
|
|
%%%-------------------------------------------------------------------
|
|
-spec list_by_calendar(CalendarId :: binary()) -> [#calendar_follow{}].
|
|
list_by_calendar(CalendarId) ->
|
|
mnesia:dirty_match_object(#calendar_follow{calendar_id = CalendarId, _ = '_'}).
|
|
|
|
%%%-------------------------------------------------------------------
|
|
%%% @doc Удалить все follow календаря (при удалении calendar).
|
|
%%% @end
|
|
%%%-------------------------------------------------------------------
|
|
-spec delete_by_calendar(CalendarId :: binary()) -> ok.
|
|
delete_by_calendar(CalendarId) ->
|
|
F = fun() ->
|
|
lists:foreach(
|
|
fun(#calendar_follow{id = Id}) ->
|
|
mnesia:delete({calendar_follow, Id})
|
|
end,
|
|
mnesia:match_object(#calendar_follow{calendar_id = CalendarId, _ = '_'})),
|
|
ok
|
|
end,
|
|
case mnesia:transaction(F) of
|
|
{atomic, ok} -> ok;
|
|
{aborted, Reason} -> error({delete_follows_failed, Reason})
|
|
end.
|
|
|
|
%%%===================================================================
|
|
%%% Internal
|
|
%%%===================================================================
|
|
|
|
find(CalendarId, UserId) ->
|
|
mnesia:match_object(#calendar_follow{calendar_id = CalendarId, user_id = UserId, _ = '_'}).
|