./ct_report/coverage/mod_muc_mnesia.COVER.html

1 %%%----------------------------------------------------------------------
2 %%% Based on file mod_muc.
3 %%%
4 %%% Original header and copyright notice:
5 %%%
6 %%% Author : Alexey Shchepin <alexey@process-one.net>
7 %%% Purpose : MUC support (XEP-0045)
8 %%%
9 %%%
10 %%% ejabberd, Copyright (C) 2002-2011 ProcessOne
11 %%%
12 %%% This program is free software; you can redistribute it and/or
13 %%% modify it under the terms of the GNU General Public License as
14 %%% published by the Free Software Foundation; either version 2 of the
15 %%% License, or (at your option) any later version.
16 %%%
17 %%% This program is distributed in the hope that it will be useful,
18 %%% but WITHOUT ANY WARRANTY; without even the implied warranty of
19 %%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 %%% General Public License for more details.
21 %%%
22 %%% You should have received a copy of the GNU General Public License
23 %%% along with this program; if not, write to the Free Software
24 %%% Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 %%%
26 %%%----------------------------------------------------------------------
27
28 -module(mod_muc_mnesia).
29 -behaviour(mod_muc_backend).
30 -export([init/2,
31 store_room/4,
32 restore_room/3,
33 forget_room/3,
34 get_rooms/2,
35 can_use_nick/4,
36 get_nick/3,
37 set_nick/4,
38 unset_nick/3]).
39
40 -include("mongoose.hrl").
41 -include("jlib.hrl").
42 -include("mod_muc.hrl").
43
44 -record(muc_registered, {
45 us_host :: {US :: jid:simple_bare_jid(), MucHost :: jid:lserver()} | '$1',
46 nick :: mod_muc:nick()
47 }).
48
49 init(_HostType, _Opts) ->
50 23 mongoose_mnesia:create_table(muc_room,
51 [{disc_copies, [node()]},
52 {attributes, record_info(fields, muc_room)}]),
53 23 mongoose_mnesia:create_table(muc_registered,
54 [{disc_copies, [node()]},
55 {attributes, record_info(fields, muc_registered)}]),
56 23 mnesia:add_table_index(muc_registered, nick),
57 23 ok.
58
59 -spec store_room(mongooseim:host_type(), jid:server(), mod_muc:room(), list())
60 -> ok | {error, term()}.
61 store_room(HostType, MucHost, RoomName, Opts) ->
62 133 F = fun() ->
63 133 mnesia:write(#muc_room{name_host = {RoomName, MucHost},
64 opts = Opts})
65 end,
66 133 Result = mnesia:transaction(F),
67 133 case Result of
68 {atomic, _} ->
69 133 ok;
70 _ ->
71
:-(
?LOG_ERROR(#{what => muc_store_room_failed,
72 sub_host => MucHost, host_type => HostType,
73
:-(
room => RoomName, reason => Result}),
74
:-(
{error, Result}
75 end.
76
77 restore_room(HostType, MucHost, RoomName) ->
78 51 try mnesia:dirty_read(muc_room, {RoomName, MucHost}) of
79 [#muc_room{opts = Opts}] ->
80 6 {ok, Opts};
81 [] ->
82 45 {error, room_not_found};
83 Other ->
84
:-(
{error, Other}
85 catch Class:Reason:Stacktrace ->
86
:-(
?LOG_ERROR(#{what => muc_restore_room_failed, room => RoomName,
87 sub_host => MucHost, host_type => HostType,
88
:-(
class => Class, reason => Reason, stacktrace => Stacktrace}),
89
:-(
{error, {Class, Reason}}
90 end.
91
92 -spec forget_room(mongooseim:host_type(), jid:server(), mod_muc:room()) ->
93 ok | {error, term()}.
94 forget_room(HostType, MucHost, RoomName) ->
95 77 F = fun() ->
96 77 mnesia:delete({muc_room, {RoomName, MucHost}})
97 end,
98 77 Result = mnesia:transaction(F),
99 77 case Result of
100 {atomic, _} ->
101 77 ok;
102 _ ->
103
:-(
?LOG_ERROR(#{what => muc_forget_room_failed,
104 sub_host => MucHost, host_type => HostType,
105
:-(
room => RoomName, reason => Result}),
106
:-(
{error, Result}
107 end.
108
109 get_rooms(HostType, MucHost) ->
110 46 Query = [{#muc_room{name_host = {'_', MucHost}, _ = '_'},
111 [],
112 ['$_']}],
113 46 try
114 46 {ok, mnesia:dirty_select(muc_room, Query)}
115 catch Class:Reason:Stacktrace ->
116
:-(
?LOG_ERROR(#{what => muc_get_rooms_failed,
117 sub_host => MucHost, host_type => HostType,
118
:-(
class => Class, reason => Reason, stacktrace => Stacktrace}),
119
:-(
{error, {Class, Reason}}
120 end.
121
122 -spec can_use_nick(mongooseim:host_type(), jid:server(),
123 jid:jid(), mod_muc:nick()) -> boolean().
124 can_use_nick(_HostType, MucHost, JID, Nick) ->
125 291 LUS = jid:to_lus(JID),
126 291 can_use_nick_internal(MucHost, Nick, LUS).
127
128 can_use_nick_internal(MucHost, Nick, LUS) ->
129 305 Query = [{#muc_registered{us_host = '$1', nick = Nick, _ = '_'},
130 [{'==', {element, 2, '$1'}, MucHost}],
131 ['$_']}],
132 305 try mnesia:dirty_select(muc_registered, Query) of
133 [] ->
134 303 true;
135 [#muc_registered{us_host = {U, _Host}}] ->
136 2 U == LUS
137 catch Class:Reason:Stacktrace ->
138
:-(
?LOG_ERROR(#{what => muc_can_use_nick_failed, sub_host => MucHost,
139
:-(
class => Class, reason => Reason, stacktrace => Stacktrace}),
140
:-(
false
141 end.
142
143 get_nick(_HostType, MucHost, From) ->
144 22 LUS = jid:to_lus(From),
145 22 try mnesia:dirty_read(muc_registered, {LUS, MucHost}) of
146 [] ->
147 8 {error, not_registered};
148 [#muc_registered{nick = Nick}] ->
149 14 {ok, Nick}
150 catch Class:Reason:Stacktrace ->
151
:-(
?LOG_ERROR(#{what => muc_get_nick_failed,
152 sub_host => MucHost, from_jid => jid:to_binary(From),
153
:-(
class => Class, reason => Reason, stacktrace => Stacktrace}),
154
:-(
{error, {Class, Reason}}
155 end.
156
157 set_nick(HostType, MucHost, From, Nick)
158 when is_binary(Nick), Nick =/= <<>> ->
159 14 LUS = jid:to_lus(From),
160 14 F = fun () ->
161 14 case can_use_nick_internal(MucHost, Nick, LUS) of
162 true ->
163 14 Object = #muc_registered{us_host = {LUS, MucHost}, nick = Nick},
164 14 mnesia:write(Object),
165 14 ok;
166 false ->
167
:-(
{error, conflict}
168 end
169 end,
170 14 case mnesia:transaction(F) of
171 {atomic, Result} ->
172 14 Result;
173 ErrorResult ->
174
:-(
?LOG_ERROR(#{what => muc_set_nick_failed, reason => ErrorResult,
175 server => HostType, sub_host => MucHost,
176
:-(
from_jid => jid:to_binary(From), nick => Nick}),
177
:-(
{error, ErrorResult}
178 end.
179
180 unset_nick(HostType, MucHost, From) ->
181 6 LUS = jid:to_lus(From),
182 6 F = fun () ->
183 6 mnesia:delete({muc_registered, {LUS, MucHost}})
184 end,
185 6 case mnesia:transaction(F) of
186 {atomic, _} ->
187 6 ok;
188 ErrorResult ->
189
:-(
?LOG_ERROR(#{what => muc_unset_nick_failed, reason => ErrorResult,
190 server => HostType, sub_host => MucHost,
191
:-(
from_jid => jid:to_binary(From)}),
192
:-(
{error, ErrorResult}
193 end.
Line Hits Source