25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-28 16:34:13 +01:00

Add SQL as mod_muc RAM backend

This commit is contained in:
Evgeniy Khramtsov 2017-03-29 12:58:01 +03:00
parent ba6c88cb90
commit 12e01a5119
10 changed files with 316 additions and 78 deletions

View File

@ -275,6 +275,27 @@ CREATE TABLE muc_registered (
CREATE INDEX i_muc_registered_nick ON muc_registered (nick); CREATE INDEX i_muc_registered_nick ON muc_registered (nick);
CREATE UNIQUE INDEX i_muc_registered_jid_host ON muc_registered (jid, host); CREATE UNIQUE INDEX i_muc_registered_jid_host ON muc_registered (jid, host);
CREATE TABLE muc_online_room (
name text NOT NULL,
host text NOT NULL,
node text NOT NULL,
pid text NOT NULL
);
CREATE UNIQUE INDEX i_muc_online_room_name_host ON muc_online_room (name, host);
CREATE TABLE muc_online_users (
username text NOT NULL,
server text NOT NULL,
resource text NOT NULL,
name text NOT NULL,
host text NOT NULL,
node text NOT NULL
);
CREATE UNIQUE INDEX i_muc_online_users ON muc_online_users (username, server, resource, name, host);
CREATE INDEX i_muc_online_users_us ON muc_online_users (username, server);
CREATE TABLE irc_custom ( CREATE TABLE irc_custom (
jid text NOT NULL, jid text NOT NULL,
host text NOT NULL, host text NOT NULL,

View File

@ -125,6 +125,30 @@ CREATE TABLE [dbo].[muc_room] (
CREATE UNIQUE CLUSTERED INDEX [muc_room_name_host] ON [muc_room] (name, host) CREATE UNIQUE CLUSTERED INDEX [muc_room_name_host] ON [muc_room] (name, host)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON); WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON);
CREATE TABLE [dbo].[muc_online_room] (
[name] [varchar] (250) NOT NULL,
[host] [varchar] (250) NOT NULL,
[node] [text] NOT NULL,
[pid] [text] NOT NULL
);
CREATE UNIQUE CLUSTERED INDEX [muc_online_room_name_host] ON [muc_online_room] (name, host)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON);
CREATE TABLE [dbo].[muc_online_users] (
[username] [varchar] (250) NOT NULL,
[server] [varchar] (250) NOT NULL,
[resource] [varchar] (250) NOT NULL,
[name] [varchar] (250) NOT NULL,
[host] [varchar] (250) NOT NULL,
node text NOT NULL
);
CREATE UNIQUE CLUSTERED INDEX [muc_online_users_i] ON [muc_online_users] (username, server, resource, name, host)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON);
CREATE UNIQUE CLUSTERED INDEX [muc_online_users_us] ON [muc_online_users] (username, server);
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON);
CREATE TABLE [dbo].[privacy_default_list] ( CREATE TABLE [dbo].[privacy_default_list] (
[username] [varchar] (250) NOT NULL, [username] [varchar] (250) NOT NULL,
[name] [varchar] (250) NOT NULL, [name] [varchar] (250) NOT NULL,

View File

@ -291,6 +291,27 @@ CREATE TABLE muc_registered (
CREATE INDEX i_muc_registered_nick USING BTREE ON muc_registered(nick(75)); CREATE INDEX i_muc_registered_nick USING BTREE ON muc_registered(nick(75));
CREATE UNIQUE INDEX i_muc_registered_jid_host USING BTREE ON muc_registered(jid(75), host(75)); CREATE UNIQUE INDEX i_muc_registered_jid_host USING BTREE ON muc_registered(jid(75), host(75));
CREATE TABLE muc_online_room (
name text NOT NULL,
host text NOT NULL,
node text NOT NULL,
pid text NOT NULL
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE UNIQUE INDEX i_muc_online_room_name_host USING BTREE ON muc_online_room(name(75), host(75));
CREATE TABLE muc_online_users (
username text NOT NULL,
server text NOT NULL,
resource text NOT NULL,
name text NOT NULL,
host text NOT NULL,
node text NOT NULL
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE UNIQUE INDEX i_muc_online_users USING BTREE ON muc_online_users(username(75), server(75), resource(75), name(75), host(75));
CREATE INDEX i_muc_online_users_us USING BTREE ON muc_online_users(username(75), server(75));
CREATE TABLE irc_custom ( CREATE TABLE irc_custom (
jid text NOT NULL, jid text NOT NULL,
host text NOT NULL, host text NOT NULL,

View File

@ -293,6 +293,27 @@ CREATE TABLE muc_registered (
CREATE INDEX i_muc_registered_nick ON muc_registered USING btree (nick); CREATE INDEX i_muc_registered_nick ON muc_registered USING btree (nick);
CREATE UNIQUE INDEX i_muc_registered_jid_host ON muc_registered USING btree (jid, host); CREATE UNIQUE INDEX i_muc_registered_jid_host ON muc_registered USING btree (jid, host);
CREATE TABLE muc_online_room (
name text NOT NULL,
host text NOT NULL,
node text NOT NULL,
pid text NOT NULL
);
CREATE UNIQUE INDEX i_muc_online_room_name_host ON muc_online_room USING btree (name, host);
CREATE TABLE muc_online_users (
username text NOT NULL,
server text NOT NULL,
resource text NOT NULL,
name text NOT NULL,
host text NOT NULL,
node text NOT NULL
);
CREATE UNIQUE INDEX i_muc_online_users ON muc_online_users USING btree (username, server, resource, name, host);
CREATE INDEX i_muc_online_users_us ON muc_online_users USING btree (username, server);
CREATE TABLE irc_custom ( CREATE TABLE irc_custom (
jid text NOT NULL, jid text NOT NULL,
host text NOT NULL, host text NOT NULL,

View File

@ -94,16 +94,16 @@
-callback get_rooms(binary(), binary()) -> [#muc_room{}]. -callback get_rooms(binary(), binary()) -> [#muc_room{}].
-callback get_nick(binary(), binary(), jid()) -> binary() | error. -callback get_nick(binary(), binary(), jid()) -> binary() | error.
-callback set_nick(binary(), binary(), jid(), binary()) -> {atomic, ok | false}. -callback set_nick(binary(), binary(), jid(), binary()) -> {atomic, ok | false}.
-callback register_online_room(binary(), binary(), pid()) -> any(). -callback register_online_room(binary(), binary(), binary(), pid()) -> any().
-callback unregister_online_room(binary(), binary(), pid()) -> any(). -callback unregister_online_room(binary(), binary(), binary(), pid()) -> any().
-callback find_online_room(binary(), binary()) -> {ok, pid()} | error. -callback find_online_room(binary(), binary(), binary()) -> {ok, pid()} | error.
-callback get_online_rooms(binary(), undefined | rsm_set()) -> [{binary(), binary(), pid()}]. -callback get_online_rooms(binary(), binary(), undefined | rsm_set()) -> [{binary(), binary(), pid()}].
-callback count_online_rooms(binary()) -> non_neg_integer(). -callback count_online_rooms(binary(), binary()) -> non_neg_integer().
-callback rsm_supported() -> boolean(). -callback rsm_supported() -> boolean().
-callback register_online_user(ljid(), binary(), binary()) -> any(). -callback register_online_user(binary(), ljid(), binary(), binary()) -> any().
-callback unregister_online_user(ljid(), binary(), binary()) -> any(). -callback unregister_online_user(binary(), ljid(), binary(), binary()) -> any().
-callback count_online_rooms_by_user(binary(), binary()) -> non_neg_integer(). -callback count_online_rooms_by_user(binary(), binary(), binary()) -> non_neg_integer().
-callback get_online_rooms_by_user(binary(), binary()) -> [{binary(), binary()}]. -callback get_online_rooms_by_user(binary(), binary(), binary()) -> [{binary(), binary()}].
%%==================================================================== %%====================================================================
%% API %% API
@ -127,7 +127,7 @@ shutdown_rooms(Host) ->
RMod = gen_mod:ram_db_mod(Host, ?MODULE), RMod = gen_mod:ram_db_mod(Host, ?MODULE),
MyHost = gen_mod:get_module_opt_host(Host, mod_muc, MyHost = gen_mod:get_module_opt_host(Host, mod_muc,
<<"conference.@HOST@">>), <<"conference.@HOST@">>),
Rooms = RMod:get_online_rooms(MyHost, undefined), Rooms = RMod:get_online_rooms(Host, MyHost, undefined),
lists:flatmap( lists:flatmap(
fun({_, _, Pid}) when node(Pid) == node() -> fun({_, _, Pid}) when node(Pid) == node() ->
Pid ! shutdown, Pid ! shutdown,
@ -180,13 +180,13 @@ can_use_nick(ServerHost, Host, JID, Nick) ->
find_online_room(Room, Host) -> find_online_room(Room, Host) ->
ServerHost = ejabberd_router:host_of_route(Host), ServerHost = ejabberd_router:host_of_route(Host),
RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE), RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE),
RMod:find_online_room(Room, Host). RMod:find_online_room(ServerHost, Room, Host).
-spec register_online_room(binary(), binary(), pid()) -> any(). -spec register_online_room(binary(), binary(), pid()) -> any().
register_online_room(Room, Host, Pid) -> register_online_room(Room, Host, Pid) ->
ServerHost = ejabberd_router:host_of_route(Host), ServerHost = ejabberd_router:host_of_route(Host),
RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE), RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE),
RMod:register_online_room(Room, Host, Pid). RMod:register_online_room(ServerHost, Room, Host, Pid).
-spec get_online_rooms(binary()) -> [{binary(), binary(), pid()}]. -spec get_online_rooms(binary()) -> [{binary(), binary(), pid()}].
get_online_rooms(Host) -> get_online_rooms(Host) ->
@ -201,22 +201,22 @@ count_online_rooms(Host) ->
-spec register_online_user(binary(), ljid(), binary(), binary()) -> any(). -spec register_online_user(binary(), ljid(), binary(), binary()) -> any().
register_online_user(ServerHost, LJID, Name, Host) -> register_online_user(ServerHost, LJID, Name, Host) ->
RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE), RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE),
RMod:register_online_user(LJID, Name, Host). RMod:register_online_user(ServerHost, LJID, Name, Host).
-spec unregister_online_user(binary(), ljid(), binary(), binary()) -> any(). -spec unregister_online_user(binary(), ljid(), binary(), binary()) -> any().
unregister_online_user(ServerHost, LJID, Name, Host) -> unregister_online_user(ServerHost, LJID, Name, Host) ->
RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE), RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE),
RMod:unregister_online_user(LJID, Name, Host). RMod:unregister_online_user(ServerHost, LJID, Name, Host).
-spec count_online_rooms_by_user(binary(), binary(), binary()) -> non_neg_integer(). -spec count_online_rooms_by_user(binary(), binary(), binary()) -> non_neg_integer().
count_online_rooms_by_user(ServerHost, LUser, LServer) -> count_online_rooms_by_user(ServerHost, LUser, LServer) ->
RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE), RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE),
RMod:count_online_rooms_by_user(LUser, LServer). RMod:count_online_rooms_by_user(ServerHost, LUser, LServer).
-spec get_online_rooms_by_user(binary(), binary(), binary()) -> [{binary(), binary()}]. -spec get_online_rooms_by_user(binary(), binary(), binary()) -> [{binary(), binary()}].
get_online_rooms_by_user(ServerHost, LUser, LServer) -> get_online_rooms_by_user(ServerHost, LUser, LServer) ->
RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE), RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE),
RMod:get_online_rooms_by_user(LUser, LServer). RMod:get_online_rooms_by_user(ServerHost, LUser, LServer).
%%==================================================================== %%====================================================================
%% gen_server callbacks %% gen_server callbacks
@ -256,7 +256,7 @@ handle_call({create, Room, From, Nick, Opts}, _From,
RoomShaper, From, RoomShaper, From,
Nick, NewOpts, QueueType), Nick, NewOpts, QueueType),
RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE), RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE),
RMod:register_online_room(Room, Host, Pid), RMod:register_online_room(ServerHost, Room, Host, Pid),
{reply, ok, State}. {reply, ok, State}.
handle_cast({reload, ServerHost, NewOpts, OldOpts}, #state{host = OldHost}) -> handle_cast({reload, ServerHost, NewOpts, OldOpts}, #state{host = OldHost}) ->
@ -318,7 +318,7 @@ handle_info({route, Packet},
handle_info({room_destroyed, {Room, Host}, Pid}, State) -> handle_info({room_destroyed, {Room, Host}, Pid}, State) ->
ServerHost = State#state.server_host, ServerHost = State#state.server_host,
RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE), RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE),
RMod:unregister_online_room(Room, Host, Pid), RMod:unregister_online_room(ServerHost, Room, Host, Pid),
{noreply, State}; {noreply, State};
handle_info(Info, State) -> handle_info(Info, State) ->
?ERROR_MSG("unexpected info: ~p", [Info]), ?ERROR_MSG("unexpected info: ~p", [Info]),
@ -491,7 +491,7 @@ do_route1(Host, ServerHost, Access, HistorySize, RoomShaper,
{_AccessRoute, AccessCreate, _AccessAdmin, _AccessPersistent} = Access, {_AccessRoute, AccessCreate, _AccessAdmin, _AccessPersistent} = Access,
{Room, _, Nick} = jid:tolower(To), {Room, _, Nick} = jid:tolower(To),
RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE), RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE),
case RMod:find_online_room(Room, Host) of case RMod:find_online_room(ServerHost, Room, Host) of
error -> error ->
case is_create_request(Packet) of case is_create_request(Packet) of
true -> true ->
@ -504,7 +504,7 @@ do_route1(Host, ServerHost, Access, HistorySize, RoomShaper,
Room, HistorySize, Room, HistorySize,
RoomShaper, From, Nick, DefRoomOpts, RoomShaper, From, Nick, DefRoomOpts,
QueueType), QueueType),
RMod:register_online_room(Room, Host, Pid), RMod:register_online_room(ServerHost, Room, Host, Pid),
mod_muc_room:route(Pid, Packet), mod_muc_room:route(Pid, Packet),
ok; ok;
false -> false ->
@ -675,13 +675,13 @@ load_permanent_rooms(Host, ServerHost, Access,
lists:foreach( lists:foreach(
fun(R) -> fun(R) ->
{Room, Host} = R#muc_room.name_host, {Room, Host} = R#muc_room.name_host,
case RMod:find_online_room(Room, Host) of case RMod:find_online_room(ServerHost, Room, Host) of
error -> error ->
{ok, Pid} = mod_muc_room:start(Host, {ok, Pid} = mod_muc_room:start(Host,
ServerHost, Access, Room, ServerHost, Access, Room,
HistorySize, RoomShaper, HistorySize, RoomShaper,
R#muc_room.opts, QueueType), R#muc_room.opts, QueueType),
RMod:register_online_room(Room, Host, Pid); RMod:register_online_room(ServerHost, Room, Host, Pid);
{ok, _} -> {ok, _} ->
ok ok
end end
@ -856,12 +856,12 @@ get_online_rooms(ServerHost, Host) ->
[{binary(), binary(), pid()}]. [{binary(), binary(), pid()}].
get_online_rooms(ServerHost, Host, RSM) -> get_online_rooms(ServerHost, Host, RSM) ->
RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE), RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE),
RMod:get_online_rooms(Host, RSM). RMod:get_online_rooms(ServerHost, Host, RSM).
-spec count_online_rooms(binary(), binary()) -> non_neg_integer(). -spec count_online_rooms(binary(), binary()) -> non_neg_integer().
count_online_rooms(ServerHost, Host) -> count_online_rooms(ServerHost, Host) ->
RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE), RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE),
RMod:count_online_rooms(Host). RMod:count_online_rooms(ServerHost, Host).
opts_to_binary(Opts) -> opts_to_binary(Opts) ->
lists:map( lists:map(

View File

@ -30,10 +30,10 @@
%% API %% API
-export([init/2, import/3, store_room/4, restore_room/3, forget_room/3, -export([init/2, import/3, store_room/4, restore_room/3, forget_room/3,
can_use_nick/4, get_rooms/2, get_nick/3, set_nick/4]). can_use_nick/4, get_rooms/2, get_nick/3, set_nick/4]).
-export([register_online_room/3, unregister_online_room/3, find_online_room/2, -export([register_online_room/4, unregister_online_room/4, find_online_room/3,
get_online_rooms/2, count_online_rooms/1, rsm_supported/0, get_online_rooms/3, count_online_rooms/2, rsm_supported/0,
register_online_user/3, unregister_online_user/3, register_online_user/4, unregister_online_user/4,
count_online_rooms_by_user/2, get_online_rooms_by_user/2]). count_online_rooms_by_user/3, get_online_rooms_by_user/3]).
-export([set_affiliation/6, set_affiliations/4, get_affiliation/5, -export([set_affiliation/6, set_affiliations/4, get_affiliation/5,
get_affiliations/3, search_affiliation/4]). get_affiliations/3, search_affiliation/4]).
%% gen_server callbacks %% gen_server callbacks
@ -157,27 +157,30 @@ get_affiliations(_ServerHost, _Room, _Host) ->
search_affiliation(_ServerHost, _Room, _Host, _Affiliation) -> search_affiliation(_ServerHost, _Room, _Host, _Affiliation) ->
{error, not_implemented}. {error, not_implemented}.
register_online_room(Room, Host, Pid) -> register_online_room(_ServerHost, Room, Host, Pid) ->
F = fun() -> F = fun() ->
mnesia:write( mnesia:write(
#muc_online_room{name_host = {Room, Host}, pid = Pid}) #muc_online_room{name_host = {Room, Host}, pid = Pid})
end, end,
mnesia:transaction(F). mnesia:transaction(F).
unregister_online_room(Room, Host, Pid) -> unregister_online_room(_ServerHost, Room, Host, Pid) ->
F = fun () -> F = fun () ->
mnesia:delete_object( mnesia:delete_object(
#muc_online_room{name_host = {Room, Host}, pid = Pid}) #muc_online_room{name_host = {Room, Host}, pid = Pid})
end, end,
mnesia:transaction(F). mnesia:transaction(F).
find_online_room(_ServerHost, Room, Host) ->
find_online_room(Room, Host).
find_online_room(Room, Host) -> find_online_room(Room, Host) ->
case mnesia:dirty_read(muc_online_room, {Room, Host}) of case mnesia:dirty_read(muc_online_room, {Room, Host}) of
[] -> error; [] -> error;
[#muc_online_room{pid = Pid}] -> {ok, Pid} [#muc_online_room{pid = Pid}] -> {ok, Pid}
end. end.
count_online_rooms(Host) -> count_online_rooms(_ServerHost, Host) ->
ets:select_count( ets:select_count(
muc_online_room, muc_online_room,
ets:fun2ms( ets:fun2ms(
@ -185,20 +188,20 @@ count_online_rooms(Host) ->
H == Host H == Host
end)). end)).
get_online_rooms(Host, get_online_rooms(_ServerHost, Host,
#rsm_set{max = Max, 'after' = After, before = undefined}) #rsm_set{max = Max, 'after' = After, before = undefined})
when is_binary(After), After /= <<"">> -> when is_binary(After), After /= <<"">> ->
lists:reverse(get_online_rooms(next, {After, Host}, Host, 0, Max, [])); lists:reverse(get_online_rooms(next, {After, Host}, Host, 0, Max, []));
get_online_rooms(Host, get_online_rooms(_ServerHost, Host,
#rsm_set{max = Max, 'after' = undefined, before = Before}) #rsm_set{max = Max, 'after' = undefined, before = Before})
when is_binary(Before), Before /= <<"">> -> when is_binary(Before), Before /= <<"">> ->
get_online_rooms(prev, {Before, Host}, Host, 0, Max, []); get_online_rooms(prev, {Before, Host}, Host, 0, Max, []);
get_online_rooms(Host, get_online_rooms(_ServerHost, Host,
#rsm_set{max = Max, 'after' = undefined, before = <<"">>}) -> #rsm_set{max = Max, 'after' = undefined, before = <<"">>}) ->
get_online_rooms(last, {<<"">>, Host}, Host, 0, Max, []); get_online_rooms(last, {<<"">>, Host}, Host, 0, Max, []);
get_online_rooms(Host, #rsm_set{max = Max}) -> get_online_rooms(_ServerHost, Host, #rsm_set{max = Max}) ->
lists:reverse(get_online_rooms(first, {<<"">>, Host}, Host, 0, Max, [])); lists:reverse(get_online_rooms(first, {<<"">>, Host}, Host, 0, Max, []));
get_online_rooms(Host, undefined) -> get_online_rooms(_ServerHost, Host, undefined) ->
mnesia:dirty_select( mnesia:dirty_select(
muc_online_room, muc_online_room,
ets:fun2ms( ets:fun2ms(
@ -248,17 +251,17 @@ get_online_rooms(Action, Key, Host, Count, Max, Items) ->
rsm_supported() -> rsm_supported() ->
true. true.
register_online_user({U, S, R}, Room, Host) -> register_online_user(_ServerHost, {U, S, R}, Room, Host) ->
ets:insert(muc_online_users, ets:insert(muc_online_users,
#muc_online_users{us = {U, S}, resource = R, #muc_online_users{us = {U, S}, resource = R,
room = Room, host = Host}). room = Room, host = Host}).
unregister_online_user({U, S, R}, Room, Host) -> unregister_online_user(_ServerHost, {U, S, R}, Room, Host) ->
ets:delete_object(muc_online_users, ets:delete_object(muc_online_users,
#muc_online_users{us = {U, S}, resource = R, #muc_online_users{us = {U, S}, resource = R,
room = Room, host = Host}). room = Room, host = Host}).
count_online_rooms_by_user(U, S) -> count_online_rooms_by_user(_ServerHost, U, S) ->
ets:select_count( ets:select_count(
muc_online_users, muc_online_users,
ets:fun2ms( ets:fun2ms(
@ -266,7 +269,7 @@ count_online_rooms_by_user(U, S) ->
U == U1 andalso S == S1 U == U1 andalso S == S1
end)). end)).
get_online_rooms_by_user(U, S) -> get_online_rooms_by_user(_ServerHost, U, S) ->
ets:select( ets:select(
muc_online_users, muc_online_users,
ets:fun2ms( ets:fun2ms(

View File

@ -30,10 +30,10 @@
%% API %% API
-export([init/2, import/3, store_room/4, restore_room/3, forget_room/3, -export([init/2, import/3, store_room/4, restore_room/3, forget_room/3,
can_use_nick/4, get_rooms/2, get_nick/3, set_nick/4]). can_use_nick/4, get_rooms/2, get_nick/3, set_nick/4]).
-export([register_online_room/3, unregister_online_room/3, find_online_room/2, -export([register_online_room/4, unregister_online_room/4, find_online_room/3,
get_online_rooms/2, count_online_rooms/1, rsm_supported/0, get_online_rooms/3, count_online_rooms/2, rsm_supported/0,
register_online_user/3, unregister_online_user/3, register_online_user/4, unregister_online_user/4,
count_online_rooms_by_user/2, get_online_rooms_by_user/2]). count_online_rooms_by_user/3, get_online_rooms_by_user/3]).
-export([set_affiliation/6, set_affiliations/4, get_affiliation/5, -export([set_affiliation/6, set_affiliations/4, get_affiliation/5,
get_affiliations/3, search_affiliation/4]). get_affiliations/3, search_affiliation/4]).
@ -140,34 +140,34 @@ get_affiliations(_ServerHost, _Room, _Host) ->
search_affiliation(_ServerHost, _Room, _Host, _Affiliation) -> search_affiliation(_ServerHost, _Room, _Host, _Affiliation) ->
{error, not_implemented}. {error, not_implemented}.
register_online_room(_, _, _) -> register_online_room(_, _, _, _) ->
erlang:error(not_implemented). erlang:error(not_implemented).
unregister_online_room(_, _, _) -> unregister_online_room(_, _, _, _) ->
erlang:error(not_implemented). erlang:error(not_implemented).
find_online_room(_, _) -> find_online_room(_, _, _) ->
erlang:error(not_implemented). erlang:error(not_implemented).
count_online_rooms(_) -> count_online_rooms(_, _) ->
erlang:error(not_implemented). erlang:error(not_implemented).
get_online_rooms(_, _) -> get_online_rooms(_, _, _) ->
erlang:error(not_implemented). erlang:error(not_implemented).
rsm_supported() -> rsm_supported() ->
false. false.
register_online_user(_, _, _) -> register_online_user(_, _, _, _) ->
erlang:error(not_implemented). erlang:error(not_implemented).
unregister_online_user(_, _, _) -> unregister_online_user(_, _, _, _) ->
erlang:error(not_implemented). erlang:error(not_implemented).
count_online_rooms_by_user(_, _) -> count_online_rooms_by_user(_, _, _) ->
erlang:error(not_implemented). erlang:error(not_implemented).
get_online_rooms_by_user(_, _) -> get_online_rooms_by_user(_, _, _) ->
erlang:error(not_implemented). erlang:error(not_implemented).
import(_LServer, <<"muc_room">>, import(_LServer, <<"muc_room">>,

View File

@ -33,10 +33,10 @@
-export([init/2, store_room/4, restore_room/3, forget_room/3, -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, can_use_nick/4, get_rooms/2, get_nick/3, set_nick/4,
import/3, export/1]). import/3, export/1]).
-export([register_online_room/3, unregister_online_room/3, find_online_room/2, -export([register_online_room/4, unregister_online_room/4, find_online_room/3,
get_online_rooms/2, count_online_rooms/1, rsm_supported/0, get_online_rooms/3, count_online_rooms/2, rsm_supported/0,
register_online_user/3, unregister_online_user/3, register_online_user/4, unregister_online_user/4,
count_online_rooms_by_user/2, get_online_rooms_by_user/2]). count_online_rooms_by_user/3, get_online_rooms_by_user/3]).
-export([set_affiliation/6, set_affiliations/4, get_affiliation/5, -export([set_affiliation/6, set_affiliations/4, get_affiliation/5,
get_affiliations/3, search_affiliation/4]). get_affiliations/3, search_affiliation/4]).
@ -48,8 +48,13 @@
%%%=================================================================== %%%===================================================================
%%% API %%% API
%%%=================================================================== %%%===================================================================
init(_Host, _Opts) -> init(Host, Opts) ->
ok. case gen_mod:ram_db_mod(Host, Opts, mod_muc) of
?MODULE ->
clean_tables(Host);
_ ->
ok
end.
store_room(LServer, Host, Name, Opts) -> store_room(LServer, Host, Name, Opts) ->
SOpts = jlib:term_to_expr(Opts), SOpts = jlib:term_to_expr(Opts),
@ -165,35 +170,126 @@ get_affiliations(_ServerHost, _Room, _Host) ->
search_affiliation(_ServerHost, _Room, _Host, _Affiliation) -> search_affiliation(_ServerHost, _Room, _Host, _Affiliation) ->
{error, not_implemented}. {error, not_implemented}.
register_online_room(_, _, _) -> register_online_room(ServerHost, Room, Host, Pid) ->
erlang:error(not_implemented). PidS = enc_pid(Pid),
NodeS = erlang:atom_to_binary(node(Pid), latin1),
case ?SQL_UPSERT(ServerHost,
"muc_online_room",
["!name=%(Room)s",
"!host=%(Host)s",
"node=%(NodeS)s",
"pid=%(PidS)s"]) of
ok ->
ok;
Err ->
?ERROR_MSG("failed to update 'muc_online_room': ~p", [Err]),
Err
end.
unregister_online_room(_, _, _) -> unregister_online_room(ServerHost, Room, Host, Pid) ->
erlang:error(not_implemented). %% TODO: report errors
PidS = enc_pid(Pid),
NodeS = erlang:atom_to_binary(node(Pid), latin1),
ejabberd_sql:sql_query(
ServerHost,
?SQL("delete from muc_online_room where name=%(Room)s and "
"host=%(Host)s and node=%(NodeS)s and pid=%(PidS)s")).
find_online_room(_, _) -> find_online_room(ServerHost, Room, Host) ->
erlang:error(not_implemented). case ejabberd_sql:sql_query(
ServerHost,
?SQL("select @(pid)s, @(node)s from muc_online_room where "
"name=%(Room)s and host=%(Host)s")) of
{selected, [{PidS, NodeS}]} ->
try {ok, dec_pid(PidS, NodeS)}
catch _:{node_down, _} -> error
end;
{selected, []} ->
error;
Err ->
?ERROR_MSG("failed to select 'muc_online_room': ~p", [Err]),
error
end.
count_online_rooms(_) -> count_online_rooms(ServerHost, Host) ->
erlang:error(not_implemented). case ejabberd_sql:sql_query(
ServerHost,
?SQL("select @(count(*))d from muc_online_room "
"where host=%(Host)s")) of
{selected, [{Num}]} ->
Num;
Err ->
?ERROR_MSG("failed to select 'muc_online_room': ~p", [Err]),
0
end.
get_online_rooms(_, _) -> get_online_rooms(ServerHost, Host, _RSM) ->
erlang:error(not_implemented). case ejabberd_sql:sql_query(
ServerHost,
?SQL("select @(name)s, @(pid)s, @(node)s from muc_online_room "
"where host=%(Host)s")) of
{selected, Rows} ->
lists:flatmap(
fun({Room, PidS, NodeS}) ->
try [{Room, Host, dec_pid(PidS, NodeS)}]
catch _:{node_down, _} -> []
end
end, Rows);
Err ->
?ERROR_MSG("failed to select 'muc_online_room': ~p", [Err]),
0
end.
rsm_supported() -> rsm_supported() ->
false. false.
register_online_user(_, _, _) -> register_online_user(ServerHost, {U, S, R}, Room, Host) ->
erlang:error(not_implemented). NodeS = erlang:atom_to_binary(node(), latin1),
case ?SQL_UPSERT(ServerHost, "muc_online_users",
["!username=%(U)s",
"!server=%(S)s",
"!resource=%(R)s",
"!name=%(Room)s",
"!host=%(Host)s",
"node=%(NodeS)s"]) of
ok ->
ok;
Err ->
?ERROR_MSG("failed to update 'muc_online_users': ~p", [Err]),
Err
end.
unregister_online_user(_, _, _) -> unregister_online_user(ServerHost, {U, S, R}, Room, Host) ->
erlang:error(not_implemented). %% TODO: report errors
ejabberd_sql:sql_query(
ServerHost,
?SQL("delete from muc_online_users where username=%(U)s and "
"server=%(S)s and resource=%(R)s and name=%(Room)s and "
"host=%(Host)s")).
count_online_rooms_by_user(_, _) -> count_online_rooms_by_user(ServerHost, U, S) ->
erlang:error(not_implemented). case ejabberd_sql:sql_query(
ServerHost,
?SQL("select @(count(*))d from muc_online_users where "
"username=%(U)s and server=%(S)s")) of
{selected, [{Num}]} ->
Num;
Err ->
?ERROR_MSG("failed to select 'muc_online_users': ~p", [Err]),
0
end.
get_online_rooms_by_user(_, _) -> get_online_rooms_by_user(ServerHost, U, S) ->
erlang:error(not_implemented). case ejabberd_sql:sql_query(
ServerHost,
?SQL("select @(name)s, @(host)s from muc_online_users where "
"username=%(U)s and server=%(S)s")) of
{selected, Rows} ->
Rows;
Err ->
?ERROR_MSG("failed to select 'muc_online_users': ~p", [Err]),
[]
end.
export(_Server) -> export(_Server) ->
[{muc_room, [{muc_room,
@ -232,3 +328,52 @@ import(_, _, _) ->
%%%=================================================================== %%%===================================================================
%%% Internal functions %%% Internal functions
%%%=================================================================== %%%===================================================================
-spec enc_pid(pid()) -> binary().
enc_pid(Pid) ->
list_to_binary(erlang:pid_to_list(Pid)).
-spec dec_pid(binary(), binary()) -> pid().
dec_pid(PidBin, NodeBin) ->
PidStr = binary_to_list(PidBin),
Pid = erlang:list_to_pid(PidStr),
case erlang:binary_to_atom(NodeBin, latin1) of
Node when Node == node() ->
Pid;
Node ->
try set_node_id(PidStr, NodeBin)
catch _:badarg ->
erlang:error({node_down, Node})
end
end.
-spec set_node_id(string(), binary()) -> pid().
set_node_id(PidStr, NodeBin) ->
ExtPidStr = erlang:pid_to_list(
binary_to_term(
<<131,103,100,(size(NodeBin)):16,NodeBin/binary,0:72>>)),
[H|_] = string:tokens(ExtPidStr, "."),
[_|T] = string:tokens(PidStr, "."),
erlang:list_to_pid(string:join([H|T], ".")).
clean_tables(ServerHost) ->
NodeS = erlang:atom_to_binary(node(), latin1),
?INFO_MSG("Cleaning SQL muc_online_room table...", []),
case ejabberd_sql:sql_query(
ServerHost,
?SQL("delete from muc_online_room where node=%(NodeS)s")) of
{updated, _} ->
ok;
Err1 ->
?ERROR_MSG("failed to clean 'muc_online_room' table: ~p", [Err1]),
Err1
end,
?INFO_MSG("Cleaning SQL muc_online_users table...", []),
case ejabberd_sql:sql_query(
ServerHost,
?SQL("delete from muc_online_users where node=%(NodeS)s")) of
{updated, _} ->
ok;
Err2 ->
?ERROR_MSG("failed to clean 'muc_online_users' table: ~p", [Err2]),
Err2
end.

View File

@ -20,6 +20,7 @@ host_config:
db_type: sql db_type: sql
mod_muc: mod_muc:
db_type: sql db_type: sql
ram_db_type: sql
mod_offline: mod_offline:
db_type: sql db_type: sql
mod_privacy: mod_privacy:
@ -77,6 +78,7 @@ Welcome to this XMPP server."
db_type: sql db_type: sql
mod_muc: mod_muc:
db_type: sql db_type: sql
ram_db_type: sql
mod_offline: mod_offline:
db_type: sql db_type: sql
mod_privacy: mod_privacy:
@ -139,6 +141,7 @@ Welcome to this XMPP server."
db_type: sql db_type: sql
mod_muc: mod_muc:
db_type: sql db_type: sql
ram_db_type: sql
mod_offline: mod_offline:
db_type: sql db_type: sql
mod_privacy: mod_privacy:

View File

@ -152,7 +152,7 @@ service_features(Config) ->
end, end,
RequiredFeatures = sets:from_list( RequiredFeatures = sets:from_list(
[?NS_DISCO_INFO, ?NS_DISCO_ITEMS, [?NS_DISCO_INFO, ?NS_DISCO_ITEMS,
?NS_REGISTER, ?NS_MUC, ?NS_RSM, ?NS_REGISTER, ?NS_MUC,
?NS_VCARD, ?NS_MUCSUB, ?NS_MUC_UNIQUE ?NS_VCARD, ?NS_MUCSUB, ?NS_MUC_UNIQUE
| MAMFeatures]), | MAMFeatures]),
ct:comment("Checking if all needed disco features are set"), ct:comment("Checking if all needed disco features are set"),