Packages
ejabberd
16.6.2
26.4.0
26.3.0
26.2.0
26.1.0
25.10.0
25.8.0
25.7.0
25.4.0
25.3.0
24.12.0
24.10.0
24.7.0
24.6.0
24.2.6
23.10.0
23.4.0
23.1.0
22.10.0
22.5.0
21.12.0
21.7.0
21.4.0
21.1.0
20.12.0
20.7.0
20.4.0
20.3.0
20.2.0
20.1.0
19.9.1
19.9.0
19.8.0
19.5.0
19.2.0
18.12.1
18.12.0
18.6.0
18.4.0
18.3.0
18.1.0
17.11.0
17.9.0
17.6.0
17.3.0
17.1.0
16.12.0-beta1
16.9.0
16.8.0
16.6.2
16.6.1
16.6.0
16.4.1
16.4.0
16.3.0
16.2.0
16.1.0-beta1
Robust, Ubiquitous and Massively Scalable Messaging Platform (XMPP, MQTT, SIP Server)
Current section
Files
Jump to
Current section
Files
src/mod_shared_roster_mnesia.erl
%%%-------------------------------------------------------------------
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
%%% @copyright (C) 2016, Evgeny Khramtsov
%%% @doc
%%%
%%% @end
%%% Created : 14 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
%%%-------------------------------------------------------------------
-module(mod_shared_roster_mnesia).
-behaviour(mod_shared_roster).
%% API
-export([init/2, list_groups/1, groups_with_opts/1, create_group/3,
delete_group/2, get_group_opts/2, set_group_opts/3,
get_user_groups/2, get_group_explicit_users/2,
get_user_displayed_groups/3, is_user_in_group/3,
add_user_to_group/3, remove_user_from_group/3, import/2]).
-include("jlib.hrl").
-include("mod_roster.hrl").
-include("mod_shared_roster.hrl").
-include("logger.hrl").
%%%===================================================================
%%% API
%%%===================================================================
init(_Host, _Opts) ->
mnesia:create_table(sr_group,
[{disc_copies, [node()]},
{attributes, record_info(fields, sr_group)}]),
mnesia:create_table(sr_user,
[{disc_copies, [node()]}, {type, bag},
{attributes, record_info(fields, sr_user)}]),
update_tables(),
mnesia:add_table_index(sr_user, group_host).
list_groups(Host) ->
mnesia:dirty_select(sr_group,
[{#sr_group{group_host = {'$1', '$2'}, _ = '_'},
[{'==', '$2', Host}], ['$1']}]).
groups_with_opts(Host) ->
Gs = mnesia:dirty_select(sr_group,
[{#sr_group{group_host = {'$1', Host}, opts = '$2',
_ = '_'},
[], [['$1', '$2']]}]),
lists:map(fun ([G, O]) -> {G, O} end, Gs).
create_group(Host, Group, Opts) ->
R = #sr_group{group_host = {Group, Host}, opts = Opts},
F = fun () -> mnesia:write(R) end,
mnesia:transaction(F).
delete_group(Host, Group) ->
GroupHost = {Group, Host},
F = fun () ->
mnesia:delete({sr_group, GroupHost}),
Users = mnesia:index_read(sr_user, GroupHost,
#sr_user.group_host),
lists:foreach(fun (UserEntry) ->
mnesia:delete_object(UserEntry)
end,
Users)
end,
mnesia:transaction(F).
get_group_opts(Host, Group) ->
case catch mnesia:dirty_read(sr_group, {Group, Host}) of
[#sr_group{opts = Opts}] -> Opts;
_ -> error
end.
set_group_opts(Host, Group, Opts) ->
R = #sr_group{group_host = {Group, Host}, opts = Opts},
F = fun () -> mnesia:write(R) end,
mnesia:transaction(F).
get_user_groups(US, Host) ->
case catch mnesia:dirty_read(sr_user, US) of
Rs when is_list(Rs) ->
[Group || #sr_user{group_host = {Group, H}} <- Rs, H == Host];
_ ->
[]
end.
get_group_explicit_users(Host, Group) ->
Read = (catch mnesia:dirty_index_read(sr_user,
{Group, Host}, #sr_user.group_host)),
case Read of
Rs when is_list(Rs) -> [R#sr_user.us || R <- Rs];
_ -> []
end.
get_user_displayed_groups(LUser, LServer, GroupsOpts) ->
case catch mnesia:dirty_read(sr_user, {LUser, LServer}) of
Rs when is_list(Rs) ->
[{Group, proplists:get_value(Group, GroupsOpts, [])}
|| #sr_user{group_host = {Group, H}} <- Rs,
H == LServer];
_ ->
[]
end.
is_user_in_group(US, Group, Host) ->
case mnesia:dirty_match_object(
#sr_user{us = US, group_host = {Group, Host}}) of
[] -> false;
_ -> true
end.
add_user_to_group(Host, US, Group) ->
R = #sr_user{us = US, group_host = {Group, Host}},
F = fun () -> mnesia:write(R) end,
mnesia:transaction(F).
remove_user_from_group(Host, US, Group) ->
R = #sr_user{us = US, group_host = {Group, Host}},
F = fun () -> mnesia:delete_object(R) end,
mnesia:transaction(F).
import(_LServer, #sr_group{} = G) ->
mnesia:dirty_write(G);
import(_LServer, #sr_user{} = U) ->
mnesia:dirty_write(U).
%%%===================================================================
%%% Internal functions
%%%===================================================================
update_tables() ->
update_sr_group_table(),
update_sr_user_table().
update_sr_group_table() ->
Fields = record_info(fields, sr_group),
case mnesia:table_info(sr_group, attributes) of
Fields ->
ejabberd_config:convert_table_to_binary(
sr_group, Fields, set,
fun(#sr_group{group_host = {G, _}}) -> G end,
fun(#sr_group{group_host = {G, H},
opts = Opts} = R) ->
R#sr_group{group_host = {iolist_to_binary(G),
iolist_to_binary(H)},
opts = mod_shared_roster:opts_to_binary(Opts)}
end);
_ ->
?INFO_MSG("Recreating sr_group table", []),
mnesia:transform_table(sr_group, ignore, Fields)
end.
update_sr_user_table() ->
Fields = record_info(fields, sr_user),
case mnesia:table_info(sr_user, attributes) of
Fields ->
ejabberd_config:convert_table_to_binary(
sr_user, Fields, bag,
fun(#sr_user{us = {U, _}}) -> U end,
fun(#sr_user{us = {U, S}, group_host = {G, H}} = R) ->
R#sr_user{us = {iolist_to_binary(U), iolist_to_binary(S)},
group_host = {iolist_to_binary(G),
iolist_to_binary(H)}}
end);
_ ->
?INFO_MSG("Recreating sr_user table", []),
mnesia:transform_table(sr_user, ignore, Fields)
end.