./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 5 mnesia:create_table(muc_room,
46 [{disc_copies, [node()]},
47 {attributes, record_info(fields, muc_room)}]),
48 5 mnesia:create_table(muc_registered,
49 [{disc_copies, [node()]},
50 {attributes, record_info(fields, muc_registered)}]),
51 5 mnesia:add_table_copy(muc_room, node(), disc_copies),
52 5 mnesia:add_table_copy(muc_registered, node(), disc_copies),
53 5 mnesia:add_table_index(muc_registered, nick),
54 5 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
:-(
F = fun() ->
60
:-(
mnesia:write(#muc_room{name_host = {RoomName, MucHost},
61 opts = Opts})
62 end,
63
:-(
Result = mnesia:transaction(F),
64
:-(
case Result of
65 {atomic, _} ->
66
:-(
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 4 try mnesia:dirty_read(muc_room, {RoomName, MucHost}) of
76 [#muc_room{opts = Opts}] ->
77
:-(
{ok, Opts};
78 [] ->
79 4 {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
:-(
F = fun() ->
93
:-(
mnesia:delete({muc_room, {RoomName, MucHost}})
94 end,
95
:-(
Result = mnesia:transaction(F),
96
:-(
case Result of
97 {atomic, _} ->
98
:-(
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
:-(
Query = [{#muc_room{name_host = {'_', MucHost}, _ = '_'},
108 [],
109 ['$_']}],
110
:-(
try
111
:-(
{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 17 LUS = jid:to_lus(JID),
123 17 can_use_nick_internal(MucHost, Nick, LUS).
124
125 can_use_nick_internal(MucHost, Nick, LUS) ->
126 17 Query = [{#muc_registered{us_host = '$1', nick = Nick, _ = '_'},
127 [{'==', {element, 2, '$1'}, MucHost}],
128 ['$_']}],
129 17 try mnesia:dirty_select(muc_registered, Query) of
130 [] ->
131 17 true;
132 [#muc_registered{us_host = {U, _Host}}] ->
133
:-(
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
:-(
LUS = jid:to_lus(From),
142
:-(
try mnesia:dirty_read(muc_registered, {LUS, MucHost}) of
143 [] ->
144
:-(
{error, not_registered};
145 [#muc_registered{nick = Nick}] ->
146
:-(
{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
:-(
LUS = jid:to_lus(From),
157
:-(
F = fun () ->
158
:-(
case can_use_nick_internal(MucHost, Nick, LUS) of
159 true ->
160
:-(
Object = #muc_registered{us_host = {LUS, MucHost}, nick = Nick},
161
:-(
mnesia:write(Object),
162
:-(
ok;
163 false ->
164
:-(
{error, conflict}
165 end
166 end,
167
:-(
case mnesia:transaction(F) of
168 {atomic, Result} ->
169
:-(
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
:-(
LUS = jid:to_lus(From),
179
:-(
F = fun () ->
180
:-(
mnesia:delete({muc_registered, {LUS, MucHost}})
181 end,
182
:-(
case mnesia:transaction(F) of
183 {atomic, _} ->
184
:-(
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