diff options
Diffstat (limited to 'src/mod_shared_roster_sql.erl')
-rw-r--r-- | src/mod_shared_roster_sql.erl | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/src/mod_shared_roster_sql.erl b/src/mod_shared_roster_sql.erl new file mode 100644 index 000000000..21ea768af --- /dev/null +++ b/src/mod_shared_roster_sql.erl @@ -0,0 +1,212 @@ +%%%------------------------------------------------------------------- +%%% @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_sql). + +-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/1, + import/2, export/1]). + +-include("jlib.hrl"). +-include("mod_roster.hrl"). +-include("mod_shared_roster.hrl"). + +%%%=================================================================== +%%% API +%%%=================================================================== +init(_Host, _Opts) -> + ok. + +list_groups(Host) -> + case ejabberd_odbc:sql_query( + Host, [<<"select name from sr_group;">>]) of + {selected, [<<"name">>], Rs} -> [G || [G] <- Rs]; + _ -> [] + end. + +groups_with_opts(Host) -> + case ejabberd_odbc:sql_query(Host, + [<<"select name, opts from sr_group;">>]) + of + {selected, [<<"name">>, <<"opts">>], Rs} -> + [{G, mod_shared_roster:opts_to_binary(ejabberd_odbc:decode_term(Opts))} + || [G, Opts] <- Rs]; + _ -> [] + end. + +create_group(Host, Group, Opts) -> + SGroup = ejabberd_odbc:escape(Group), + SOpts = ejabberd_odbc:encode_term(Opts), + F = fun () -> + odbc_queries:update_t(<<"sr_group">>, + [<<"name">>, <<"opts">>], [SGroup, SOpts], + [<<"name='">>, SGroup, <<"'">>]) + end, + ejabberd_odbc:sql_transaction(Host, F). + +delete_group(Host, Group) -> + SGroup = ejabberd_odbc:escape(Group), + F = fun () -> + ejabberd_odbc:sql_query_t([<<"delete from sr_group where name='">>, + SGroup, <<"';">>]), + ejabberd_odbc:sql_query_t([<<"delete from sr_user where grp='">>, + SGroup, <<"';">>]) + end, + case ejabberd_odbc:sql_transaction(Host, F) of + {atomic,{updated,_}} -> {atomic, ok}; + Res -> Res + end. + +get_group_opts(Host, Group) -> + SGroup = ejabberd_odbc:escape(Group), + case catch ejabberd_odbc:sql_query( + Host, + [<<"select opts from sr_group where name='">>, + SGroup, <<"';">>]) of + {selected, [<<"opts">>], [[SOpts]]} -> + mod_shared_roster:opts_to_binary(ejabberd_odbc:decode_term(SOpts)); + _ -> error + end. + +set_group_opts(Host, Group, Opts) -> + SGroup = ejabberd_odbc:escape(Group), + SOpts = ejabberd_odbc:encode_term(Opts), + F = fun () -> + odbc_queries:update_t(<<"sr_group">>, + [<<"name">>, <<"opts">>], [SGroup, SOpts], + [<<"name='">>, SGroup, <<"'">>]) + end, + ejabberd_odbc:sql_transaction(Host, F). + +get_user_groups(US, Host) -> + SJID = make_jid_s(US), + case catch ejabberd_odbc:sql_query( + Host, + [<<"select grp from sr_user where jid='">>, + SJID, <<"';">>]) of + {selected, [<<"grp">>], Rs} -> [G || [G] <- Rs]; + _ -> [] + end. + +get_group_explicit_users(Host, Group) -> + SGroup = ejabberd_odbc:escape(Group), + case catch ejabberd_odbc:sql_query( + Host, + [<<"select jid from sr_user where grp='">>, + SGroup, <<"';">>]) of + {selected, [<<"jid">>], Rs} -> + lists:map( + fun([JID]) -> + {U, S, _} = jid:tolower(jid:from_string(JID)), + {U, S} + end, Rs); + _ -> + [] + end. + +get_user_displayed_groups(LUser, LServer, GroupsOpts) -> + SJID = make_jid_s(LUser, LServer), + case catch ejabberd_odbc:sql_query( + LServer, + [<<"select grp from sr_user where jid='">>, + SJID, <<"';">>]) of + {selected, [<<"grp">>], Rs} -> + [{Group, proplists:get_value(Group, GroupsOpts, [])} + || [Group] <- Rs]; + _ -> [] + end. + +is_user_in_group(US, Group, Host) -> + SJID = make_jid_s(US), + SGroup = ejabberd_odbc:escape(Group), + case catch ejabberd_odbc:sql_query(Host, + [<<"select * from sr_user where jid='">>, + SJID, <<"' and grp='">>, SGroup, + <<"';">>]) of + {selected, _, []} -> false; + _ -> true + end. + +add_user_to_group(Host, US, Group) -> + SJID = make_jid_s(US), + SGroup = ejabberd_odbc:escape(Group), + F = fun () -> + odbc_queries:update_t(<<"sr_user">>, + [<<"jid">>, <<"grp">>], [SJID, SGroup], + [<<"jid='">>, SJID, <<"' and grp='">>, + SGroup, <<"'">>]) + end, + ejabberd_odbc:sql_transaction(Host, F). + +remove_user_from_group(Host, US, Group) -> + SJID = make_jid_s(US), + SGroup = ejabberd_odbc:escape(Group), + F = fun () -> + ejabberd_odbc:sql_query_t([<<"delete from sr_user where jid='">>, + SJID, <<"' and grp='">>, SGroup, + <<"';">>]), + ok + end, + ejabberd_odbc:sql_transaction(Host, F). + +export(_Server) -> + [{sr_group, + fun(Host, #sr_group{group_host = {Group, LServer}, opts = Opts}) + when LServer == Host -> + SGroup = ejabberd_odbc:escape(Group), + SOpts = ejabberd_odbc:encode_term(Opts), + [[<<"delete from sr_group where name='">>, Group, <<"';">>], + [<<"insert into sr_group(name, opts) values ('">>, + SGroup, <<"', '">>, SOpts, <<"');">>]]; + (_Host, _R) -> + [] + end}, + {sr_user, + fun(Host, #sr_user{us = {U, S}, group_host = {Group, LServer}}) + when LServer == Host -> + SGroup = ejabberd_odbc:escape(Group), + SJID = ejabberd_odbc:escape( + jid:to_string( + jid:tolower( + jid:make(U, S, <<"">>)))), + [[<<"delete from sr_user where jid='">>, SJID, + <<"'and grp='">>, Group, <<"';">>], + [<<"insert into sr_user(jid, grp) values ('">>, + SJID, <<"', '">>, SGroup, <<"');">>]]; + (_Host, _R) -> + [] + end}]. + +import(LServer) -> + [{<<"select name, opts from sr_group;">>, + fun([Group, SOpts]) -> + #sr_group{group_host = {Group, LServer}, + opts = ejabberd_odbc:decode_term(SOpts)} + end}, + {<<"select jid, grp from sr_user;">>, + fun([SJID, Group]) -> + #jid{luser = U, lserver = S} = jid:from_string(SJID), + #sr_user{us = {U, S}, group_host = {Group, LServer}} + end}]. + +import(_, _) -> + pass. + +%%%=================================================================== +%%% Internal functions +%%%=================================================================== +make_jid_s(U, S) -> + ejabberd_odbc:escape(jid:to_string(jid:tolower(jid:make(U, S, <<"">>)))). + +make_jid_s({U, S}) -> make_jid_s(U, S). |