aboutsummaryrefslogtreecommitdiff
path: root/src/mod_muc_sql.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/mod_muc_sql.erl')
-rw-r--r--src/mod_muc_sql.erl202
1 files changed, 202 insertions, 0 deletions
diff --git a/src/mod_muc_sql.erl b/src/mod_muc_sql.erl
new file mode 100644
index 000000000..55628d43e
--- /dev/null
+++ b/src/mod_muc_sql.erl
@@ -0,0 +1,202 @@
+%%%-------------------------------------------------------------------
+%%% @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_sql).
+
+-behaviour(mod_muc).
+
+%% API
+-export([init/2, store_room/4, restore_room/3, forget_room/3,
+ can_use_nick/4, get_rooms/2, get_nick/3, set_nick/4,
+ import/1, import/2, export/1]).
+
+-include("jlib.hrl").
+-include("mod_muc.hrl").
+-include("logger.hrl").
+
+%%%===================================================================
+%%% API
+%%%===================================================================
+init(_Host, _Opts) ->
+ ok.
+
+store_room(LServer, Host, Name, Opts) ->
+ SName = ejabberd_sql:escape(Name),
+ SHost = ejabberd_sql:escape(Host),
+ SOpts = ejabberd_sql:encode_term(Opts),
+ F = fun () ->
+ sql_queries:update_t(<<"muc_room">>,
+ [<<"name">>, <<"host">>, <<"opts">>],
+ [SName, SHost, SOpts],
+ [<<"name='">>, SName, <<"' and host='">>,
+ SHost, <<"'">>])
+ end,
+ ejabberd_sql:sql_transaction(LServer, F).
+
+restore_room(LServer, Host, Name) ->
+ SName = ejabberd_sql:escape(Name),
+ SHost = ejabberd_sql:escape(Host),
+ case catch ejabberd_sql:sql_query(LServer,
+ [<<"select opts from muc_room where name='">>,
+ SName, <<"' and host='">>, SHost,
+ <<"';">>]) of
+ {selected, [<<"opts">>], [[Opts]]} ->
+ mod_muc:opts_to_binary(ejabberd_sql:decode_term(Opts));
+ _ ->
+ error
+ end.
+
+forget_room(LServer, Host, Name) ->
+ SName = ejabberd_sql:escape(Name),
+ SHost = ejabberd_sql:escape(Host),
+ F = fun () ->
+ ejabberd_sql:sql_query_t([<<"delete from muc_room where name='">>,
+ SName, <<"' and host='">>, SHost,
+ <<"';">>])
+ end,
+ ejabberd_sql:sql_transaction(LServer, F).
+
+can_use_nick(LServer, Host, JID, Nick) ->
+ SJID = jid:to_string(jid:tolower(jid:remove_resource(JID))),
+ SNick = ejabberd_sql:escape(Nick),
+ SHost = ejabberd_sql:escape(Host),
+ case catch ejabberd_sql:sql_query(LServer,
+ [<<"select jid from muc_registered ">>,
+ <<"where nick='">>, SNick,
+ <<"' and host='">>, SHost, <<"';">>]) of
+ {selected, [<<"jid">>], [[SJID1]]} -> SJID == SJID1;
+ _ -> true
+ end.
+
+get_rooms(LServer, Host) ->
+ SHost = ejabberd_sql:escape(Host),
+ case catch ejabberd_sql:sql_query(LServer,
+ [<<"select name, opts from muc_room ">>,
+ <<"where host='">>, SHost, <<"';">>]) of
+ {selected, [<<"name">>, <<"opts">>], RoomOpts} ->
+ lists:map(
+ fun([Room, Opts]) ->
+ #muc_room{name_host = {Room, Host},
+ opts = mod_muc:opts_to_binary(
+ ejabberd_sql:decode_term(Opts))}
+ end, RoomOpts);
+ Err ->
+ ?ERROR_MSG("failed to get rooms: ~p", [Err]),
+ []
+ end.
+
+get_nick(LServer, Host, From) ->
+ SJID = ejabberd_sql:escape(jid:to_string(jid:tolower(jid:remove_resource(From)))),
+ SHost = ejabberd_sql:escape(Host),
+ case catch ejabberd_sql:sql_query(LServer,
+ [<<"select nick from muc_registered where "
+ "jid='">>,
+ SJID, <<"' and host='">>, SHost,
+ <<"';">>]) of
+ {selected, [<<"nick">>], [[Nick]]} -> Nick;
+ _ -> error
+ end.
+
+set_nick(LServer, Host, From, Nick) ->
+ JID = jid:to_string(jid:tolower(jid:remove_resource(From))),
+ SJID = ejabberd_sql:escape(JID),
+ SNick = ejabberd_sql:escape(Nick),
+ SHost = ejabberd_sql:escape(Host),
+ F = fun () ->
+ case Nick of
+ <<"">> ->
+ ejabberd_sql:sql_query_t(
+ [<<"delete from muc_registered where ">>,
+ <<"jid='">>, SJID,
+ <<"' and host='">>, Host,
+ <<"';">>]),
+ ok;
+ _ ->
+ Allow = case ejabberd_sql:sql_query_t(
+ [<<"select jid from muc_registered ">>,
+ <<"where nick='">>,
+ SNick,
+ <<"' and host='">>,
+ SHost, <<"';">>]) of
+ {selected, [<<"jid">>], [[J]]} -> J == JID;
+ _ -> true
+ end,
+ if Allow ->
+ sql_queries:update_t(<<"muc_registered">>,
+ [<<"jid">>, <<"host">>,
+ <<"nick">>],
+ [SJID, SHost, SNick],
+ [<<"jid='">>, SJID,
+ <<"' and host='">>, SHost,
+ <<"'">>]),
+ ok;
+ true ->
+ false
+ end
+ end
+ end,
+ ejabberd_sql:sql_transaction(LServer, F).
+
+export(_Server) ->
+ [{muc_room,
+ fun(Host, #muc_room{name_host = {Name, RoomHost}, opts = Opts}) ->
+ case str:suffix(Host, RoomHost) of
+ true ->
+ SName = ejabberd_sql:escape(Name),
+ SRoomHost = ejabberd_sql:escape(RoomHost),
+ SOpts = ejabberd_sql:encode_term(Opts),
+ [[<<"delete from muc_room where name='">>, SName,
+ <<"' and host='">>, SRoomHost, <<"';">>],
+ [<<"insert into muc_room(name, host, opts) ",
+ "values (">>,
+ <<"'">>, SName, <<"', '">>, SRoomHost,
+ <<"', '">>, SOpts, <<"');">>]];
+ false ->
+ []
+ end
+ end},
+ {muc_registered,
+ fun(Host, #muc_registered{us_host = {{U, S}, RoomHost},
+ nick = Nick}) ->
+ case str:suffix(Host, RoomHost) of
+ true ->
+ SJID = ejabberd_sql:escape(
+ jid:to_string(
+ jid:make(U, S, <<"">>))),
+ SNick = ejabberd_sql:escape(Nick),
+ SRoomHost = ejabberd_sql:escape(RoomHost),
+ [[<<"delete from muc_registered where jid='">>,
+ SJID, <<"' and host='">>, SRoomHost, <<"';">>],
+ [<<"insert into muc_registered(jid, host, "
+ "nick) values ('">>,
+ SJID, <<"', '">>, SRoomHost, <<"', '">>, SNick,
+ <<"');">>]];
+ false ->
+ []
+ end
+ end}].
+
+import(_LServer) ->
+ [{<<"select name, host, opts from muc_room;">>,
+ fun([Name, RoomHost, SOpts]) ->
+ Opts = mod_muc:opts_to_binary(ejabberd_sql:decode_term(SOpts)),
+ #muc_room{name_host = {Name, RoomHost}, opts = Opts}
+ end},
+ {<<"select jid, host, nick from muc_registered;">>,
+ fun([J, RoomHost, Nick]) ->
+ #jid{user = U, server = S} = jid:from_string(J),
+ #muc_registered{us_host = {{U, S}, RoomHost},
+ nick = Nick}
+ end}].
+
+import(_, _) ->
+ pass.
+
+%%%===================================================================
+%%% Internal functions
+%%%===================================================================