./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 init(_HostType, _Opts) ->
45 16 mnesia:create_table(muc_room,
46 [{disc_copies, [node()]},
47 {attributes, record_info(fields, muc_room)}]),
48 16 mnesia:create_table(muc_registered,
49 [{disc_copies, [node()]},
50 {attributes, record_info(fields, muc_registered)}]),
51 16 mnesia:add_table_copy(muc_room, node(), disc_copies),
52 16 mnesia:add_table_copy(muc_registered, node(), disc_copies),
53 16 mnesia:add_table_index(muc_registered, nick),
54 16 ok.
55
56 -spec store_room(mongooseim:host_type(), jid:server(), mod_muc:room(), list())
57 -> ok | {error, term()}.
58 store_room(HostType, MucHost, RoomName, Opts) ->
59 144 F = fun() ->
60 144 mnesia:write(#muc_room{name_host = {RoomName, MucHost},
61 opts = Opts})
62 end,
63 144 Result = mnesia:transaction(F),
64 144 case Result of
65 {atomic, _} ->
66 144 ok;
67 _ ->
68
:-(
?LOG_ERROR(#{what => muc_store_room_failed,
69 sub_host => MucHost, host_type => HostType,
70
:-(
room => RoomName, reason => Result}),
71
:-(
{error, Result}
72 end.
73
74 restore_room(HostType, MucHost, RoomName) ->
75 56 try mnesia:dirty_read(muc_room, {RoomName, MucHost}) of
76 [#muc_room{opts = Opts}] ->
77 10 {ok, Opts};
78 [] ->
79 46 {error, room_not_found};
80 Other ->
81
:-(
{error, Other}
82 catch Class:Reason:Stacktrace ->
83
:-(
?LOG_ERROR(#{what => muc_restore_room_failed, room => RoomName,
84 sub_host => MucHost, host_type => HostType,
85
:-(
class => Class, reason => Reason, stacktrace => Stacktrace}),
86
:-(
{error, {Class, Reason}}
87 end.
88
89 -spec forget_room(mongooseim:host_type(), jid:server(), mod_muc:room()) ->
90 ok | {error, term()}.
91 forget_room(HostType, MucHost, RoomName) ->
92 86 F = fun() ->
93 86 mnesia:delete({muc_room, {RoomName, MucHost}})
94 end,
95 86 Result = mnesia:transaction(F),
96 86 case Result of
97 {atomic, _} ->
98 86 ok;
99 _ ->
100
:-(
?LOG_ERROR(#{what => muc_forget_room_failed,
101 sub_host => MucHost, host_type => HostType,
102
:-(
room => RoomName, reason => Result}),
103
:-(
{error, Result}
104 end.
105
106 get_rooms(HostType, MucHost) ->
107 32 Query = [{#muc_room{name_host = {'_', MucHost}, _ = '_'},
108 [],
109 ['$_']}],
110 32 try
111 32 {ok, mnesia:dirty_select(muc_room, Query)}
112 catch Class:Reason:Stacktrace ->
113
:-(
?LOG_ERROR(#{what => muc_get_rooms_failed,
114 sub_host => MucHost, host_type => HostType,
115
:-(
class => Class, reason => Reason, stacktrace => Stacktrace}),
116
:-(
{error, {Class, Reason}}
117 end.
118
119 -spec can_use_nick(mongooseim:host_type(), jid:server(),
120 ejabberd:jid(), mod_muc:nick()) -> boolean().
121 can_use_nick(_HostType, MucHost, JID, Nick) ->
122 274 LUS = jid:to_lus(JID),
123 274 can_use_nick_internal(MucHost, Nick, LUS).
124
125 can_use_nick_internal(MucHost, Nick, LUS) ->
126 288 Query = [{#muc_registered{us_host = '$1', nick = Nick, _ = '_'},
127 [{'==', {element, 2, '$1'}, MucHost}],
128 ['$_']}],
129 288 try mnesia:dirty_select(muc_registered, Query) of
130 [] ->
131 286 true;
132 [#muc_registered{us_host = {U, _Host}}] ->
133 2 U == LUS
134 catch Class:Reason:Stacktrace ->
135
:-(
?LOG_ERROR(#{what => muc_can_use_nick_failed, sub_host => MucHost,
136
:-(
class => Class, reason => Reason, stacktrace => Stacktrace}),
137
:-(
false
138 end.
139
140 get_nick(_HostType, MucHost, From) ->
141 22 LUS = jid:to_lus(From),
142 22 try mnesia:dirty_read(muc_registered, {LUS, MucHost}) of
143 [] ->
144 8 {error, not_registered};
145 [#muc_registered{nick = Nick}] ->
146 14 {ok, Nick}
147 catch Class:Reason:Stacktrace ->
148
:-(
?LOG_ERROR(#{what => muc_get_nick_failed,
149 sub_host => MucHost, from_jid => jid:to_binary(From),
150
:-(
class => Class, reason => Reason, stacktrace => Stacktrace}),
151
:-(
{error, {Class, Reason}}
152 end.
153
154 set_nick(HostType, MucHost, From, Nick)
155 when is_binary(Nick), Nick =/= <<>> ->
156 14 LUS = jid:to_lus(From),
157 14 F = fun () ->
158 14 case can_use_nick_internal(MucHost, Nick, LUS) of
159 true ->
160 14 Object = #muc_registered{us_host = {LUS, MucHost}, nick = Nick},
161 14 mnesia:write(Object),
162 14 ok;
163 false ->
164
:-(
{error, conflict}
165 end
166 end,
167 14 case mnesia:transaction(F) of
168 {atomic, Result} ->
169 14 Result;
170 ErrorResult ->
171
:-(
?LOG_ERROR(#{what => muc_set_nick_failed, reason => ErrorResult,
172 server => HostType, sub_host => MucHost,
173
:-(
from_jid => jid:to_binary(From), nick => Nick}),
174
:-(
{error, ErrorResult}
175 end.
176
177 unset_nick(HostType, MucHost, From) ->
178 6 LUS = jid:to_lus(From),
179 6 F = fun () ->
180 6 mnesia:delete({muc_registered, {LUS, MucHost}})
181 end,
182 6 case mnesia:transaction(F) of
183 {atomic, _} ->
184 6 ok;
185 ErrorResult ->
186
:-(
?LOG_ERROR(#{what => muc_unset_nick_failed, reason => ErrorResult,
187 server => HostType, sub_host => MucHost,
188
:-(
from_jid => jid:to_binary(From)}),
189
:-(
{error, ErrorResult}
190 end.
Line Hits Source