]> granicus.if.org Git - ejabberd/commitdiff
Add SQL to Mnesia converter
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>
Sun, 21 Jul 2013 10:24:36 +0000 (20:24 +1000)
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>
Sun, 21 Jul 2013 13:10:38 +0000 (23:10 +1000)
16 files changed:
src/ejabberd_auth.erl
src/ejabberd_auth_internal.erl
src/ejabberd_odbc.erl
src/ejd2odbc.erl
src/mod_announce.erl
src/mod_irc.erl
src/mod_last.erl
src/mod_muc.erl
src/mod_offline.erl
src/mod_privacy.erl
src/mod_private.erl
src/mod_roster.erl
src/mod_shared_roster.erl
src/mod_vcard.erl
src/mod_vcard_xupdate.erl
src/odbc_queries.erl

index a82c343e4ce923886fe5993587bdefe39edcd9ac..7cc40ae1eb145c29a96370999db8006f97e00dd9 100644 (file)
@@ -35,8 +35,8 @@
         check_password/5, check_password_with_authmodule/3,
         check_password_with_authmodule/5, try_register/3,
         dirty_get_registered_users/0, get_vh_registered_users/1,
-        get_vh_registered_users/2, export/1,
-        get_vh_registered_users_number/1,
+        get_vh_registered_users/2, export/1, import/1,
+        get_vh_registered_users_number/1, import/3,
         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,
@@ -437,3 +437,11 @@ auth_modules(Server) ->
 
 export(Server) ->
     ejabberd_auth_internal:export(Server).
+
+import(Server) ->
+    ejabberd_auth_internal:import(Server).
+
+import(Server, mnesia, Passwd) ->
+    ejabberd_auth_internal:import(Server, mnesia, Passwd);
+import(_, _, _) ->
+    pass.
index f66b09c88b6479bca9874523f140933a950a1728..5a6c1b10a21acad7eb460266b9635175caf1fec2 100644 (file)
@@ -38,8 +38,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,
-        plain_password_required/0]).
+        remove_user/3, store_type/0, export/1, import/1,
+        import/3, plain_password_required/0]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -474,3 +474,14 @@ export(_Server) ->
          (_Host, _R) ->
               []
       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.
index b530f8f29c7a8fe9433ce1ce81dda9dce0bded49..93780557974dc1926c72d4ae648acf1fdeb88662 100644 (file)
@@ -515,6 +515,9 @@ pgsql_to_odbc({ok, PGSQLResult}) ->
 pgsql_item_to_odbc({<<"SELECT", _/binary>>, Rows,
                    Recs}) ->
     {selected, [element(1, Row) || Row <- Rows], Recs};
+pgsql_item_to_odbc({<<"FETCH", _/binary>>, Rows,
+                   Recs}) ->
+    {selected, [element(1, Row) || Row <- Rows], Recs};
 pgsql_item_to_odbc(<<"INSERT ", OIDN/binary>>) ->
     [_OID, N] = str:tokens(OIDN, <<" ">>),
     {updated, jlib:binary_to_integer(N)};
index b96503dbe6b19754450593c8f7e8669791b8ba0d..8777a759756de36dcb91a7e8911a64cf51f58528 100644 (file)
 
 -author('alexey@process-one.net').
 
--export([export/2, export/3]).
+-include("logger.hrl").
+
+-export([export/2, export/3, import_file/2, import/2, import/3]).
 
 -define(MAX_RECORDS_PER_TRANSACTION, 100).
 
+-record(dump, {fd, cont = start}).
+
 %%%----------------------------------------------------------------------
 %%% API
 %%%----------------------------------------------------------------------
 %%% - Output can be either odbc to export to the configured relational
 %%%   database or "Filename" to export to text file.
 
+modules() ->
+    [ejabberd_auth,
+     mod_announce,
+     mod_caps,
+     mod_irc,
+     mod_last,
+     mod_muc,
+     mod_offline,
+     mod_privacy,
+     mod_private,
+     mod_roster,
+     mod_shared_roster,
+     mod_vcard,
+     mod_vcard_xupdate].
+
 export(Server, Output) ->
     LServer = jlib:nameprep(iolist_to_binary(Server)),
-    Modules = [ejabberd_auth,
-               mod_announce,
-               mod_caps,
-               mod_irc,
-               mod_last,
-               mod_muc,
-               mod_offline,
-               mod_privacy,
-               mod_private,
-               mod_roster,
-               mod_shared_roster,
-               mod_vcard,
-               mod_vcard_xupdate],
+    Modules = modules(),
     IO = prepare_output(Output),
     lists:foreach(
       fun(Module) ->
@@ -73,6 +80,47 @@ export(Server, Output, Module) ->
       end, Module:export(Server)),
     close_output(Output, IO).
 
+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 = jlib:nameprep(Server),
+            Mods = [{Mod, gen_mod:db_type(LServer, Mod)}
+                    || Mod <- modules(), gen_mod:is_loaded(LServer, Mod)],
+            AuthMods = case lists:member(ejabberd_auth_internal,
+                                         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) ->
+    LServer = jlib:nameprep(iolist_to_binary(Server)),
+    Modules = modules(),
+    IO = prepare_output(Output, disk_log),
+    lists:foreach(
+      fun(Module) ->
+              import(LServer, IO, Module)
+      end, Modules),
+    close_output(Output, IO).
+
+import(Server, Output, Module) ->
+    LServer = jlib:nameprep(iolist_to_binary(Server)),
+    IO = prepare_output(Output, disk_log),
+    lists:foreach(
+      fun({SelectQuery, ConvertFun}) ->
+              import(LServer, SelectQuery, IO, ConvertFun)
+      end, Module:import(Server)),
+    close_output(Output, IO).
+
 %%%----------------------------------------------------------------------
 %%% Internal functions
 %%%----------------------------------------------------------------------
@@ -109,18 +157,97 @@ output(_LServer, Table, Fd, SQLs) ->
     file:write(Fd, ["-- \n-- Mnesia table: ", atom_to_list(Table),
                     "\n--\n", SQLs]).
 
-prepare_output(FileName) when is_list(FileName); is_binary(FileName) ->
+import(LServer, SelectQuery, IO, ConvertFun) ->
+    F = fun() ->
+                ejabberd_odbc:sql_query_t(
+                  iolist_to_binary(
+                    [<<"declare c cursor for ">>, SelectQuery])),
+                fetch(IO, ConvertFun)
+        end,
+    ejabberd_odbc:sql_transaction(LServer, F).
+
+fetch(IO, ConvertFun) ->
+    fetch(IO, ConvertFun, undefined).
+
+fetch(IO, ConvertFun, PrevRow) ->
+    case ejabberd_odbc:sql_query_t([<<"fetch c;">>]) of
+        {selected, _, [Row]} when Row == PrevRow ->
+            %% Avoid calling ConvertFun with the same input
+            fetch(IO, ConvertFun, Row);
+        {selected, _, [Row]} ->
+            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,
+            fetch(IO, ConvertFun, Row);
+        {selected, _, []} ->
+            ok;
+        Err ->
+            erlang:error(Err)
+    end.
+
+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).
+
+prepare_output(FileName, Type) when is_binary(FileName) ->
+    prepare_output(binary_to_list(FileName), Type);
+prepare_output(FileName, normal) when is_list(FileName) ->
     case file:open(FileName, [write, raw]) of
         {ok, Fd} ->
             Fd;
         Err ->
             exit(Err)
     end;
-prepare_output(Output) ->
+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 ->
-    file:close(Fd),
+    case Fd of
+        #dump{} ->
+            disk_log:close(Fd#dump.fd);
+        _ ->
+            file:close(Fd)
+    end,
     ok;
 close_output(_, _) ->
     ok.
index 8d72b4bf7a4da0f3c25484f95950cede9db79957..b558897a07b1120a86a7f5f4bd3e8a8c22ad9873 100644 (file)
@@ -35,7 +35,9 @@
 -export([start/2,
         init/0,
         stop/1,
-         export/1,
+        export/1,
+         import/1,
+         import/3,
         announce/3,
         send_motd/1,
         disco_identity/5,
@@ -1072,3 +1074,21 @@ export(_Server) ->
          (_Host, _R) ->
               []
       end}].
+
+import(LServer) ->
+    [{<<"select xml from motd where username='';">>,
+      fun([XML]) ->
+              El = xml_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(_LServer, mnesia, #motd{} = Motd) ->
+    mnesia:dirty_write(Motd);
+import(_LServer, mnesia, #motd_users{} = Users) ->
+    mnesia:dirty_write(Users);
+import(_, _, _) ->
+    pass.
index 9d9246fad3cf51b132b26a16ebeb4676bbe3ef3e..3aa57002fcf1bc4f2f097fc9c236ed9e4df0c7ab 100644 (file)
@@ -33,8 +33,8 @@
 -behaviour(gen_mod).
 
 %% API
--export([start_link/2, start/2, stop/1, export/1,
-        closed_connection/3, get_connection_params/3]).
+-export([start_link/2, start/2, stop/1, export/1, import/1,
+        import/3, closed_connection/3, get_connection_params/3]).
 
 %% gen_server callbacks
 -export([init/1, handle_call/3, handle_cast/2,
@@ -1288,3 +1288,17 @@ export(_Server) ->
                       []
               end
       end}].
+
+import(_LServer) ->
+    [{<<"select jid, host, data from irc_custom;">>,
+      fun([SJID, IRCHost, SData]) ->
+              #jid{luser = U, lserver = S} = jlib:string_to_jid(SJID),
+              Data = ejabberd_odbc:decode_term(SData),
+              #irc_custom{us_host = {{U, S}, IRCHost},
+                          data = Data}
+      end}].
+
+import(_LServer, mnesia, #irc_custom{} = R) ->
+    mnesia:dirty_write(R);
+import(_, _, _) ->
+    pass.
index 28fcda63a31f8cb1e367b55ad7c23c88631a802a..3ea86b3505452f8c081a73971ae7341766b2f68d 100644 (file)
@@ -31,7 +31,7 @@
 -behaviour(gen_mod).
 
 -export([start/2, stop/1, process_local_iq/3, export/1,
-        process_sm_iq/3, on_presence_update/4,
+        process_sm_iq/3, on_presence_update/4, import/1, import/3,
         store_last_info/4, get_last_info/2, remove_user/2]).
 
 -include("ejabberd.hrl").
@@ -305,3 +305,17 @@ export(_Server) ->
          (_Host, _R) ->
               []
       end}].
+
+import(LServer) ->
+    [{<<"select username, seconds, state from last">>,
+      fun([LUser, TimeStamp, State]) ->
+              #last_activity{us = {LUser, LServer},
+                             timestamp = jlib:binary_to_integer(
+                                           TimeStamp),
+                             status = State}
+      end}].
+
+import(_LServer, mnesia, #last_activity{} = LA) ->
+    mnesia:dirty_write(LA);
+import(_, _, _) ->
+    pass.
index 6b87f157920dc5d6a5161979ea098470aafba031..cfed60a3c234cd61df11374d22814bce204853d1 100644 (file)
@@ -44,6 +44,9 @@
          shutdown_rooms/1,
         process_iq_disco_items/4,
         broadcast_service_message/2,
+         export/1,
+         import/1,
+         import/3,
         can_use_nick/4]).
 
 %% gen_server callbacks
@@ -1141,3 +1144,64 @@ update_muc_registered_table(_Host) ->
          ?INFO_MSG("Recreating muc_registered table", []),
          mnesia:transform_table(muc_registered, ignore, Fields)
     end.
+
+export(_Server) ->
+    [{muc_room,
+      fun(Host, #muc_room{name_host = {Name, RoomHost}, opts = Opts}) ->
+              case str:suffix(Host, RoomHost) of
+                  true ->
+                      SName = ejabberd_odbc:escape(Name),
+                      SRoomHost = ejabberd_odbc:escape(RoomHost),
+                      SOpts = ejabberd_odbc:encode_term(Opts),
+                      [[<<"delete from muc_room where name='">>, SName,
+                        <<"' and host='">>, SRoomHost, <<"';">>],
+                       [<<"insert into muc_room(name, host, opts) ",
+                          "values (">>,
+                        <<"'">>, SName, <<"', '">>, SRoomHost,
+                        <<"', '">>, SOpts, <<"');">>]];
+                  false ->
+                      []
+              end
+      end},
+     {muc_registered,
+      fun(Host, #muc_registered{us_host = {{U, S}, RoomHost},
+                                nick = Nick}) ->
+              case str:suffix(Host, RoomHost) of
+                  true ->
+                      SJID = ejabberd_odbc:escape(
+                               jlib:jid_to_string(
+                                 jlib:make_jid(U, S, <<"">>))),
+                      SNick = ejabberd_odbc:escape(Nick),
+                      SRoomHost = ejabberd_odbc:escape(RoomHost),
+                      [[<<"delete from muc_registered where jid='">>,
+                        SJID, <<"' and host='">>, SRoomHost, <<"';">>],
+                       [<<"insert into muc_registered(jid, host, "
+                          "nick) values ('">>,
+                        SJID, <<"', '">>, SRoomHost, <<"', '">>, SNick,
+                        <<"');">>]];
+                  false ->
+                      []
+              end
+      end}].
+
+import(_LServer) ->
+    [{<<"select name, host, opts from muc_room;">>,
+      fun([Name, RoomHost, SOpts]) ->
+              Opts = opts_to_binary(ejabberd_odbc: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} =
+                  jlib:string_to_jid(J),
+              #muc_registered{us_host = {{U, S}, RoomHost},
+                              nick = Nick}
+      end}].
+
+import(_LServer, mnesia, #muc_room{} = R) ->
+    mnesia:dirty_write(R);
+import(_LServer, mnesia, #muc_registered{} = R) ->
+    mnesia:dirty_write(R);
+import(_, _, _) ->
+    pass.
index 5033174856cff7ed4874e73d73282a3703e857aa..10ee7b4099b5ef7d64b3ff47f5f964029652a210 100644 (file)
@@ -42,6 +42,9 @@
         remove_expired_messages/1,
         remove_old_messages/2,
         remove_user/2,
+         import/1,
+         import/3,
+         export/1,
         get_queue_length/2,
          get_offline_els/2,
         webadmin_page/3,
@@ -873,3 +876,60 @@ count_offline_messages(LUser, LServer) ->
         _ ->
             0
     end.
+
+export(_Server) ->
+    [{offline_msg,
+      fun(Host, #offline_msg{us = {LUser, LServer},
+                             timestamp = TimeStamp, from = From, to = To,
+                             packet = Packet})
+            when LServer == Host ->
+              Username = ejabberd_odbc:escape(LUser),
+              #xmlel{name = Name, attrs = Attrs, children = Els} =
+                  Packet,
+              Attrs2 =
+                  jlib:replace_from_to_attrs(jlib:jid_to_string(From),
+                                             jlib:jid_to_string(To),
+                                             Attrs),
+              NewPacket = #xmlel{name = Name, attrs = Attrs2,
+                                 children =
+                                     Els ++
+                                     [jlib:timestamp_to_xml(
+                                        calendar:now_to_universal_time(TimeStamp),
+                                        utc,
+                                        jlib:make_jid(<<"">>,
+                                                      LServer,
+                                                      <<"">>),
+                                        <<"Offline Storage">>),
+                                      jlib:timestamp_to_xml(
+                                        calendar:now_to_universal_time(TimeStamp))]},
+              XML =
+                  ejabberd_odbc:escape(xml:element_to_binary(NewPacket)),
+              [[<<"delete from spool where username='">>, Username, <<"';">>],
+               [<<"insert into spool(username, xml) values ('">>,
+                Username, <<"', '">>, XML, <<"');">>]];
+         (_Host, _R) ->
+              []
+      end}].
+
+import(LServer) ->
+    [{<<"select username, xml from spool;">>,
+      fun([LUser, XML]) ->
+              El = #xmlel{} = xml_stream:parse_element(XML),
+              From = #jid{} = jlib:string_to_jid(
+                                xml:get_attr_s(<<"from">>, El)),
+              To = #jid{} = jlib:string_to_jid(
+                              xml:get_attr_s(<<"to">>, El)),
+              Stamp = xml:get_path_s(El, [{elem, <<"delay">>},
+                                          {elem, <<"stamp">>},
+                                          cdata]),
+              {_, _, _} = TS = jlib:datetime_string_to_timestamp(Stamp),
+              Expire = find_x_expire(TS, El#xmlel.children),
+              #offline_msg{us = {LUser, LServer},
+                           from = From, to = To,
+                           timestamp = TS, expire = Expire}
+      end}].
+
+import(_LServer, mnesia, #offline_msg{} = Msg) ->
+    mnesia:dirty_write(Msg);
+import(_, _, _) ->
+    pass.
index ab77a30d37456bb9f297a678b6c56095d239acdf..5edfccd28105cd19cafc4e8b58f5a5e4551e6d6e 100644 (file)
 
 -behaviour(gen_mod).
 
--export([start/2, stop/1, process_iq/3, export/1,
+-export([start/2, stop/1, process_iq/3, export/1, import/1,
         process_iq_set/4, process_iq_get/5, get_user_list/3,
         check_packet/6, remove_user/2, item_to_raw/1,
         raw_to_item/1, is_list_needdb/1, updated_list/3,
-         item_to_xml/1, get_user_lists/2]).
+         item_to_xml/1, get_user_lists/2, import/3]).
 
 %% For mod_blocking
 -export([sql_add_privacy_list/2,
@@ -965,6 +965,11 @@ sql_get_privacy_list_data(LUser, LServer, Name) ->
     odbc_queries:get_privacy_list_data(LServer, Username,
                                       SName).
 
+sql_get_privacy_list_data_t(LUser, Name) ->
+    Username = ejabberd_odbc:escape(LUser),
+    SName = ejabberd_odbc:escape(Name),
+    odbc_queries:get_privacy_list_data_t(Username, SName).
+
 sql_get_privacy_list_data_by_id(ID, LServer) ->
     odbc_queries:get_privacy_list_data_by_id(LServer, ID).
 
@@ -1098,3 +1103,37 @@ get_id() ->
     ID = 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(_LServer, mnesia, #privacy{} = P) ->
+    mnesia:dirty_write(P);
+import(_, _, _) ->
+    pass.
index 19e1e038ea6cb242211c81615a836a0442d54fd9..ae7068480d5f5572c67d107f73c0b76db713f90c 100644 (file)
@@ -30,8 +30,8 @@
 
 -behaviour(gen_mod).
 
--export([start/2, stop/1, process_sm_iq/3,
-        remove_user/2, get_data/2, export/1]).
+-export([start/2, stop/1, process_sm_iq/3, import/3,
+        remove_user/2, get_data/2, export/1, import/1]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -277,3 +277,16 @@ export(_Server) ->
          (_Host, _R) ->
               []
       end}].
+
+import(LServer) ->
+    [{<<"select username, namespace, data from private_storage;">>,
+      fun([LUser, XMLNS, XML]) ->
+              El = #xmlel{} = xml_stream:parse_element(XML),
+              #private_storage{usns = {LUser, LServer, XMLNS},
+                               xml = El}
+      end}].
+
+import(_LServer, mnesia, #private_storage{} = PS) ->
+    mnesia:dirty_write(PS);
+import(_, _, _) ->
+    pass.
index 1ab618a43f5c850cd62360ebf21c47013a600e9b..e048229156f46114aa2179c87c09a146bb6c4555 100644 (file)
@@ -39,8 +39,8 @@
 
 -behaviour(gen_mod).
 
--export([start/2, stop/1, process_iq/3, export/1,
-        process_local_iq/3, get_user_roster/2,
+-export([start/2, stop/1, process_iq/3, export/1, import/1,
+        process_local_iq/3, get_user_roster/2, import/3,
         get_subscription_lists/3, get_roster/2,
         get_in_pending_subscriptions/3, in_subscription/6,
         out_subscription/4, set_items/3, remove_user/2,
@@ -1569,3 +1569,29 @@ export(_Server) ->
          (_Host, _R) ->
               []
       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_odbc:escape(LUser),
+              SJID = ejabberd_odbc:escape(JID),
+              {selected, _, Rows} =
+                  ejabberd_odbc: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(_LServer, mnesia, #roster{} = R) ->
+    mnesia:dirty_write(R);
+import(_LServer, mnesia, #roster_version{} = RV) ->
+    mnesia:dirty_write(RV);
+import(_, _, _) ->
+    ok.
index 2501ef2b520f71e53ac3cd407a97d9c66ebfd1e8..743b1dd620d087b4f15144851a0582330083069d 100644 (file)
@@ -30,9 +30,9 @@
 
 -behaviour(gen_mod).
 
--export([start/2, stop/1, item_to_xml/1, export/1,
+-export([start/2, stop/1, item_to_xml/1, export/1, import/1,
         webadmin_menu/3, webadmin_page/3, get_user_roster/2,
-        get_subscription_lists/3, get_jid_info/4,
+        get_subscription_lists/3, get_jid_info/4, import/3,
         process_item/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,
@@ -1334,3 +1334,22 @@ export(_Server) ->
          (_Host, _R) ->
               []
       end}].
+
+import(LServer) ->
+    [{<<"select name, opts from sr_group;">>,
+      fun([Group, SOpts]) ->
+              #sr_group{group_host = {Group, LServer},
+                        opts = ejabberd_odbc:decode_term(SOpts)}
+      end},
+     {<<"select jid, grp from sr_user;">>,
+      fun([SJID, Group]) ->
+              #jid{luser = U, lserver = S} = jlib:string_to_jid(SJID),
+              #sr_user{us = {U, S}, group_host = {Group, LServer}}
+      end}].
+
+import(_LServer, mnesia, #sr_group{} = G) ->
+    mnesia:dirty_write(G);
+import(_LServer, mnesia, #sr_user{} = U) ->
+    mnesia:dirty_write(U);
+import(_, _, _) ->
+    pass.
index fa657df5d55233957745b76aa9d6b62335251ce1..08feb071a387ab7a6a9e577771d9cc7321e4a750 100644 (file)
@@ -32,7 +32,7 @@
 
 -export([start/2, init/3, stop/1, get_sm_features/5,
         process_local_iq/3, process_sm_iq/3, reindex_vcards/0,
-        remove_user/2, export/1]).
+        remove_user/2, export/1, import/1, import/3]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -1006,3 +1006,39 @@ export(_Server) ->
          (_Host, _R) ->
               []
       end}].
+
+import(LServer) ->
+    [{<<"select username, vcard from vcard;">>,
+      fun([LUser, SVCard]) ->
+              #xmlel{} = VCARD = xml_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(_LServer, mnesia, #vcard{} = VCard) ->
+    mnesia:dirty_write(VCard);
+import(_LServer, mnesia, #vcard_search{} = S) ->
+    mnesia:dirty_write(S);
+import(_, _, _) ->
+    pass.
index 4c70315f781eff03bd301209ca2a581456e09478..b2ea34419598984642c927b9b9d98704a2de5554 100644 (file)
@@ -13,7 +13,7 @@
 -export([start/2, stop/1]).
 
 %% hooks
--export([update_presence/3, vcard_set/3, export/1]).
+-export([update_presence/3, vcard_set/3, export/1, import/1, import/3]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -203,3 +203,14 @@ export(_Server) ->
          (_Host, _R) ->
               []
       end}].
+
+import(LServer) ->
+    [{<<"select username, hash from vcard_xupdate;">>,
+      fun([LUser, Hash]) ->
+              #vcard_xupdate{us = {LUser, LServer}, hash = Hash}
+      end}].
+
+import(_LServer, mnesia, #vcard_xupdate{} = R) ->
+    mnesia:dirty_write(R);
+import(_, _, _) ->
+    pass.
index e8fb473792f0b2f2c94c593dccf76985f1a7896d..23b8e8da66df8f84f1fb5d8b403a12a3d72fa779 100644 (file)
@@ -45,7 +45,7 @@
         get_default_privacy_list_t/1, get_privacy_list_names/2,
         get_privacy_list_names_t/1, get_privacy_list_id/3,
         get_privacy_list_id_t/2, get_privacy_list_data/3,
-        get_privacy_list_data_by_id/2,
+        get_privacy_list_data_by_id/2, get_privacy_list_data_t/2,
         get_privacy_list_data_by_id_t/1,
         set_default_privacy_list/2,
         unset_default_privacy_list/2,
@@ -519,6 +519,15 @@ get_privacy_list_data(LServer, Username, SName) ->
                             Username, <<"' and name='">>, SName,
                             <<"') order by ord;">>]).
 
+get_privacy_list_data_t(Username, SName) ->
+    ejabberd_odbc:sql_query_t([<<"select t, value, action, ord, match_all, "
+                                 "match_iq, match_message, match_presence_in, "
+                                 "match_presence_out from privacy_list_data "
+                                 "where id = (select id from privacy_list "
+                                 "where             username='">>,
+                               Username, <<"' and name='">>, SName,
+                               <<"') order by ord;">>]).
+
 get_privacy_list_data_by_id(LServer, ID) ->
     ejabberd_odbc:sql_query(LServer,
                            [<<"select t, value, action, ord, match_all, "