]> granicus.if.org Git - ejabberd/commitdiff
Improve ODBC import
authorChristophe Romain <christophe.romain@process-one.net>
Tue, 22 Nov 2016 13:48:01 +0000 (14:48 +0100)
committerChristophe Romain <christophe.romain@process-one.net>
Tue, 22 Nov 2016 13:48:01 +0000 (14:48 +0100)
43 files changed:
src/ejabberd_auth.erl
src/ejabberd_auth_mnesia.erl
src/ejabberd_auth_riak.erl
src/ejd2sql.erl
src/mod_announce.erl
src/mod_announce_mnesia.erl
src/mod_announce_riak.erl
src/mod_announce_sql.erl
src/mod_caps.erl
src/mod_caps_mnesia.erl
src/mod_caps_riak.erl
src/mod_caps_sql.erl
src/mod_last.erl
src/mod_last_sql.erl
src/mod_muc.erl
src/mod_muc_mnesia.erl
src/mod_muc_riak.erl
src/mod_muc_sql.erl
src/mod_offline.erl
src/mod_offline_mnesia.erl
src/mod_offline_sql.erl
src/mod_privacy.erl
src/mod_privacy_sql.erl
src/mod_private.erl
src/mod_private_mnesia.erl
src/mod_private_riak.erl
src/mod_private_sql.erl
src/mod_roster.erl
src/mod_roster_mnesia.erl
src/mod_roster_riak.erl
src/mod_roster_sql.erl
src/mod_shared_roster.erl
src/mod_shared_roster_mnesia.erl
src/mod_shared_roster_riak.erl
src/mod_shared_roster_sql.erl
src/mod_vcard.erl
src/mod_vcard_mnesia.erl
src/mod_vcard_riak.erl
src/mod_vcard_sql.erl
src/mod_vcard_xupdate.erl
src/mod_vcard_xupdate_mnesia.erl
src/mod_vcard_xupdate_riak.erl
src/mod_vcard_xupdate_sql.erl

index 6b7f537c0bb8487bdf23cd2a29b722bb16486eef..74c8009c2bfdde98834eb1c21a7e6e04a2d518f2 100644 (file)
@@ -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) ->
index f36c9fbc7b4b50d3003bb7cf24a9eaab8a7e8ef4..2e9ef5c9494598d74838e5dfdfa82242b1668501 100644 (file)
@@ -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].
index 05add262e0ed5302ba31aa23517379bea245e2a9..51571c4e27901db34cd2d98214d1330d1818bec8 100644 (file)
@@ -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].
index 7bace05ddcf60559ec8839fb845aab29c80fb1f8..9b7fdbbef61fece71be3adbf3f080b3c05b3584c 100644 (file)
 -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
 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 = <<Tab/binary, ".txt">>,
+              {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, <<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) ->
     lists:map(
       fun(#sql_query{} = SQL) ->
index 1d93cbe65458cc65b6e716e9432bd97b3d0f624c..a1c60f3c9c5eae71a159ab991373f63cab2d1e3f 100644 (file)
@@ -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_start(LServer, DBType) ->
+    Mod = gen_mod:db_mod(DBType, ?MODULE),
+    Mod:init(LServer, []).
 
-import(LServer, DBType, LA) ->
+import(LServer, {sql, _}, DBType, Tab, List) ->
     Mod = gen_mod:db_mod(DBType, ?MODULE),
-    Mod:import(LServer, LA).
+    Mod:import(LServer, Tab, List).
 
-mod_opt_type(access) ->
-    fun acl:access_rules_validator/1;
+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].
index b5a1f590e8d9018fc2d632584346573dc30004b2..23b2a5ba3bbc7ec627e0d873572c1b2844b26e39 100644 (file)
@@ -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
index 879eb196da5b5f6a31b5e9fdc2cdd79cec5feb8e..242adee0c4913ca4b81e37f5cd5ce8bebf0eacfb 100644 (file)
@@ -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
index 37b4412d34a20b082d3f9d030f29bcebf10b4c05..90e3f9d758f15b05dd9e71c350e23889acdbc91f 100644 (file)
@@ -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
index 65a745d2d9bc03122eaf443a034606b94519b709..3a4492f5ccae3c69408f47d5342ed7bff7a3331b 100644 (file)
 -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) ->
index 0bf04b2c3b9ff0e66ec2160bdf893b19bdc6d91a..660fcb4effa3506be4e2c4f16a80076d8a095775 100644 (file)
@@ -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
 %%%===================================================================
index 6e59ba8679755510fab8013bb1ce087f1aace83f..a504bb6ce94c65d9b64cd84874be6978a5c0b2a4 100644 (file)
@@ -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
 %%%===================================================================
index dde301575a591f0091ce56af7026bdb5651f5d9d..fee0f096024373e2df2e7c36ee682ab3c25281a3 100644 (file)
@@ -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
 %%%===================================================================
index 56e3b1c5ebcc7d755c440b56bec83b68688d47a6..47db0b6c62e4f19bc8cbc0bd54b313bac88f1255 100644 (file)
@@ -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).
 
-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() ->
+    [{<<"last">>, 3}].
 
-import(LServer, DBType, LA) ->
+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).
+
 transform_options(Opts) ->
     lists:foldl(fun transform_options/2, [], Opts).
 
index 718f01dff8112487aaf09b58ed617f58ef3a97bb..0351e668cac506c0d0ba4a1477266ba2845ac150 100644 (file)
@@ -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.
index 1f8b2479c845d2cb32053852a37e25e88ca6b41c..28008aaaea6a31b5f4351fca2920b1fcc7ff4a7d 100644 (file)
@@ -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_start(LServer, DBType) ->
+    Mod = gen_mod:db_mod(DBType, ?MODULE),
+    Mod:init(LServer, []).
 
-import(LServer, DBType, Data) ->
+import(LServer, {sql, _}, DBType, Tab, L) ->
     Mod = gen_mod:db_mod(DBType, ?MODULE),
-    Mod:import(LServer, Data).
+    Mod:import(LServer, Tab, L).
 
 mod_opt_type(access) ->
     fun acl:access_rules_validator/1;
index e3ae369787fb1ccf1fedeafcf73fce37943a2e69..072dddaae650a750bb8471db52e0556105740996 100644 (file)
@@ -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
index bc6e5959a29911e9ef526c2b5b1a0c5912818ebc..ada08ace61fe1b3e9082a604565cd8292613bc4f 100644 (file)
@@ -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
index 3139b531690d8329b55fd3a128f94119f913f082..4b6be7d068ab6b183eda06f5b7ad913e83d6a6aa 100644 (file)
 -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
index d007bf3c6e7cf97c317784d234ad56d7f7ddc21d..241677b2ab53efa180c5a545c5da7802f7d77064 100644 (file)
@@ -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, []).
+
+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(LServer, Data).
+    Mod:import(Msg).
 
 mod_opt_type(access_max_user_messages) ->
     fun acl:shaper_rules_validator/1;
index 9fec9c4d56c041484b89bfef552928762e9bd7e1..e84f7078aedfbb0314aaf9e84018b4bcb4bda464 100644 (file)
@@ -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).
 
 %%%===================================================================
index 025aa56f5e653948fce9931980585fbb9a9db0d7..e626df4257658c1272f2915a4eaf9a0b079f22c7 100644 (file)
@@ -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
index d4c8464f1d4612c6b8ee9e0a5804d90ac9adc0e1..97a8f18046022c3d3da6385ed1f5f272194dd9e9 100644 (file)
 
 -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 || <<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) ->
     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) ->
     [].
 
index 10f3cddc8e941cd28b600a8218547ada5e2ecab7..a39e36766001d33cf4b3c40fe7db6a05e468faad 100644 (file)
@@ -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
index 565500d4a683c1e7c5da136f11b8b09ebd354929..d11cad36f3b4d1417dd88bb74d3fde768155bd91 100644 (file)
@@ -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) ->
     [].
index d1bf20c857b9fe39f3c74f609b72daa633fa5a03..84871c1e71440454434d8094917df4a564cd08b7 100644 (file)
@@ -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).
 
 %%%===================================================================
index b05e7d725e05a8f0da15edce82a3060fd73528f1..7b091c4a643984545b5e6c1b4116b8743492de6e 100644 (file)
@@ -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}}]}]).
 
index eb113d923837ceabd329d4eec5dc1e1707009c1a..b459916e4bcd94da667c1c64b2dffa288be185f0 100644 (file)
@@ -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
index 2da09d317ef5a862c3a55112d7e990cb067dd1be..89578571cb02c41511254eb08a5fd6722bac244f 100644 (file)
@@ -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_start(LServer, DBType) ->
+    Mod = gen_mod:db_mod(DBType, ?MODULE),
+    ets:new(rostergroups_tmp, [private, named_table, bag]),
+    Mod:init(LServer, []),
+    ok.
 
-import(LServer, DBType, R) ->
+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, R).
+    Mod:import(LServer, <<"roster_version">>, [LUser, Ver]).
 
 mod_opt_type(access) ->
     fun acl:access_rules_validator/1;
index 398f105d5873ed5080625a1874a6660b2af7a595..1a33407e17eeea9f33d790a0b6466bbc0236aa75 100644 (file)
@@ -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).
 
 %%%===================================================================
index 9ed5e7927b353635cae04cd0122a4078d8b184a0..53f0e7fb4ba309ad6e55f273922080a6ea1403b5 100644 (file)
 
 %% 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()).
 
 %%%===================================================================
index 4d97aead084ad60f246a163b7cb6b07326f538ee..708a2029514b82c4c395ae8f63633854efed6d23 100644 (file)
@@ -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
index 45d91bccd9d3a119bc93fe7c4d8ee9bc06d8809d..8ef0f41b50f8fbb46842c423f447f40e6211b363 100644 (file)
@@ -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_start(LServer, DBType) ->
+    Mod = gen_mod:db_mod(DBType, ?MODULE),
+    Mod:init(LServer, []).
 
-import(LServer, DBType, Data) ->
+import(LServer, {sql, _}, DBType, Tab, L) ->
     Mod = gen_mod:db_mod(DBType, ?MODULE),
-    Mod:import(LServer, Data).
+    Mod:import(LServer, Tab, L).
 
 mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end;
 mod_opt_type(_) -> [db_type].
index eb7c3c37d1553ae26712642a25798a67e8add998..0f9e93bf6ce8aa0f471548fee690d8676a35169e 100644 (file)
         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
index 49d6edfcddf987ffc2d72aca017bd0e9b1ce10d7..bdb750981cc344b87cfe93b27df3e6565aee63a9 100644 (file)
         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
index 5cffffeb35e34f8ef79c22804f867eeec720806a..9f723f8398e21872c0a5a50edcfde7850d24b1cb 100644 (file)
@@ -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
index 35b907f953aaaf70bb7baba991a513a99a461860..dc947620605f1dad01714341cbb5ba23a6d6e9ca 100644 (file)
@@ -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,17 +448,20 @@ remove_user(User, Server) ->
     Mod = gen_mod:db_mod(LServer, ?MODULE),
     Mod:remove_user(LUser, LServer).
 
-export(LServer) ->
-    Mod = gen_mod:db_mod(LServer, ?MODULE),
-    Mod:export(LServer).
+import_info() ->
+    [{<<"vcard">>, 3}, {<<"vcard_search">>, 24}].
 
-import(LServer) ->
-    Mod = gen_mod:db_mod(LServer, ?MODULE),
-    Mod:import(LServer).
+import_start(LServer, DBType) ->
+    Mod = gen_mod:db_mod(DBType, ?MODULE),
+    Mod:init(LServer, []).
 
-import(LServer, DBType, VCard) ->
+import(LServer, {sql, _}, DBType, Tab, L) ->
     Mod = gen_mod:db_mod(DBType, ?MODULE),
-    Mod:import(LServer, VCard).
+    Mod:import(LServer, Tab, L).
+
+export(LServer) ->
+    Mod = gen_mod:db_mod(LServer, ?MODULE),
+    Mod:export(LServer).
 
 depends(_Host, _Opts) ->
     [].
index 3b64c29eff03543cb9aa14fc81c35cf7f359f642..a4a5f25626bf9a4db1ca00629365dd260fc61ec6 100644 (file)
@@ -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
index 23f05f17d9feca4a9fbc2f19306e6600e5db573a..411ec45fa3f2c458847887cdb5be2c209cf17058 100644 (file)
@@ -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.
 
 %%%===================================================================
index 129f76b5a0dcc505bcc47a00ec62f8fe76513463..7fd64c44ea940e9218c6717a9725c60c2cfdaf88 100644 (file)
@@ -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
index 27688e8fbdaa2a081db7378b4e9b72052c231f20..4d1dfa2fc5946b5e64e083b473659d1af94845e3 100644 (file)
 -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}).
 
-export(LServer) ->
-    Mod = gen_mod:db_mod(LServer, ?MODULE),
-    Mod:export(LServer).
+import_info() ->
+    [{<<"vcard_xupdate">>, 3}].
 
-import(LServer) ->
-    Mod = gen_mod:db_mod(LServer, ?MODULE),
-    Mod:import(LServer).
+import_start(LServer, DBType) ->
+    Mod = gen_mod:db_mod(DBType, ?MODULE),
+    Mod:init(LServer, []).
 
-import(LServer, DBType, LA) ->
+import(LServer, {sql, _}, DBType, Tab, [LUser, Hash, TimeStamp]) ->
     Mod = gen_mod:db_mod(DBType, ?MODULE),
-    Mod:import(LServer, LA).
+    Mod:import(LServer, Tab, [LUser, Hash, TimeStamp]).
+
+export(LServer) ->
+    Mod = gen_mod:db_mod(LServer, ?MODULE),
+    Mod:export(LServer).
 
 mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end;
 mod_opt_type(_) -> [db_type].
index f1b1693e43ff0b3b6a3919b6ea412af7441d6733..3f8d6fcab23b6949630150278bcad059c1bf6d2c 100644 (file)
@@ -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
index 242485bf281e3100302c831822dcf6d49b2d1941..cff77f887f1c6164e9bfc6d1d2b2fa200e577f56 100644 (file)
@@ -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
index 938114b8f7b745a6debcd0b4c7d203e494c0d196..fd2716c3378e03d172b04b5514ce2830ce5c3b76 100644 (file)
@@ -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