feat: calendar follow API (POST/DELETE follow, GET following). Refs EventHub/EventHubFront#9
This commit is contained in:
Executable
+111
@@ -0,0 +1,111 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @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, _ = '_'}).
|
||||
Reference in New Issue
Block a user