diff options
author | Evgeniy Khramtsov <ekhramtsov@process-one.net> | 2016-04-13 21:07:32 +0300 |
---|---|---|
committer | Evgeniy Khramtsov <ekhramtsov@process-one.net> | 2016-04-13 21:07:32 +0300 |
commit | 0b439a7d5b28a5de8d4c2e108333ad20189b580e (patch) | |
tree | de6ced6a618ed7fb3122526626d44d73512ff836 /src/mod_muc_mnesia.erl | |
parent | Clean mod_vcard.erl from DB specific code (diff) |
Clean mod_muc.erl from DB specific code
Diffstat (limited to '')
-rw-r--r-- | src/mod_muc_mnesia.erl | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/src/mod_muc_mnesia.erl b/src/mod_muc_mnesia.erl new file mode 100644 index 000000000..e3ae36978 --- /dev/null +++ b/src/mod_muc_mnesia.erl @@ -0,0 +1,163 @@ +%%%------------------------------------------------------------------- +%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net> +%%% @copyright (C) 2016, Evgeny Khramtsov +%%% @doc +%%% +%%% @end +%%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net> +%%%------------------------------------------------------------------- +-module(mod_muc_mnesia). + +-behaviour(mod_muc). + +%% API +-export([init/2, import/2, store_room/4, restore_room/3, forget_room/3, + can_use_nick/4, get_rooms/2, get_nick/3, set_nick/4]). + +-include("mod_muc.hrl"). +-include("logger.hrl"). + +%%%=================================================================== +%%% API +%%%=================================================================== +init(_Host, Opts) -> + MyHost = proplists:get_value(host, Opts), + mnesia:create_table(muc_room, + [{disc_copies, [node()]}, + {attributes, + record_info(fields, muc_room)}]), + mnesia:create_table(muc_registered, + [{disc_copies, [node()]}, + {attributes, + record_info(fields, muc_registered)}]), + update_tables(MyHost), + mnesia:add_table_index(muc_registered, nick). + +store_room(_LServer, Host, Name, Opts) -> + F = fun () -> + mnesia:write(#muc_room{name_host = {Name, Host}, + opts = Opts}) + end, + mnesia:transaction(F). + +restore_room(_LServer, Host, Name) -> + case catch mnesia:dirty_read(muc_room, {Name, Host}) of + [#muc_room{opts = Opts}] -> Opts; + _ -> error + end. + +forget_room(_LServer, Host, Name) -> + F = fun () -> mnesia:delete({muc_room, {Name, Host}}) + end, + mnesia:transaction(F). + +can_use_nick(_LServer, Host, JID, Nick) -> + {LUser, LServer, _} = jid:tolower(JID), + LUS = {LUser, LServer}, + case catch mnesia:dirty_select(muc_registered, + [{#muc_registered{us_host = '$1', + nick = Nick, _ = '_'}, + [{'==', {element, 2, '$1'}, Host}], + ['$_']}]) + of + {'EXIT', _Reason} -> true; + [] -> true; + [#muc_registered{us_host = {U, _Host}}] -> U == LUS + end. + +get_rooms(_LServer, Host) -> + mnesia:dirty_select(muc_room, + [{#muc_room{name_host = {'_', Host}, + _ = '_'}, + [], ['$_']}]). + +get_nick(_LServer, Host, From) -> + {LUser, LServer, _} = jid:tolower(From), + LUS = {LUser, LServer}, + case mnesia:dirty_read(muc_registered, {LUS, Host}) of + [] -> error; + [#muc_registered{nick = Nick}] -> Nick + end. + +set_nick(_LServer, Host, From, Nick) -> + {LUser, LServer, _} = jid:tolower(From), + LUS = {LUser, LServer}, + F = fun () -> + case Nick of + <<"">> -> + mnesia:delete({muc_registered, {LUS, Host}}), + ok; + _ -> + Allow = case mnesia:select( + muc_registered, + [{#muc_registered{us_host = + '$1', + nick = Nick, + _ = '_'}, + [{'==', {element, 2, '$1'}, + Host}], + ['$_']}]) of + [] -> true; + [#muc_registered{us_host = {U, _Host}}] -> + U == LUS + end, + if Allow -> + mnesia:write(#muc_registered{ + us_host = {LUS, Host}, + nick = Nick}), + ok; + true -> + false + end + end + end, + mnesia:transaction(F). + +import(_LServer, #muc_room{} = R) -> + mnesia:dirty_write(R); +import(_LServer, #muc_registered{} = R) -> + mnesia:dirty_write(R). + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== +update_tables(Host) -> + update_muc_room_table(Host), + update_muc_registered_table(Host). + +update_muc_room_table(_Host) -> + Fields = record_info(fields, muc_room), + case mnesia:table_info(muc_room, attributes) of + Fields -> + ejabberd_config:convert_table_to_binary( + muc_room, Fields, set, + fun(#muc_room{name_host = {N, _}}) -> N end, + fun(#muc_room{name_host = {N, H}, + opts = Opts} = R) -> + R#muc_room{name_host = {iolist_to_binary(N), + iolist_to_binary(H)}, + opts = mod_muc:opts_to_binary(Opts)} + end); + _ -> + ?INFO_MSG("Recreating muc_room table", []), + mnesia:transform_table(muc_room, ignore, Fields) + end. + +update_muc_registered_table(_Host) -> + Fields = record_info(fields, muc_registered), + case mnesia:table_info(muc_registered, attributes) of + Fields -> + ejabberd_config:convert_table_to_binary( + muc_registered, Fields, set, + fun(#muc_registered{us_host = {_, H}}) -> H end, + fun(#muc_registered{us_host = {{U, S}, H}, + nick = Nick} = R) -> + R#muc_registered{us_host = {{iolist_to_binary(U), + iolist_to_binary(S)}, + iolist_to_binary(H)}, + nick = iolist_to_binary(Nick)} + end); + _ -> + ?INFO_MSG("Recreating muc_registered table", []), + mnesia:transform_table(muc_registered, ignore, Fields) + end. |