diff --git a/src/ejabberd_auth.erl b/src/ejabberd_auth.erl index 6b7f537c0..74c8009c2 100644 --- a/src/ejabberd_auth.erl +++ b/src/ejabberd_auth.erl @@ -36,8 +36,8 @@ check_password/6, check_password_with_authmodule/4, check_password_with_authmodule/6, try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, - get_vh_registered_users/2, export/1, import/1, - get_vh_registered_users_number/1, import/3, + get_vh_registered_users/2, export/1, import_info/0, + get_vh_registered_users_number/1, import/5, import_start/2, get_vh_registered_users_number/2, get_password/2, get_password_s/2, get_password_with_authmodule/2, is_user_exists/2, is_user_exists_in_other_modules/3, @@ -438,15 +438,20 @@ auth_modules(Server) -> export(Server) -> ejabberd_auth_mnesia:export(Server). -import(Server) -> - ejabberd_auth_mnesia:import(Server). +import_info() -> + [{<<"users">>, 3}]. -import(Server, mnesia, Passwd) -> - ejabberd_auth_mnesia:import(Server, mnesia, Passwd); -import(Server, riak, Passwd) -> - ejabberd_auth_riak:import(Server, riak, Passwd); -import(_, _, _) -> - pass. +import_start(_LServer, mnesia) -> + ejabberd_auth_mnesia:init_db(); +import_start(_LServer, _) -> + ok. + +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) -> fun (V) when is_list(V) -> diff --git a/src/ejabberd_auth_mnesia.erl b/src/ejabberd_auth_mnesia.erl index f36c9fbc7..2e9ef5c94 100644 --- a/src/ejabberd_auth_mnesia.erl +++ b/src/ejabberd_auth_mnesia.erl @@ -40,8 +40,8 @@ get_vh_registered_users_number/1, get_vh_registered_users_number/2, get_password/2, get_password_s/2, is_user_exists/2, remove_user/2, - remove_user/3, store_type/0, export/1, import/1, - import/3, plain_password_required/0, opt_type/1]). + remove_user/3, store_type/0, export/1, import/2, + plain_password_required/0, opt_type/1]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -493,16 +493,9 @@ export(_Server) -> [] end}]. -import(LServer) -> - [{<<"select username, password from users;">>, - fun([LUser, Password]) -> - #passwd{us = {LUser, LServer}, password = Password} - end}]. - -import(_LServer, mnesia, #passwd{} = P) -> - mnesia:dirty_write(P); -import(_, _, _) -> - pass. +import(LServer, [LUser, Password, _TimeStamp]) -> + mnesia:dirty_write( + #passwd{us = {LUser, LServer}, password = Password}). opt_type(auth_password_format) -> fun (V) -> V end; opt_type(_) -> [auth_password_format]. diff --git a/src/ejabberd_auth_riak.erl b/src/ejabberd_auth_riak.erl index 05add262e..51571c4e2 100644 --- a/src/ejabberd_auth_riak.erl +++ b/src/ejabberd_auth_riak.erl @@ -27,6 +27,8 @@ -compile([{parse_transform, ejabberd_sql_pt}]). +-behaviour(ejabberd_config). + -author('alexey@process-one.net'). -behaviour(ejabberd_auth). @@ -39,8 +41,8 @@ get_vh_registered_users_number/1, get_vh_registered_users_number/2, get_password/2, get_password_s/2, is_user_exists/2, remove_user/2, - remove_user/3, store_type/0, export/1, import/3, - plain_password_required/0]). + remove_user/3, store_type/0, export/1, import/2, + plain_password_required/0, opt_type/1]). -export([passwd_schema/0]). -include("ejabberd.hrl"). @@ -301,7 +303,9 @@ export(_Server) -> [] end}]. -import(LServer, riak, #passwd{} = Passwd) -> - ejabberd_riak:put(Passwd, passwd_schema(), [{'2i', [{<<"host">>, LServer}]}]); -import(_, _, _) -> - pass. +import(LServer, [LUser, Password, _TimeStamp]) -> + Passwd = #passwd{us = {LUser, LServer}, password = Password}, + ejabberd_riak:put(Passwd, passwd_schema(), [{'2i', [{<<"host">>, LServer}]}]). + +opt_type(auth_password_format) -> fun (V) -> V end; +opt_type(_) -> [auth_password_format]. diff --git a/src/ejd2sql.erl b/src/ejd2sql.erl index 7bace05dd..9b7fdbbef 100644 --- a/src/ejd2sql.erl +++ b/src/ejd2sql.erl @@ -30,12 +30,12 @@ -include("logger.hrl"). -include("ejabberd_sql_pt.hrl"). --export([export/2, export/3, import_file/2, import/2, - import/3, delete/1]). +-export([export/2, export/3, import/3, import/4, delete/1, import_info/1]). + -define(MAX_RECORDS_PER_TRANSACTION, 100). --record(dump, {fd, cont = start}). +-record(sql_dump, {fd, type}). %%%---------------------------------------------------------------------- %%% API @@ -50,13 +50,14 @@ modules() -> [ejabberd_auth, mod_announce, + mod_caps, mod_irc, mod_last, mod_muc, mod_offline, mod_privacy, mod_private, - %% mod_pubsub, + mod_pubsub, mod_roster, mod_shared_roster, mod_vcard, @@ -100,49 +101,44 @@ delete(Server, Module) -> delete(LServer, Table, ConvertFun) end, Module:export(Server)). -import_file(Server, FileName) when is_binary(FileName) -> - 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), +import(Server, Dir, ToType) -> lists:foreach( - fun(Module) -> - import(LServer, IO, Opts, Module) - end, Modules), - close_output(Output, IO). + fun(Mod) -> + ?INFO_MSG("importing ~p...", [Mod]), + import(Mod, Server, Dir, ToType) + end, modules()). -import(Server, Output, Opts, Module) -> +import(Mod, Server, Dir, ToType) -> 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( - fun({SelectQuery, ConvertFun}) -> - import(LServer, SelectQuery, IO, ConvertFun, Opts) - end, Module:import(Server)), - close_output(Output, IO). + fun({File, Tab, _Mod, FieldsNumber}) -> + FileName = filename:join([Dir, File]), + case open_sql_dump(FileName) of + {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 = <>, + {FileName, Tab, Mod, FieldsNum} + end, Info). %%%---------------------------------------------------------------------- %%% Internal functions @@ -200,79 +196,6 @@ delete(LServer, Table, ConvertFun) -> end, 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, normal). @@ -285,25 +208,11 @@ prepare_output(FileName, normal) when is_list(FileName) -> Err -> exit(Err) 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) -> Output. close_output(FileName, Fd) when FileName /= Fd -> - case Fd of - #dump{} -> - disk_log:close(Fd#dump.fd); - _ -> - file:close(Fd) - end, + file:close(Fd), ok; close_output(_, _) -> ok. @@ -321,6 +230,129 @@ flatten1([H|T], Acc) -> flatten1([], 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, <>} -> + 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, <>} -> + case file:read(Fd, ValSize) of + {ok, <>} -> + 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 + <> -> + NewBuf = <>, + read_lines(Fd, N-1, <<"">>, [NewBuf|Acc]); + _ -> + NewBuf = <>, + read_lines(Fd, N, NewBuf, Acc) + end; + {ok, Data} -> + NewBuf = <>, + 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) -> lists:map( fun(#sql_query{} = SQL) -> diff --git a/src/mod_announce.erl b/src/mod_announce.erl index 1d93cbe65..a1c60f3c9 100644 --- a/src/mod_announce.erl +++ b/src/mod_announce.erl @@ -31,8 +31,8 @@ -behaviour(gen_mod). --export([start/2, init/0, stop/1, export/1, import/1, - import/3, announce/3, send_motd/1, disco_identity/5, +-export([start/2, init/0, stop/1, export/1, import_info/0, + import_start/2, import/5, announce/3, send_motd/1, disco_identity/5, disco_features/5, disco_items/5, depends/2, send_announcement_to_all/3, announce_commands/4, announce_items/4, mod_opt_type/1]). @@ -43,7 +43,7 @@ -include("mod_announce.hrl"). -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(binary(), xmlel()) -> {atomic, any()}. -callback delete_motd(binary()) -> {atomic, any()}. @@ -832,15 +832,17 @@ export(LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:export(LServer). -import(LServer) -> - Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:import(LServer). +import_info() -> + [{<<"motd">>, 3}]. -import(LServer, DBType, LA) -> +import_start(LServer, DBType) -> Mod = gen_mod:db_mod(DBType, ?MODULE), - Mod:import(LServer, LA). + Mod:init(LServer, []). -mod_opt_type(access) -> - fun acl:access_rules_validator/1; +import(LServer, {sql, _}, DBType, Tab, List) -> + 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(_) -> [access, db_type]. diff --git a/src/mod_announce_mnesia.erl b/src/mod_announce_mnesia.erl index b5a1f590e..23b2a5ba3 100644 --- a/src/mod_announce_mnesia.erl +++ b/src/mod_announce_mnesia.erl @@ -11,7 +11,7 @@ %% API -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("mod_announce.hrl"). @@ -81,10 +81,11 @@ set_motd_user(LUser, LServer) -> end, mnesia:transaction(F). -import(_LServer, #motd{} = Motd) -> - mnesia:dirty_write(Motd); -import(_LServer, #motd_users{} = Users) -> - mnesia:dirty_write(Users). +import(LServer, <<"motd">>, [<<>>, XML, _TimeStamp]) -> + El = fxml_stream:parse_element(XML), + mnesia:dirty_write(#motd{server = LServer, packet = El}); +import(LServer, <<"motd">>, [LUser, <<>>, _TimeStamp]) -> + mnesia:dirty_write(#motd_users{us = {LUser, LServer}}). %%%=================================================================== %%% Internal functions diff --git a/src/mod_announce_riak.erl b/src/mod_announce_riak.erl index 879eb196d..242adee0c 100644 --- a/src/mod_announce_riak.erl +++ b/src/mod_announce_riak.erl @@ -11,7 +11,7 @@ %% API -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("mod_announce.hrl"). @@ -71,11 +71,13 @@ set_motd_user(LUser, LServer) -> #motd_users{us = {LUser, LServer}}, motd_users_schema(), [{'2i', [{<<"server">>, LServer}]}])}. -import(_LServer, #motd{} = Motd) -> - ejabberd_riak:put(Motd, motd_schema()); -import(_LServer, #motd_users{us = {_, S}} = Users) -> +import(LServer, <<"motd">>, [<<>>, XML, _TimeStamp]) -> + El = fxml_stream:parse_element(XML), + 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(), - [{'2i', [{<<"server">>, S}]}]). + [{'2i', [{<<"server">>, LServer}]}]). %%%=================================================================== %%% Internal functions diff --git a/src/mod_announce_sql.erl b/src/mod_announce_sql.erl index 37b4412d3..90e3f9d75 100644 --- a/src/mod_announce_sql.erl +++ b/src/mod_announce_sql.erl @@ -13,8 +13,8 @@ %% API -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, - import/2, export/1]). + get_motd/1, is_motd_user/2, set_motd_user/2, import/3, + export/1]). -include("xmpp.hrl"). -include("mod_announce.hrl"). @@ -108,19 +108,8 @@ export(_Server) -> [] end}]. -import(LServer) -> - [{<<"select xml from motd where username='';">>, - 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. +import(_, _, _) -> + ok. %%%=================================================================== %%% Internal functions diff --git a/src/mod_caps.erl b/src/mod_caps.erl index 65a745d2d..3a4492f5c 100644 --- a/src/mod_caps.erl +++ b/src/mod_caps.erl @@ -55,20 +55,16 @@ -include("logger.hrl"). -include("xmpp.hrl"). +-include("mod_caps.hrl"). -define(PROCNAME, ejabberd_mod_caps). -define(BAD_HASH_LIFETIME, 600). --record(caps_features, -{ - node_pair = {<<"">>, <<"">>} :: {binary(), binary()}, - features = [] :: [binary()] | pos_integer() -}). - -record(state, {host = <<"">> :: binary()}). -callback init(binary(), gen_mod:opts()) -> any(). +-callback import(binary(), {binary(), binary()}, [binary() | pos_integer()]) -> ok. -callback caps_read(binary(), {binary(), binary()}) -> {ok, non_neg_integer() | [binary()]} | error. -callback caps_write(binary(), {binary(), binary()}, @@ -525,9 +521,6 @@ is_valid_node(Node) -> false end. -caps_features_schema() -> - {record_info(fields, caps_features), #caps_features{}}. - export(LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:export(LServer). @@ -559,24 +552,8 @@ import_next(_LServer, _DBType, '$end_of_table') -> ok; import_next(LServer, DBType, NodePair) -> Features = [F || {_, F} <- ets:lookup(caps_features_tmp, NodePair)], - case Features of - [I] when is_integer(I), DBType == mnesia -> - 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, + Mod = gen_mod:db_mod(DBType, ?MODULE), + Mod:import(LServer, NodePair, Features), import_next(LServer, DBType, ets:next(caps_features_tmp, NodePair)). mod_opt_type(cache_life_time) -> diff --git a/src/mod_caps_mnesia.erl b/src/mod_caps_mnesia.erl index 0bf04b2c3..660fcb4ef 100644 --- a/src/mod_caps_mnesia.erl +++ b/src/mod_caps_mnesia.erl @@ -10,7 +10,7 @@ -behaviour(mod_caps). %% 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("logger.hrl"). @@ -46,6 +46,13 @@ caps_write(_LServer, Node, Features) -> mnesia:dirty_write(#caps_features{node_pair = Node, 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 %%%=================================================================== diff --git a/src/mod_caps_riak.erl b/src/mod_caps_riak.erl index 6e59ba867..a504bb6ce 100644 --- a/src/mod_caps_riak.erl +++ b/src/mod_caps_riak.erl @@ -10,7 +10,7 @@ -behaviour(mod_caps). %% 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"). @@ -31,6 +31,15 @@ caps_write(_LServer, Node, Features) -> features = Features}, 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 %%%=================================================================== diff --git a/src/mod_caps_sql.erl b/src/mod_caps_sql.erl index dde301575..fee0f0960 100644 --- a/src/mod_caps_sql.erl +++ b/src/mod_caps_sql.erl @@ -12,7 +12,7 @@ -compile([{parse_transform, ejabberd_sql_pt}]). %% 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("ejabberd_sql_pt.hrl"). @@ -53,6 +53,9 @@ export(_Server) -> [] end}]. +import(_, _, _) -> + ok. + %%%=================================================================== %%% Internal functions %%%=================================================================== diff --git a/src/mod_last.erl b/src/mod_last.erl index 56e3b1c5e..47db0b6c6 100644 --- a/src/mod_last.erl +++ b/src/mod_last.erl @@ -34,8 +34,8 @@ -behaviour(gen_mod). -export([start/2, stop/1, process_local_iq/1, export/1, - process_sm_iq/1, on_presence_update/4, import/1, - import/3, store_last_info/4, get_last_info/2, + process_sm_iq/1, on_presence_update/4, import_info/0, + import/5, store_last_info/4, get_last_info/2, remove_user/2, transform_options/1, mod_opt_type/1, opt_type/1, register_user/2, depends/2]). @@ -207,18 +207,28 @@ remove_user(User, Server) -> Mod = gen_mod:db_mod(LServer, ?MODULE), 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) -> Mod = gen_mod:db_mod(LServer, ?MODULE), 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) -> lists:foldl(fun transform_options/2, [], Opts). diff --git a/src/mod_last_sql.erl b/src/mod_last_sql.erl index 718f01dff..0351e668c 100644 --- a/src/mod_last_sql.erl +++ b/src/mod_last_sql.erl @@ -13,7 +13,7 @@ %% API -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("logger.hrl"). @@ -43,9 +43,6 @@ store_last_info(LUser, LServer, TimeStamp, Status) -> remove_user(LUser, LServer) -> sql_queries:del_last(LServer, LUser). -import(_LServer, _LA) -> - pass. - export(_Server) -> [{last_activity, fun(Host, #last_activity{us = {LUser, LServer}, @@ -58,15 +55,5 @@ export(_Server) -> [] end}]. -import(LServer) -> - [{<<"select username, seconds, state from last">>, - fun([LUser, TimeStamp, State]) -> - #last_activity{us = {LUser, LServer}, - timestamp = binary_to_integer( - TimeStamp), - status = State} - end}]. - -%%%=================================================================== -%%% Internal functions -%%%=================================================================== +import(_LServer, _LA) -> + pass. diff --git a/src/mod_muc.erl b/src/mod_muc.erl index 1f8b2479c..28008aaae 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -51,8 +51,9 @@ process_mucsub/1, broadcast_service_message/2, export/1, - import/1, - import/3, + import_info/0, + import/5, + import_start/2, opts_to_binary/1, can_use_nick/4]). @@ -79,7 +80,7 @@ -type muc_room_opts() :: [{atom(), 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 restore_room(binary(), binary(), binary()) -> muc_room_opts() | error. -callback forget_room(binary(), binary(), binary()) -> {atomic, any()}. @@ -904,13 +905,16 @@ export(LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:export(LServer). -import(LServer) -> - Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:import(LServer). +import_info() -> + [{<<"muc_room">>, 4}, {<<"muc_registered">>, 4}]. -import(LServer, DBType, Data) -> +import_start(LServer, DBType) -> 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) -> fun acl:access_rules_validator/1; diff --git a/src/mod_muc_mnesia.erl b/src/mod_muc_mnesia.erl index e3ae36978..072dddaae 100644 --- a/src/mod_muc_mnesia.erl +++ b/src/mod_muc_mnesia.erl @@ -9,11 +9,15 @@ -module(mod_muc_mnesia). -behaviour(mod_muc). +-behaviour(mod_muc_room). %% 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]). +-export([set_affiliation/6, set_affiliations/4, get_affiliation/5, + get_affiliations/3, search_affiliation/4]). +-include("jlib.hrl"). -include("mod_muc.hrl"). -include("logger.hrl"). @@ -113,10 +117,33 @@ set_nick(_LServer, Host, From, Nick) -> end, mnesia:transaction(F). -import(_LServer, #muc_room{} = R) -> - mnesia:dirty_write(R); -import(_LServer, #muc_registered{} = R) -> - mnesia:dirty_write(R). +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}. + +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 diff --git a/src/mod_muc_riak.erl b/src/mod_muc_riak.erl index bc6e5959a..ada08ace6 100644 --- a/src/mod_muc_riak.erl +++ b/src/mod_muc_riak.erl @@ -9,11 +9,15 @@ -module(mod_muc_riak). -behaviour(mod_muc). +-behaviour(mod_muc_room). %% 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]). +-export([set_affiliation/6, set_affiliations/4, get_affiliation/5, + get_affiliations/3, search_affiliation/4]). +-include("jlib.hrl"). -include("mod_muc.hrl"). %%%=================================================================== @@ -101,11 +105,33 @@ set_nick(LServer, Host, From, Nick) -> end end}. -import(_LServer, #muc_room{} = R) -> - ejabberd_riak:put(R, muc_room_schema()); -import(_LServer, #muc_registered{us_host = {_, Host}, nick = Nick} = R) -> +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}. + +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(), - [{'2i', [{<<"nick_host">>, {Nick, Host}}]}]). + [{'2i', [{<<"nick_host">>, {Nick, RoomHost}}]}]). %%%=================================================================== %%% Internal functions diff --git a/src/mod_muc_sql.erl b/src/mod_muc_sql.erl index 3139b5316..4b6be7d06 100644 --- a/src/mod_muc_sql.erl +++ b/src/mod_muc_sql.erl @@ -11,11 +11,14 @@ -compile([{parse_transform, ejabberd_sql_pt}]). -behaviour(mod_muc). +-behaviour(mod_muc_room). %% API -export([init/2, store_room/4, restore_room/3, forget_room/3, can_use_nick/4, get_rooms/2, get_nick/3, set_nick/4, - import/1, import/2, export/1]). + import/3, export/1]). +-export([set_affiliation/6, set_affiliations/4, get_affiliation/5, + get_affiliations/3, search_affiliation/4]). -include("jid.hrl"). -include("mod_muc.hrl"). @@ -127,6 +130,21 @@ set_nick(LServer, Host, From, Nick) -> end, 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) -> [{muc_room, fun(Host, #muc_room{name_host = {Name, RoomHost}, opts = Opts}) -> @@ -158,21 +176,8 @@ export(_Server) -> end end}]. -import(_LServer) -> - [{<<"select name, host, opts from muc_room;">>, - fun([Name, RoomHost, SOpts]) -> - Opts = mod_muc:opts_to_binary(ejabberd_sql:decode_term(SOpts)), - #muc_room{name_host = {Name, RoomHost}, opts = Opts} - end}, - {<<"select jid, host, nick from muc_registered;">>, - fun([J, RoomHost, Nick]) -> - #jid{user = U, server = S} = jid:from_string(J), - #muc_registered{us_host = {{U, S}, RoomHost}, - nick = Nick} - end}]. - -import(_, _) -> - pass. +import(_, _, _) -> + ok. %%%=================================================================== %%% Internal functions diff --git a/src/mod_offline.erl b/src/mod_offline.erl index d007bf3c6..241677b2a 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -53,8 +53,9 @@ remove_expired_messages/1, remove_old_messages/2, remove_user/2, - import/1, - import/3, + import_info/0, + import_start/2, + import/5, export/1, get_queue_length/2, count_offline_messages/2, @@ -90,7 +91,7 @@ -type us() :: {binary(), binary()}. -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{}], non_neg_integer(), non_neg_integer()) -> {atomic, any()}. @@ -851,13 +852,35 @@ export(LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:export(LServer). -import(LServer) -> - Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:import(LServer). +import_info() -> + [{<<"spool">>, 4}]. -import(LServer, DBType, Data) -> +import_start(LServer, DBType) -> 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) -> fun acl:shaper_rules_validator/1; diff --git a/src/mod_offline_mnesia.erl b/src/mod_offline_mnesia.erl index 9fec9c4d5..e84f7078a 100644 --- a/src/mod_offline_mnesia.erl +++ b/src/mod_offline_mnesia.erl @@ -13,7 +13,7 @@ -export([init/2, store_messages/5, pop_messages/2, remove_expired_messages/1, remove_old_messages/2, remove_user/2, read_message_headers/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("mod_offline.hrl"). @@ -164,7 +164,7 @@ count_messages(LUser, LServer) -> _ -> 0 end. -import(_LServer, #offline_msg{} = Msg) -> +import(#offline_msg{} = Msg) -> mnesia:dirty_write(Msg). %%%=================================================================== diff --git a/src/mod_offline_sql.erl b/src/mod_offline_sql.erl index 025aa56f5..e626df425 100644 --- a/src/mod_offline_sql.erl +++ b/src/mod_offline_sql.erl @@ -15,8 +15,7 @@ -export([init/2, store_messages/5, pop_messages/2, remove_expired_messages/1, remove_old_messages/2, remove_user/2, read_message_headers/2, read_message/3, remove_message/3, read_all_messages/2, - remove_all_messages/2, count_messages/2, import/1, import/2, - export/1]). + remove_all_messages/2, count_messages/2, import/1, export/1]). -include("xmpp.hrl"). -include("mod_offline.hrl"). @@ -193,29 +192,8 @@ export(_Server) -> [] end}]. -import(LServer) -> - [{<<"select username, xml from spool;">>, - 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. +import(_) -> + ok. %%%=================================================================== %%% Internal functions diff --git a/src/mod_privacy.erl b/src/mod_privacy.erl index d4c8464f1..97a8f1804 100644 --- a/src/mod_privacy.erl +++ b/src/mod_privacy.erl @@ -31,11 +31,11 @@ -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, check_packet/6, remove_user/2, encode_list_item/1, 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]). -include("ejabberd.hrl"). @@ -46,7 +46,7 @@ -include("mod_privacy.hrl"). -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_list_get(binary(), binary(), binary()) -> [listitem()] | error | not_found. -callback process_default_set(binary(), binary(), binary() | none) -> {atomic, any()}. @@ -544,18 +544,108 @@ updated_list(_, #userlist{name = OldName} = Old, true -> Old 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 || <> <= 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, [<>, + 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. + +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) -> Mod = gen_mod:db_mod(LServer, ?MODULE), 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) -> []. diff --git a/src/mod_privacy_sql.erl b/src/mod_privacy_sql.erl index 10f3cddc8..a39e36766 100644 --- a/src/mod_privacy_sql.erl +++ b/src/mod_privacy_sql.erl @@ -17,7 +17,7 @@ process_default_set/3, process_active_set/3, remove_privacy_list/3, set_privacy_list/1, 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, sql_add_privacy_list/2, @@ -249,37 +249,8 @@ get_id() -> put(id, ID + 1), ID + 1. -import(LServer) -> - [{<<"select username from privacy_list;">>, - 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. +import(_) -> + ok. %%%=================================================================== %%% Internal functions diff --git a/src/mod_private.erl b/src/mod_private.erl index 565500d4a..d11cad36f 100644 --- a/src/mod_private.erl +++ b/src/mod_private.erl @@ -31,9 +31,9 @@ -behaviour(gen_mod). --export([start/2, stop/1, process_sm_iq/1, import/3, - remove_user/2, get_data/2, get_data/3, export/1, import/1, - mod_opt_type/1, set_data/3, depends/2]). +-export([start/2, stop/1, process_sm_iq/1, import_info/0, + remove_user/2, get_data/2, get_data/3, export/1, + import/5, import_start/2, mod_opt_type/1, set_data/3, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -42,7 +42,7 @@ -include("mod_private.hrl"). -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 get_data(binary(), binary(), binary()) -> {ok, xmlel()} | error. -callback get_all_data(binary(), binary()) -> [xmlel()]. @@ -124,17 +124,20 @@ remove_user(User, Server) -> Mod = gen_mod:db_mod(Server, ?MODULE), 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) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:export(LServer). -import(LServer) -> - Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:import(LServer). - -import(LServer, DBType, PD) -> +import(LServer, {sql, _}, DBType, Tab, L) -> Mod = gen_mod:db_mod(DBType, ?MODULE), - Mod:import(LServer, PD). + Mod:import(LServer, Tab, L). depends(_Host, _Opts) -> []. diff --git a/src/mod_private_mnesia.erl b/src/mod_private_mnesia.erl index d1bf20c85..84871c1e7 100644 --- a/src/mod_private_mnesia.erl +++ b/src/mod_private_mnesia.erl @@ -11,7 +11,7 @@ %% API -export([init/2, set_data/3, get_data/3, get_all_data/2, remove_user/2, - import/2]). + import/3]). -include("xmpp.hrl"). -include("mod_private.hrl"). @@ -72,7 +72,10 @@ remove_user(LUser, LServer) -> end, 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). %%%=================================================================== diff --git a/src/mod_private_riak.erl b/src/mod_private_riak.erl index b05e7d725..7b091c4a6 100644 --- a/src/mod_private_riak.erl +++ b/src/mod_private_riak.erl @@ -12,7 +12,7 @@ %% API -export([init/2, set_data/3, get_data/3, get_all_data/2, remove_user/2, - import/2]). + import/3]). -include("xmpp.hrl"). -include("mod_private.hrl"). @@ -56,7 +56,10 @@ remove_user(LUser, LServer) -> {atomic, ejabberd_riak:delete_by_index(private_storage, <<"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(), [{'2i', [{<<"us">>, {LUser, LServer}}]}]). diff --git a/src/mod_private_sql.erl b/src/mod_private_sql.erl index eb113d923..b459916e4 100644 --- a/src/mod_private_sql.erl +++ b/src/mod_private_sql.erl @@ -12,7 +12,7 @@ %% API -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("mod_private.hrl"). @@ -77,16 +77,8 @@ export(_Server) -> [] end}]. -import(LServer) -> - [{<<"select username, namespace, data from private_storage;">>, - fun([LUser, XMLNS, XML]) -> - El = #xmlel{} = fxml_stream:parse_element(XML), - #private_storage{usns = {LUser, LServer, XMLNS}, - xml = El} - end}]. - -import(_, _) -> - pass. +import(_, _, _) -> + ok. %%%=================================================================== %%% Internal functions diff --git a/src/mod_roster.erl b/src/mod_roster.erl index 2da09d317..89578571c 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -42,8 +42,9 @@ -behaviour(gen_mod). -export([start/2, stop/1, process_iq/1, export/1, - import/1, process_local_iq/1, get_user_roster/2, - import/3, get_subscription_lists/3, get_roster/2, + import_info/0, process_local_iq/1, get_user_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, out_subscription/4, set_items/3, remove_user/2, get_jid_info/4, encode_item/1, webadmin_page/3, @@ -65,7 +66,7 @@ -export_type([subscription/0]). -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 write_roster_version(binary(), binary(), boolean(), binary()) -> any(). -callback get_roster(binary(), binary()) -> [#roster{}]. @@ -1022,13 +1023,34 @@ export(LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:export(LServer). -import(LServer) -> - Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:import(LServer). +import_info() -> + [{<<"roster_version">>, 2}, + {<<"rostergroups">>, 3}, + {<<"rosterusers">>, 10}]. -import(LServer, DBType, R) -> +import_start(LServer, DBType) -> 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) -> fun acl:access_rules_validator/1; diff --git a/src/mod_roster_mnesia.erl b/src/mod_roster_mnesia.erl index 398f105d5..1a33407e1 100644 --- a/src/mod_roster_mnesia.erl +++ b/src/mod_roster_mnesia.erl @@ -15,7 +15,7 @@ get_roster/2, get_roster_by_jid/3, get_only_items/2, roster_subscribe/4, get_roster_by_jid_with_groups/3, 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("logger.hrl"). @@ -51,7 +51,7 @@ write_roster_version(LUser, LServer, InTransaction, Ver) -> end. 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) -> case mnesia:read({roster, {LUser, LServer, LJID}}) of @@ -103,9 +103,13 @@ read_subscription_and_groups(LUser, LServer, LJID) -> transaction(_LServer, F) -> mnesia:transaction(F). -import(_LServer, #roster{} = R) -> +create_roster(RItem) -> + mnesia:dirty_write(RItem). + +import(_LServer, <<"rosterusers">>, #roster{} = 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). %%%=================================================================== diff --git a/src/mod_roster_riak.erl b/src/mod_roster_riak.erl index 9ed5e7927..53f0e7fb4 100644 --- a/src/mod_roster_riak.erl +++ b/src/mod_roster_riak.erl @@ -13,10 +13,10 @@ %% API -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, 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"). @@ -41,8 +41,8 @@ write_roster_version(LUser, LServer, _InTransaction, Ver) -> get_roster(LUser, LServer) -> case ejabberd_riak:get_by_index(roster, roster_schema(), <<"us">>, {LUser, LServer}) of - {ok, Items} -> Items; - _Err -> [] + {ok, Items} -> {ok, Items}; + _Err -> error end. get_roster_by_jid(LUser, LServer, LJID) -> @@ -96,10 +96,17 @@ read_subscription_and_groups(LUser, LServer, LJID) -> error end. -import(_LServer, #roster{us = {LUser, LServer}} = R) -> - ejabberd_riak:put(R, roster_schema(), +create_roster(#roster{us = {LUser, LServer}} = RItem) -> + 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}}]}]); -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()). %%%=================================================================== diff --git a/src/mod_roster_sql.erl b/src/mod_roster_sql.erl index 4d97aead0..708a20295 100644 --- a/src/mod_roster_sql.erl +++ b/src/mod_roster_sql.erl @@ -18,7 +18,7 @@ roster_subscribe/4, get_roster_by_jid_with_groups/3, remove_user/2, update_roster/4, del_roster/3, transaction/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("ejabberd_sql_pt.hrl"). @@ -185,27 +185,8 @@ export(_Server) -> [] end}]. -import(LServer) -> - [{<<"select username, jid, nick, subscription, " - "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. +import(_, _, _) -> + ok. %%%=================================================================== %%% Internal functions diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl index 45d91bccd..8ef0f41b5 100644 --- a/src/mod_shared_roster.erl +++ b/src/mod_shared_roster.erl @@ -30,9 +30,9 @@ -behaviour(gen_mod). -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_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, unset_presence/4, register_user/2, remove_user/2, list_groups/1, create_group/2, create_group/3, @@ -56,7 +56,7 @@ -type group_options() :: [{atom(), 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 groups_with_opts(binary()) -> [{binary(), group_options()}]. -callback create_group(binary(), binary(), group_options()) -> {atomic, any()}. @@ -1072,13 +1072,16 @@ export(LServer) -> Mod = gen_mod:db_mod(LServer, ?MODULE), Mod:export(LServer). -import(LServer) -> - Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:import(LServer). +import_info() -> + [{<<"sr_group">>, 3}, {<<"sr_user">>, 3}]. -import(LServer, DBType, Data) -> +import_start(LServer, DBType) -> 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]. diff --git a/src/mod_shared_roster_mnesia.erl b/src/mod_shared_roster_mnesia.erl index eb7c3c37d..0f9e93bf6 100644 --- a/src/mod_shared_roster_mnesia.erl +++ b/src/mod_shared_roster_mnesia.erl @@ -15,11 +15,12 @@ delete_group/2, get_group_opts/2, set_group_opts/3, get_user_groups/2, get_group_explicit_users/2, get_user_displayed_groups/3, is_user_in_group/3, - add_user_to_group/3, remove_user_from_group/3, import/2]). + add_user_to_group/3, remove_user_from_group/3, import/3]). -include("mod_roster.hrl"). -include("mod_shared_roster.hrl"). -include("logger.hrl"). +-include("xmpp.hrl"). %%%=================================================================== %%% API @@ -118,10 +119,14 @@ remove_user_from_group(Host, US, Group) -> F = fun () -> mnesia:delete_object(R) end, 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); -import(_LServer, #sr_user{} = U) -> - mnesia:dirty_write(U). +import(LServer, <<"sr_user">>, [SJID, Group, _TimeStamp]) -> + #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 diff --git a/src/mod_shared_roster_riak.erl b/src/mod_shared_roster_riak.erl index 49d6edfcd..bdb750981 100644 --- a/src/mod_shared_roster_riak.erl +++ b/src/mod_shared_roster_riak.erl @@ -15,10 +15,11 @@ delete_group/2, get_group_opts/2, set_group_opts/3, get_user_groups/2, get_group_explicit_users/2, get_user_displayed_groups/3, is_user_in_group/3, - add_user_to_group/3, remove_user_from_group/3, import/2]). + add_user_to_group/3, remove_user_from_group/3, import/3]). -include("mod_roster.hrl"). -include("mod_shared_roster.hrl"). +-include("xmpp.hrl"). %%%=================================================================== %%% API @@ -120,13 +121,17 @@ add_user_to_group(Host, US, Group) -> remove_user_from_group(Host, US, Group) -> {atomic, ejabberd_riak:delete(sr_group, {US, {Group, Host}})}. -import(_LServer, #sr_group{group_host = {_, Host}} = G) -> - ejabberd_riak:put(G, sr_group_schema(), [{'2i', [{<<"host">>, Host}]}]); -import(_LServer, #sr_user{us = US, group_host = {Group, Host}} = User) -> +import(LServer, <<"sr_group">>, [Group, SOpts, _TimeStamp]) -> + G = #sr_group{group_host = {Group, LServer}, + 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(), - [{i, {US, {Group, Host}}}, - {'2i', [{<<"us">>, US}, - {<<"group_host">>, {Group, Host}}]}]). + [{i, {{U, S}, {Group, LServer}}}, + {'2i', [{<<"us">>, {U, S}}, + {<<"group_host">>, {Group, LServer}}]}]). %%%=================================================================== %%% Internal functions diff --git a/src/mod_shared_roster_sql.erl b/src/mod_shared_roster_sql.erl index 5cffffeb3..9f723f839 100644 --- a/src/mod_shared_roster_sql.erl +++ b/src/mod_shared_roster_sql.erl @@ -17,8 +17,8 @@ delete_group/2, get_group_opts/2, set_group_opts/3, get_user_groups/2, get_group_explicit_users/2, get_user_displayed_groups/3, is_user_in_group/3, - add_user_to_group/3, remove_user_from_group/3, import/1, - import/2, export/1]). + add_user_to_group/3, remove_user_from_group/3, import/3, + export/1]). -include("jid.hrl"). -include("mod_roster.hrl"). @@ -177,20 +177,8 @@ export(_Server) -> [] end}]. -import(LServer) -> - [{<<"select name, opts from sr_group;">>, - 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. +import(_, _, _) -> + ok. %%%=================================================================== %%% Internal functions diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index 35b907f95..dc9476206 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -34,8 +34,8 @@ -export([start/2, init/3, stop/1, get_sm_features/5, process_local_iq/1, process_sm_iq/1, string2lower/1, - remove_user/2, export/1, import/1, import/3, depends/2, - process_search/1, process_vcard/1, get_vcard/2, + remove_user/2, export/1, import_info/0, import/5, import_start/2, + depends/2, process_search/1, process_vcard/1, get_vcard/2, disco_items/5, disco_features/5, disco_identity/5, 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 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 set_vcard(binary(), binary(), xmlel(), #vcard_search{}) -> {atomic, any()}. @@ -59,6 +59,7 @@ -callback search(binary(), [{binary(), [binary()]}], boolean(), infinity | pos_integer()) -> [{binary(), binary()}]. -callback remove_user(binary(), binary()) -> {atomic, any()}. +-callback is_search_supported(binary()) -> boolean(). start(Host, Opts) -> Mod = gen_mod:db_mod(Host, Opts, ?MODULE), @@ -105,6 +106,15 @@ init(Host, ServerHost, Search) -> false -> loop(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) end. @@ -438,18 +448,21 @@ remove_user(User, Server) -> Mod = gen_mod:db_mod(LServer, ?MODULE), 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) -> Mod = gen_mod:db_mod(LServer, ?MODULE), 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) -> []. diff --git a/src/mod_vcard_mnesia.erl b/src/mod_vcard_mnesia.erl index 3b64c29ef..a4a5f2562 100644 --- a/src/mod_vcard_mnesia.erl +++ b/src/mod_vcard_mnesia.erl @@ -11,8 +11,9 @@ -behaviour(mod_vcard). %% 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]). +-export([is_search_supported/1]). -include("ejabberd.hrl"). -include("xmpp.hrl"). @@ -47,6 +48,9 @@ init(_Host, _Opts) -> stop(_Host) -> ok. +is_search_supported(_ServerHost) -> + true. + get_vcard(LUser, LServer) -> US = {LUser, LServer}, F = fun () -> mnesia:read({vcard, US}) end, @@ -121,10 +125,29 @@ remove_user(LUser, LServer) -> end, 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); -import(_LServer, #vcard_search{} = S) -> - mnesia:dirty_write(S). +import(LServer, <<"vcard_search">>, + [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 diff --git a/src/mod_vcard_riak.erl b/src/mod_vcard_riak.erl index 23f05f17d..411ec45fa 100644 --- a/src/mod_vcard_riak.erl +++ b/src/mod_vcard_riak.erl @@ -12,7 +12,8 @@ %% API -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("mod_vcard.hrl"). @@ -26,6 +27,9 @@ init(_Host, _Opts) -> stop(_Host) -> ok. +is_search_supported(_LServer) -> + false. + get_vcard(LUser, LServer) -> case ejabberd_riak:get(vcard, vcard_schema(), {LUser, LServer}) of {ok, R} -> @@ -101,7 +105,9 @@ search_reported(_LServer) -> remove_user(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, lfn = LFN, family = Family, @@ -150,7 +156,7 @@ import(_LServer, #vcard{us = {LUser, LServer}, vcard = El} = VCard) -> {<<"lorgname">>, LOrgName}, {<<"orgunit">>, OrgUnit}, {<<"lorgunit">>, LOrgUnit}]}]); -import(_LServer, #vcard_search{}) -> +import(_LServer, <<"vcard_search">>, _) -> ok. %%%=================================================================== diff --git a/src/mod_vcard_sql.erl b/src/mod_vcard_sql.erl index 129f76b5a..7fd64c44e 100644 --- a/src/mod_vcard_sql.erl +++ b/src/mod_vcard_sql.erl @@ -14,7 +14,8 @@ %% API -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("mod_vcard.hrl"). @@ -30,6 +31,9 @@ init(_Host, _Opts) -> stop(_Host) -> ok. +is_search_supported(_LServer) -> + true. + get_vcard(LUser, LServer) -> case catch sql_queries:get_vcard(LServer, LUser) of {selected, [{SVCARD}]} -> @@ -188,37 +192,8 @@ export(_Server) -> [] end}]. -import(LServer) -> - [{<<"select username, vcard from vcard;">>, - 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. +import(_, _, _) -> + ok. %%%=================================================================== %%% Internal functions diff --git a/src/mod_vcard_xupdate.erl b/src/mod_vcard_xupdate.erl index 27688e8fb..4d1dfa2fc 100644 --- a/src/mod_vcard_xupdate.erl +++ b/src/mod_vcard_xupdate.erl @@ -13,14 +13,15 @@ -export([start/2, stop/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("logger.hrl"). -include("xmpp.hrl"). -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 get_xupdate(binary(), binary()) -> binary() | undefined. -callback remove_xupdate(binary(), binary()) -> {atomic, any()}. @@ -94,17 +95,20 @@ presence_with_xupdate(Presence, User, Host) -> Presence1 = xmpp:remove_subtag(Presence, #vcard_xupdate{}), 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) -> Mod = gen_mod:db_mod(LServer, ?MODULE), 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]. diff --git a/src/mod_vcard_xupdate_mnesia.erl b/src/mod_vcard_xupdate_mnesia.erl index f1b1693e4..3f8d6fcab 100644 --- a/src/mod_vcard_xupdate_mnesia.erl +++ b/src/mod_vcard_xupdate_mnesia.erl @@ -10,7 +10,7 @@ -behaviour(mod_vcard_xupdate). %% 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("logger.hrl"). @@ -45,8 +45,9 @@ remove_xupdate(LUser, LServer) -> end, mnesia:transaction(F). -import(_LServer, #vcard_xupdate{} = R) -> - mnesia:dirty_write(R). +import(LServer, <<"vcard_xupdate">>, [LUser, Hash, _TimeStamp]) -> + mnesia:dirty_write( + #vcard_xupdate{us = {LUser, LServer}, hash = Hash}). %%%=================================================================== %%% Internal functions diff --git a/src/mod_vcard_xupdate_riak.erl b/src/mod_vcard_xupdate_riak.erl index 242485bf2..cff77f887 100644 --- a/src/mod_vcard_xupdate_riak.erl +++ b/src/mod_vcard_xupdate_riak.erl @@ -11,7 +11,7 @@ -behaviour(mod_vcard_xupdate). %% 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"). @@ -36,8 +36,10 @@ get_xupdate(LUser, LServer) -> remove_xupdate(LUser, LServer) -> {atomic, ejabberd_riak:delete(vcard_xupdate, {LUser, LServer})}. -import(_LServer, #vcard_xupdate{} = R) -> - ejabberd_riak:put(R, vcard_xupdate_schema()). +import(LServer, <<"vcard_xupdate">>, [LUser, Hash, _TimeStamp]) -> + ejabberd_riak:put( + #vcard_xupdate{us = {LUser, LServer}, hash = Hash}, + vcard_xupdate_schema()). %%%=================================================================== %%% Internal functions diff --git a/src/mod_vcard_xupdate_sql.erl b/src/mod_vcard_xupdate_sql.erl index 938114b8f..fd2716c33 100644 --- a/src/mod_vcard_xupdate_sql.erl +++ b/src/mod_vcard_xupdate_sql.erl @@ -13,8 +13,8 @@ -behaviour(mod_vcard_xupdate). %% API --export([init/2, import/2, add_xupdate/3, get_xupdate/2, remove_xupdate/2, - import/1, export/1]). +-export([init/2, import/3, add_xupdate/3, get_xupdate/2, remove_xupdate/2, + export/1]). -include("mod_vcard_xupdate.hrl"). -include("ejabberd_sql_pt.hrl"). @@ -62,14 +62,8 @@ export(_Server) -> [] end}]. -import(LServer) -> - [{<<"select username, hash from vcard_xupdate;">>, - fun([LUser, Hash]) -> - #vcard_xupdate{us = {LUser, LServer}, hash = Hash} - end}]. - -import(_LServer, _) -> - pass. +import(_, _, _) -> + ok. %%%=================================================================== %%% Internal functions