mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-28 16:34:13 +01:00
Improve ODBC import
This commit is contained in:
parent
577eeb642f
commit
fbfbb96872
@ -36,8 +36,8 @@
|
|||||||
check_password/6, check_password_with_authmodule/4,
|
check_password/6, check_password_with_authmodule/4,
|
||||||
check_password_with_authmodule/6, try_register/3,
|
check_password_with_authmodule/6, try_register/3,
|
||||||
dirty_get_registered_users/0, get_vh_registered_users/1,
|
dirty_get_registered_users/0, get_vh_registered_users/1,
|
||||||
get_vh_registered_users/2, export/1, import/1,
|
get_vh_registered_users/2, export/1, import_info/0,
|
||||||
get_vh_registered_users_number/1, import/3,
|
get_vh_registered_users_number/1, import/5, import_start/2,
|
||||||
get_vh_registered_users_number/2, get_password/2,
|
get_vh_registered_users_number/2, get_password/2,
|
||||||
get_password_s/2, get_password_with_authmodule/2,
|
get_password_s/2, get_password_with_authmodule/2,
|
||||||
is_user_exists/2, is_user_exists_in_other_modules/3,
|
is_user_exists/2, is_user_exists_in_other_modules/3,
|
||||||
@ -438,15 +438,20 @@ auth_modules(Server) ->
|
|||||||
export(Server) ->
|
export(Server) ->
|
||||||
ejabberd_auth_mnesia:export(Server).
|
ejabberd_auth_mnesia:export(Server).
|
||||||
|
|
||||||
import(Server) ->
|
import_info() ->
|
||||||
ejabberd_auth_mnesia:import(Server).
|
[{<<"users">>, 3}].
|
||||||
|
|
||||||
import(Server, mnesia, Passwd) ->
|
import_start(_LServer, mnesia) ->
|
||||||
ejabberd_auth_mnesia:import(Server, mnesia, Passwd);
|
ejabberd_auth_mnesia:init_db();
|
||||||
import(Server, riak, Passwd) ->
|
import_start(_LServer, _) ->
|
||||||
ejabberd_auth_riak:import(Server, riak, Passwd);
|
ok.
|
||||||
import(_, _, _) ->
|
|
||||||
pass.
|
import(Server, {sql, _}, mnesia, <<"users">>, Fields) ->
|
||||||
|
ejabberd_auth_mnesia:import(Server, Fields);
|
||||||
|
import(Server, {sql, _}, riak, <<"users">>, Fields) ->
|
||||||
|
ejabberd_auth_riak:import(Server, Fields);
|
||||||
|
import(_LServer, {sql, _}, sql, <<"users">>, _) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
opt_type(auth_method) ->
|
opt_type(auth_method) ->
|
||||||
fun (V) when is_list(V) ->
|
fun (V) when is_list(V) ->
|
||||||
|
@ -40,8 +40,8 @@
|
|||||||
get_vh_registered_users_number/1,
|
get_vh_registered_users_number/1,
|
||||||
get_vh_registered_users_number/2, get_password/2,
|
get_vh_registered_users_number/2, get_password/2,
|
||||||
get_password_s/2, is_user_exists/2, remove_user/2,
|
get_password_s/2, is_user_exists/2, remove_user/2,
|
||||||
remove_user/3, store_type/0, export/1, import/1,
|
remove_user/3, store_type/0, export/1, import/2,
|
||||||
import/3, plain_password_required/0, opt_type/1]).
|
plain_password_required/0, opt_type/1]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
@ -493,16 +493,9 @@ export(_Server) ->
|
|||||||
[]
|
[]
|
||||||
end}].
|
end}].
|
||||||
|
|
||||||
import(LServer) ->
|
import(LServer, [LUser, Password, _TimeStamp]) ->
|
||||||
[{<<"select username, password from users;">>,
|
mnesia:dirty_write(
|
||||||
fun([LUser, Password]) ->
|
#passwd{us = {LUser, LServer}, password = Password}).
|
||||||
#passwd{us = {LUser, LServer}, password = Password}
|
|
||||||
end}].
|
|
||||||
|
|
||||||
import(_LServer, mnesia, #passwd{} = P) ->
|
|
||||||
mnesia:dirty_write(P);
|
|
||||||
import(_, _, _) ->
|
|
||||||
pass.
|
|
||||||
|
|
||||||
opt_type(auth_password_format) -> fun (V) -> V end;
|
opt_type(auth_password_format) -> fun (V) -> V end;
|
||||||
opt_type(_) -> [auth_password_format].
|
opt_type(_) -> [auth_password_format].
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
-compile([{parse_transform, ejabberd_sql_pt}]).
|
-compile([{parse_transform, ejabberd_sql_pt}]).
|
||||||
|
|
||||||
|
-behaviour(ejabberd_config).
|
||||||
|
|
||||||
-author('alexey@process-one.net').
|
-author('alexey@process-one.net').
|
||||||
|
|
||||||
-behaviour(ejabberd_auth).
|
-behaviour(ejabberd_auth).
|
||||||
@ -39,8 +41,8 @@
|
|||||||
get_vh_registered_users_number/1,
|
get_vh_registered_users_number/1,
|
||||||
get_vh_registered_users_number/2, get_password/2,
|
get_vh_registered_users_number/2, get_password/2,
|
||||||
get_password_s/2, is_user_exists/2, remove_user/2,
|
get_password_s/2, is_user_exists/2, remove_user/2,
|
||||||
remove_user/3, store_type/0, export/1, import/3,
|
remove_user/3, store_type/0, export/1, import/2,
|
||||||
plain_password_required/0]).
|
plain_password_required/0, opt_type/1]).
|
||||||
-export([passwd_schema/0]).
|
-export([passwd_schema/0]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
@ -301,7 +303,9 @@ export(_Server) ->
|
|||||||
[]
|
[]
|
||||||
end}].
|
end}].
|
||||||
|
|
||||||
import(LServer, riak, #passwd{} = Passwd) ->
|
import(LServer, [LUser, Password, _TimeStamp]) ->
|
||||||
ejabberd_riak:put(Passwd, passwd_schema(), [{'2i', [{<<"host">>, LServer}]}]);
|
Passwd = #passwd{us = {LUser, LServer}, password = Password},
|
||||||
import(_, _, _) ->
|
ejabberd_riak:put(Passwd, passwd_schema(), [{'2i', [{<<"host">>, LServer}]}]).
|
||||||
pass.
|
|
||||||
|
opt_type(auth_password_format) -> fun (V) -> V end;
|
||||||
|
opt_type(_) -> [auth_password_format].
|
||||||
|
294
src/ejd2sql.erl
294
src/ejd2sql.erl
@ -30,12 +30,12 @@
|
|||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
-include("ejabberd_sql_pt.hrl").
|
-include("ejabberd_sql_pt.hrl").
|
||||||
|
|
||||||
-export([export/2, export/3, import_file/2, import/2,
|
-export([export/2, export/3, import/3, import/4, delete/1, import_info/1]).
|
||||||
import/3, delete/1]).
|
|
||||||
|
|
||||||
-define(MAX_RECORDS_PER_TRANSACTION, 100).
|
-define(MAX_RECORDS_PER_TRANSACTION, 100).
|
||||||
|
|
||||||
-record(dump, {fd, cont = start}).
|
-record(sql_dump, {fd, type}).
|
||||||
|
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
%%% API
|
%%% API
|
||||||
@ -50,13 +50,14 @@
|
|||||||
modules() ->
|
modules() ->
|
||||||
[ejabberd_auth,
|
[ejabberd_auth,
|
||||||
mod_announce,
|
mod_announce,
|
||||||
|
mod_caps,
|
||||||
mod_irc,
|
mod_irc,
|
||||||
mod_last,
|
mod_last,
|
||||||
mod_muc,
|
mod_muc,
|
||||||
mod_offline,
|
mod_offline,
|
||||||
mod_privacy,
|
mod_privacy,
|
||||||
mod_private,
|
mod_private,
|
||||||
%% mod_pubsub,
|
mod_pubsub,
|
||||||
mod_roster,
|
mod_roster,
|
||||||
mod_shared_roster,
|
mod_shared_roster,
|
||||||
mod_vcard,
|
mod_vcard,
|
||||||
@ -100,49 +101,44 @@ delete(Server, Module) ->
|
|||||||
delete(LServer, Table, ConvertFun)
|
delete(LServer, Table, ConvertFun)
|
||||||
end, Module:export(Server)).
|
end, Module:export(Server)).
|
||||||
|
|
||||||
import_file(Server, FileName) when is_binary(FileName) ->
|
import(Server, Dir, ToType) ->
|
||||||
import(Server, binary_to_list(FileName));
|
|
||||||
import_file(Server, FileName) ->
|
|
||||||
case disk_log:open([{name, make_ref()},
|
|
||||||
{file, FileName},
|
|
||||||
{mode, read_only}]) of
|
|
||||||
{ok, Fd} ->
|
|
||||||
LServer = jid:nameprep(Server),
|
|
||||||
Mods = [{Mod, gen_mod:db_type(LServer, Mod)}
|
|
||||||
|| Mod <- modules(), gen_mod:is_loaded(LServer, Mod)],
|
|
||||||
AuthMods = case lists:member(ejabberd_auth_mnesia,
|
|
||||||
ejabberd_auth:auth_modules(LServer)) of
|
|
||||||
true ->
|
|
||||||
[{ejabberd_auth, mnesia}];
|
|
||||||
false ->
|
|
||||||
[]
|
|
||||||
end,
|
|
||||||
import_dump(LServer, AuthMods ++ Mods, #dump{fd = Fd});
|
|
||||||
Err ->
|
|
||||||
exit(Err)
|
|
||||||
end.
|
|
||||||
|
|
||||||
import(Server, Output) ->
|
|
||||||
import(Server, Output, [{fast, true}]).
|
|
||||||
|
|
||||||
import(Server, Output, Opts) ->
|
|
||||||
LServer = jid:nameprep(iolist_to_binary(Server)),
|
|
||||||
Modules = modules(),
|
|
||||||
IO = prepare_output(Output, disk_log),
|
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun(Module) ->
|
fun(Mod) ->
|
||||||
import(LServer, IO, Opts, Module)
|
?INFO_MSG("importing ~p...", [Mod]),
|
||||||
end, Modules),
|
import(Mod, Server, Dir, ToType)
|
||||||
close_output(Output, IO).
|
end, modules()).
|
||||||
|
|
||||||
import(Server, Output, Opts, Module) ->
|
import(Mod, Server, Dir, ToType) ->
|
||||||
LServer = jid:nameprep(iolist_to_binary(Server)),
|
LServer = jid:nameprep(iolist_to_binary(Server)),
|
||||||
IO = prepare_output(Output, disk_log),
|
try Mod:import_start(LServer, ToType)
|
||||||
|
catch error:undef -> ok end,
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun({SelectQuery, ConvertFun}) ->
|
fun({File, Tab, _Mod, FieldsNumber}) ->
|
||||||
import(LServer, SelectQuery, IO, ConvertFun, Opts)
|
FileName = filename:join([Dir, File]),
|
||||||
end, Module:import(Server)),
|
case open_sql_dump(FileName) of
|
||||||
close_output(Output, IO).
|
{ok, #sql_dump{type = FromType} = Dump} ->
|
||||||
|
import_rows(LServer, {sql, FromType}, ToType,
|
||||||
|
Tab, Mod, Dump, FieldsNumber),
|
||||||
|
close_sql_dump(Dump);
|
||||||
|
{error, enoent} ->
|
||||||
|
ok;
|
||||||
|
eof ->
|
||||||
|
?INFO_MSG("It seems like SQL dump ~s is empty", [FileName]);
|
||||||
|
Err ->
|
||||||
|
?ERROR_MSG("Failed to open SQL dump ~s: ~s",
|
||||||
|
[FileName, format_error(Err)])
|
||||||
|
end
|
||||||
|
end, import_info(Mod)),
|
||||||
|
try Mod:import_stop(LServer, ToType)
|
||||||
|
catch error:undef -> ok end.
|
||||||
|
|
||||||
|
import_info(Mod) ->
|
||||||
|
Info = Mod:import_info(),
|
||||||
|
lists:map(
|
||||||
|
fun({Tab, FieldsNum}) ->
|
||||||
|
FileName = <<Tab/binary, ".txt">>,
|
||||||
|
{FileName, Tab, Mod, FieldsNum}
|
||||||
|
end, Info).
|
||||||
|
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
@ -200,79 +196,6 @@ delete(LServer, Table, ConvertFun) ->
|
|||||||
end,
|
end,
|
||||||
mnesia:transaction(F).
|
mnesia:transaction(F).
|
||||||
|
|
||||||
import(LServer, SelectQuery, IO, ConvertFun, Opts) ->
|
|
||||||
F = case proplists:get_bool(fast, Opts) of
|
|
||||||
true ->
|
|
||||||
fun() ->
|
|
||||||
case ejabberd_sql:sql_query_t(SelectQuery) of
|
|
||||||
{selected, _, Rows} ->
|
|
||||||
lists:foldl(fun process_sql_row/2,
|
|
||||||
{IO, ConvertFun, undefined}, Rows);
|
|
||||||
Err ->
|
|
||||||
erlang:error(Err)
|
|
||||||
end
|
|
||||||
end;
|
|
||||||
false ->
|
|
||||||
fun() ->
|
|
||||||
ejabberd_sql:sql_query_t(
|
|
||||||
[iolist_to_binary(
|
|
||||||
[<<"declare c cursor for ">>, SelectQuery])]),
|
|
||||||
fetch(IO, ConvertFun, undefined)
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
ejabberd_sql:sql_transaction(LServer, F).
|
|
||||||
|
|
||||||
fetch(IO, ConvertFun, PrevRow) ->
|
|
||||||
case ejabberd_sql:sql_query_t([<<"fetch c;">>]) of
|
|
||||||
{selected, _, [Row]} ->
|
|
||||||
process_sql_row(Row, {IO, ConvertFun, PrevRow}),
|
|
||||||
fetch(IO, ConvertFun, Row);
|
|
||||||
{selected, _, []} ->
|
|
||||||
ok;
|
|
||||||
Err ->
|
|
||||||
erlang:error(Err)
|
|
||||||
end.
|
|
||||||
|
|
||||||
process_sql_row(Row, {IO, ConvertFun, PrevRow}) when Row == PrevRow ->
|
|
||||||
%% Avoid calling ConvertFun with the same input
|
|
||||||
{IO, ConvertFun, Row};
|
|
||||||
process_sql_row(Row, {IO, ConvertFun, _PrevRow}) ->
|
|
||||||
case catch ConvertFun(Row) of
|
|
||||||
{'EXIT', _} = Err ->
|
|
||||||
?ERROR_MSG("failed to convert ~p: ~p", [Row, Err]);
|
|
||||||
Term ->
|
|
||||||
ok = disk_log:log(IO#dump.fd, Term)
|
|
||||||
end,
|
|
||||||
{IO, ConvertFun, Row}.
|
|
||||||
|
|
||||||
import_dump(LServer, Mods, #dump{fd = Fd, cont = Cont}) ->
|
|
||||||
case disk_log:chunk(Fd, Cont) of
|
|
||||||
{NewCont, Terms} ->
|
|
||||||
import_terms(LServer, Mods, Terms),
|
|
||||||
import_dump(LServer, Mods, #dump{fd = Fd, cont = NewCont});
|
|
||||||
eof ->
|
|
||||||
ok;
|
|
||||||
Err ->
|
|
||||||
exit(Err)
|
|
||||||
end.
|
|
||||||
|
|
||||||
import_terms(LServer, Mods, [Term|Terms]) ->
|
|
||||||
import_term(LServer, Mods, Term),
|
|
||||||
import_terms(LServer, Mods, Terms);
|
|
||||||
import_terms(_LServer, _Mods, []) ->
|
|
||||||
ok.
|
|
||||||
|
|
||||||
import_term(LServer, [{Mod, DBType}|Mods], Term) ->
|
|
||||||
case catch Mod:import(LServer, DBType, Term) of
|
|
||||||
pass -> import_term(LServer, Mods, Term);
|
|
||||||
ok -> ok;
|
|
||||||
Err ->
|
|
||||||
?ERROR_MSG("failed to import ~p for module ~p: ~p",
|
|
||||||
[Term, Mod, Err])
|
|
||||||
end;
|
|
||||||
import_term(_LServer, [], _Term) ->
|
|
||||||
ok.
|
|
||||||
|
|
||||||
prepare_output(FileName) ->
|
prepare_output(FileName) ->
|
||||||
prepare_output(FileName, normal).
|
prepare_output(FileName, normal).
|
||||||
|
|
||||||
@ -285,25 +208,11 @@ prepare_output(FileName, normal) when is_list(FileName) ->
|
|||||||
Err ->
|
Err ->
|
||||||
exit(Err)
|
exit(Err)
|
||||||
end;
|
end;
|
||||||
prepare_output(FileName, disk_log) when is_list(FileName) ->
|
|
||||||
case disk_log:open([{name, make_ref()},
|
|
||||||
{repair, truncate},
|
|
||||||
{file, FileName}]) of
|
|
||||||
{ok, Fd} ->
|
|
||||||
#dump{fd = Fd};
|
|
||||||
Err ->
|
|
||||||
exit(Err)
|
|
||||||
end;
|
|
||||||
prepare_output(Output, _Type) ->
|
prepare_output(Output, _Type) ->
|
||||||
Output.
|
Output.
|
||||||
|
|
||||||
close_output(FileName, Fd) when FileName /= Fd ->
|
close_output(FileName, Fd) when FileName /= Fd ->
|
||||||
case Fd of
|
file:close(Fd),
|
||||||
#dump{} ->
|
|
||||||
disk_log:close(Fd#dump.fd);
|
|
||||||
_ ->
|
|
||||||
file:close(Fd)
|
|
||||||
end,
|
|
||||||
ok;
|
ok;
|
||||||
close_output(_, _) ->
|
close_output(_, _) ->
|
||||||
ok.
|
ok.
|
||||||
@ -321,6 +230,129 @@ flatten1([H|T], Acc) ->
|
|||||||
flatten1([], Acc) ->
|
flatten1([], Acc) ->
|
||||||
Acc.
|
Acc.
|
||||||
|
|
||||||
|
import_rows(LServer, FromType, ToType, Tab, Mod, Dump, FieldsNumber) ->
|
||||||
|
case read_row_from_sql_dump(Dump, FieldsNumber) of
|
||||||
|
{ok, Fields} ->
|
||||||
|
case catch Mod:import(LServer, FromType, ToType, Tab, Fields) of
|
||||||
|
ok ->
|
||||||
|
ok;
|
||||||
|
Err ->
|
||||||
|
?ERROR_MSG("Failed to import fields ~p for tab ~p: ~p",
|
||||||
|
[Fields, Tab, Err])
|
||||||
|
end,
|
||||||
|
import_rows(LServer, FromType, ToType,
|
||||||
|
Tab, Mod, Dump, FieldsNumber);
|
||||||
|
eof ->
|
||||||
|
ok;
|
||||||
|
Err ->
|
||||||
|
?ERROR_MSG("Failed to read row from SQL dump: ~s",
|
||||||
|
[format_error(Err)])
|
||||||
|
end.
|
||||||
|
|
||||||
|
open_sql_dump(FileName) ->
|
||||||
|
case file:open(FileName, [raw, read, binary, read_ahead]) of
|
||||||
|
{ok, Fd} ->
|
||||||
|
case file:read(Fd, 11) of
|
||||||
|
{ok, <<"PGCOPY\n", 16#ff, "\r\n", 0>>} ->
|
||||||
|
case skip_pgcopy_header(Fd) of
|
||||||
|
ok ->
|
||||||
|
{ok, #sql_dump{fd = Fd, type = pgsql}};
|
||||||
|
Err ->
|
||||||
|
Err
|
||||||
|
end;
|
||||||
|
{ok, _} ->
|
||||||
|
file:position(Fd, 0),
|
||||||
|
{ok, #sql_dump{fd = Fd, type = mysql}};
|
||||||
|
Err ->
|
||||||
|
Err
|
||||||
|
end;
|
||||||
|
Err ->
|
||||||
|
Err
|
||||||
|
end.
|
||||||
|
|
||||||
|
close_sql_dump(#sql_dump{fd = Fd}) ->
|
||||||
|
file:close(Fd).
|
||||||
|
|
||||||
|
read_row_from_sql_dump(#sql_dump{fd = Fd, type = pgsql}, _) ->
|
||||||
|
case file:read(Fd, 2) of
|
||||||
|
{ok, <<(-1):16/signed>>} ->
|
||||||
|
eof;
|
||||||
|
{ok, <<FieldsNum:16>>} ->
|
||||||
|
read_fields(Fd, FieldsNum, []);
|
||||||
|
{ok, _} ->
|
||||||
|
{error, eof};
|
||||||
|
eof ->
|
||||||
|
{error, eof};
|
||||||
|
{error, _} = Err ->
|
||||||
|
Err
|
||||||
|
end;
|
||||||
|
read_row_from_sql_dump(#sql_dump{fd = Fd, type = mysql}, FieldsNum) ->
|
||||||
|
read_lines(Fd, FieldsNum, <<"">>, []).
|
||||||
|
|
||||||
|
skip_pgcopy_header(Fd) ->
|
||||||
|
try
|
||||||
|
{ok, <<_:4/binary, ExtSize:32>>} = file:read(Fd, 8),
|
||||||
|
{ok, <<_:ExtSize/binary>>} = file:read(Fd, ExtSize),
|
||||||
|
ok
|
||||||
|
catch error:{badmatch, {error, _} = Err} ->
|
||||||
|
Err;
|
||||||
|
error:{badmatch, _} ->
|
||||||
|
{error, eof}
|
||||||
|
end.
|
||||||
|
|
||||||
|
read_fields(_Fd, 0, Acc) ->
|
||||||
|
{ok, lists:reverse(Acc)};
|
||||||
|
read_fields(Fd, N, Acc) ->
|
||||||
|
case file:read(Fd, 4) of
|
||||||
|
{ok, <<(-1):32/signed>>} ->
|
||||||
|
read_fields(Fd, N-1, [null|Acc]);
|
||||||
|
{ok, <<ValSize:32>>} ->
|
||||||
|
case file:read(Fd, ValSize) of
|
||||||
|
{ok, <<Val:ValSize/binary>>} ->
|
||||||
|
read_fields(Fd, N-1, [Val|Acc]);
|
||||||
|
{ok, _} ->
|
||||||
|
{error, eof};
|
||||||
|
Err ->
|
||||||
|
Err
|
||||||
|
end;
|
||||||
|
{ok, _} ->
|
||||||
|
{error, eof};
|
||||||
|
eof ->
|
||||||
|
{error, eof};
|
||||||
|
{error, _} = Err ->
|
||||||
|
Err
|
||||||
|
end.
|
||||||
|
|
||||||
|
read_lines(_Fd, 0, <<"">>, Acc) ->
|
||||||
|
{ok, lists:reverse(Acc)};
|
||||||
|
read_lines(Fd, N, Buf, Acc) ->
|
||||||
|
case file:read_line(Fd) of
|
||||||
|
{ok, Data} when size(Data) >= 2 ->
|
||||||
|
Size = size(Data) - 2,
|
||||||
|
case Data of
|
||||||
|
<<Val:Size/binary, 0, $\n>> ->
|
||||||
|
NewBuf = <<Buf/binary, Val/binary>>,
|
||||||
|
read_lines(Fd, N-1, <<"">>, [NewBuf|Acc]);
|
||||||
|
_ ->
|
||||||
|
NewBuf = <<Buf/binary, Data/binary>>,
|
||||||
|
read_lines(Fd, N, NewBuf, Acc)
|
||||||
|
end;
|
||||||
|
{ok, Data} ->
|
||||||
|
NewBuf = <<Buf/binary, Data/binary>>,
|
||||||
|
read_lines(Fd, N, NewBuf, Acc);
|
||||||
|
eof when Buf == <<"">>, Acc == [] ->
|
||||||
|
eof;
|
||||||
|
eof ->
|
||||||
|
{error, eof};
|
||||||
|
{error, _} = Err ->
|
||||||
|
Err
|
||||||
|
end.
|
||||||
|
|
||||||
|
format_error({error, eof}) ->
|
||||||
|
"unexpected end of file";
|
||||||
|
format_error({error, Posix}) ->
|
||||||
|
file:format_error(Posix).
|
||||||
|
|
||||||
format_queries(SQLs) ->
|
format_queries(SQLs) ->
|
||||||
lists:map(
|
lists:map(
|
||||||
fun(#sql_query{} = SQL) ->
|
fun(#sql_query{} = SQL) ->
|
||||||
|
@ -31,8 +31,8 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, init/0, stop/1, export/1, import/1,
|
-export([start/2, init/0, stop/1, export/1, import_info/0,
|
||||||
import/3, announce/3, send_motd/1, disco_identity/5,
|
import_start/2, import/5, announce/3, send_motd/1, disco_identity/5,
|
||||||
disco_features/5, disco_items/5, depends/2,
|
disco_features/5, disco_items/5, depends/2,
|
||||||
send_announcement_to_all/3, announce_commands/4,
|
send_announcement_to_all/3, announce_commands/4,
|
||||||
announce_items/4, mod_opt_type/1]).
|
announce_items/4, mod_opt_type/1]).
|
||||||
@ -43,7 +43,7 @@
|
|||||||
-include("mod_announce.hrl").
|
-include("mod_announce.hrl").
|
||||||
|
|
||||||
-callback init(binary(), gen_mod:opts()) -> any().
|
-callback init(binary(), gen_mod:opts()) -> any().
|
||||||
-callback import(binary(), #motd{} | #motd_users{}) -> ok | pass.
|
-callback import(binary(), binary(), [binary()]) -> ok.
|
||||||
-callback set_motd_users(binary(), [{binary(), binary(), binary()}]) -> {atomic, any()}.
|
-callback set_motd_users(binary(), [{binary(), binary(), binary()}]) -> {atomic, any()}.
|
||||||
-callback set_motd(binary(), xmlel()) -> {atomic, any()}.
|
-callback set_motd(binary(), xmlel()) -> {atomic, any()}.
|
||||||
-callback delete_motd(binary()) -> {atomic, any()}.
|
-callback delete_motd(binary()) -> {atomic, any()}.
|
||||||
@ -832,15 +832,17 @@ export(LServer) ->
|
|||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
Mod:export(LServer).
|
Mod:export(LServer).
|
||||||
|
|
||||||
import(LServer) ->
|
import_info() ->
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
[{<<"motd">>, 3}].
|
||||||
Mod:import(LServer).
|
|
||||||
|
|
||||||
import(LServer, DBType, LA) ->
|
import_start(LServer, DBType) ->
|
||||||
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||||
Mod:import(LServer, LA).
|
Mod:init(LServer, []).
|
||||||
|
|
||||||
mod_opt_type(access) ->
|
import(LServer, {sql, _}, DBType, Tab, List) ->
|
||||||
fun acl:access_rules_validator/1;
|
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||||
|
Mod:import(LServer, Tab, List).
|
||||||
|
|
||||||
|
mod_opt_type(access) -> fun acl:access_rules_validator/1;
|
||||||
mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end;
|
mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end;
|
||||||
mod_opt_type(_) -> [access, db_type].
|
mod_opt_type(_) -> [access, db_type].
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([init/2, set_motd_users/2, set_motd/2, delete_motd/1,
|
-export([init/2, set_motd_users/2, set_motd/2, delete_motd/1,
|
||||||
get_motd/1, is_motd_user/2, set_motd_user/2, import/2]).
|
get_motd/1, is_motd_user/2, set_motd_user/2, import/3]).
|
||||||
|
|
||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
-include("mod_announce.hrl").
|
-include("mod_announce.hrl").
|
||||||
@ -81,10 +81,11 @@ set_motd_user(LUser, LServer) ->
|
|||||||
end,
|
end,
|
||||||
mnesia:transaction(F).
|
mnesia:transaction(F).
|
||||||
|
|
||||||
import(_LServer, #motd{} = Motd) ->
|
import(LServer, <<"motd">>, [<<>>, XML, _TimeStamp]) ->
|
||||||
mnesia:dirty_write(Motd);
|
El = fxml_stream:parse_element(XML),
|
||||||
import(_LServer, #motd_users{} = Users) ->
|
mnesia:dirty_write(#motd{server = LServer, packet = El});
|
||||||
mnesia:dirty_write(Users).
|
import(LServer, <<"motd">>, [LUser, <<>>, _TimeStamp]) ->
|
||||||
|
mnesia:dirty_write(#motd_users{us = {LUser, LServer}}).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([init/2, set_motd_users/2, set_motd/2, delete_motd/1,
|
-export([init/2, set_motd_users/2, set_motd/2, delete_motd/1,
|
||||||
get_motd/1, is_motd_user/2, set_motd_user/2, import/2]).
|
get_motd/1, is_motd_user/2, set_motd_user/2, import/3]).
|
||||||
|
|
||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
-include("mod_announce.hrl").
|
-include("mod_announce.hrl").
|
||||||
@ -71,11 +71,13 @@ set_motd_user(LUser, LServer) ->
|
|||||||
#motd_users{us = {LUser, LServer}}, motd_users_schema(),
|
#motd_users{us = {LUser, LServer}}, motd_users_schema(),
|
||||||
[{'2i', [{<<"server">>, LServer}]}])}.
|
[{'2i', [{<<"server">>, LServer}]}])}.
|
||||||
|
|
||||||
import(_LServer, #motd{} = Motd) ->
|
import(LServer, <<"motd">>, [<<>>, XML, _TimeStamp]) ->
|
||||||
ejabberd_riak:put(Motd, motd_schema());
|
El = fxml_stream:parse_element(XML),
|
||||||
import(_LServer, #motd_users{us = {_, S}} = Users) ->
|
ejabberd_riak:put(#motd{server = LServer, packet = El}, motd_schema());
|
||||||
|
import(LServer, <<"motd">>, [LUser, <<>>, _TimeStamp]) ->
|
||||||
|
Users = #motd_users{us = {LUser, LServer}},
|
||||||
ejabberd_riak:put(Users, motd_users_schema(),
|
ejabberd_riak:put(Users, motd_users_schema(),
|
||||||
[{'2i', [{<<"server">>, S}]}]).
|
[{'2i', [{<<"server">>, LServer}]}]).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([init/2, set_motd_users/2, set_motd/2, delete_motd/1,
|
-export([init/2, set_motd_users/2, set_motd/2, delete_motd/1,
|
||||||
get_motd/1, is_motd_user/2, set_motd_user/2, import/1,
|
get_motd/1, is_motd_user/2, set_motd_user/2, import/3,
|
||||||
import/2, export/1]).
|
export/1]).
|
||||||
|
|
||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
-include("mod_announce.hrl").
|
-include("mod_announce.hrl").
|
||||||
@ -108,19 +108,8 @@ export(_Server) ->
|
|||||||
[]
|
[]
|
||||||
end}].
|
end}].
|
||||||
|
|
||||||
import(LServer) ->
|
import(_, _, _) ->
|
||||||
[{<<"select xml from motd where username='';">>,
|
ok.
|
||||||
fun([XML]) ->
|
|
||||||
El = fxml_stream:parse_element(XML),
|
|
||||||
#motd{server = LServer, packet = El}
|
|
||||||
end},
|
|
||||||
{<<"select username from motd where xml='';">>,
|
|
||||||
fun([LUser]) ->
|
|
||||||
#motd_users{us = {LUser, LServer}}
|
|
||||||
end}].
|
|
||||||
|
|
||||||
import(_, _) ->
|
|
||||||
pass.
|
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
|
@ -55,20 +55,16 @@
|
|||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
|
|
||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
|
-include("mod_caps.hrl").
|
||||||
|
|
||||||
-define(PROCNAME, ejabberd_mod_caps).
|
-define(PROCNAME, ejabberd_mod_caps).
|
||||||
|
|
||||||
-define(BAD_HASH_LIFETIME, 600).
|
-define(BAD_HASH_LIFETIME, 600).
|
||||||
|
|
||||||
-record(caps_features,
|
|
||||||
{
|
|
||||||
node_pair = {<<"">>, <<"">>} :: {binary(), binary()},
|
|
||||||
features = [] :: [binary()] | pos_integer()
|
|
||||||
}).
|
|
||||||
|
|
||||||
-record(state, {host = <<"">> :: binary()}).
|
-record(state, {host = <<"">> :: binary()}).
|
||||||
|
|
||||||
-callback init(binary(), gen_mod:opts()) -> any().
|
-callback init(binary(), gen_mod:opts()) -> any().
|
||||||
|
-callback import(binary(), {binary(), binary()}, [binary() | pos_integer()]) -> ok.
|
||||||
-callback caps_read(binary(), {binary(), binary()}) ->
|
-callback caps_read(binary(), {binary(), binary()}) ->
|
||||||
{ok, non_neg_integer() | [binary()]} | error.
|
{ok, non_neg_integer() | [binary()]} | error.
|
||||||
-callback caps_write(binary(), {binary(), binary()},
|
-callback caps_write(binary(), {binary(), binary()},
|
||||||
@ -525,9 +521,6 @@ is_valid_node(Node) ->
|
|||||||
false
|
false
|
||||||
end.
|
end.
|
||||||
|
|
||||||
caps_features_schema() ->
|
|
||||||
{record_info(fields, caps_features), #caps_features{}}.
|
|
||||||
|
|
||||||
export(LServer) ->
|
export(LServer) ->
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
Mod:export(LServer).
|
Mod:export(LServer).
|
||||||
@ -559,24 +552,8 @@ import_next(_LServer, _DBType, '$end_of_table') ->
|
|||||||
ok;
|
ok;
|
||||||
import_next(LServer, DBType, NodePair) ->
|
import_next(LServer, DBType, NodePair) ->
|
||||||
Features = [F || {_, F} <- ets:lookup(caps_features_tmp, NodePair)],
|
Features = [F || {_, F} <- ets:lookup(caps_features_tmp, NodePair)],
|
||||||
case Features of
|
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||||
[I] when is_integer(I), DBType == mnesia ->
|
Mod:import(LServer, NodePair, Features),
|
||||||
mnesia:dirty_write(
|
|
||||||
#caps_features{node_pair = NodePair, features = I});
|
|
||||||
[I] when is_integer(I), DBType == riak ->
|
|
||||||
ejabberd_riak:put(
|
|
||||||
#caps_features{node_pair = NodePair, features = I},
|
|
||||||
caps_features_schema());
|
|
||||||
_ when DBType == mnesia ->
|
|
||||||
mnesia:dirty_write(
|
|
||||||
#caps_features{node_pair = NodePair, features = Features});
|
|
||||||
_ when DBType == riak ->
|
|
||||||
ejabberd_riak:put(
|
|
||||||
#caps_features{node_pair = NodePair, features = Features},
|
|
||||||
caps_features_schema());
|
|
||||||
_ when DBType == sql ->
|
|
||||||
ok
|
|
||||||
end,
|
|
||||||
import_next(LServer, DBType, ets:next(caps_features_tmp, NodePair)).
|
import_next(LServer, DBType, ets:next(caps_features_tmp, NodePair)).
|
||||||
|
|
||||||
mod_opt_type(cache_life_time) ->
|
mod_opt_type(cache_life_time) ->
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
-behaviour(mod_caps).
|
-behaviour(mod_caps).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([init/2, caps_read/2, caps_write/3]).
|
-export([init/2, caps_read/2, caps_write/3, import/3]).
|
||||||
|
|
||||||
-include("mod_caps.hrl").
|
-include("mod_caps.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
@ -46,6 +46,13 @@ caps_write(_LServer, Node, Features) ->
|
|||||||
mnesia:dirty_write(#caps_features{node_pair = Node,
|
mnesia:dirty_write(#caps_features{node_pair = Node,
|
||||||
features = Features}).
|
features = Features}).
|
||||||
|
|
||||||
|
import(_LServer, NodePair, [I]) when is_integer(I) ->
|
||||||
|
mnesia:dirty_write(
|
||||||
|
#caps_features{node_pair = NodePair, features = I});
|
||||||
|
import(_LServer, NodePair, Features) ->
|
||||||
|
mnesia:dirty_write(
|
||||||
|
#caps_features{node_pair = NodePair, features = Features}).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
-behaviour(mod_caps).
|
-behaviour(mod_caps).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([init/2, caps_read/2, caps_write/3]).
|
-export([init/2, caps_read/2, caps_write/3, import/3]).
|
||||||
|
|
||||||
-include("mod_caps.hrl").
|
-include("mod_caps.hrl").
|
||||||
|
|
||||||
@ -31,6 +31,15 @@ caps_write(_LServer, Node, Features) ->
|
|||||||
features = Features},
|
features = Features},
|
||||||
caps_features_schema()).
|
caps_features_schema()).
|
||||||
|
|
||||||
|
import(_LServer, NodePair, [I]) when is_integer(I) ->
|
||||||
|
ejabberd_riak:put(
|
||||||
|
#caps_features{node_pair = NodePair, features = I},
|
||||||
|
caps_features_schema());
|
||||||
|
import(_LServer, NodePair, Features) ->
|
||||||
|
ejabberd_riak:put(
|
||||||
|
#caps_features{node_pair = NodePair, features = Features},
|
||||||
|
caps_features_schema()).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
-compile([{parse_transform, ejabberd_sql_pt}]).
|
-compile([{parse_transform, ejabberd_sql_pt}]).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([init/2, caps_read/2, caps_write/3, export/1]).
|
-export([init/2, caps_read/2, caps_write/3, export/1, import/3]).
|
||||||
|
|
||||||
-include("mod_caps.hrl").
|
-include("mod_caps.hrl").
|
||||||
-include("ejabberd_sql_pt.hrl").
|
-include("ejabberd_sql_pt.hrl").
|
||||||
@ -53,6 +53,9 @@ export(_Server) ->
|
|||||||
[]
|
[]
|
||||||
end}].
|
end}].
|
||||||
|
|
||||||
|
import(_, _, _) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
|
@ -34,8 +34,8 @@
|
|||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, stop/1, process_local_iq/1, export/1,
|
-export([start/2, stop/1, process_local_iq/1, export/1,
|
||||||
process_sm_iq/1, on_presence_update/4, import/1,
|
process_sm_iq/1, on_presence_update/4, import_info/0,
|
||||||
import/3, store_last_info/4, get_last_info/2,
|
import/5, store_last_info/4, get_last_info/2,
|
||||||
remove_user/2, transform_options/1, mod_opt_type/1,
|
remove_user/2, transform_options/1, mod_opt_type/1,
|
||||||
opt_type/1, register_user/2, depends/2]).
|
opt_type/1, register_user/2, depends/2]).
|
||||||
|
|
||||||
@ -207,18 +207,28 @@ remove_user(User, Server) ->
|
|||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
Mod:remove_user(LUser, LServer).
|
Mod:remove_user(LUser, LServer).
|
||||||
|
|
||||||
|
import_info() ->
|
||||||
|
[{<<"last">>, 3}].
|
||||||
|
|
||||||
|
import_start(LServer, DBType) ->
|
||||||
|
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||||
|
Mod:init(LServer, []).
|
||||||
|
|
||||||
|
import(LServer, {sql, _}, DBType, <<"last">>, [LUser, TimeStamp, State]) ->
|
||||||
|
TS = case TimeStamp of
|
||||||
|
<<"">> -> 0;
|
||||||
|
_ -> jlib:binary_to_integer(TimeStamp)
|
||||||
|
end,
|
||||||
|
LA = #last_activity{us = {LUser, LServer},
|
||||||
|
timestamp = TS,
|
||||||
|
status = State},
|
||||||
|
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||||
|
Mod:import(LServer, LA).
|
||||||
|
|
||||||
export(LServer) ->
|
export(LServer) ->
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
Mod:export(LServer).
|
Mod:export(LServer).
|
||||||
|
|
||||||
import(LServer) ->
|
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
|
||||||
Mod:import(LServer).
|
|
||||||
|
|
||||||
import(LServer, DBType, LA) ->
|
|
||||||
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
|
||||||
Mod:import(LServer, LA).
|
|
||||||
|
|
||||||
transform_options(Opts) ->
|
transform_options(Opts) ->
|
||||||
lists:foldl(fun transform_options/2, [], Opts).
|
lists:foldl(fun transform_options/2, [], Opts).
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([init/2, get_last/2, store_last_info/4, remove_user/2,
|
-export([init/2, get_last/2, store_last_info/4, remove_user/2,
|
||||||
import/1, import/2, export/1]).
|
import/2, export/1]).
|
||||||
|
|
||||||
-include("mod_last.hrl").
|
-include("mod_last.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
@ -43,9 +43,6 @@ store_last_info(LUser, LServer, TimeStamp, Status) ->
|
|||||||
remove_user(LUser, LServer) ->
|
remove_user(LUser, LServer) ->
|
||||||
sql_queries:del_last(LServer, LUser).
|
sql_queries:del_last(LServer, LUser).
|
||||||
|
|
||||||
import(_LServer, _LA) ->
|
|
||||||
pass.
|
|
||||||
|
|
||||||
export(_Server) ->
|
export(_Server) ->
|
||||||
[{last_activity,
|
[{last_activity,
|
||||||
fun(Host, #last_activity{us = {LUser, LServer},
|
fun(Host, #last_activity{us = {LUser, LServer},
|
||||||
@ -58,15 +55,5 @@ export(_Server) ->
|
|||||||
[]
|
[]
|
||||||
end}].
|
end}].
|
||||||
|
|
||||||
import(LServer) ->
|
import(_LServer, _LA) ->
|
||||||
[{<<"select username, seconds, state from last">>,
|
pass.
|
||||||
fun([LUser, TimeStamp, State]) ->
|
|
||||||
#last_activity{us = {LUser, LServer},
|
|
||||||
timestamp = binary_to_integer(
|
|
||||||
TimeStamp),
|
|
||||||
status = State}
|
|
||||||
end}].
|
|
||||||
|
|
||||||
%%%===================================================================
|
|
||||||
%%% Internal functions
|
|
||||||
%%%===================================================================
|
|
||||||
|
@ -51,8 +51,9 @@
|
|||||||
process_mucsub/1,
|
process_mucsub/1,
|
||||||
broadcast_service_message/2,
|
broadcast_service_message/2,
|
||||||
export/1,
|
export/1,
|
||||||
import/1,
|
import_info/0,
|
||||||
import/3,
|
import/5,
|
||||||
|
import_start/2,
|
||||||
opts_to_binary/1,
|
opts_to_binary/1,
|
||||||
can_use_nick/4]).
|
can_use_nick/4]).
|
||||||
|
|
||||||
@ -79,7 +80,7 @@
|
|||||||
|
|
||||||
-type muc_room_opts() :: [{atom(), any()}].
|
-type muc_room_opts() :: [{atom(), any()}].
|
||||||
-callback init(binary(), gen_mod:opts()) -> any().
|
-callback init(binary(), gen_mod:opts()) -> any().
|
||||||
-callback import(binary(), #muc_room{} | #muc_registered{}) -> ok | pass.
|
-callback import(binary(), binary(), [binary()]) -> ok.
|
||||||
-callback store_room(binary(), binary(), binary(), list()) -> {atomic, any()}.
|
-callback store_room(binary(), binary(), binary(), list()) -> {atomic, any()}.
|
||||||
-callback restore_room(binary(), binary(), binary()) -> muc_room_opts() | error.
|
-callback restore_room(binary(), binary(), binary()) -> muc_room_opts() | error.
|
||||||
-callback forget_room(binary(), binary(), binary()) -> {atomic, any()}.
|
-callback forget_room(binary(), binary(), binary()) -> {atomic, any()}.
|
||||||
@ -904,13 +905,16 @@ export(LServer) ->
|
|||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
Mod:export(LServer).
|
Mod:export(LServer).
|
||||||
|
|
||||||
import(LServer) ->
|
import_info() ->
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
[{<<"muc_room">>, 4}, {<<"muc_registered">>, 4}].
|
||||||
Mod:import(LServer).
|
|
||||||
|
|
||||||
import(LServer, DBType, Data) ->
|
import_start(LServer, DBType) ->
|
||||||
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||||
Mod:import(LServer, Data).
|
Mod:init(LServer, []).
|
||||||
|
|
||||||
|
import(LServer, {sql, _}, DBType, Tab, L) ->
|
||||||
|
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||||
|
Mod:import(LServer, Tab, L).
|
||||||
|
|
||||||
mod_opt_type(access) ->
|
mod_opt_type(access) ->
|
||||||
fun acl:access_rules_validator/1;
|
fun acl:access_rules_validator/1;
|
||||||
|
@ -9,11 +9,15 @@
|
|||||||
-module(mod_muc_mnesia).
|
-module(mod_muc_mnesia).
|
||||||
|
|
||||||
-behaviour(mod_muc).
|
-behaviour(mod_muc).
|
||||||
|
-behaviour(mod_muc_room).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([init/2, import/2, 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([set_affiliation/6, set_affiliations/4, get_affiliation/5,
|
||||||
|
get_affiliations/3, search_affiliation/4]).
|
||||||
|
|
||||||
|
-include("jlib.hrl").
|
||||||
-include("mod_muc.hrl").
|
-include("mod_muc.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
|
|
||||||
@ -113,10 +117,33 @@ set_nick(_LServer, Host, From, Nick) ->
|
|||||||
end,
|
end,
|
||||||
mnesia:transaction(F).
|
mnesia:transaction(F).
|
||||||
|
|
||||||
import(_LServer, #muc_room{} = R) ->
|
set_affiliation(_ServerHost, _Room, _Host, _JID, _Affiliation, _Reason) ->
|
||||||
mnesia:dirty_write(R);
|
{error, not_implemented}.
|
||||||
import(_LServer, #muc_registered{} = R) ->
|
|
||||||
mnesia:dirty_write(R).
|
set_affiliations(_ServerHost, _Room, _Host, _Affiliations) ->
|
||||||
|
{error, not_implemented}.
|
||||||
|
|
||||||
|
get_affiliation(_ServerHost, _Room, _Host, _LUser, _LServer) ->
|
||||||
|
{error, not_implemented}.
|
||||||
|
|
||||||
|
get_affiliations(_ServerHost, _Room, _Host) ->
|
||||||
|
{error, not_implemented}.
|
||||||
|
|
||||||
|
search_affiliation(_ServerHost, _Room, _Host, _Affiliation) ->
|
||||||
|
{error, not_implemented}.
|
||||||
|
|
||||||
|
import(_LServer, <<"muc_room">>,
|
||||||
|
[Name, RoomHost, SOpts, _TimeStamp]) ->
|
||||||
|
Opts = mod_muc:opts_to_binary(ejabberd_sql:decode_term(SOpts)),
|
||||||
|
mnesia:dirty_write(
|
||||||
|
#muc_room{name_host = {Name, RoomHost},
|
||||||
|
opts = Opts});
|
||||||
|
import(_LServer, <<"muc_registered">>,
|
||||||
|
[J, RoomHost, Nick, _TimeStamp]) ->
|
||||||
|
#jid{user = U, server = S} = jid:from_string(J),
|
||||||
|
mnesia:dirty_write(
|
||||||
|
#muc_registered{us_host = {{U, S}, RoomHost},
|
||||||
|
nick = Nick}).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
|
@ -9,11 +9,15 @@
|
|||||||
-module(mod_muc_riak).
|
-module(mod_muc_riak).
|
||||||
|
|
||||||
-behaviour(mod_muc).
|
-behaviour(mod_muc).
|
||||||
|
-behaviour(mod_muc_room).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([init/2, import/2, 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([set_affiliation/6, set_affiliations/4, get_affiliation/5,
|
||||||
|
get_affiliations/3, search_affiliation/4]).
|
||||||
|
|
||||||
|
-include("jlib.hrl").
|
||||||
-include("mod_muc.hrl").
|
-include("mod_muc.hrl").
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
@ -101,11 +105,33 @@ set_nick(LServer, Host, From, Nick) ->
|
|||||||
end
|
end
|
||||||
end}.
|
end}.
|
||||||
|
|
||||||
import(_LServer, #muc_room{} = R) ->
|
set_affiliation(_ServerHost, _Room, _Host, _JID, _Affiliation, _Reason) ->
|
||||||
ejabberd_riak:put(R, muc_room_schema());
|
{error, not_implemented}.
|
||||||
import(_LServer, #muc_registered{us_host = {_, Host}, nick = Nick} = R) ->
|
|
||||||
|
set_affiliations(_ServerHost, _Room, _Host, _Affiliations) ->
|
||||||
|
{error, not_implemented}.
|
||||||
|
|
||||||
|
get_affiliation(_ServerHost, _Room, _Host, _LUser, _LServer) ->
|
||||||
|
{error, not_implemented}.
|
||||||
|
|
||||||
|
get_affiliations(_ServerHost, _Room, _Host) ->
|
||||||
|
{error, not_implemented}.
|
||||||
|
|
||||||
|
search_affiliation(_ServerHost, _Room, _Host, _Affiliation) ->
|
||||||
|
{error, not_implemented}.
|
||||||
|
|
||||||
|
import(_LServer, <<"muc_room">>,
|
||||||
|
[Name, RoomHost, SOpts, _TimeStamp]) ->
|
||||||
|
Opts = mod_muc:opts_to_binary(ejabberd_sql:decode_term(SOpts)),
|
||||||
|
ejabberd_riak:put(
|
||||||
|
#muc_room{name_host = {Name, RoomHost}, opts = Opts},
|
||||||
|
muc_room_schema());
|
||||||
|
import(_LServer, <<"muc_registered">>,
|
||||||
|
[J, RoomHost, Nick, _TimeStamp]) ->
|
||||||
|
#jid{user = U, server = S} = jid:from_string(J),
|
||||||
|
R = #muc_registered{us_host = {{U, S}, RoomHost}, nick = Nick},
|
||||||
ejabberd_riak:put(R, muc_registered_schema(),
|
ejabberd_riak:put(R, muc_registered_schema(),
|
||||||
[{'2i', [{<<"nick_host">>, {Nick, Host}}]}]).
|
[{'2i', [{<<"nick_host">>, {Nick, RoomHost}}]}]).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
|
@ -11,11 +11,14 @@
|
|||||||
-compile([{parse_transform, ejabberd_sql_pt}]).
|
-compile([{parse_transform, ejabberd_sql_pt}]).
|
||||||
|
|
||||||
-behaviour(mod_muc).
|
-behaviour(mod_muc).
|
||||||
|
-behaviour(mod_muc_room).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-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/1, import/2, export/1]).
|
import/3, export/1]).
|
||||||
|
-export([set_affiliation/6, set_affiliations/4, get_affiliation/5,
|
||||||
|
get_affiliations/3, search_affiliation/4]).
|
||||||
|
|
||||||
-include("jid.hrl").
|
-include("jid.hrl").
|
||||||
-include("mod_muc.hrl").
|
-include("mod_muc.hrl").
|
||||||
@ -127,6 +130,21 @@ set_nick(LServer, Host, From, Nick) ->
|
|||||||
end,
|
end,
|
||||||
ejabberd_sql:sql_transaction(LServer, F).
|
ejabberd_sql:sql_transaction(LServer, F).
|
||||||
|
|
||||||
|
set_affiliation(_ServerHost, _Room, _Host, _JID, _Affiliation, _Reason) ->
|
||||||
|
{error, not_implemented}.
|
||||||
|
|
||||||
|
set_affiliations(_ServerHost, _Room, _Host, _Affiliations) ->
|
||||||
|
{error, not_implemented}.
|
||||||
|
|
||||||
|
get_affiliation(_ServerHost, _Room, _Host, _LUser, _LServer) ->
|
||||||
|
{error, not_implemented}.
|
||||||
|
|
||||||
|
get_affiliations(_ServerHost, _Room, _Host) ->
|
||||||
|
{error, not_implemented}.
|
||||||
|
|
||||||
|
search_affiliation(_ServerHost, _Room, _Host, _Affiliation) ->
|
||||||
|
{error, not_implemented}.
|
||||||
|
|
||||||
export(_Server) ->
|
export(_Server) ->
|
||||||
[{muc_room,
|
[{muc_room,
|
||||||
fun(Host, #muc_room{name_host = {Name, RoomHost}, opts = Opts}) ->
|
fun(Host, #muc_room{name_host = {Name, RoomHost}, opts = Opts}) ->
|
||||||
@ -158,21 +176,8 @@ export(_Server) ->
|
|||||||
end
|
end
|
||||||
end}].
|
end}].
|
||||||
|
|
||||||
import(_LServer) ->
|
import(_, _, _) ->
|
||||||
[{<<"select name, host, opts from muc_room;">>,
|
ok.
|
||||||
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
|
%%% Internal functions
|
||||||
|
@ -53,8 +53,9 @@
|
|||||||
remove_expired_messages/1,
|
remove_expired_messages/1,
|
||||||
remove_old_messages/2,
|
remove_old_messages/2,
|
||||||
remove_user/2,
|
remove_user/2,
|
||||||
import/1,
|
import_info/0,
|
||||||
import/3,
|
import_start/2,
|
||||||
|
import/5,
|
||||||
export/1,
|
export/1,
|
||||||
get_queue_length/2,
|
get_queue_length/2,
|
||||||
count_offline_messages/2,
|
count_offline_messages/2,
|
||||||
@ -90,7 +91,7 @@
|
|||||||
|
|
||||||
-type us() :: {binary(), binary()}.
|
-type us() :: {binary(), binary()}.
|
||||||
-callback init(binary(), gen_mod:opts()) -> any().
|
-callback init(binary(), gen_mod:opts()) -> any().
|
||||||
-callback import(binary(), #offline_msg{}) -> ok | pass.
|
-callback import(#offline_msg{}) -> ok.
|
||||||
-callback store_messages(binary(), us(), [#offline_msg{}],
|
-callback store_messages(binary(), us(), [#offline_msg{}],
|
||||||
non_neg_integer(), non_neg_integer()) ->
|
non_neg_integer(), non_neg_integer()) ->
|
||||||
{atomic, any()}.
|
{atomic, any()}.
|
||||||
@ -851,13 +852,35 @@ export(LServer) ->
|
|||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
Mod:export(LServer).
|
Mod:export(LServer).
|
||||||
|
|
||||||
import(LServer) ->
|
import_info() ->
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
[{<<"spool">>, 4}].
|
||||||
Mod:import(LServer).
|
|
||||||
|
|
||||||
import(LServer, DBType, Data) ->
|
import_start(LServer, DBType) ->
|
||||||
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||||
Mod:import(LServer, Data).
|
Mod:import(LServer, []).
|
||||||
|
|
||||||
|
import(LServer, {sql, _}, DBType, <<"spool">>,
|
||||||
|
[LUser, XML, _Seq, _TimeStamp]) ->
|
||||||
|
El = fxml_stream:parse_element(XML),
|
||||||
|
From = #jid{} = jid:from_string(
|
||||||
|
fxml:get_attr_s(<<"from">>, El#xmlel.attrs)),
|
||||||
|
To = #jid{} = jid:from_string(
|
||||||
|
fxml:get_attr_s(<<"to">>, El#xmlel.attrs)),
|
||||||
|
Stamp = fxml:get_path_s(El, [{elem, <<"delay">>},
|
||||||
|
{attr, <<"stamp">>}]),
|
||||||
|
TS = case jlib:datetime_string_to_timestamp(Stamp) of
|
||||||
|
{MegaSecs, Secs, _} ->
|
||||||
|
{MegaSecs, Secs, 0};
|
||||||
|
undefined ->
|
||||||
|
p1_time_compat:timestamp()
|
||||||
|
end,
|
||||||
|
US = {LUser, LServer},
|
||||||
|
Expire = find_x_expire(TS, El#xmlel.children),
|
||||||
|
Msg = #offline_msg{us = US, packet = El,
|
||||||
|
from = From, to = To,
|
||||||
|
timestamp = TS, expire = Expire},
|
||||||
|
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||||
|
Mod:import(Msg).
|
||||||
|
|
||||||
mod_opt_type(access_max_user_messages) ->
|
mod_opt_type(access_max_user_messages) ->
|
||||||
fun acl:shaper_rules_validator/1;
|
fun acl:shaper_rules_validator/1;
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
-export([init/2, store_messages/5, pop_messages/2, remove_expired_messages/1,
|
-export([init/2, store_messages/5, pop_messages/2, remove_expired_messages/1,
|
||||||
remove_old_messages/2, remove_user/2, read_message_headers/2,
|
remove_old_messages/2, remove_user/2, read_message_headers/2,
|
||||||
read_message/3, remove_message/3, read_all_messages/2,
|
read_message/3, remove_message/3, read_all_messages/2,
|
||||||
remove_all_messages/2, count_messages/2, import/2]).
|
remove_all_messages/2, count_messages/2, import/1]).
|
||||||
|
|
||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
-include("mod_offline.hrl").
|
-include("mod_offline.hrl").
|
||||||
@ -164,7 +164,7 @@ count_messages(LUser, LServer) ->
|
|||||||
_ -> 0
|
_ -> 0
|
||||||
end.
|
end.
|
||||||
|
|
||||||
import(_LServer, #offline_msg{} = Msg) ->
|
import(#offline_msg{} = Msg) ->
|
||||||
mnesia:dirty_write(Msg).
|
mnesia:dirty_write(Msg).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
|
@ -15,8 +15,7 @@
|
|||||||
-export([init/2, store_messages/5, pop_messages/2, remove_expired_messages/1,
|
-export([init/2, store_messages/5, pop_messages/2, remove_expired_messages/1,
|
||||||
remove_old_messages/2, remove_user/2, read_message_headers/2,
|
remove_old_messages/2, remove_user/2, read_message_headers/2,
|
||||||
read_message/3, remove_message/3, read_all_messages/2,
|
read_message/3, remove_message/3, read_all_messages/2,
|
||||||
remove_all_messages/2, count_messages/2, import/1, import/2,
|
remove_all_messages/2, count_messages/2, import/1, export/1]).
|
||||||
export/1]).
|
|
||||||
|
|
||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
-include("mod_offline.hrl").
|
-include("mod_offline.hrl").
|
||||||
@ -193,29 +192,8 @@ export(_Server) ->
|
|||||||
[]
|
[]
|
||||||
end}].
|
end}].
|
||||||
|
|
||||||
import(LServer) ->
|
import(_) ->
|
||||||
[{<<"select username, xml from spool;">>,
|
ok.
|
||||||
fun([LUser, XML]) ->
|
|
||||||
El = #xmlel{} = fxml_stream:parse_element(XML),
|
|
||||||
#message{} = Pkt = xmpp:decode(El, ?NS_CLIENT, [ignore_els]),
|
|
||||||
From = Pkt#message.from,
|
|
||||||
To = case Pkt#message.to of
|
|
||||||
undefined -> jid:make(LUser, LServer);
|
|
||||||
JID -> JID
|
|
||||||
end,
|
|
||||||
TS = case xmpp:get_subtag(Pkt, #delay{}) of
|
|
||||||
#delay{stamp = Stamp} -> Stamp;
|
|
||||||
false -> p1_time_compat:timestamp()
|
|
||||||
end,
|
|
||||||
Expire = mod_offline:find_x_expire(TS, Pkt),
|
|
||||||
#offline_msg{us = {LUser, LServer},
|
|
||||||
from = From, to = To,
|
|
||||||
packet = El,
|
|
||||||
timestamp = TS, expire = Expire}
|
|
||||||
end}].
|
|
||||||
|
|
||||||
import(_, _) ->
|
|
||||||
pass.
|
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
|
@ -31,11 +31,11 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, stop/1, process_iq/1, export/1, import/1,
|
-export([start/2, stop/1, process_iq/1, export/1, import_info/0,
|
||||||
process_iq_set/3, process_iq_get/3, get_user_list/3,
|
process_iq_set/3, process_iq_get/3, get_user_list/3,
|
||||||
check_packet/6, remove_user/2, encode_list_item/1,
|
check_packet/6, remove_user/2, encode_list_item/1,
|
||||||
is_list_needdb/1, updated_list/3,
|
is_list_needdb/1, updated_list/3,
|
||||||
item_to_xml/1, get_user_lists/2, import/3,
|
item_to_xml/1, get_user_lists/2, import/5,
|
||||||
set_privacy_list/1, mod_opt_type/1, depends/2]).
|
set_privacy_list/1, mod_opt_type/1, depends/2]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
@ -46,7 +46,7 @@
|
|||||||
-include("mod_privacy.hrl").
|
-include("mod_privacy.hrl").
|
||||||
|
|
||||||
-callback init(binary(), gen_mod:opts()) -> any().
|
-callback init(binary(), gen_mod:opts()) -> any().
|
||||||
-callback import(binary(), #privacy{}) -> ok | pass.
|
-callback import(#privacy{}) -> ok.
|
||||||
-callback process_lists_get(binary(), binary()) -> {none | binary(), [binary()]} | error.
|
-callback process_lists_get(binary(), binary()) -> {none | binary(), [binary()]} | error.
|
||||||
-callback process_list_get(binary(), binary(), binary()) -> [listitem()] | error | not_found.
|
-callback process_list_get(binary(), binary(), binary()) -> [listitem()] | error | not_found.
|
||||||
-callback process_default_set(binary(), binary(), binary() | none) -> {atomic, any()}.
|
-callback process_default_set(binary(), binary(), binary() | none) -> {atomic, any()}.
|
||||||
@ -544,18 +544,108 @@ updated_list(_, #userlist{name = OldName} = Old,
|
|||||||
true -> Old
|
true -> Old
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
numeric_to_binary(<<0, 0, _/binary>>) ->
|
||||||
|
<<"0">>;
|
||||||
|
numeric_to_binary(<<0, _, _:6/binary, T/binary>>) ->
|
||||||
|
Res = lists:foldl(
|
||||||
|
fun(X, Sum) ->
|
||||||
|
Sum*10000 + X
|
||||||
|
end, 0, [X || <<X:16>> <= T]),
|
||||||
|
jlib:integer_to_binary(Res).
|
||||||
|
|
||||||
|
bool_to_binary(<<0>>) -> <<"0">>;
|
||||||
|
bool_to_binary(<<1>>) -> <<"1">>.
|
||||||
|
|
||||||
|
prepare_list_data(mysql, [ID|Row]) ->
|
||||||
|
[jlib:binary_to_integer(ID)|Row];
|
||||||
|
prepare_list_data(pgsql, [<<ID:64>>,
|
||||||
|
SType, SValue, SAction, SOrder, SMatchAll,
|
||||||
|
SMatchIQ, SMatchMessage, SMatchPresenceIn,
|
||||||
|
SMatchPresenceOut]) ->
|
||||||
|
[ID, SType, SValue, SAction,
|
||||||
|
numeric_to_binary(SOrder),
|
||||||
|
bool_to_binary(SMatchAll),
|
||||||
|
bool_to_binary(SMatchIQ),
|
||||||
|
bool_to_binary(SMatchMessage),
|
||||||
|
bool_to_binary(SMatchPresenceIn),
|
||||||
|
bool_to_binary(SMatchPresenceOut)].
|
||||||
|
|
||||||
|
prepare_id(mysql, ID) ->
|
||||||
|
jlib:binary_to_integer(ID);
|
||||||
|
prepare_id(pgsql, <<ID:32>>) ->
|
||||||
|
ID.
|
||||||
|
|
||||||
|
import_info() ->
|
||||||
|
[{<<"privacy_default_list">>, 2},
|
||||||
|
{<<"privacy_list_data">>, 10},
|
||||||
|
{<<"privacy_list">>, 4}].
|
||||||
|
|
||||||
|
import_start(LServer, DBType) ->
|
||||||
|
ets:new(privacy_default_list_tmp, [private, named_table]),
|
||||||
|
ets:new(privacy_list_data_tmp, [private, named_table, bag]),
|
||||||
|
ets:new(privacy_list_tmp, [private, named_table, bag,
|
||||||
|
{keypos, #privacy.us}]),
|
||||||
|
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||||
|
Mod:init(LServer, []).
|
||||||
|
|
||||||
|
import(LServer, {sql, _}, _DBType, <<"privacy_default_list">>, [LUser, Name]) ->
|
||||||
|
US = {LUser, LServer},
|
||||||
|
ets:insert(privacy_default_list_tmp, {US, Name}),
|
||||||
|
ok;
|
||||||
|
import(LServer, {sql, SQLType}, _DBType, <<"privacy_list_data">>, Row1) ->
|
||||||
|
[ID|Row] = prepare_list_data(SQLType, Row1),
|
||||||
|
case mod_privacy_sql:raw_to_item(Row) of
|
||||||
|
[Item] ->
|
||||||
|
IS = {ID, LServer},
|
||||||
|
ets:insert(privacy_list_data_tmp, {IS, Item}),
|
||||||
|
ok;
|
||||||
|
[] ->
|
||||||
|
ok
|
||||||
|
end;
|
||||||
|
import(LServer, {sql, SQLType}, _DBType, <<"privacy_list">>,
|
||||||
|
[LUser, Name, ID, _TimeStamp]) ->
|
||||||
|
US = {LUser, LServer},
|
||||||
|
IS = {prepare_id(SQLType, ID), LServer},
|
||||||
|
Default = case ets:lookup(privacy_default_list_tmp, US) of
|
||||||
|
[{_, Name}] -> Name;
|
||||||
|
_ -> none
|
||||||
|
end,
|
||||||
|
case [Item || {_, Item} <- ets:lookup(privacy_list_data_tmp, IS)] of
|
||||||
|
[_|_] = Items ->
|
||||||
|
Privacy = #privacy{us = {LUser, LServer},
|
||||||
|
default = Default,
|
||||||
|
lists = [{Name, Items}]},
|
||||||
|
ets:insert(privacy_list_tmp, Privacy),
|
||||||
|
ets:delete(privacy_list_data_tmp, IS),
|
||||||
|
ok;
|
||||||
|
_ ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
||||||
|
import_stop(_LServer, DBType) ->
|
||||||
|
import_next(DBType, ets:first(privacy_list_tmp)),
|
||||||
|
ets:delete(privacy_default_list_tmp),
|
||||||
|
ets:delete(privacy_list_data_tmp),
|
||||||
|
ets:delete(privacy_list_tmp),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
import_next(_DBType, '$end_of_table') ->
|
||||||
|
ok;
|
||||||
|
import_next(DBType, US) ->
|
||||||
|
[P|_] = Ps = ets:lookup(privacy_list_tmp, US),
|
||||||
|
Lists = lists:flatmap(
|
||||||
|
fun(#privacy{lists = Lists}) ->
|
||||||
|
Lists
|
||||||
|
end, Ps),
|
||||||
|
Privacy = P#privacy{lists = Lists},
|
||||||
|
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||||
|
Mod:import(Privacy),
|
||||||
|
import_next(DBType, ets:next(privacy_list_tmp, US)).
|
||||||
|
|
||||||
export(LServer) ->
|
export(LServer) ->
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
Mod:export(LServer).
|
Mod:export(LServer).
|
||||||
|
|
||||||
import(LServer) ->
|
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
|
||||||
Mod:import(LServer).
|
|
||||||
|
|
||||||
import(LServer, DBType, Data) ->
|
|
||||||
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
|
||||||
Mod:import(LServer, Data).
|
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
process_default_set/3, process_active_set/3,
|
process_default_set/3, process_active_set/3,
|
||||||
remove_privacy_list/3, set_privacy_list/1,
|
remove_privacy_list/3, set_privacy_list/1,
|
||||||
set_privacy_list/4, get_user_list/2, get_user_lists/2,
|
set_privacy_list/4, get_user_list/2, get_user_lists/2,
|
||||||
remove_user/2, import/1, import/2, export/1]).
|
remove_user/2, import/1, export/1]).
|
||||||
|
|
||||||
-export([item_to_raw/1, raw_to_item/1,
|
-export([item_to_raw/1, raw_to_item/1,
|
||||||
sql_add_privacy_list/2,
|
sql_add_privacy_list/2,
|
||||||
@ -249,37 +249,8 @@ get_id() ->
|
|||||||
put(id, ID + 1),
|
put(id, ID + 1),
|
||||||
ID + 1.
|
ID + 1.
|
||||||
|
|
||||||
import(LServer) ->
|
import(_) ->
|
||||||
[{<<"select username from privacy_list;">>,
|
ok.
|
||||||
fun([LUser]) ->
|
|
||||||
Default = case sql_get_default_privacy_list_t(LUser) of
|
|
||||||
{selected, [<<"name">>], []} ->
|
|
||||||
none;
|
|
||||||
{selected, [<<"name">>], [[DefName]]} ->
|
|
||||||
DefName;
|
|
||||||
_ ->
|
|
||||||
none
|
|
||||||
end,
|
|
||||||
{selected, [<<"name">>], Names} =
|
|
||||||
sql_get_privacy_list_names_t(LUser),
|
|
||||||
Lists = lists:flatmap(
|
|
||||||
fun([Name]) ->
|
|
||||||
case sql_get_privacy_list_data_t(LUser, Name) of
|
|
||||||
{selected, _, RItems} ->
|
|
||||||
[{Name,
|
|
||||||
lists:map(fun raw_to_item/1,
|
|
||||||
RItems)}];
|
|
||||||
_ ->
|
|
||||||
[]
|
|
||||||
end
|
|
||||||
end, Names),
|
|
||||||
#privacy{default = Default,
|
|
||||||
us = {LUser, LServer},
|
|
||||||
lists = Lists}
|
|
||||||
end}].
|
|
||||||
|
|
||||||
import(_, _) ->
|
|
||||||
pass.
|
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
|
@ -31,9 +31,9 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, stop/1, process_sm_iq/1, import/3,
|
-export([start/2, stop/1, process_sm_iq/1, import_info/0,
|
||||||
remove_user/2, get_data/2, get_data/3, export/1, import/1,
|
remove_user/2, get_data/2, get_data/3, export/1,
|
||||||
mod_opt_type/1, set_data/3, depends/2]).
|
import/5, import_start/2, mod_opt_type/1, set_data/3, depends/2]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
@ -42,7 +42,7 @@
|
|||||||
-include("mod_private.hrl").
|
-include("mod_private.hrl").
|
||||||
|
|
||||||
-callback init(binary(), gen_mod:opts()) -> any().
|
-callback init(binary(), gen_mod:opts()) -> any().
|
||||||
-callback import(binary(), #private_storage{}) -> ok | pass.
|
-callback import(binary(), binary(), [binary()]) -> ok.
|
||||||
-callback set_data(binary(), binary(), [{binary(), xmlel()}]) -> {atomic, any()}.
|
-callback set_data(binary(), binary(), [{binary(), xmlel()}]) -> {atomic, any()}.
|
||||||
-callback get_data(binary(), binary(), binary()) -> {ok, xmlel()} | error.
|
-callback get_data(binary(), binary(), binary()) -> {ok, xmlel()} | error.
|
||||||
-callback get_all_data(binary(), binary()) -> [xmlel()].
|
-callback get_all_data(binary(), binary()) -> [xmlel()].
|
||||||
@ -124,17 +124,20 @@ remove_user(User, Server) ->
|
|||||||
Mod = gen_mod:db_mod(Server, ?MODULE),
|
Mod = gen_mod:db_mod(Server, ?MODULE),
|
||||||
Mod:remove_user(LUser, LServer).
|
Mod:remove_user(LUser, LServer).
|
||||||
|
|
||||||
|
import_info() ->
|
||||||
|
[{<<"private_storage">>, 4}].
|
||||||
|
|
||||||
|
import_start(LServer, DBType) ->
|
||||||
|
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||||
|
Mod:init(LServer, []).
|
||||||
|
|
||||||
export(LServer) ->
|
export(LServer) ->
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
Mod:export(LServer).
|
Mod:export(LServer).
|
||||||
|
|
||||||
import(LServer) ->
|
import(LServer, {sql, _}, DBType, Tab, L) ->
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
|
||||||
Mod:import(LServer).
|
|
||||||
|
|
||||||
import(LServer, DBType, PD) ->
|
|
||||||
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||||
Mod:import(LServer, PD).
|
Mod:import(LServer, Tab, L).
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([init/2, set_data/3, get_data/3, get_all_data/2, remove_user/2,
|
-export([init/2, set_data/3, get_data/3, get_all_data/2, remove_user/2,
|
||||||
import/2]).
|
import/3]).
|
||||||
|
|
||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
-include("mod_private.hrl").
|
-include("mod_private.hrl").
|
||||||
@ -72,7 +72,10 @@ remove_user(LUser, LServer) ->
|
|||||||
end,
|
end,
|
||||||
mnesia:transaction(F).
|
mnesia:transaction(F).
|
||||||
|
|
||||||
import(_LServer, #private_storage{} = PS) ->
|
import(LServer, <<"private_storage">>,
|
||||||
|
[LUser, XMLNS, XML, _TimeStamp]) ->
|
||||||
|
El = #xmlel{} = fxml_stream:parse_element(XML),
|
||||||
|
PS = #private_storage{usns = {LUser, LServer, XMLNS}, xml = El},
|
||||||
mnesia:dirty_write(PS).
|
mnesia:dirty_write(PS).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([init/2, set_data/3, get_data/3, get_all_data/2, remove_user/2,
|
-export([init/2, set_data/3, get_data/3, get_all_data/2, remove_user/2,
|
||||||
import/2]).
|
import/3]).
|
||||||
|
|
||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
-include("mod_private.hrl").
|
-include("mod_private.hrl").
|
||||||
@ -56,7 +56,10 @@ remove_user(LUser, LServer) ->
|
|||||||
{atomic, ejabberd_riak:delete_by_index(private_storage,
|
{atomic, ejabberd_riak:delete_by_index(private_storage,
|
||||||
<<"us">>, {LUser, LServer})}.
|
<<"us">>, {LUser, LServer})}.
|
||||||
|
|
||||||
import(_LServer, #private_storage{usns = {LUser, LServer, _}} = PS) ->
|
import(LServer, <<"private_storage">>,
|
||||||
|
[LUser, XMLNS, XML, _TimeStamp]) ->
|
||||||
|
El = #xmlel{} = fxml_stream:parse_element(XML),
|
||||||
|
PS = #private_storage{usns = {LUser, LServer, XMLNS}, xml = El},
|
||||||
ejabberd_riak:put(PS, private_storage_schema(),
|
ejabberd_riak:put(PS, private_storage_schema(),
|
||||||
[{'2i', [{<<"us">>, {LUser, LServer}}]}]).
|
[{'2i', [{<<"us">>, {LUser, LServer}}]}]).
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([init/2, set_data/3, get_data/3, get_all_data/2, remove_user/2,
|
-export([init/2, set_data/3, get_data/3, get_all_data/2, remove_user/2,
|
||||||
import/1, import/2, export/1]).
|
import/3, export/1]).
|
||||||
|
|
||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
-include("mod_private.hrl").
|
-include("mod_private.hrl").
|
||||||
@ -77,16 +77,8 @@ export(_Server) ->
|
|||||||
[]
|
[]
|
||||||
end}].
|
end}].
|
||||||
|
|
||||||
import(LServer) ->
|
import(_, _, _) ->
|
||||||
[{<<"select username, namespace, data from private_storage;">>,
|
ok.
|
||||||
fun([LUser, XMLNS, XML]) ->
|
|
||||||
El = #xmlel{} = fxml_stream:parse_element(XML),
|
|
||||||
#private_storage{usns = {LUser, LServer, XMLNS},
|
|
||||||
xml = El}
|
|
||||||
end}].
|
|
||||||
|
|
||||||
import(_, _) ->
|
|
||||||
pass.
|
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
|
@ -42,8 +42,9 @@
|
|||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, stop/1, process_iq/1, export/1,
|
-export([start/2, stop/1, process_iq/1, export/1,
|
||||||
import/1, process_local_iq/1, get_user_roster/2,
|
import_info/0, process_local_iq/1, get_user_roster/2,
|
||||||
import/3, get_subscription_lists/3, get_roster/2,
|
import/5, get_subscription_lists/3, get_roster/2,
|
||||||
|
import_start/2, import_stop/2,
|
||||||
get_in_pending_subscriptions/3, in_subscription/6,
|
get_in_pending_subscriptions/3, in_subscription/6,
|
||||||
out_subscription/4, set_items/3, remove_user/2,
|
out_subscription/4, set_items/3, remove_user/2,
|
||||||
get_jid_info/4, encode_item/1, webadmin_page/3,
|
get_jid_info/4, encode_item/1, webadmin_page/3,
|
||||||
@ -65,7 +66,7 @@
|
|||||||
-export_type([subscription/0]).
|
-export_type([subscription/0]).
|
||||||
|
|
||||||
-callback init(binary(), gen_mod:opts()) -> any().
|
-callback init(binary(), gen_mod:opts()) -> any().
|
||||||
-callback import(binary(), #roster{} | #roster_version{}) -> ok | pass.
|
-callback import(binary(), binary(), #roster{} | [binary()]) -> ok.
|
||||||
-callback read_roster_version(binary(), binary()) -> binary() | error.
|
-callback read_roster_version(binary(), binary()) -> binary() | error.
|
||||||
-callback write_roster_version(binary(), binary(), boolean(), binary()) -> any().
|
-callback write_roster_version(binary(), binary(), boolean(), binary()) -> any().
|
||||||
-callback get_roster(binary(), binary()) -> [#roster{}].
|
-callback get_roster(binary(), binary()) -> [#roster{}].
|
||||||
@ -1022,13 +1023,34 @@ export(LServer) ->
|
|||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
Mod:export(LServer).
|
Mod:export(LServer).
|
||||||
|
|
||||||
import(LServer) ->
|
import_info() ->
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
[{<<"roster_version">>, 2},
|
||||||
Mod:import(LServer).
|
{<<"rostergroups">>, 3},
|
||||||
|
{<<"rosterusers">>, 10}].
|
||||||
|
|
||||||
import(LServer, DBType, R) ->
|
import_start(LServer, DBType) ->
|
||||||
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||||
Mod:import(LServer, R).
|
ets:new(rostergroups_tmp, [private, named_table, bag]),
|
||||||
|
Mod:init(LServer, []),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
import_stop(_LServer, _DBType) ->
|
||||||
|
ets:delete(rostergroups_tmp),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
import(LServer, {sql, _}, _DBType, <<"rostergroups">>, [LUser, SJID, Group]) ->
|
||||||
|
LJID = jid:tolower(jid:from_string(SJID)),
|
||||||
|
ets:insert(rostergroups_tmp, {{LUser, LServer, LJID}, Group}),
|
||||||
|
ok;
|
||||||
|
import(LServer, {sql, _}, DBType, <<"rosterusers">>, Row) ->
|
||||||
|
I = mod_roster_sql:raw_to_record(LServer, lists:sublist(Row, 9)),
|
||||||
|
Groups = [G || {_, G} <- ets:lookup(rostergroups_tmp, I#roster.usj)],
|
||||||
|
RosterItem = I#roster{groups = Groups},
|
||||||
|
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||||
|
Mod:import(LServer, <<"rosterusers">>, RosterItem);
|
||||||
|
import(LServer, {sql, _}, DBType, <<"roster_version">>, [LUser, Ver]) ->
|
||||||
|
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||||
|
Mod:import(LServer, <<"roster_version">>, [LUser, Ver]).
|
||||||
|
|
||||||
mod_opt_type(access) ->
|
mod_opt_type(access) ->
|
||||||
fun acl:access_rules_validator/1;
|
fun acl:access_rules_validator/1;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
get_roster/2, get_roster_by_jid/3, get_only_items/2,
|
get_roster/2, get_roster_by_jid/3, get_only_items/2,
|
||||||
roster_subscribe/4, get_roster_by_jid_with_groups/3,
|
roster_subscribe/4, get_roster_by_jid_with_groups/3,
|
||||||
remove_user/2, update_roster/4, del_roster/3, transaction/2,
|
remove_user/2, update_roster/4, del_roster/3, transaction/2,
|
||||||
read_subscription_and_groups/3, import/2]).
|
read_subscription_and_groups/3, import/3, create_roster/1]).
|
||||||
|
|
||||||
-include("mod_roster.hrl").
|
-include("mod_roster.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
@ -51,7 +51,7 @@ write_roster_version(LUser, LServer, InTransaction, Ver) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
get_roster(LUser, LServer) ->
|
get_roster(LUser, LServer) ->
|
||||||
mnesia:dirty_index_read(roster, {LUser, LServer}, #roster.us).
|
{ok, mnesia:dirty_index_read(roster, {LUser, LServer}, #roster.us)}.
|
||||||
|
|
||||||
get_roster_by_jid(LUser, LServer, LJID) ->
|
get_roster_by_jid(LUser, LServer, LJID) ->
|
||||||
case mnesia:read({roster, {LUser, LServer, LJID}}) of
|
case mnesia:read({roster, {LUser, LServer, LJID}}) of
|
||||||
@ -103,9 +103,13 @@ read_subscription_and_groups(LUser, LServer, LJID) ->
|
|||||||
transaction(_LServer, F) ->
|
transaction(_LServer, F) ->
|
||||||
mnesia:transaction(F).
|
mnesia:transaction(F).
|
||||||
|
|
||||||
import(_LServer, #roster{} = R) ->
|
create_roster(RItem) ->
|
||||||
|
mnesia:dirty_write(RItem).
|
||||||
|
|
||||||
|
import(_LServer, <<"rosterusers">>, #roster{} = R) ->
|
||||||
mnesia:dirty_write(R);
|
mnesia:dirty_write(R);
|
||||||
import(_LServer, #roster_version{} = RV) ->
|
import(LServer, <<"roster_version">>, [LUser, Ver]) ->
|
||||||
|
RV = #roster_version{us = {LUser, LServer}, version = Ver},
|
||||||
mnesia:dirty_write(RV).
|
mnesia:dirty_write(RV).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
|
@ -13,10 +13,10 @@
|
|||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([init/2, read_roster_version/2, write_roster_version/4,
|
-export([init/2, read_roster_version/2, write_roster_version/4,
|
||||||
get_roster/2, get_roster_by_jid/3,
|
get_roster/2, get_roster_by_jid/3, create_roster/1,
|
||||||
roster_subscribe/4, get_roster_by_jid_with_groups/3,
|
roster_subscribe/4, get_roster_by_jid_with_groups/3,
|
||||||
remove_user/2, update_roster/4, del_roster/3, transaction/2,
|
remove_user/2, update_roster/4, del_roster/3, transaction/2,
|
||||||
read_subscription_and_groups/3, get_only_items/2, import/2]).
|
read_subscription_and_groups/3, get_only_items/2, import/3]).
|
||||||
|
|
||||||
-include("mod_roster.hrl").
|
-include("mod_roster.hrl").
|
||||||
|
|
||||||
@ -41,8 +41,8 @@ write_roster_version(LUser, LServer, _InTransaction, Ver) ->
|
|||||||
get_roster(LUser, LServer) ->
|
get_roster(LUser, LServer) ->
|
||||||
case ejabberd_riak:get_by_index(roster, roster_schema(),
|
case ejabberd_riak:get_by_index(roster, roster_schema(),
|
||||||
<<"us">>, {LUser, LServer}) of
|
<<"us">>, {LUser, LServer}) of
|
||||||
{ok, Items} -> Items;
|
{ok, Items} -> {ok, Items};
|
||||||
_Err -> []
|
_Err -> error
|
||||||
end.
|
end.
|
||||||
|
|
||||||
get_roster_by_jid(LUser, LServer, LJID) ->
|
get_roster_by_jid(LUser, LServer, LJID) ->
|
||||||
@ -96,10 +96,17 @@ read_subscription_and_groups(LUser, LServer, LJID) ->
|
|||||||
error
|
error
|
||||||
end.
|
end.
|
||||||
|
|
||||||
import(_LServer, #roster{us = {LUser, LServer}} = R) ->
|
create_roster(#roster{us = {LUser, LServer}} = RItem) ->
|
||||||
ejabberd_riak:put(R, roster_schema(),
|
ejabberd_riak:put(
|
||||||
|
RItem, roster_schema(),
|
||||||
|
[{'2i', [{<<"us">>, {LUser, LServer}}]}]).
|
||||||
|
|
||||||
|
import(_LServer, <<"rosterusers">>, RosterItem) ->
|
||||||
|
{LUser, LServer} = RosterItem#roster.us,
|
||||||
|
ejabberd_riak:put(RosterItem, roster_schema(),
|
||||||
[{'2i', [{<<"us">>, {LUser, LServer}}]}]);
|
[{'2i', [{<<"us">>, {LUser, LServer}}]}]);
|
||||||
import(_LServer, #roster_version{} = RV) ->
|
import(LServer, <<"roster_version">>, [LUser, Ver]) ->
|
||||||
|
RV = #roster_version{us = {LUser, LServer}, version = Ver},
|
||||||
ejabberd_riak:put(RV, roster_version_schema()).
|
ejabberd_riak:put(RV, roster_version_schema()).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
roster_subscribe/4, get_roster_by_jid_with_groups/3,
|
roster_subscribe/4, get_roster_by_jid_with_groups/3,
|
||||||
remove_user/2, update_roster/4, del_roster/3, transaction/2,
|
remove_user/2, update_roster/4, del_roster/3, transaction/2,
|
||||||
read_subscription_and_groups/3, get_only_items/2,
|
read_subscription_and_groups/3, get_only_items/2,
|
||||||
import/1, import/2, export/1]).
|
import/3, export/1]).
|
||||||
|
|
||||||
-include("mod_roster.hrl").
|
-include("mod_roster.hrl").
|
||||||
-include("ejabberd_sql_pt.hrl").
|
-include("ejabberd_sql_pt.hrl").
|
||||||
@ -185,27 +185,8 @@ export(_Server) ->
|
|||||||
[]
|
[]
|
||||||
end}].
|
end}].
|
||||||
|
|
||||||
import(LServer) ->
|
import(_, _, _) ->
|
||||||
[{<<"select username, jid, nick, subscription, "
|
ok.
|
||||||
"ask, askmessage, server, subscribe, type from rosterusers;">>,
|
|
||||||
fun([LUser, JID|_] = Row) ->
|
|
||||||
Item = raw_to_record(LServer, Row),
|
|
||||||
Username = ejabberd_sql:escape(LUser),
|
|
||||||
SJID = ejabberd_sql:escape(JID),
|
|
||||||
{selected, _, Rows} =
|
|
||||||
ejabberd_sql:sql_query_t(
|
|
||||||
[<<"select grp from rostergroups where username='">>,
|
|
||||||
Username, <<"' and jid='">>, SJID, <<"'">>]),
|
|
||||||
Groups = [Grp || [Grp] <- Rows],
|
|
||||||
Item#roster{groups = Groups}
|
|
||||||
end},
|
|
||||||
{<<"select username, version from roster_version;">>,
|
|
||||||
fun([LUser, Ver]) ->
|
|
||||||
#roster_version{us = {LUser, LServer}, version = Ver}
|
|
||||||
end}].
|
|
||||||
|
|
||||||
import(_, _) ->
|
|
||||||
pass.
|
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
|
@ -30,9 +30,9 @@
|
|||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, stop/1, export/1,
|
-export([start/2, stop/1, export/1,
|
||||||
import/1, webadmin_menu/3, webadmin_page/3,
|
import_info/0, webadmin_menu/3, webadmin_page/3,
|
||||||
get_user_roster/2, get_subscription_lists/3,
|
get_user_roster/2, get_subscription_lists/3,
|
||||||
get_jid_info/4, import/3, process_item/2,
|
get_jid_info/4, import/5, process_item/2, import_start/2,
|
||||||
in_subscription/6, out_subscription/4, user_available/1,
|
in_subscription/6, out_subscription/4, user_available/1,
|
||||||
unset_presence/4, register_user/2, remove_user/2,
|
unset_presence/4, register_user/2, remove_user/2,
|
||||||
list_groups/1, create_group/2, create_group/3,
|
list_groups/1, create_group/2, create_group/3,
|
||||||
@ -56,7 +56,7 @@
|
|||||||
|
|
||||||
-type group_options() :: [{atom(), any()}].
|
-type group_options() :: [{atom(), any()}].
|
||||||
-callback init(binary(), gen_mod:opts()) -> any().
|
-callback init(binary(), gen_mod:opts()) -> any().
|
||||||
-callback import(binary(), #sr_user{} | #sr_group{}) -> ok | pass.
|
-callback import(binary(), binary(), [binary()]) -> ok.
|
||||||
-callback list_groups(binary()) -> [binary()].
|
-callback list_groups(binary()) -> [binary()].
|
||||||
-callback groups_with_opts(binary()) -> [{binary(), group_options()}].
|
-callback groups_with_opts(binary()) -> [{binary(), group_options()}].
|
||||||
-callback create_group(binary(), binary(), group_options()) -> {atomic, any()}.
|
-callback create_group(binary(), binary(), group_options()) -> {atomic, any()}.
|
||||||
@ -1072,13 +1072,16 @@ export(LServer) ->
|
|||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
Mod:export(LServer).
|
Mod:export(LServer).
|
||||||
|
|
||||||
import(LServer) ->
|
import_info() ->
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
[{<<"sr_group">>, 3}, {<<"sr_user">>, 3}].
|
||||||
Mod:import(LServer).
|
|
||||||
|
|
||||||
import(LServer, DBType, Data) ->
|
import_start(LServer, DBType) ->
|
||||||
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||||
Mod:import(LServer, Data).
|
Mod:init(LServer, []).
|
||||||
|
|
||||||
|
import(LServer, {sql, _}, DBType, Tab, L) ->
|
||||||
|
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||||
|
Mod:import(LServer, Tab, L).
|
||||||
|
|
||||||
mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end;
|
mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end;
|
||||||
mod_opt_type(_) -> [db_type].
|
mod_opt_type(_) -> [db_type].
|
||||||
|
@ -15,11 +15,12 @@
|
|||||||
delete_group/2, get_group_opts/2, set_group_opts/3,
|
delete_group/2, get_group_opts/2, set_group_opts/3,
|
||||||
get_user_groups/2, get_group_explicit_users/2,
|
get_user_groups/2, get_group_explicit_users/2,
|
||||||
get_user_displayed_groups/3, is_user_in_group/3,
|
get_user_displayed_groups/3, is_user_in_group/3,
|
||||||
add_user_to_group/3, remove_user_from_group/3, import/2]).
|
add_user_to_group/3, remove_user_from_group/3, import/3]).
|
||||||
|
|
||||||
-include("mod_roster.hrl").
|
-include("mod_roster.hrl").
|
||||||
-include("mod_shared_roster.hrl").
|
-include("mod_shared_roster.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
|
-include("xmpp.hrl").
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% API
|
%%% API
|
||||||
@ -118,10 +119,14 @@ remove_user_from_group(Host, US, Group) ->
|
|||||||
F = fun () -> mnesia:delete_object(R) end,
|
F = fun () -> mnesia:delete_object(R) end,
|
||||||
mnesia:transaction(F).
|
mnesia:transaction(F).
|
||||||
|
|
||||||
import(_LServer, #sr_group{} = G) ->
|
import(LServer, <<"sr_group">>, [Group, SOpts, _TimeStamp]) ->
|
||||||
|
G = #sr_group{group_host = {Group, LServer},
|
||||||
|
opts = ejabberd_sql:decode_term(SOpts)},
|
||||||
mnesia:dirty_write(G);
|
mnesia:dirty_write(G);
|
||||||
import(_LServer, #sr_user{} = U) ->
|
import(LServer, <<"sr_user">>, [SJID, Group, _TimeStamp]) ->
|
||||||
mnesia:dirty_write(U).
|
#jid{luser = U, lserver = S} = jid:from_string(SJID),
|
||||||
|
User = #sr_user{us = {U, S}, group_host = {Group, LServer}},
|
||||||
|
mnesia:dirty_write(User).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
|
@ -15,10 +15,11 @@
|
|||||||
delete_group/2, get_group_opts/2, set_group_opts/3,
|
delete_group/2, get_group_opts/2, set_group_opts/3,
|
||||||
get_user_groups/2, get_group_explicit_users/2,
|
get_user_groups/2, get_group_explicit_users/2,
|
||||||
get_user_displayed_groups/3, is_user_in_group/3,
|
get_user_displayed_groups/3, is_user_in_group/3,
|
||||||
add_user_to_group/3, remove_user_from_group/3, import/2]).
|
add_user_to_group/3, remove_user_from_group/3, import/3]).
|
||||||
|
|
||||||
-include("mod_roster.hrl").
|
-include("mod_roster.hrl").
|
||||||
-include("mod_shared_roster.hrl").
|
-include("mod_shared_roster.hrl").
|
||||||
|
-include("xmpp.hrl").
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% API
|
%%% API
|
||||||
@ -120,13 +121,17 @@ add_user_to_group(Host, US, Group) ->
|
|||||||
remove_user_from_group(Host, US, Group) ->
|
remove_user_from_group(Host, US, Group) ->
|
||||||
{atomic, ejabberd_riak:delete(sr_group, {US, {Group, Host}})}.
|
{atomic, ejabberd_riak:delete(sr_group, {US, {Group, Host}})}.
|
||||||
|
|
||||||
import(_LServer, #sr_group{group_host = {_, Host}} = G) ->
|
import(LServer, <<"sr_group">>, [Group, SOpts, _TimeStamp]) ->
|
||||||
ejabberd_riak:put(G, sr_group_schema(), [{'2i', [{<<"host">>, Host}]}]);
|
G = #sr_group{group_host = {Group, LServer},
|
||||||
import(_LServer, #sr_user{us = US, group_host = {Group, Host}} = User) ->
|
opts = ejabberd_sql:decode_term(SOpts)},
|
||||||
|
ejabberd_riak:put(G, sr_group_schema(), [{'2i', [{<<"host">>, LServer}]}]);
|
||||||
|
import(LServer, <<"sr_user">>, [SJID, Group|_]) ->
|
||||||
|
#jid{luser = U, lserver = S} = jid:from_string(SJID),
|
||||||
|
User = #sr_user{us = {U, S}, group_host = {Group, LServer}},
|
||||||
ejabberd_riak:put(User, sr_user_schema(),
|
ejabberd_riak:put(User, sr_user_schema(),
|
||||||
[{i, {US, {Group, Host}}},
|
[{i, {{U, S}, {Group, LServer}}},
|
||||||
{'2i', [{<<"us">>, US},
|
{'2i', [{<<"us">>, {U, S}},
|
||||||
{<<"group_host">>, {Group, Host}}]}]).
|
{<<"group_host">>, {Group, LServer}}]}]).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
delete_group/2, get_group_opts/2, set_group_opts/3,
|
delete_group/2, get_group_opts/2, set_group_opts/3,
|
||||||
get_user_groups/2, get_group_explicit_users/2,
|
get_user_groups/2, get_group_explicit_users/2,
|
||||||
get_user_displayed_groups/3, is_user_in_group/3,
|
get_user_displayed_groups/3, is_user_in_group/3,
|
||||||
add_user_to_group/3, remove_user_from_group/3, import/1,
|
add_user_to_group/3, remove_user_from_group/3, import/3,
|
||||||
import/2, export/1]).
|
export/1]).
|
||||||
|
|
||||||
-include("jid.hrl").
|
-include("jid.hrl").
|
||||||
-include("mod_roster.hrl").
|
-include("mod_roster.hrl").
|
||||||
@ -177,20 +177,8 @@ export(_Server) ->
|
|||||||
[]
|
[]
|
||||||
end}].
|
end}].
|
||||||
|
|
||||||
import(LServer) ->
|
import(_, _, _) ->
|
||||||
[{<<"select name, opts from sr_group;">>,
|
ok.
|
||||||
fun([Group, SOpts]) ->
|
|
||||||
#sr_group{group_host = {Group, LServer},
|
|
||||||
opts = ejabberd_sql: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
|
%%% Internal functions
|
||||||
|
@ -34,8 +34,8 @@
|
|||||||
|
|
||||||
-export([start/2, init/3, stop/1, get_sm_features/5,
|
-export([start/2, init/3, stop/1, get_sm_features/5,
|
||||||
process_local_iq/1, process_sm_iq/1, string2lower/1,
|
process_local_iq/1, process_sm_iq/1, string2lower/1,
|
||||||
remove_user/2, export/1, import/1, import/3, depends/2,
|
remove_user/2, export/1, import_info/0, import/5, import_start/2,
|
||||||
process_search/1, process_vcard/1, get_vcard/2,
|
depends/2, process_search/1, process_vcard/1, get_vcard/2,
|
||||||
disco_items/5, disco_features/5, disco_identity/5,
|
disco_items/5, disco_features/5, disco_identity/5,
|
||||||
decode_iq_subel/1, mod_opt_type/1, set_vcard/3, make_vcard_search/4]).
|
decode_iq_subel/1, mod_opt_type/1, set_vcard/3, make_vcard_search/4]).
|
||||||
|
|
||||||
@ -50,7 +50,7 @@
|
|||||||
|
|
||||||
-callback init(binary(), gen_mod:opts()) -> any().
|
-callback init(binary(), gen_mod:opts()) -> any().
|
||||||
-callback stop(binary()) -> any().
|
-callback stop(binary()) -> any().
|
||||||
-callback import(binary(), #vcard{} | #vcard_search{}) -> ok | pass.
|
-callback import(binary(), binary(), [binary()]) -> ok.
|
||||||
-callback get_vcard(binary(), binary()) -> [xmlel()] | error.
|
-callback get_vcard(binary(), binary()) -> [xmlel()] | error.
|
||||||
-callback set_vcard(binary(), binary(),
|
-callback set_vcard(binary(), binary(),
|
||||||
xmlel(), #vcard_search{}) -> {atomic, any()}.
|
xmlel(), #vcard_search{}) -> {atomic, any()}.
|
||||||
@ -59,6 +59,7 @@
|
|||||||
-callback search(binary(), [{binary(), [binary()]}], boolean(),
|
-callback search(binary(), [{binary(), [binary()]}], boolean(),
|
||||||
infinity | pos_integer()) -> [{binary(), binary()}].
|
infinity | pos_integer()) -> [{binary(), binary()}].
|
||||||
-callback remove_user(binary(), binary()) -> {atomic, any()}.
|
-callback remove_user(binary(), binary()) -> {atomic, any()}.
|
||||||
|
-callback is_search_supported(binary()) -> boolean().
|
||||||
|
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
||||||
@ -105,6 +106,15 @@ init(Host, ServerHost, Search) ->
|
|||||||
false -> loop(Host, ServerHost);
|
false -> loop(Host, ServerHost);
|
||||||
_ ->
|
_ ->
|
||||||
ejabberd_router:register_route(Host, ServerHost),
|
ejabberd_router:register_route(Host, ServerHost),
|
||||||
|
Mod = gen_mod:db_mod(ServerHost, ?MODULE),
|
||||||
|
case Mod:is_search_supported(ServerHost) of
|
||||||
|
false ->
|
||||||
|
?WARNING_MSG("vcard search functionality is "
|
||||||
|
"not implemented for ~s backend",
|
||||||
|
[gen_mod:db_type(ServerHost, ?MODULE)]);
|
||||||
|
true ->
|
||||||
|
ejabberd_router:register_route(Host, ServerHost)
|
||||||
|
end,
|
||||||
loop(Host, ServerHost)
|
loop(Host, ServerHost)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
@ -438,18 +448,21 @@ remove_user(User, Server) ->
|
|||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
Mod:remove_user(LUser, LServer).
|
Mod:remove_user(LUser, LServer).
|
||||||
|
|
||||||
|
import_info() ->
|
||||||
|
[{<<"vcard">>, 3}, {<<"vcard_search">>, 24}].
|
||||||
|
|
||||||
|
import_start(LServer, DBType) ->
|
||||||
|
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||||
|
Mod:init(LServer, []).
|
||||||
|
|
||||||
|
import(LServer, {sql, _}, DBType, Tab, L) ->
|
||||||
|
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||||
|
Mod:import(LServer, Tab, L).
|
||||||
|
|
||||||
export(LServer) ->
|
export(LServer) ->
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
Mod:export(LServer).
|
Mod:export(LServer).
|
||||||
|
|
||||||
import(LServer) ->
|
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
|
||||||
Mod:import(LServer).
|
|
||||||
|
|
||||||
import(LServer, DBType, VCard) ->
|
|
||||||
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
|
||||||
Mod:import(LServer, VCard).
|
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
|
@ -11,8 +11,9 @@
|
|||||||
-behaviour(mod_vcard).
|
-behaviour(mod_vcard).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([init/2, stop/1, import/2, get_vcard/2, set_vcard/4, search/4,
|
-export([init/2, stop/1, import/3, get_vcard/2, set_vcard/4, search/4,
|
||||||
search_fields/1, search_reported/1, remove_user/2]).
|
search_fields/1, search_reported/1, remove_user/2]).
|
||||||
|
-export([is_search_supported/1]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
@ -47,6 +48,9 @@ init(_Host, _Opts) ->
|
|||||||
stop(_Host) ->
|
stop(_Host) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
is_search_supported(_ServerHost) ->
|
||||||
|
true.
|
||||||
|
|
||||||
get_vcard(LUser, LServer) ->
|
get_vcard(LUser, LServer) ->
|
||||||
US = {LUser, LServer},
|
US = {LUser, LServer},
|
||||||
F = fun () -> mnesia:read({vcard, US}) end,
|
F = fun () -> mnesia:read({vcard, US}) end,
|
||||||
@ -121,10 +125,29 @@ remove_user(LUser, LServer) ->
|
|||||||
end,
|
end,
|
||||||
mnesia:transaction(F).
|
mnesia:transaction(F).
|
||||||
|
|
||||||
import(_LServer, #vcard{} = VCard) ->
|
import(LServer, <<"vcard">>, [LUser, XML, _TimeStamp]) ->
|
||||||
|
#xmlel{} = El = fxml_stream:parse_element(XML),
|
||||||
|
VCard = #vcard{us = {LUser, LServer}, vcard = El},
|
||||||
mnesia:dirty_write(VCard);
|
mnesia:dirty_write(VCard);
|
||||||
import(_LServer, #vcard_search{} = S) ->
|
import(LServer, <<"vcard_search">>,
|
||||||
mnesia:dirty_write(S).
|
[User, LUser, FN, LFN,
|
||||||
|
Family, LFamily, Given, LGiven,
|
||||||
|
Middle, LMiddle, Nickname, LNickname,
|
||||||
|
BDay, LBDay, CTRY, LCTRY, Locality, LLocality,
|
||||||
|
EMail, LEMail, OrgName, LOrgName, OrgUnit, LOrgUnit]) ->
|
||||||
|
mnesia:dirty_write(
|
||||||
|
#vcard_search{us = {LUser, LServer},
|
||||||
|
user = {User, LServer}, luser = LUser,
|
||||||
|
fn = FN, lfn = LFN, family = Family,
|
||||||
|
lfamily = LFamily, given = Given,
|
||||||
|
lgiven = LGiven, middle = Middle,
|
||||||
|
lmiddle = LMiddle, nickname = Nickname,
|
||||||
|
lnickname = LNickname, bday = BDay,
|
||||||
|
lbday = LBDay, ctry = CTRY, lctry = LCTRY,
|
||||||
|
locality = Locality, llocality = LLocality,
|
||||||
|
email = EMail, lemail = LEMail,
|
||||||
|
orgname = OrgName, lorgname = LOrgName,
|
||||||
|
orgunit = OrgUnit, lorgunit = LOrgUnit}).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([init/2, get_vcard/2, set_vcard/4, search/4, remove_user/2,
|
-export([init/2, get_vcard/2, set_vcard/4, search/4, remove_user/2,
|
||||||
search_fields/1, search_reported/1, import/2, stop/1]).
|
search_fields/1, search_reported/1, import/3, stop/1]).
|
||||||
|
-export([is_search_supported/1]).
|
||||||
|
|
||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
-include("mod_vcard.hrl").
|
-include("mod_vcard.hrl").
|
||||||
@ -26,6 +27,9 @@ init(_Host, _Opts) ->
|
|||||||
stop(_Host) ->
|
stop(_Host) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
is_search_supported(_LServer) ->
|
||||||
|
false.
|
||||||
|
|
||||||
get_vcard(LUser, LServer) ->
|
get_vcard(LUser, LServer) ->
|
||||||
case ejabberd_riak:get(vcard, vcard_schema(), {LUser, LServer}) of
|
case ejabberd_riak:get(vcard, vcard_schema(), {LUser, LServer}) of
|
||||||
{ok, R} ->
|
{ok, R} ->
|
||||||
@ -101,7 +105,9 @@ search_reported(_LServer) ->
|
|||||||
remove_user(LUser, LServer) ->
|
remove_user(LUser, LServer) ->
|
||||||
{atomic, ejabberd_riak:delete(vcard, {LUser, LServer})}.
|
{atomic, ejabberd_riak:delete(vcard, {LUser, LServer})}.
|
||||||
|
|
||||||
import(_LServer, #vcard{us = {LUser, LServer}, vcard = El} = VCard) ->
|
import(LServer, <<"vcard">>, [LUser, XML, _TimeStamp]) ->
|
||||||
|
El = fxml_stream:parse_element(XML),
|
||||||
|
VCard = #vcard{us = {LUser, LServer}, vcard = El},
|
||||||
#vcard_search{fn = FN,
|
#vcard_search{fn = FN,
|
||||||
lfn = LFN,
|
lfn = LFN,
|
||||||
family = Family,
|
family = Family,
|
||||||
@ -150,7 +156,7 @@ import(_LServer, #vcard{us = {LUser, LServer}, vcard = El} = VCard) ->
|
|||||||
{<<"lorgname">>, LOrgName},
|
{<<"lorgname">>, LOrgName},
|
||||||
{<<"orgunit">>, OrgUnit},
|
{<<"orgunit">>, OrgUnit},
|
||||||
{<<"lorgunit">>, LOrgUnit}]}]);
|
{<<"lorgunit">>, LOrgUnit}]}]);
|
||||||
import(_LServer, #vcard_search{}) ->
|
import(_LServer, <<"vcard_search">>, _) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
|
@ -14,7 +14,8 @@
|
|||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([init/2, stop/1, get_vcard/2, set_vcard/4, search/4, remove_user/2,
|
-export([init/2, stop/1, get_vcard/2, set_vcard/4, search/4, remove_user/2,
|
||||||
search_fields/1, search_reported/1, import/1, import/2, export/1]).
|
search_fields/1, search_reported/1, import/3, export/1]).
|
||||||
|
-export([is_search_supported/1]).
|
||||||
|
|
||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
-include("mod_vcard.hrl").
|
-include("mod_vcard.hrl").
|
||||||
@ -30,6 +31,9 @@ init(_Host, _Opts) ->
|
|||||||
stop(_Host) ->
|
stop(_Host) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
is_search_supported(_LServer) ->
|
||||||
|
true.
|
||||||
|
|
||||||
get_vcard(LUser, LServer) ->
|
get_vcard(LUser, LServer) ->
|
||||||
case catch sql_queries:get_vcard(LServer, LUser) of
|
case catch sql_queries:get_vcard(LServer, LUser) of
|
||||||
{selected, [{SVCARD}]} ->
|
{selected, [{SVCARD}]} ->
|
||||||
@ -188,37 +192,8 @@ export(_Server) ->
|
|||||||
[]
|
[]
|
||||||
end}].
|
end}].
|
||||||
|
|
||||||
import(LServer) ->
|
import(_, _, _) ->
|
||||||
[{<<"select username, vcard from vcard;">>,
|
ok.
|
||||||
fun([LUser, SVCard]) ->
|
|
||||||
#xmlel{} = VCARD = fxml_stream:parse_element(SVCard),
|
|
||||||
#vcard{us = {LUser, LServer}, vcard = VCARD}
|
|
||||||
end},
|
|
||||||
{<<"select username, lusername, fn, lfn, family, lfamily, "
|
|
||||||
"given, lgiven, middle, lmiddle, nickname, lnickname, "
|
|
||||||
"bday, lbday, ctry, lctry, locality, llocality, email, "
|
|
||||||
"lemail, orgname, lorgname, orgunit, lorgunit from vcard_search;">>,
|
|
||||||
fun([User, LUser, FN, LFN,
|
|
||||||
Family, LFamily, Given, LGiven,
|
|
||||||
Middle, LMiddle, Nickname, LNickname,
|
|
||||||
BDay, LBDay, CTRY, LCTRY, Locality, LLocality,
|
|
||||||
EMail, LEMail, OrgName, LOrgName, OrgUnit, LOrgUnit]) ->
|
|
||||||
#vcard_search{us = {LUser, LServer},
|
|
||||||
user = {User, LServer}, luser = LUser,
|
|
||||||
fn = FN, lfn = LFN, family = Family,
|
|
||||||
lfamily = LFamily, given = Given,
|
|
||||||
lgiven = LGiven, middle = Middle,
|
|
||||||
lmiddle = LMiddle, nickname = Nickname,
|
|
||||||
lnickname = LNickname, bday = BDay,
|
|
||||||
lbday = LBDay, ctry = CTRY, lctry = LCTRY,
|
|
||||||
locality = Locality, llocality = LLocality,
|
|
||||||
email = EMail, lemail = LEMail,
|
|
||||||
orgname = OrgName, lorgname = LOrgName,
|
|
||||||
orgunit = OrgUnit, lorgunit = LOrgUnit}
|
|
||||||
end}].
|
|
||||||
|
|
||||||
import(_, _) ->
|
|
||||||
pass.
|
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
|
@ -13,14 +13,15 @@
|
|||||||
-export([start/2, stop/1]).
|
-export([start/2, stop/1]).
|
||||||
|
|
||||||
-export([update_presence/3, vcard_set/3, export/1,
|
-export([update_presence/3, vcard_set/3, export/1,
|
||||||
import/1, import/3, mod_opt_type/1, depends/2]).
|
import_info/0, import/5, import_start/2,
|
||||||
|
mod_opt_type/1, depends/2]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
|
|
||||||
-callback init(binary(), gen_mod:opts()) -> any().
|
-callback init(binary(), gen_mod:opts()) -> any().
|
||||||
-callback import(binary(), #vcard_xupdate{}) -> ok | pass.
|
-callback import(binary(), binary(), [binary()]) -> ok.
|
||||||
-callback add_xupdate(binary(), binary(), binary()) -> {atomic, any()}.
|
-callback add_xupdate(binary(), binary(), binary()) -> {atomic, any()}.
|
||||||
-callback get_xupdate(binary(), binary()) -> binary() | undefined.
|
-callback get_xupdate(binary(), binary()) -> binary() | undefined.
|
||||||
-callback remove_xupdate(binary(), binary()) -> {atomic, any()}.
|
-callback remove_xupdate(binary(), binary()) -> {atomic, any()}.
|
||||||
@ -94,17 +95,20 @@ presence_with_xupdate(Presence, User, Host) ->
|
|||||||
Presence1 = xmpp:remove_subtag(Presence, #vcard_xupdate{}),
|
Presence1 = xmpp:remove_subtag(Presence, #vcard_xupdate{}),
|
||||||
xmpp:set_subtag(Presence1, #vcard_xupdate{hash = Hash}).
|
xmpp:set_subtag(Presence1, #vcard_xupdate{hash = Hash}).
|
||||||
|
|
||||||
|
import_info() ->
|
||||||
|
[{<<"vcard_xupdate">>, 3}].
|
||||||
|
|
||||||
|
import_start(LServer, DBType) ->
|
||||||
|
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||||
|
Mod:init(LServer, []).
|
||||||
|
|
||||||
|
import(LServer, {sql, _}, DBType, Tab, [LUser, Hash, TimeStamp]) ->
|
||||||
|
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
||||||
|
Mod:import(LServer, Tab, [LUser, Hash, TimeStamp]).
|
||||||
|
|
||||||
export(LServer) ->
|
export(LServer) ->
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
Mod:export(LServer).
|
Mod:export(LServer).
|
||||||
|
|
||||||
import(LServer) ->
|
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
|
||||||
Mod:import(LServer).
|
|
||||||
|
|
||||||
import(LServer, DBType, LA) ->
|
|
||||||
Mod = gen_mod:db_mod(DBType, ?MODULE),
|
|
||||||
Mod:import(LServer, LA).
|
|
||||||
|
|
||||||
mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end;
|
mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end;
|
||||||
mod_opt_type(_) -> [db_type].
|
mod_opt_type(_) -> [db_type].
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
-behaviour(mod_vcard_xupdate).
|
-behaviour(mod_vcard_xupdate).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([init/2, import/2, add_xupdate/3, get_xupdate/2, remove_xupdate/2]).
|
-export([init/2, import/3, add_xupdate/3, get_xupdate/2, remove_xupdate/2]).
|
||||||
|
|
||||||
-include("mod_vcard_xupdate.hrl").
|
-include("mod_vcard_xupdate.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
@ -45,8 +45,9 @@ remove_xupdate(LUser, LServer) ->
|
|||||||
end,
|
end,
|
||||||
mnesia:transaction(F).
|
mnesia:transaction(F).
|
||||||
|
|
||||||
import(_LServer, #vcard_xupdate{} = R) ->
|
import(LServer, <<"vcard_xupdate">>, [LUser, Hash, _TimeStamp]) ->
|
||||||
mnesia:dirty_write(R).
|
mnesia:dirty_write(
|
||||||
|
#vcard_xupdate{us = {LUser, LServer}, hash = Hash}).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
-behaviour(mod_vcard_xupdate).
|
-behaviour(mod_vcard_xupdate).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([init/2, import/2, add_xupdate/3, get_xupdate/2, remove_xupdate/2]).
|
-export([init/2, import/3, add_xupdate/3, get_xupdate/2, remove_xupdate/2]).
|
||||||
|
|
||||||
-include("mod_vcard_xupdate.hrl").
|
-include("mod_vcard_xupdate.hrl").
|
||||||
|
|
||||||
@ -36,8 +36,10 @@ get_xupdate(LUser, LServer) ->
|
|||||||
remove_xupdate(LUser, LServer) ->
|
remove_xupdate(LUser, LServer) ->
|
||||||
{atomic, ejabberd_riak:delete(vcard_xupdate, {LUser, LServer})}.
|
{atomic, ejabberd_riak:delete(vcard_xupdate, {LUser, LServer})}.
|
||||||
|
|
||||||
import(_LServer, #vcard_xupdate{} = R) ->
|
import(LServer, <<"vcard_xupdate">>, [LUser, Hash, _TimeStamp]) ->
|
||||||
ejabberd_riak:put(R, vcard_xupdate_schema()).
|
ejabberd_riak:put(
|
||||||
|
#vcard_xupdate{us = {LUser, LServer}, hash = Hash},
|
||||||
|
vcard_xupdate_schema()).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
-behaviour(mod_vcard_xupdate).
|
-behaviour(mod_vcard_xupdate).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([init/2, import/2, add_xupdate/3, get_xupdate/2, remove_xupdate/2,
|
-export([init/2, import/3, add_xupdate/3, get_xupdate/2, remove_xupdate/2,
|
||||||
import/1, export/1]).
|
export/1]).
|
||||||
|
|
||||||
-include("mod_vcard_xupdate.hrl").
|
-include("mod_vcard_xupdate.hrl").
|
||||||
-include("ejabberd_sql_pt.hrl").
|
-include("ejabberd_sql_pt.hrl").
|
||||||
@ -62,14 +62,8 @@ export(_Server) ->
|
|||||||
[]
|
[]
|
||||||
end}].
|
end}].
|
||||||
|
|
||||||
import(LServer) ->
|
import(_, _, _) ->
|
||||||
[{<<"select username, hash from vcard_xupdate;">>,
|
ok.
|
||||||
fun([LUser, Hash]) ->
|
|
||||||
#vcard_xupdate{us = {LUser, LServer}, hash = Hash}
|
|
||||||
end}].
|
|
||||||
|
|
||||||
import(_LServer, _) ->
|
|
||||||
pass.
|
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
|
Loading…
Reference in New Issue
Block a user