./ct_report/coverage/mod_event_pusher_push_mnesia.COVER.html

1 %%%-------------------------------------------------------------------
2 %%% @author Rafal Slota
3 %%% @copyright (C) 2017 Erlang Solutions Ltd.
4 %%% This software is released under the Apache License, Version 2.0
5 %%% cited in 'LICENSE.txt'.
6 %%% @end
7 %%%-------------------------------------------------------------------
8 %%% @doc
9 %%% Mnesia backend for mod_event_pusher_push.
10 %%% @end
11 %%%-------------------------------------------------------------------
12 -module(mod_event_pusher_push_mnesia).
13 -author("Rafal Slota").
14 -behavior(mod_event_pusher_push_backend).
15
16 %%--------------------------------------------------------------------
17 %% Exports
18 %%--------------------------------------------------------------------
19
20 -export([init/2]).
21 -export([enable/4,
22 disable/1,
23 disable/3,
24 get_publish_services/1]).
25
26 %%--------------------------------------------------------------------
27 %% Definitions
28 %%--------------------------------------------------------------------
29
30 -record(push_subscription, {
31 user_jid :: key() | undefined,
32 pubsub_jid :: jid:jid(),
33 pubsub_node :: mod_event_pusher_push:pubsub_node(),
34 form :: mod_event_pusher_push:form()
35 }).
36
37 -type key() :: jid:simple_bare_jid().
38 -type sub_record() :: #push_subscription{}.
39
40 %%--------------------------------------------------------------------
41 %% Backend callbacks
42 %%--------------------------------------------------------------------
43
44 -spec init(Host :: jid:server(), Opts :: list()) -> ok.
45 init(_Host, _Opts) ->
46 16 mnesia:create_table(push_subscription,
47 [{disc_copies, [node()]},
48 {type, bag},
49 {attributes, record_info(fields, push_subscription)}]),
50 16 mnesia:add_table_copy(push_subscription, node(), disc_copies),
51 16 ok.
52
53
54 -spec enable(UserJID :: jid:jid(), PubsubJID :: jid:jid(),
55 Node :: mod_event_pusher_push:pubsub_node(), Form :: mod_event_pusher_push:form()) ->
56 ok | {error, Reason :: term()}.
57 enable(User, PubSub, Node, Forms) ->
58 86 disable(User, PubSub, Node),
59 86 write(make_record(User, PubSub, Node, Forms)).
60
61
62 -spec disable(UserJID :: jid:jid()) -> ok | {error, Reason :: term()}.
63 disable(User) ->
64 2 delete(key(User)).
65
66 -spec disable(UserJID :: jid:jid(), PubsubJID :: jid:jid(),
67 Node :: mod_event_pusher_push:pubsub_node() | undefined) ->
68 ok | {error, Reason :: term()}.
69 disable(User, PubsubJID, Node) ->
70 97 Result =
71 exec(
72 fun() ->
73 97 Filtered =
74 11 [Record ||
75 #push_subscription{pubsub_jid = RecPubsubJID,
76 97 pubsub_node = RecNode} = Record <- read(key(User)),
77 18 RecPubsubJID == PubsubJID,
78 18 Node == undefined orelse RecNode == Node],
79
80 97 [mnesia:delete_object(Record) || Record <- Filtered]
81 end),
82
83 97 case Result of
84 {error, _} = E ->
85
:-(
E;
86 _ ->
87 97 ok
88 end.
89
90
91 -spec get_publish_services(User :: jid:jid()) ->
92 {ok, [{PubSub :: jid:jid(),
93 Node :: mod_event_pusher_push:pubsub_node(),
94 Form :: mod_event_pusher_push:form()}]} |
95 {error, Reason :: term()}.
96 get_publish_services(User) ->
97 152 case safe_read(key(User)) of
98 {ok, Records} ->
99 152 {ok, [{PubsubJID, Node, Forms} ||
100 #push_subscription{pubsub_jid = PubsubJID,
101 pubsub_node = Node,
102 152 form = Forms} <- Records]};
103 {error, _} = E ->
104
:-(
E
105 end.
106
107 %%--------------------------------------------------------------------
108 %% Helper functions
109 %%--------------------------------------------------------------------
110
111 -spec read(key()) -> [sub_record()] | no_return().
112 read(Key) ->
113 249 F = fun() -> mnesia:read({push_subscription, Key}) end,
114 249 mnesia:async_dirty(F).
115
116 -spec safe_read(key()) -> {ok, [sub_record()]} | {error, Reason :: term()}.
117 safe_read(Key) ->
118 152 try read(Key) of
119 Records ->
120 152 {ok, Records}
121 catch
122 _:Reason ->
123
:-(
{error, Reason}
124 end.
125
126 -spec write(sub_record()) -> ok | {error, Reason :: term()}.
127 write(Record) ->
128 86 F = fun() -> mnesia:write(Record) end,
129 86 exec(F).
130
131 -spec delete(key()) -> ok | {error, Reason :: term()}.
132 delete(Key) ->
133 2 F = fun() -> mnesia:delete({push_subscription, Key}) end,
134 2 exec(F).
135
136 -spec exec(fun(() -> any())) -> Result :: any().
137 exec(F) ->
138 185 mnesia:sync_dirty(F).
139
140 -spec make_record(UserJID :: jid:jid(), PubsubJID :: jid:jid(),
141 Node :: mod_event_pusher_push:pubsub_node(),
142 Form :: mod_event_pusher_push:form()) -> sub_record().
143 make_record(UserJID, PubsubJID, Node, Form) ->
144 86 #push_subscription{
145 user_jid = key(UserJID),
146 pubsub_jid = PubsubJID,
147 pubsub_node = Node,
148 form = Form
149 }.
150
151 -spec key(jid:jid()) -> key().
152 key(JID) ->
153 337 jid:to_lus(JID).
Line Hits Source