aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Romain <christophe.romain@process-one.net>2016-11-22 14:48:01 +0100
committerChristophe Romain <christophe.romain@process-one.net>2016-11-22 14:48:01 +0100
commitfbfbb968727617ae9bbeedc9b3d4adb7636ad5da (patch)
treee48dafe80850fe41be32a3ab47f27e6e130b832b
parentAdd new xmpp repo as dependency in mix.exs (diff)
Improve ODBC import
-rw-r--r--src/ejabberd_auth.erl25
-rw-r--r--src/ejabberd_auth_mnesia.erl17
-rw-r--r--src/ejabberd_auth_riak.erl16
-rw-r--r--src/ejd2sql.erl294
-rw-r--r--src/mod_announce.erl22
-rw-r--r--src/mod_announce_mnesia.erl11
-rw-r--r--src/mod_announce_riak.erl12
-rw-r--r--src/mod_announce_sql.erl19
-rw-r--r--src/mod_caps.erl31
-rw-r--r--src/mod_caps_mnesia.erl9
-rw-r--r--src/mod_caps_riak.erl11
-rw-r--r--src/mod_caps_sql.erl5
-rw-r--r--src/mod_last.erl30
-rw-r--r--src/mod_last_sql.erl19
-rw-r--r--src/mod_muc.erl20
-rw-r--r--src/mod_muc_mnesia.erl37
-rw-r--r--src/mod_muc_riak.erl36
-rw-r--r--src/mod_muc_sql.erl37
-rw-r--r--src/mod_offline.erl39
-rw-r--r--src/mod_offline_mnesia.erl4
-rw-r--r--src/mod_offline_sql.erl28
-rw-r--r--src/mod_privacy.erl112
-rw-r--r--src/mod_privacy_sql.erl35
-rw-r--r--src/mod_private.erl23
-rw-r--r--src/mod_private_mnesia.erl7
-rw-r--r--src/mod_private_riak.erl7
-rw-r--r--src/mod_private_sql.erl14
-rw-r--r--src/mod_roster.erl38
-rw-r--r--src/mod_roster_mnesia.erl12
-rw-r--r--src/mod_roster_riak.erl21
-rw-r--r--src/mod_roster_sql.erl25
-rw-r--r--src/mod_shared_roster.erl19
-rw-r--r--src/mod_shared_roster_mnesia.erl13
-rw-r--r--src/mod_shared_roster_riak.erl19
-rw-r--r--src/mod_shared_roster_sql.erl20
-rw-r--r--src/mod_vcard.erl35
-rw-r--r--src/mod_vcard_mnesia.erl31
-rw-r--r--src/mod_vcard_riak.erl12
-rw-r--r--src/mod_vcard_sql.erl39
-rw-r--r--src/mod_vcard_xupdate.erl24
-rw-r--r--src/mod_vcard_xupdate_mnesia.erl7
-rw-r--r--src/mod_vcard_xupdate_riak.erl8
-rw-r--r--src/mod_vcard_xupdate_sql.erl14
43 files changed, 718 insertions, 539 deletions
diff --git a/src/ejabberd_auth.erl b/src/ejabberd_auth.erl
index 6b7f537c0..74c8009c2 100644
--- a/src/ejabberd_auth.erl
+++ b/src/ejabberd_auth.erl
@@ -36,8 +36,8 @@
check_password/6, check_password_with_authmodule/4,
check_password_with_authmodule/6, try_register/3,
dirty_get_registered_users/0, get_vh_registered_users/1,
- get_vh_registered_users/2, export/1, import/1,
- get_vh_registered_users_number/1, import/3,
+ get_vh_registered_users/2, export/1, import_info/0,
+ get_vh_registered_users_number/1, import/5, import_start/2,
get_vh_registered_users_number/2, get_password/2,
get_password_s/2, get_password_with_authmodule/2,
is_user_exists/2, is_user_exists_in_other_modules/3,
@@ -438,15 +438,20 @@ auth_modules(Server) ->
export(Server) ->
ejabberd_auth_mnesia:export(Server).
-import(Server) ->
- ejabberd_auth_mnesia:import(Server).
+import_info() ->
+ [{<<"users">>, 3}].
-import(Server, mnesia, Passwd) ->
- ejabberd_auth_mnesia:import(Server, mnesia, Passwd);
-import(Server, riak, Passwd) ->
- ejabberd_auth_riak:import(Server, riak, Passwd);
-import(_, _, _) ->
- pass.
+import_start(_LServer, mnesia) ->
+ ejabberd_auth_mnesia:init_db();
+import_start(_LServer, _) ->
+ ok.
+
+import(Server, {sql, _}, mnesia, <<"users">>, Fields) ->
+ ejabberd_auth_mnesia:import(Server, Fields);
+import(Server, {sql, _}, riak, <<"users">>, Fields) ->
+ ejabberd_auth_riak:import(Server, Fields);
+import(_LServer, {sql, _}, sql, <<"users">>, _) ->
+ ok.
opt_type(auth_method) ->
fun (V) when is_list(V) ->
diff --git a/src/ejabberd_auth_mnesia.erl b/src/ejabberd_auth_mnesia.erl
index f36c9fbc7..2e9ef5c94 100644
--- a/src/ejabberd_auth_mnesia.erl
+++ b/src/ejabberd_auth_mnesia.erl
@@ -40,8 +40,8 @@
get_vh_registered_users_number/1,
get_vh_registered_users_number/2, get_password/2,
get_password_s/2, is_user_exists/2, remove_user/2,
- remove_user/3, store_type/0, export/1, import/1,
- import/3, plain_password_required/0, opt_type/1]).
+ remove_user/3, store_type/0, export/1, import/2,
+ plain_password_required/0, opt_type/1]).
-include("ejabberd.hrl").
-include("logger.hrl").
@@ -493,16 +493,9 @@ export(_Server) ->
[]
end}].
-import(LServer) ->
- [{<<"select username, password from users;">>,
- fun([LUser, Password]) ->
- #passwd{us = {LUser, LServer}, password = Password}
- end}].
-
-import(_LServer, mnesia, #passwd{} = P) ->
- mnesia:dirty_write(P);
-import(_, _, _) ->
- pass.
+import(LServer, [LUser, Password, _TimeStamp]) ->
+ mnesia:dirty_write(
+ #passwd{us = {LUser, LServer}, password = Password}).
opt_type(auth_password_format) -> fun (V) -> V end;
opt_type(_) -> [auth_password_format].
diff --git a/src/ejabberd_auth_riak.erl b/src/ejabberd_auth_riak.erl
index 05add262e..51571c4e2 100644
--- a/src/ejabberd_auth_riak.erl
+++ b/src/ejabberd_auth_riak.erl
@@ -27,6 +27,8 @@
-compile([{parse_transform, ejabberd_sql_pt}]).
+-behaviour(ejabberd_config).
+
-author('alexey@process-one.net').
-behaviour(ejabberd_auth).
@@ -39,8 +41,8 @@
get_vh_registered_users_number/1,
get_vh_registered_users_number/2, get_password/2,
get_password_s/2, is_user_exists/2, remove_user/2,
- remove_user/3, store_type/0, export/1, import/3,
- plain_password_required/0]).
+ remove_user/3, store_type/0, export/1, import/2,
+ plain_password_required/0, opt_type/1]).
-export([passwd_schema/0]).
-include("ejabberd.hrl").
@@ -301,7 +303,9 @@ export(_Server) ->
[]
end}].
-import(LServer, riak, #passwd{} = Passwd) ->
- ejabberd_riak:put(Passwd, passwd_schema(), [{'2i', [{<<"host">>, LServer}]}]);
-import(_, _, _) ->
- pass.
+import(LServer, [LUser, Password, _TimeStamp]) ->
+ Passwd = #passwd{us = {LUser, LServer}, password = Password},
+ ejabberd_riak:put(Passwd, passwd_schema(), [{'2i', [{<<"host">>, LServer}]}]).
+
+opt_type(auth_password_format) -> fun (V) -> V end;
+opt_type(_) -> [auth_password_format].
diff --git a/src/ejd2sql.erl b/src/ejd2sql.erl
index 7bace05dd..9b7fdbbef 100644
--- a/src/ejd2sql.erl
+++ b/src/ejd2sql.erl
@@ -30,12 +30,12 @@
-include("logger.hrl").
-include("ejabberd_sql_pt.hrl").
--export([export/2, export/3, import_file/2, import/2,
- import/3, delete/1]).
+-export([export/2, export/3, import/3, import/4, delete/1, import_info/1]).
+
-define(MAX_RECORDS_PER_TRANSACTION, 100).
--record(dump, {fd, cont = start}).
+-record(sql_dump, {fd, type}).
%%%----------------------------------------------------------------------
%%% API
@@ -50,13 +50,14 @@
modules() ->
[ejabberd_auth,
mod_announce,
+ mod_caps,
mod_irc,
mod_last,
mod_muc,
mod_offline,
mod_privacy,
mod_private,
- %% mod_pubsub,
+ mod_pubsub,
mod_roster,
mod_shared_roster,
mod_vcard,
@@ -100,49 +101,44 @@ delete(Server, Module) ->
delete(LServer, Table, ConvertFun)
end, Module:export(Server)).
-import_file(Server, FileName) when is_binary(FileName) ->
- import(Server, binary_to_list(FileName));
-import_file(Server, FileName) ->
- case disk_log:open([{name, make_ref()},
- {file, FileName},
- {mode, read_only}]) of
- {ok, Fd} ->
- LServer = jid:nameprep(Server),
- Mods = [{Mod, gen_mod:db_type(LServer, Mod)}
- || Mod <- modules(), gen_mod:is_loaded(LServer, Mod)],
- AuthMods = case lists:member(ejabberd_auth_mnesia,
- ejabberd_auth:auth_modules(LServer)) of
- true ->
- [{ejabberd_auth, mnesia}];
- false ->
- []
- end,
- import_dump(LServer, AuthMods ++ Mods, #dump{fd = Fd});
- Err ->
- exit(Err)
- end.
-
-import(Server, Output) ->
- import(Server, Output, [{fast, true}]).
-
-import(Server, Output, Opts) ->
- LServer = jid:nameprep(iolist_to_binary(Server)),
- Modules = modules(),
- IO = prepare_output(Output, disk_log),
+import(Server, Dir, ToType) ->
lists:foreach(
- fun(Module) ->
- import(LServer, IO, Opts, Module)
- end, Modules),
- close_output(Output, IO).
+ fun(Mod) ->
+ ?INFO_MSG("importing ~p...", [Mod]),
+ import(Mod, Server, Dir, ToType)
+ end, modules()).
-import(Server, Output, Opts, Module) ->
+import(Mod, Server, Dir, ToType) ->
LServer = jid:nameprep(iolist_to_binary(Server)),
- IO = prepare_output(Output, disk_log),
+ try Mod:import_start(LServer, ToType)
+ catch error:undef -> ok end,
lists:foreach(
- fun({SelectQuery, ConvertFun}) ->
- import(LServer, SelectQuery, IO, ConvertFun, Opts)
- end, Module:import(Server)),
- close_output(Output, IO).
+ fun({File, Tab, _Mod, FieldsNumber}) ->
+ FileName = filename:join([Dir, File]),
+ case open_sql_dump(FileName) of
+ {ok, #sql_dump{type = FromType} = Dump} ->
+ import_rows(LServer, {sql, FromType}, ToType,
+ Tab, Mod, Dump, FieldsNumber),
+ close_sql_dump(Dump);
+ {error, enoent} ->
+ ok;
+ eof ->
+ ?INFO_MSG("It seems like SQL dump ~s is empty", [FileName]);
+ Err ->
+ ?ERROR_MSG("Failed to open SQL dump ~s: ~s",
+ [FileName, format_error(Err)])
+ end
+ end, import_info(Mod)),
+ try Mod:import_stop(LServer, ToType)
+ catch error:undef -> ok end.
+
+import_info(Mod) ->
+ Info = Mod:import_info(),
+ lists:map(
+ fun({Tab, FieldsNum}) ->
+ FileName = <<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) ->
diff --git a/src/mod_announce.erl b/src/mod_announce.erl
index 1d93cbe65..a1c60f3c9 100644
--- a/src/mod_announce.erl
+++ b/src/mod_announce.erl
@@ -31,8 +31,8 @@
-behaviour(gen_mod).
--export([start/2, init/0, stop/1, export/1, import/1,
- import/3, announce/3, send_motd/1, disco_identity/5,
+-export([start/2, init/0, stop/1, export/1, import_info/0,
+ import_start/2, import/5, announce/3, send_motd/1, disco_identity/5,
disco_features/5, disco_items/5, depends/2,
send_announcement_to_all/3, announce_commands/4,
announce_items/4, mod_opt_type/1]).
@@ -43,7 +43,7 @@
-include("mod_announce.hrl").
-callback init(binary(), gen_mod:opts()) -> any().
--callback import(binary(), #motd{} | #motd_users{}) -> ok | pass.
+-callback import(binary(), binary(), [binary()]) -> ok.
-callback set_motd_users(binary(), [{binary(), binary(), binary()}]) -> {atomic, any()}.
-callback set_motd(binary(), xmlel()) -> {atomic, any()}.
-callback delete_motd(binary()) -> {atomic, any()}.
@@ -832,15 +832,17 @@ export(LServer) ->
Mod = gen_mod:db_mod(LServer, ?MODULE),
Mod:export(LServer).
-import(LServer) ->
- Mod = gen_mod:db_mod(LServer, ?MODULE),
- Mod:import(LServer).
+import_info() ->
+ [{<<"motd">>, 3}].
+
+import_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].
diff --git a/src/mod_announce_mnesia.erl b/src/mod_announce_mnesia.erl
index b5a1f590e..23b2a5ba3 100644
--- a/src/mod_announce_mnesia.erl
+++ b/src/mod_announce_mnesia.erl
@@ -11,7 +11,7 @@
%% API
-export([init/2, set_motd_users/2, set_motd/2, delete_motd/1,
- get_motd/1, is_motd_user/2, set_motd_user/2, import/2]).
+ get_motd/1, is_motd_user/2, set_motd_user/2, import/3]).
-include("xmpp.hrl").
-include("mod_announce.hrl").
@@ -81,10 +81,11 @@ set_motd_user(LUser, LServer) ->
end,
mnesia:transaction(F).
-import(_LServer, #motd{} = Motd) ->
- mnesia:dirty_write(Motd);
-import(_LServer, #motd_users{} = Users) ->
- mnesia:dirty_write(Users).
+import(LServer, <<"motd">>, [<<>>, XML, _TimeStamp]) ->
+ El = fxml_stream:parse_element(XML),
+ mnesia:dirty_write(#motd{server = LServer, packet = El});
+import(LServer, <<"motd">>, [LUser, <<>>, _TimeStamp]) ->
+ mnesia:dirty_write(#motd_users{us = {LUser, LServer}}).
%%%===================================================================
%%% Internal functions
diff --git a/src/mod_announce_riak.erl b/src/mod_announce_riak.erl
index 879eb196d..242adee0c 100644
--- a/src/mod_announce_riak.erl
+++ b/src/mod_announce_riak.erl
@@ -11,7 +11,7 @@
%% API
-export([init/2, set_motd_users/2, set_motd/2, delete_motd/1,
- get_motd/1, is_motd_user/2, set_motd_user/2, import/2]).
+ get_motd/1, is_motd_user/2, set_motd_user/2, import/3]).
-include("xmpp.hrl").
-include("mod_announce.hrl").
@@ -71,11 +71,13 @@ set_motd_user(LUser, LServer) ->
#motd_users{us = {LUser, LServer}}, motd_users_schema(),
[{'2i', [{<<"server">>, LServer}]}])}.
-import(_LServer, #motd{} = Motd) ->
- ejabberd_riak:put(Motd, motd_schema());
-import(_LServer, #motd_users{us = {_, S}} = Users) ->
+import(LServer, <<"motd">>, [<<>>, XML, _TimeStamp]) ->
+ El = fxml_stream:parse_element(XML),
+ ejabberd_riak:put(#motd{server = LServer, packet = El}, motd_schema());
+import(LServer, <<"motd">>, [LUser, <<>>, _TimeStamp]) ->
+ Users = #motd_users{us = {LUser, LServer}},
ejabberd_riak:put(Users, motd_users_schema(),
- [{'2i', [{<<"server">>, S}]}]).
+ [{'2i', [{<<"server">>, LServer}]}]).
%%%===================================================================
%%% Internal functions
diff --git a/src/mod_announce_sql.erl b/src/mod_announce_sql.erl
index 37b4412d3..90e3f9d75 100644
--- a/src/mod_announce_sql.erl
+++ b/src/mod_announce_sql.erl
@@ -13,8 +13,8 @@
%% API
-export([init/2, set_motd_users/2, set_motd/2, delete_motd/1,
- get_motd/1, is_motd_user/2, set_motd_user/2, import/1,
- import/2, export/1]).
+ get_motd/1, is_motd_user/2, set_motd_user/2, import/3,
+ export/1]).
-include("xmpp.hrl").
-include("mod_announce.hrl").
@@ -108,19 +108,8 @@ export(_Server) ->
[]
end}].
-import(LServer) ->
- [{<<"select xml from motd where username='';">>,
- fun([XML]) ->
- El = fxml_stream:parse_element(XML),
- #motd{server = LServer, packet = El}
- end},
- {<<"select username from motd where xml='';">>,
- fun([LUser]) ->
- #motd_users{us = {LUser, LServer}}
- end}].
-
-import(_, _) ->
- pass.
+import(_, _, _) ->
+ ok.
%%%===================================================================
%%% Internal functions
diff --git a/src/mod_caps.erl b/src/mod_caps.erl
index 65a745d2d..3a4492f5c 100644
--- a/src/mod_caps.erl
+++ b/src/mod_caps.erl
@@ -55,20 +55,16 @@
-include("logger.hrl").
-include("xmpp.hrl").
+-include("mod_caps.hrl").
-define(PROCNAME, ejabberd_mod_caps).
-define(BAD_HASH_LIFETIME, 600).
--record(caps_features,
-{
- node_pair = {<<"">>, <<"">>} :: {binary(), binary()},
- features = [] :: [binary()] | pos_integer()
-}).
-
-record(state, {host = <<"">> :: binary()}).
-callback init(binary(), gen_mod:opts()) -> any().
+-callback import(binary(), {binary(), binary()}, [binary() | pos_integer()]) -> ok.
-callback caps_read(binary(), {binary(), binary()}) ->
{ok, non_neg_integer() | [binary()]} | error.
-callback caps_write(binary(), {binary(), binary()},
@@ -525,9 +521,6 @@ is_valid_node(Node) ->
false
end.
-caps_features_schema() ->
- {record_info(fields, caps_features), #caps_features{}}.
-
export(LServer) ->
Mod = gen_mod:db_mod(LServer, ?MODULE),
Mod:export(LServer).
@@ -559,24 +552,8 @@ import_next(_LServer, _DBType, '$end_of_table') ->
ok;
import_next(LServer, DBType, NodePair) ->
Features = [F || {_, F} <- ets:lookup(caps_features_tmp, NodePair)],
- case Features of
- [I] when is_integer(I), DBType == mnesia ->
- mnesia:dirty_write(
- #caps_features{node_pair = NodePair, features = I});
- [I] when is_integer(I), DBType == riak ->
- ejabberd_riak:put(
- #caps_features{node_pair = NodePair, features = I},
- caps_features_schema());
- _ when DBType == mnesia ->
- mnesia:dirty_write(
- #caps_features{node_pair = NodePair, features = Features});
- _ when DBType == riak ->
- ejabberd_riak:put(
- #caps_features{node_pair = NodePair, features = Features},
- caps_features_schema());
- _ when DBType == sql ->
- ok
- end,
+ Mod = gen_mod:db_mod(DBType, ?MODULE),
+ Mod:import(LServer, NodePair, Features),
import_next(LServer, DBType, ets:next(caps_features_tmp, NodePair)).
mod_opt_type(cache_life_time) ->
diff --git a/src/mod_caps_mnesia.erl b/src/mod_caps_mnesia.erl
index 0bf04b2c3..660fcb4ef 100644
--- a/src/mod_caps_mnesia.erl
+++ b/src/mod_caps_mnesia.erl
@@ -10,7 +10,7 @@
-behaviour(mod_caps).
%% API
--export([init/2, caps_read/2, caps_write/3]).
+-export([init/2, caps_read/2, caps_write/3, import/3]).
-include("mod_caps.hrl").
-include("logger.hrl").
@@ -46,6 +46,13 @@ caps_write(_LServer, Node, Features) ->
mnesia:dirty_write(#caps_features{node_pair = Node,
features = Features}).
+import(_LServer, NodePair, [I]) when is_integer(I) ->
+ mnesia:dirty_write(
+ #caps_features{node_pair = NodePair, features = I});
+import(_LServer, NodePair, Features) ->
+ mnesia:dirty_write(
+ #caps_features{node_pair = NodePair, features = Features}).
+
%%%===================================================================
%%% Internal functions
%%%===================================================================
diff --git a/src/mod_caps_riak.erl b/src/mod_caps_riak.erl
index 6e59ba867..a504bb6ce 100644
--- a/src/mod_caps_riak.erl
+++ b/src/mod_caps_riak.erl
@@ -10,7 +10,7 @@
-behaviour(mod_caps).
%% API
--export([init/2, caps_read/2, caps_write/3]).
+-export([init/2, caps_read/2, caps_write/3, import/3]).
-include("mod_caps.hrl").
@@ -31,6 +31,15 @@ caps_write(_LServer, Node, Features) ->
features = Features},
caps_features_schema()).
+import(_LServer, NodePair, [I]) when is_integer(I) ->
+ ejabberd_riak:put(
+ #caps_features{node_pair = NodePair, features = I},
+ caps_features_schema());
+import(_LServer, NodePair, Features) ->
+ ejabberd_riak:put(
+ #caps_features{node_pair = NodePair, features = Features},
+ caps_features_schema()).
+
%%%===================================================================
%%% Internal functions
%%%===================================================================
diff --git a/src/mod_caps_sql.erl b/src/mod_caps_sql.erl
index dde301575..fee0f0960 100644
--- a/src/mod_caps_sql.erl
+++ b/src/mod_caps_sql.erl
@@ -12,7 +12,7 @@
-compile([{parse_transform, ejabberd_sql_pt}]).
%% API
--export([init/2, caps_read/2, caps_write/3, export/1]).
+-export([init/2, caps_read/2, caps_write/3, export/1, import/3]).
-include("mod_caps.hrl").
-include("ejabberd_sql_pt.hrl").
@@ -53,6 +53,9 @@ export(_Server) ->
[]
end}].
+import(_, _, _) ->
+ ok.
+
%%%===================================================================
%%% Internal functions
%%%===================================================================
diff --git a/src/mod_last.erl b/src/mod_last.erl
index 56e3b1c5e..47db0b6c6 100644
--- a/src/mod_last.erl
+++ b/src/mod_last.erl
@@ -34,8 +34,8 @@
-behaviour(gen_mod).
-export([start/2, stop/1, process_local_iq/1, export/1,
- process_sm_iq/1, on_presence_update/4, import/1,
- import/3, store_last_info/4, get_last_info/2,
+ process_sm_iq/1, on_presence_update/4, import_info/0,
+ import/5, store_last_info/4, get_last_info/2,
remove_user/2, transform_options/1, mod_opt_type/1,
opt_type/1, register_user/2, depends/2]).
@@ -207,18 +207,28 @@ remove_user(User, Server) ->
Mod = gen_mod:db_mod(LServer, ?MODULE),
Mod:remove_user(LUser, LServer).
-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).
diff --git a/src/mod_last_sql.erl b/src/mod_last_sql.erl
index 718f01dff..0351e668c 100644
--- a/src/mod_last_sql.erl
+++ b/src/mod_last_sql.erl
@@ -13,7 +13,7 @@
%% API
-export([init/2, get_last/2, store_last_info/4, remove_user/2,
- import/1, import/2, export/1]).
+ import/2, export/1]).
-include("mod_last.hrl").
-include("logger.hrl").
@@ -43,9 +43,6 @@ store_last_info(LUser, LServer, TimeStamp, Status) ->
remove_user(LUser, LServer) ->
sql_queries:del_last(LServer, LUser).
-import(_LServer, _LA) ->
- pass.
-
export(_Server) ->
[{last_activity,
fun(Host, #last_activity{us = {LUser, LServer},
@@ -58,15 +55,5 @@ export(_Server) ->
[]
end}].
-import(LServer) ->
- [{<<"select username, seconds, state from last">>,
- fun([LUser, TimeStamp, State]) ->
- #last_activity{us = {LUser, LServer},
- timestamp = binary_to_integer(
- TimeStamp),
- status = State}
- end}].
-
-%%%===================================================================
-%%% Internal functions
-%%%===================================================================
+import(_LServer, _LA) ->
+ pass.
diff --git a/src/mod_muc.erl b/src/mod_muc.erl
index 1f8b2479c..28008aaae 100644
--- a/src/mod_muc.erl
+++ b/src/mod_muc.erl
@@ -51,8 +51,9 @@
process_mucsub/1,
broadcast_service_message/2,
export/1,
- import/1,
- import/3,
+ import_info/0,
+ import/5,
+ import_start/2,
opts_to_binary/1,
can_use_nick/4]).
@@ -79,7 +80,7 @@
-type muc_room_opts() :: [{atom(), any()}].
-callback init(binary(), gen_mod:opts()) -> any().
--callback import(binary(), #muc_room{} | #muc_registered{}) -> ok | pass.
+-callback import(binary(), binary(), [binary()]) -> ok.
-callback store_room(binary(), binary(), binary(), list()) -> {atomic, any()}.
-callback restore_room(binary(), binary(), binary()) -> muc_room_opts() | error.
-callback forget_room(binary(), binary(), binary()) -> {atomic, any()}.
@@ -904,13 +905,16 @@ export(LServer) ->
Mod = gen_mod:db_mod(LServer, ?MODULE),
Mod:export(LServer).
-import(LServer) ->
- Mod = gen_mod:db_mod(LServer, ?MODULE),
- Mod:import(LServer).
+import_info() ->
+ [{<<"muc_room">>, 4}, {<<"muc_registered">>, 4}].
+
+import_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;
diff --git a/src/mod_muc_mnesia.erl b/src/mod_muc_mnesia.erl
index e3ae36978..072dddaae 100644
--- a/src/mod_muc_mnesia.erl
+++ b/src/mod_muc_mnesia.erl
@@ -9,11 +9,15 @@
-module(mod_muc_mnesia).
-behaviour(mod_muc).
+-behaviour(mod_muc_room).
%% API
--export([init/2, import/2, store_room/4, restore_room/3, forget_room/3,
+-export([init/2, import/3, store_room/4, restore_room/3, forget_room/3,
can_use_nick/4, get_rooms/2, get_nick/3, set_nick/4]).
+-export([set_affiliation/6, set_affiliations/4, get_affiliation/5,
+ get_affiliations/3, search_affiliation/4]).
+-include("jlib.hrl").
-include("mod_muc.hrl").
-include("logger.hrl").
@@ -113,10 +117,33 @@ set_nick(_LServer, Host, From, Nick) ->
end,
mnesia:transaction(F).
-import(_LServer, #muc_room{} = R) ->
- mnesia:dirty_write(R);
-import(_LServer, #muc_registered{} = R) ->
- mnesia:dirty_write(R).
+set_affiliation(_ServerHost, _Room, _Host, _JID, _Affiliation, _Reason) ->
+ {error, not_implemented}.
+
+set_affiliations(_ServerHost, _Room, _Host, _Affiliations) ->
+ {error, not_implemented}.
+
+get_affiliation(_ServerHost, _Room, _Host, _LUser, _LServer) ->
+ {error, not_implemented}.
+
+get_affiliations(_ServerHost, _Room, _Host) ->
+ {error, not_implemented}.
+
+search_affiliation(_ServerHost, _Room, _Host, _Affiliation) ->
+ {error, not_implemented}.
+
+import(_LServer, <<"muc_room">>,
+ [Name, RoomHost, SOpts, _TimeStamp]) ->
+ Opts = mod_muc:opts_to_binary(ejabberd_sql:decode_term(SOpts)),
+ mnesia:dirty_write(
+ #muc_room{name_host = {Name, RoomHost},
+ opts = Opts});
+import(_LServer, <<"muc_registered">>,
+ [J, RoomHost, Nick, _TimeStamp]) ->
+ #jid{user = U, server = S} = jid:from_string(J),
+ mnesia:dirty_write(
+ #muc_registered{us_host = {{U, S}, RoomHost},
+ nick = Nick}).
%%%===================================================================
%%% Internal functions
diff --git a/src/mod_muc_riak.erl b/src/mod_muc_riak.erl
index bc6e5959a..ada08ace6 100644
--- a/src/mod_muc_riak.erl
+++ b/src/mod_muc_riak.erl
@@ -9,11 +9,15 @@
-module(mod_muc_riak).
-behaviour(mod_muc).
+-behaviour(mod_muc_room).
%% API
--export([init/2, import/2, store_room/4, restore_room/3, forget_room/3,
+-export([init/2, import/3, store_room/4, restore_room/3, forget_room/3,
can_use_nick/4, get_rooms/2, get_nick/3, set_nick/4]).
+-export([set_affiliation/6, set_affiliations/4, get_affiliation/5,
+ get_affiliations/3, search_affiliation/4]).
+-include("jlib.hrl").
-include("mod_muc.hrl").
%%%===================================================================
@@ -101,11 +105,33 @@ set_nick(LServer, Host, From, Nick) ->
end
end}.
-import(_LServer, #muc_room{} = R) ->
- ejabberd_riak:put(R, muc_room_schema());
-import(_LServer, #muc_registered{us_host = {_, Host}, nick = Nick} = R) ->
+set_affiliation(_ServerHost, _Room, _Host, _JID, _Affiliation, _Reason) ->
+ {error, not_implemented}.
+
+set_affiliations(_ServerHost, _Room, _Host, _Affiliations) ->
+ {error, not_implemented}.
+
+get_affiliation(_ServerHost, _Room, _Host, _LUser, _LServer) ->
+ {error, not_implemented}.
+
+get_affiliations(_ServerHost, _Room, _Host) ->
+ {error, not_implemented}.
+
+search_affiliation(_ServerHost, _Room, _Host, _Affiliation) ->
+ {error, not_implemented}.
+
+import(_LServer, <<"muc_room">>,
+ [Name, RoomHost, SOpts, _TimeStamp]) ->
+ Opts = mod_muc:opts_to_binary(ejabberd_sql:decode_term(SOpts)),
+ ejabberd_riak:put(
+ #muc_room{name_host = {Name, RoomHost}, opts = Opts},
+ muc_room_schema());
+import(_LServer, <<"muc_registered">>,
+ [J, RoomHost, Nick, _TimeStamp]) ->
+ #jid{user = U, server = S} = jid:from_string(J),
+ R = #muc_registered{us_host = {{U, S}, RoomHost}, nick = Nick},
ejabberd_riak:put(R, muc_registered_schema(),
- [{'2i', [{<<"nick_host">>, {Nick, Host}}]}]).
+ [{'2i', [{<<"nick_host">>, {Nick, RoomHost}}]}]).
%%%===================================================================
%%% Internal functions
diff --git a/src/mod_muc_sql.erl b/src/mod_muc_sql.erl
index 3139b5316..4b6be7d06 100644
--- a/src/mod_muc_sql.erl
+++ b/src/mod_muc_sql.erl
@@ -11,11 +11,14 @@
-compile([{parse_transform, ejabberd_sql_pt}]).
-behaviour(mod_muc).
+-behaviour(mod_muc_room).
%% API
-export([init/2, store_room/4, restore_room/3, forget_room/3,
can_use_nick/4, get_rooms/2, get_nick/3, set_nick/4,
- import/1, import/2, export/1]).
+ import/3, export/1]).
+-export([set_affiliation/6, set_affiliations/4, get_affiliation/5,
+ get_affiliations/3, search_affiliation/4]).
-include("jid.hrl").
-include("mod_muc.hrl").
@@ -127,6 +130,21 @@ set_nick(LServer, Host, From, Nick) ->
end,
ejabberd_sql:sql_transaction(LServer, F).
+set_affiliation(_ServerHost, _Room, _Host, _JID, _Affiliation, _Reason) ->
+ {error, not_implemented}.
+
+set_affiliations(_ServerHost, _Room, _Host, _Affiliations) ->
+ {error, not_implemented}.
+
+get_affiliation(_ServerHost, _Room, _Host, _LUser, _LServer) ->
+ {error, not_implemented}.
+
+get_affiliations(_ServerHost, _Room, _Host) ->
+ {error, not_implemented}.
+
+search_affiliation(_ServerHost, _Room, _Host, _Affiliation) ->
+ {error, not_implemented}.
+
export(_Server) ->
[{muc_room,
fun(Host, #muc_room{name_host = {Name, RoomHost}, opts = Opts}) ->
@@ -158,21 +176,8 @@ export(_Server) ->
end
end}].
-import(_LServer) ->
- [{<<"select name, host, opts from muc_room;">>,
- fun([Name, RoomHost, SOpts]) ->
- Opts = mod_muc:opts_to_binary(ejabberd_sql:decode_term(SOpts)),
- #muc_room{name_host = {Name, RoomHost}, opts = Opts}
- end},
- {<<"select jid, host, nick from muc_registered;">>,
- fun([J, RoomHost, Nick]) ->
- #jid{user = U, server = S} = jid:from_string(J),
- #muc_registered{us_host = {{U, S}, RoomHost},
- nick = Nick}
- end}].
-
-import(_, _) ->
- pass.
+import(_, _, _) ->
+ ok.
%%%===================================================================
%%% Internal functions
diff --git a/src/mod_offline.erl b/src/mod_offline.erl
index d007bf3c6..241677b2a 100644
--- a/src/mod_offline.erl
+++ b/src/mod_offline.erl
@@ -53,8 +53,9 @@
remove_expired_messages/1,
remove_old_messages/2,
remove_user/2,
- import/1,
- import/3,
+ import_info/0,
+ import_start/2,
+ import/5,
export/1,
get_queue_length/2,
count_offline_messages/2,
@@ -90,7 +91,7 @@
-type us() :: {binary(), binary()}.
-callback init(binary(), gen_mod:opts()) -> any().
--callback import(binary(), #offline_msg{}) -> ok | pass.
+-callback import(#offline_msg{}) -> ok.
-callback store_messages(binary(), us(), [#offline_msg{}],
non_neg_integer(), non_neg_integer()) ->
{atomic, any()}.
@@ -851,13 +852,35 @@ export(LServer) ->
Mod = gen_mod:db_mod(LServer, ?MODULE),
Mod:export(LServer).
-import(LServer) ->
- Mod = gen_mod:db_mod(LServer, ?MODULE),
- Mod:import(LServer).
+import_info() ->
+ [{<<"spool">>, 4}].
-import(LServer, DBType, Data) ->
+import_start(LServer, DBType) ->
+ Mod = gen_mod:db_mod(DBType, ?MODULE),
+ Mod:import(LServer, []).
+
+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;
diff --git a/src/mod_offline_mnesia.erl b/src/mod_offline_mnesia.erl
index 9fec9c4d5..e84f7078a 100644
--- a/src/mod_offline_mnesia.erl
+++ b/src/mod_offline_mnesia.erl
@@ -13,7 +13,7 @@
-export([init/2, store_messages/5, pop_messages/2, remove_expired_messages/1,
remove_old_messages/2, remove_user/2, read_message_headers/2,
read_message/3, remove_message/3, read_all_messages/2,
- remove_all_messages/2, count_messages/2, import/2]).
+ remove_all_messages/2, count_messages/2, import/1]).
-include("xmpp.hrl").
-include("mod_offline.hrl").
@@ -164,7 +164,7 @@ count_messages(LUser, LServer) ->
_ -> 0
end.
-import(_LServer, #offline_msg{} = Msg) ->
+import(#offline_msg{} = Msg) ->
mnesia:dirty_write(Msg).
%%%===================================================================
diff --git a/src/mod_offline_sql.erl b/src/mod_offline_sql.erl
index 025aa56f5..e626df425 100644
--- a/src/mod_offline_sql.erl
+++ b/src/mod_offline_sql.erl
@@ -15,8 +15,7 @@
-export([init/2, store_messages/5, pop_messages/2, remove_expired_messages/1,
remove_old_messages/2, remove_user/2, read_message_headers/2,
read_message/3, remove_message/3, read_all_messages/2,
- remove_all_messages/2, count_messages/2, import/1, import/2,
- export/1]).
+ remove_all_messages/2, count_messages/2, import/1, export/1]).
-include("xmpp.hrl").
-include("mod_offline.hrl").
@@ -193,29 +192,8 @@ export(_Server) ->
[]
end}].
-import(LServer) ->
- [{<<"select username, xml from spool;">>,
- fun([LUser, XML]) ->
- El = #xmlel{} = fxml_stream:parse_element(XML),
- #message{} = Pkt = xmpp:decode(El, ?NS_CLIENT, [ignore_els]),
- From = Pkt#message.from,
- To = case Pkt#message.to of
- undefined -> jid:make(LUser, LServer);
- JID -> JID
- end,
- TS = case xmpp:get_subtag(Pkt, #delay{}) of
- #delay{stamp = Stamp} -> Stamp;
- false -> p1_time_compat:timestamp()
- end,
- Expire = mod_offline:find_x_expire(TS, Pkt),
- #offline_msg{us = {LUser, LServer},
- from = From, to = To,
- packet = El,
- timestamp = TS, expire = Expire}
- end}].
-
-import(_, _) ->
- pass.
+import(_) ->
+ ok.
%%%===================================================================
%%% Internal functions
diff --git a/src/mod_privacy.erl b/src/mod_privacy.erl
index d4c8464f1..97a8f1804 100644
--- a/src/mod_privacy.erl
+++ b/src/mod_privacy.erl
@@ -31,11 +31,11 @@
-behaviour(gen_mod).
--export([start/2, stop/1, process_iq/1, export/1, import/1,
+-export([start/2, stop/1, process_iq/1, export/1, import_info/0,
process_iq_set/3, process_iq_get/3, get_user_list/3,
check_packet/6, remove_user/2, encode_list_item/1,
is_list_needdb/1, updated_list/3,
- item_to_xml/1, get_user_lists/2, import/3,
+ item_to_xml/1, get_user_lists/2, import/5,
set_privacy_list/1, mod_opt_type/1, depends/2]).
-include("ejabberd.hrl").
@@ -46,7 +46,7 @@
-include("mod_privacy.hrl").
-callback init(binary(), gen_mod:opts()) -> any().
--callback import(binary(), #privacy{}) -> ok | pass.
+-callback import(#privacy{}) -> ok.
-callback process_lists_get(binary(), binary()) -> {none | binary(), [binary()]} | error.
-callback process_list_get(binary(), binary(), binary()) -> [listitem()] | error | not_found.
-callback process_default_set(binary(), binary(), binary() | none) -> {atomic, any()}.
@@ -544,18 +544,108 @@ updated_list(_, #userlist{name = OldName} = Old,
true -> Old
end.
+numeric_to_binary(<<0, 0, _/binary>>) ->
+ <<"0">>;
+numeric_to_binary(<<0, _, _:6/binary, T/binary>>) ->
+ Res = lists:foldl(
+ fun(X, Sum) ->
+ Sum*10000 + X
+ end, 0, [X || <<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) ->
[].
diff --git a/src/mod_privacy_sql.erl b/src/mod_privacy_sql.erl
index 10f3cddc8..a39e36766 100644
--- a/src/mod_privacy_sql.erl
+++ b/src/mod_privacy_sql.erl
@@ -17,7 +17,7 @@
process_default_set/3, process_active_set/3,
remove_privacy_list/3, set_privacy_list/1,
set_privacy_list/4, get_user_list/2, get_user_lists/2,
- remove_user/2, import/1, import/2, export/1]).
+ remove_user/2, import/1, export/1]).
-export([item_to_raw/1, raw_to_item/1,
sql_add_privacy_list/2,
@@ -249,37 +249,8 @@ get_id() ->
put(id, ID + 1),
ID + 1.
-import(LServer) ->
- [{<<"select username from privacy_list;">>,
- fun([LUser]) ->
- Default = case sql_get_default_privacy_list_t(LUser) of
- {selected, [<<"name">>], []} ->
- none;
- {selected, [<<"name">>], [[DefName]]} ->
- DefName;
- _ ->
- none
- end,
- {selected, [<<"name">>], Names} =
- sql_get_privacy_list_names_t(LUser),
- Lists = lists:flatmap(
- fun([Name]) ->
- case sql_get_privacy_list_data_t(LUser, Name) of
- {selected, _, RItems} ->
- [{Name,
- lists:map(fun raw_to_item/1,
- RItems)}];
- _ ->
- []
- end
- end, Names),
- #privacy{default = Default,
- us = {LUser, LServer},
- lists = Lists}
- end}].
-
-import(_, _) ->
- pass.
+import(_) ->
+ ok.
%%%===================================================================
%%% Internal functions
diff --git a/src/mod_private.erl b/src/mod_private.erl
index 565500d4a..d11cad36f 100644
--- a/src/mod_private.erl
+++ b/src/mod_private.erl
@@ -31,9 +31,9 @@
-behaviour(gen_mod).
--export([start/2, stop/1, process_sm_iq/1, import/3,
- remove_user/2, get_data/2, get_data/3, export/1, import/1,
- mod_opt_type/1, set_data/3, depends/2]).
+-export([start/2, stop/1, process_sm_iq/1, import_info/0,
+ remove_user/2, get_data/2, get_data/3, export/1,
+ import/5, import_start/2, mod_opt_type/1, set_data/3, depends/2]).
-include("ejabberd.hrl").
-include("logger.hrl").
@@ -42,7 +42,7 @@
-include("mod_private.hrl").
-callback init(binary(), gen_mod:opts()) -> any().
--callback import(binary(), #private_storage{}) -> ok | pass.
+-callback import(binary(), binary(), [binary()]) -> ok.
-callback set_data(binary(), binary(), [{binary(), xmlel()}]) -> {atomic, any()}.
-callback get_data(binary(), binary(), binary()) -> {ok, xmlel()} | error.
-callback get_all_data(binary(), binary()) -> [xmlel()].
@@ -124,17 +124,20 @@ remove_user(User, Server) ->
Mod = gen_mod:db_mod(Server, ?MODULE),
Mod:remove_user(LUser, LServer).
+import_info() ->
+ [{<<"private_storage">>, 4}].
+
+import_start(LServer, DBType) ->
+ Mod = gen_mod:db_mod(DBType, ?MODULE),
+ Mod:init(LServer, []).
+
export(LServer) ->
Mod = gen_mod:db_mod(LServer, ?MODULE),
Mod:export(LServer).
-import(LServer) ->
- Mod = gen_mod:db_mod(LServer, ?MODULE),
- Mod:import(LServer).
-
-import(LServer, DBType, PD) ->
+import(LServer, {sql, _}, DBType, Tab, L) ->
Mod = gen_mod:db_mod(DBType, ?MODULE),
- Mod:import(LServer, PD).
+ Mod:import(LServer, Tab, L).
depends(_Host, _Opts) ->
[].
diff --git a/src/mod_private_mnesia.erl b/src/mod_private_mnesia.erl
index d1bf20c85..84871c1e7 100644
--- a/src/mod_private_mnesia.erl
+++ b/src/mod_private_mnesia.erl
@@ -11,7 +11,7 @@
%% API
-export([init/2, set_data/3, get_data/3, get_all_data/2, remove_user/2,
- import/2]).
+ import/3]).
-include("xmpp.hrl").
-include("mod_private.hrl").
@@ -72,7 +72,10 @@ remove_user(LUser, LServer) ->
end,
mnesia:transaction(F).
-import(_LServer, #private_storage{} = PS) ->
+import(LServer, <<"private_storage">>,
+ [LUser, XMLNS, XML, _TimeStamp]) ->
+ El = #xmlel{} = fxml_stream:parse_element(XML),
+ PS = #private_storage{usns = {LUser, LServer, XMLNS}, xml = El},
mnesia:dirty_write(PS).
%%%===================================================================
diff --git a/src/mod_private_riak.erl b/src/mod_private_riak.erl
index b05e7d725..7b091c4a6 100644
--- a/src/mod_private_riak.erl
+++ b/src/mod_private_riak.erl
@@ -12,7 +12,7 @@
%% API
-export([init/2, set_data/3, get_data/3, get_all_data/2, remove_user/2,
- import/2]).
+ import/3]).
-include("xmpp.hrl").
-include("mod_private.hrl").
@@ -56,7 +56,10 @@ remove_user(LUser, LServer) ->
{atomic, ejabberd_riak:delete_by_index(private_storage,
<<"us">>, {LUser, LServer})}.
-import(_LServer, #private_storage{usns = {LUser, LServer, _}} = PS) ->
+import(LServer, <<"private_storage">>,
+ [LUser, XMLNS, XML, _TimeStamp]) ->
+ El = #xmlel{} = fxml_stream:parse_element(XML),
+ PS = #private_storage{usns = {LUser, LServer, XMLNS}, xml = El},
ejabberd_riak:put(PS, private_storage_schema(),
[{'2i', [{<<"us">>, {LUser, LServer}}]}]).
diff --git a/src/mod_private_sql.erl b/src/mod_private_sql.erl
index eb113d923..b459916e4 100644
--- a/src/mod_private_sql.erl
+++ b/src/mod_private_sql.erl
@@ -12,7 +12,7 @@
%% API
-export([init/2, set_data/3, get_data/3, get_all_data/2, remove_user/2,
- import/1, import/2, export/1]).
+ import/3, export/1]).
-include("xmpp.hrl").
-include("mod_private.hrl").
@@ -77,16 +77,8 @@ export(_Server) ->
[]
end}].
-import(LServer) ->
- [{<<"select username, namespace, data from private_storage;">>,
- fun([LUser, XMLNS, XML]) ->
- El = #xmlel{} = fxml_stream:parse_element(XML),
- #private_storage{usns = {LUser, LServer, XMLNS},
- xml = El}
- end}].
-
-import(_, _) ->
- pass.
+import(_, _, _) ->
+ ok.
%%%===================================================================
%%% Internal functions
diff --git a/src/mod_roster.erl b/src/mod_roster.erl
index 2da09d317..89578571c 100644
--- a/src/mod_roster.erl
+++ b/src/mod_roster.erl
@@ -42,8 +42,9 @@
-behaviour(gen_mod).
-export([start/2, stop/1, process_iq/1, export/1,
- import/1, process_local_iq/1, get_user_roster/2,
- import/3, get_subscription_lists/3, get_roster/2,
+ import_info/0, process_local_iq/1, get_user_roster/2,
+ import/5, get_subscription_lists/3, get_roster/2,
+ import_start/2, import_stop/2,
get_in_pending_subscriptions/3, in_subscription/6,
out_subscription/4, set_items/3, remove_user/2,
get_jid_info/4, encode_item/1, webadmin_page/3,
@@ -65,7 +66,7 @@
-export_type([subscription/0]).
-callback init(binary(), gen_mod:opts()) -> any().
--callback import(binary(), #roster{} | #roster_version{}) -> ok | pass.
+-callback import(binary(), binary(), #roster{} | [binary()]) -> ok.
-callback read_roster_version(binary(), binary()) -> binary() | error.
-callback write_roster_version(binary(), binary(), boolean(), binary()) -> any().
-callback get_roster(binary(), binary()) -> [#roster{}].
@@ -1022,13 +1023,34 @@ export(LServer) ->
Mod = gen_mod:db_mod(LServer, ?MODULE),
Mod:export(LServer).
-import(LServer) ->
- Mod = gen_mod:db_mod(LServer, ?MODULE),
- Mod:import(LServer).
+import_info() ->
+ [{<<"roster_version">>, 2},
+ {<<"rostergroups">>, 3},
+ {<<"rosterusers">>, 10}].
+
+import_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;
diff --git a/src/mod_roster_mnesia.erl b/src/mod_roster_mnesia.erl
index 398f105d5..1a33407e1 100644
--- a/src/mod_roster_mnesia.erl
+++ b/src/mod_roster_mnesia.erl
@@ -15,7 +15,7 @@
get_roster/2, get_roster_by_jid/3, get_only_items/2,
roster_subscribe/4, get_roster_by_jid_with_groups/3,
remove_user/2, update_roster/4, del_roster/3, transaction/2,
- read_subscription_and_groups/3, import/2]).
+ read_subscription_and_groups/3, import/3, create_roster/1]).
-include("mod_roster.hrl").
-include("logger.hrl").
@@ -51,7 +51,7 @@ write_roster_version(LUser, LServer, InTransaction, Ver) ->
end.
get_roster(LUser, LServer) ->
- mnesia:dirty_index_read(roster, {LUser, LServer}, #roster.us).
+ {ok, mnesia:dirty_index_read(roster, {LUser, LServer}, #roster.us)}.
get_roster_by_jid(LUser, LServer, LJID) ->
case mnesia:read({roster, {LUser, LServer, LJID}}) of
@@ -103,9 +103,13 @@ read_subscription_and_groups(LUser, LServer, LJID) ->
transaction(_LServer, F) ->
mnesia:transaction(F).
-import(_LServer, #roster{} = R) ->
+create_roster(RItem) ->
+ mnesia:dirty_write(RItem).
+
+import(_LServer, <<"rosterusers">>, #roster{} = R) ->
mnesia:dirty_write(R);
-import(_LServer, #roster_version{} = RV) ->
+import(LServer, <<"roster_version">>, [LUser, Ver]) ->
+ RV = #roster_version{us = {LUser, LServer}, version = Ver},
mnesia:dirty_write(RV).
%%%===================================================================
diff --git a/src/mod_roster_riak.erl b/src/mod_roster_riak.erl
index 9ed5e7927..53f0e7fb4 100644
--- a/src/mod_roster_riak.erl
+++ b/src/mod_roster_riak.erl
@@ -13,10 +13,10 @@
%% API
-export([init/2, read_roster_version/2, write_roster_version/4,
- get_roster/2, get_roster_by_jid/3,
+ get_roster/2, get_roster_by_jid/3, create_roster/1,
roster_subscribe/4, get_roster_by_jid_with_groups/3,
remove_user/2, update_roster/4, del_roster/3, transaction/2,
- read_subscription_and_groups/3, get_only_items/2, import/2]).
+ read_subscription_and_groups/3, get_only_items/2, import/3]).
-include("mod_roster.hrl").
@@ -41,8 +41,8 @@ write_roster_version(LUser, LServer, _InTransaction, Ver) ->
get_roster(LUser, LServer) ->
case ejabberd_riak:get_by_index(roster, roster_schema(),
<<"us">>, {LUser, LServer}) of
- {ok, Items} -> Items;
- _Err -> []
+ {ok, Items} -> {ok, Items};
+ _Err -> error
end.
get_roster_by_jid(LUser, LServer, LJID) ->
@@ -96,10 +96,17 @@ read_subscription_and_groups(LUser, LServer, LJID) ->
error
end.
-import(_LServer, #roster{us = {LUser, LServer}} = R) ->
- ejabberd_riak:put(R, roster_schema(),
+create_roster(#roster{us = {LUser, LServer}} = RItem) ->
+ ejabberd_riak:put(
+ RItem, roster_schema(),
+ [{'2i', [{<<"us">>, {LUser, LServer}}]}]).
+
+import(_LServer, <<"rosterusers">>, RosterItem) ->
+ {LUser, LServer} = RosterItem#roster.us,
+ ejabberd_riak:put(RosterItem, roster_schema(),
[{'2i', [{<<"us">>, {LUser, LServer}}]}]);
-import(_LServer, #roster_version{} = RV) ->
+import(LServer, <<"roster_version">>, [LUser, Ver]) ->
+ RV = #roster_version{us = {LUser, LServer}, version = Ver},
ejabberd_riak:put(RV, roster_version_schema()).
%%%===================================================================
diff --git a/src/mod_roster_sql.erl b/src/mod_roster_sql.erl
index 4d97aead0..708a20295 100644
--- a/src/mod_roster_sql.erl
+++ b/src/mod_roster_sql.erl
@@ -18,7 +18,7 @@
roster_subscribe/4, get_roster_by_jid_with_groups/3,
remove_user/2, update_roster/4, del_roster/3, transaction/2,
read_subscription_and_groups/3, get_only_items/2,
- import/1, import/2, export/1]).
+ import/3, export/1]).
-include("mod_roster.hrl").
-include("ejabberd_sql_pt.hrl").
@@ -185,27 +185,8 @@ export(_Server) ->
[]
end}].
-import(LServer) ->
- [{<<"select username, jid, nick, subscription, "
- "ask, askmessage, server, subscribe, type from rosterusers;">>,
- fun([LUser, JID|_] = Row) ->
- Item = raw_to_record(LServer, Row),
- Username = ejabberd_sql:escape(LUser),
- SJID = ejabberd_sql:escape(JID),
- {selected, _, Rows} =
- ejabberd_sql:sql_query_t(
- [<<"select grp from rostergroups where username='">>,
- Username, <<"' and jid='">>, SJID, <<"'">>]),
- Groups = [Grp || [Grp] <- Rows],
- Item#roster{groups = Groups}
- end},
- {<<"select username, version from roster_version;">>,
- fun([LUser, Ver]) ->
- #roster_version{us = {LUser, LServer}, version = Ver}
- end}].
-
-import(_, _) ->
- pass.
+import(_, _, _) ->
+ ok.
%%%===================================================================
%%% Internal functions
diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl
index 45d91bccd..8ef0f41b5 100644
--- a/src/mod_shared_roster.erl
+++ b/src/mod_shared_roster.erl
@@ -30,9 +30,9 @@
-behaviour(gen_mod).
-export([start/2, stop/1, export/1,
- import/1, webadmin_menu/3, webadmin_page/3,
+ import_info/0, webadmin_menu/3, webadmin_page/3,
get_user_roster/2, get_subscription_lists/3,
- get_jid_info/4, import/3, process_item/2,
+ get_jid_info/4, import/5, process_item/2, import_start/2,
in_subscription/6, out_subscription/4, user_available/1,
unset_presence/4, register_user/2, remove_user/2,
list_groups/1, create_group/2, create_group/3,
@@ -56,7 +56,7 @@
-type group_options() :: [{atom(), any()}].
-callback init(binary(), gen_mod:opts()) -> any().
--callback import(binary(), #sr_user{} | #sr_group{}) -> ok | pass.
+-callback import(binary(), binary(), [binary()]) -> ok.
-callback list_groups(binary()) -> [binary()].
-callback groups_with_opts(binary()) -> [{binary(), group_options()}].
-callback create_group(binary(), binary(), group_options()) -> {atomic, any()}.
@@ -1072,13 +1072,16 @@ export(LServer) ->
Mod = gen_mod:db_mod(LServer, ?MODULE),
Mod:export(LServer).
-import(LServer) ->
- Mod = gen_mod:db_mod(LServer, ?MODULE),
- Mod:import(LServer).
+import_info() ->
+ [{<<"sr_group">>, 3}, {<<"sr_user">>, 3}].
+
+import_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].
diff --git a/src/mod_shared_roster_mnesia.erl b/src/mod_shared_roster_mnesia.erl
index eb7c3c37d..0f9e93bf6 100644
--- a/src/mod_shared_roster_mnesia.erl
+++ b/src/mod_shared_roster_mnesia.erl
@@ -15,11 +15,12 @@
delete_group/2, get_group_opts/2, set_group_opts/3,
get_user_groups/2, get_group_explicit_users/2,
get_user_displayed_groups/3, is_user_in_group/3,
- add_user_to_group/3, remove_user_from_group/3, import/2]).
+ add_user_to_group/3, remove_user_from_group/3, import/3]).
-include("mod_roster.hrl").
-include("mod_shared_roster.hrl").
-include("logger.hrl").
+-include("xmpp.hrl").
%%%===================================================================
%%% API
@@ -118,10 +119,14 @@ remove_user_from_group(Host, US, Group) ->
F = fun () -> mnesia:delete_object(R) end,
mnesia:transaction(F).
-import(_LServer, #sr_group{} = G) ->
+import(LServer, <<"sr_group">>, [Group, SOpts, _TimeStamp]) ->
+ G = #sr_group{group_host = {Group, LServer},
+ opts = ejabberd_sql:decode_term(SOpts)},
mnesia:dirty_write(G);
-import(_LServer, #sr_user{} = U) ->
- mnesia:dirty_write(U).
+import(LServer, <<"sr_user">>, [SJID, Group, _TimeStamp]) ->
+ #jid{luser = U, lserver = S} = jid:from_string(SJID),
+ User = #sr_user{us = {U, S}, group_host = {Group, LServer}},
+ mnesia:dirty_write(User).
%%%===================================================================
%%% Internal functions
diff --git a/src/mod_shared_roster_riak.erl b/src/mod_shared_roster_riak.erl
index 49d6edfcd..bdb750981 100644
--- a/src/mod_shared_roster_riak.erl
+++ b/src/mod_shared_roster_riak.erl
@@ -15,10 +15,11 @@
delete_group/2, get_group_opts/2, set_group_opts/3,
get_user_groups/2, get_group_explicit_users/2,
get_user_displayed_groups/3, is_user_in_group/3,
- add_user_to_group/3, remove_user_from_group/3, import/2]).
+ add_user_to_group/3, remove_user_from_group/3, import/3]).
-include("mod_roster.hrl").
-include("mod_shared_roster.hrl").
+-include("xmpp.hrl").
%%%===================================================================
%%% API
@@ -120,13 +121,17 @@ add_user_to_group(Host, US, Group) ->
remove_user_from_group(Host, US, Group) ->
{atomic, ejabberd_riak:delete(sr_group, {US, {Group, Host}})}.
-import(_LServer, #sr_group{group_host = {_, Host}} = G) ->
- ejabberd_riak:put(G, sr_group_schema(), [{'2i', [{<<"host">>, Host}]}]);
-import(_LServer, #sr_user{us = US, group_host = {Group, Host}} = User) ->
+import(LServer, <<"sr_group">>, [Group, SOpts, _TimeStamp]) ->
+ G = #sr_group{group_host = {Group, LServer},
+ opts = ejabberd_sql:decode_term(SOpts)},
+ ejabberd_riak:put(G, sr_group_schema(), [{'2i', [{<<"host">>, LServer}]}]);
+import(LServer, <<"sr_user">>, [SJID, Group|_]) ->
+ #jid{luser = U, lserver = S} = jid:from_string(SJID),
+ User = #sr_user{us = {U, S}, group_host = {Group, LServer}},
ejabberd_riak:put(User, sr_user_schema(),
- [{i, {US, {Group, Host}}},
- {'2i', [{<<"us">>, US},
- {<<"group_host">>, {Group, Host}}]}]).
+ [{i, {{U, S}, {Group, LServer}}},
+ {'2i', [{<<"us">>, {U, S}},
+ {<<"group_host">>, {Group, LServer}}]}]).
%%%===================================================================
%%% Internal functions
diff --git a/src/mod_shared_roster_sql.erl b/src/mod_shared_roster_sql.erl
index 5cffffeb3..9f723f839 100644
--- a/src/mod_shared_roster_sql.erl
+++ b/src/mod_shared_roster_sql.erl
@@ -17,8 +17,8 @@
delete_group/2, get_group_opts/2, set_group_opts/3,
get_user_groups/2, get_group_explicit_users/2,
get_user_displayed_groups/3, is_user_in_group/3,
- add_user_to_group/3, remove_user_from_group/3, import/1,
- import/2, export/1]).
+ add_user_to_group/3, remove_user_from_group/3, import/3,
+ export/1]).
-include("jid.hrl").
-include("mod_roster.hrl").
@@ -177,20 +177,8 @@ export(_Server) ->
[]
end}].
-import(LServer) ->
- [{<<"select name, opts from sr_group;">>,
- fun([Group, SOpts]) ->
- #sr_group{group_host = {Group, LServer},
- opts = ejabberd_sql:decode_term(SOpts)}
- end},
- {<<"select jid, grp from sr_user;">>,
- fun([SJID, Group]) ->
- #jid{luser = U, lserver = S} = jid:from_string(SJID),
- #sr_user{us = {U, S}, group_host = {Group, LServer}}
- end}].
-
-import(_, _) ->
- pass.
+import(_, _, _) ->
+ ok.
%%%===================================================================
%%% Internal functions
diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl
index 35b907f95..dc9476206 100644
--- a/src/mod_vcard.erl
+++ b/src/mod_vcard.erl
@@ -34,8 +34,8 @@
-export([start/2, init/3, stop/1, get_sm_features/5,
process_local_iq/1, process_sm_iq/1, string2lower/1,
- remove_user/2, export/1, import/1, import/3, depends/2,
- process_search/1, process_vcard/1, get_vcard/2,
+ remove_user/2, export/1, import_info/0, import/5, import_start/2,
+ depends/2, process_search/1, process_vcard/1, get_vcard/2,
disco_items/5, disco_features/5, disco_identity/5,
decode_iq_subel/1, mod_opt_type/1, set_vcard/3, make_vcard_search/4]).
@@ -50,7 +50,7 @@
-callback init(binary(), gen_mod:opts()) -> any().
-callback stop(binary()) -> any().
--callback import(binary(), #vcard{} | #vcard_search{}) -> ok | pass.
+-callback import(binary(), binary(), [binary()]) -> ok.
-callback get_vcard(binary(), binary()) -> [xmlel()] | error.
-callback set_vcard(binary(), binary(),
xmlel(), #vcard_search{}) -> {atomic, any()}.
@@ -59,6 +59,7 @@
-callback search(binary(), [{binary(), [binary()]}], boolean(),
infinity | pos_integer()) -> [{binary(), binary()}].
-callback remove_user(binary(), binary()) -> {atomic, any()}.
+-callback is_search_supported(binary()) -> boolean().
start(Host, Opts) ->
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
@@ -105,6 +106,15 @@ init(Host, ServerHost, Search) ->
false -> loop(Host, ServerHost);
_ ->
ejabberd_router:register_route(Host, ServerHost),
+ Mod = gen_mod:db_mod(ServerHost, ?MODULE),
+ case Mod:is_search_supported(ServerHost) of
+ false ->
+ ?WARNING_MSG("vcard search functionality is "
+ "not implemented for ~s backend",
+ [gen_mod:db_type(ServerHost, ?MODULE)]);
+ true ->
+ ejabberd_router:register_route(Host, ServerHost)
+ end,
loop(Host, ServerHost)
end.
@@ -438,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) ->
[].
diff --git a/src/mod_vcard_mnesia.erl b/src/mod_vcard_mnesia.erl
index 3b64c29ef..a4a5f2562 100644
--- a/src/mod_vcard_mnesia.erl
+++ b/src/mod_vcard_mnesia.erl
@@ -11,8 +11,9 @@
-behaviour(mod_vcard).
%% API
--export([init/2, stop/1, import/2, get_vcard/2, set_vcard/4, search/4,
+-export([init/2, stop/1, import/3, get_vcard/2, set_vcard/4, search/4,
search_fields/1, search_reported/1, remove_user/2]).
+-export([is_search_supported/1]).
-include("ejabberd.hrl").
-include("xmpp.hrl").
@@ -47,6 +48,9 @@ init(_Host, _Opts) ->
stop(_Host) ->
ok.
+is_search_supported(_ServerHost) ->
+ true.
+
get_vcard(LUser, LServer) ->
US = {LUser, LServer},
F = fun () -> mnesia:read({vcard, US}) end,
@@ -121,10 +125,29 @@ remove_user(LUser, LServer) ->
end,
mnesia:transaction(F).
-import(_LServer, #vcard{} = VCard) ->
+import(LServer, <<"vcard">>, [LUser, XML, _TimeStamp]) ->
+ #xmlel{} = El = fxml_stream:parse_element(XML),
+ VCard = #vcard{us = {LUser, LServer}, vcard = El},
mnesia:dirty_write(VCard);
-import(_LServer, #vcard_search{} = S) ->
- mnesia:dirty_write(S).
+import(LServer, <<"vcard_search">>,
+ [User, LUser, FN, LFN,
+ Family, LFamily, Given, LGiven,
+ Middle, LMiddle, Nickname, LNickname,
+ BDay, LBDay, CTRY, LCTRY, Locality, LLocality,
+ EMail, LEMail, OrgName, LOrgName, OrgUnit, LOrgUnit]) ->
+ mnesia:dirty_write(
+ #vcard_search{us = {LUser, LServer},
+ user = {User, LServer}, luser = LUser,
+ fn = FN, lfn = LFN, family = Family,
+ lfamily = LFamily, given = Given,
+ lgiven = LGiven, middle = Middle,
+ lmiddle = LMiddle, nickname = Nickname,
+ lnickname = LNickname, bday = BDay,
+ lbday = LBDay, ctry = CTRY, lctry = LCTRY,
+ locality = Locality, llocality = LLocality,
+ email = EMail, lemail = LEMail,
+ orgname = OrgName, lorgname = LOrgName,
+ orgunit = OrgUnit, lorgunit = LOrgUnit}).
%%%===================================================================
%%% Internal functions
diff --git a/src/mod_vcard_riak.erl b/src/mod_vcard_riak.erl
index 23f05f17d..411ec45fa 100644
--- a/src/mod_vcard_riak.erl
+++ b/src/mod_vcard_riak.erl
@@ -12,7 +12,8 @@
%% API
-export([init/2, get_vcard/2, set_vcard/4, search/4, remove_user/2,
- search_fields/1, search_reported/1, import/2, stop/1]).
+ search_fields/1, search_reported/1, import/3, stop/1]).
+-export([is_search_supported/1]).
-include("xmpp.hrl").
-include("mod_vcard.hrl").
@@ -26,6 +27,9 @@ init(_Host, _Opts) ->
stop(_Host) ->
ok.
+is_search_supported(_LServer) ->
+ false.
+
get_vcard(LUser, LServer) ->
case ejabberd_riak:get(vcard, vcard_schema(), {LUser, LServer}) of
{ok, R} ->
@@ -101,7 +105,9 @@ search_reported(_LServer) ->
remove_user(LUser, LServer) ->
{atomic, ejabberd_riak:delete(vcard, {LUser, LServer})}.
-import(_LServer, #vcard{us = {LUser, LServer}, vcard = El} = VCard) ->
+import(LServer, <<"vcard">>, [LUser, XML, _TimeStamp]) ->
+ El = fxml_stream:parse_element(XML),
+ VCard = #vcard{us = {LUser, LServer}, vcard = El},
#vcard_search{fn = FN,
lfn = LFN,
family = Family,
@@ -150,7 +156,7 @@ import(_LServer, #vcard{us = {LUser, LServer}, vcard = El} = VCard) ->
{<<"lorgname">>, LOrgName},
{<<"orgunit">>, OrgUnit},
{<<"lorgunit">>, LOrgUnit}]}]);
-import(_LServer, #vcard_search{}) ->
+import(_LServer, <<"vcard_search">>, _) ->
ok.
%%%===================================================================
diff --git a/src/mod_vcard_sql.erl b/src/mod_vcard_sql.erl
index 129f76b5a..7fd64c44e 100644
--- a/src/mod_vcard_sql.erl
+++ b/src/mod_vcard_sql.erl
@@ -14,7 +14,8 @@
%% API
-export([init/2, stop/1, get_vcard/2, set_vcard/4, search/4, remove_user/2,
- search_fields/1, search_reported/1, import/1, import/2, export/1]).
+ search_fields/1, search_reported/1, import/3, export/1]).
+-export([is_search_supported/1]).
-include("xmpp.hrl").
-include("mod_vcard.hrl").
@@ -30,6 +31,9 @@ init(_Host, _Opts) ->
stop(_Host) ->
ok.
+is_search_supported(_LServer) ->
+ true.
+
get_vcard(LUser, LServer) ->
case catch sql_queries:get_vcard(LServer, LUser) of
{selected, [{SVCARD}]} ->
@@ -188,37 +192,8 @@ export(_Server) ->
[]
end}].
-import(LServer) ->
- [{<<"select username, vcard from vcard;">>,
- fun([LUser, SVCard]) ->
- #xmlel{} = VCARD = fxml_stream:parse_element(SVCard),
- #vcard{us = {LUser, LServer}, vcard = VCARD}
- end},
- {<<"select username, lusername, fn, lfn, family, lfamily, "
- "given, lgiven, middle, lmiddle, nickname, lnickname, "
- "bday, lbday, ctry, lctry, locality, llocality, email, "
- "lemail, orgname, lorgname, orgunit, lorgunit from vcard_search;">>,
- fun([User, LUser, FN, LFN,
- Family, LFamily, Given, LGiven,
- Middle, LMiddle, Nickname, LNickname,
- BDay, LBDay, CTRY, LCTRY, Locality, LLocality,
- EMail, LEMail, OrgName, LOrgName, OrgUnit, LOrgUnit]) ->
- #vcard_search{us = {LUser, LServer},
- user = {User, LServer}, luser = LUser,
- fn = FN, lfn = LFN, family = Family,
- lfamily = LFamily, given = Given,
- lgiven = LGiven, middle = Middle,
- lmiddle = LMiddle, nickname = Nickname,
- lnickname = LNickname, bday = BDay,
- lbday = LBDay, ctry = CTRY, lctry = LCTRY,
- locality = Locality, llocality = LLocality,
- email = EMail, lemail = LEMail,
- orgname = OrgName, lorgname = LOrgName,
- orgunit = OrgUnit, lorgunit = LOrgUnit}
- end}].
-
-import(_, _) ->
- pass.
+import(_, _, _) ->
+ ok.
%%%===================================================================
%%% Internal functions
diff --git a/src/mod_vcard_xupdate.erl b/src/mod_vcard_xupdate.erl
index 27688e8fb..4d1dfa2fc 100644
--- a/src/mod_vcard_xupdate.erl
+++ b/src/mod_vcard_xupdate.erl
@@ -13,14 +13,15 @@
-export([start/2, stop/1]).
-export([update_presence/3, vcard_set/3, export/1,
- import/1, import/3, mod_opt_type/1, depends/2]).
+ import_info/0, import/5, import_start/2,
+ mod_opt_type/1, depends/2]).
-include("ejabberd.hrl").
-include("logger.hrl").
-include("xmpp.hrl").
-callback init(binary(), gen_mod:opts()) -> any().
--callback import(binary(), #vcard_xupdate{}) -> ok | pass.
+-callback import(binary(), binary(), [binary()]) -> ok.
-callback add_xupdate(binary(), binary(), binary()) -> {atomic, any()}.
-callback get_xupdate(binary(), binary()) -> binary() | undefined.
-callback remove_xupdate(binary(), binary()) -> {atomic, any()}.
@@ -94,17 +95,20 @@ presence_with_xupdate(Presence, User, Host) ->
Presence1 = xmpp:remove_subtag(Presence, #vcard_xupdate{}),
xmpp:set_subtag(Presence1, #vcard_xupdate{hash = Hash}).
-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].
diff --git a/src/mod_vcard_xupdate_mnesia.erl b/src/mod_vcard_xupdate_mnesia.erl
index f1b1693e4..3f8d6fcab 100644
--- a/src/mod_vcard_xupdate_mnesia.erl
+++ b/src/mod_vcard_xupdate_mnesia.erl
@@ -10,7 +10,7 @@
-behaviour(mod_vcard_xupdate).
%% API
--export([init/2, import/2, add_xupdate/3, get_xupdate/2, remove_xupdate/2]).
+-export([init/2, import/3, add_xupdate/3, get_xupdate/2, remove_xupdate/2]).
-include("mod_vcard_xupdate.hrl").
-include("logger.hrl").
@@ -45,8 +45,9 @@ remove_xupdate(LUser, LServer) ->
end,
mnesia:transaction(F).
-import(_LServer, #vcard_xupdate{} = R) ->
- mnesia:dirty_write(R).
+import(LServer, <<"vcard_xupdate">>, [LUser, Hash, _TimeStamp]) ->
+ mnesia:dirty_write(
+ #vcard_xupdate{us = {LUser, LServer}, hash = Hash}).
%%%===================================================================
%%% Internal functions
diff --git a/src/mod_vcard_xupdate_riak.erl b/src/mod_vcard_xupdate_riak.erl
index 242485bf2..cff77f887 100644
--- a/src/mod_vcard_xupdate_riak.erl
+++ b/src/mod_vcard_xupdate_riak.erl
@@ -11,7 +11,7 @@
-behaviour(mod_vcard_xupdate).
%% API
--export([init/2, import/2, add_xupdate/3, get_xupdate/2, remove_xupdate/2]).
+-export([init/2, import/3, add_xupdate/3, get_xupdate/2, remove_xupdate/2]).
-include("mod_vcard_xupdate.hrl").
@@ -36,8 +36,10 @@ get_xupdate(LUser, LServer) ->
remove_xupdate(LUser, LServer) ->
{atomic, ejabberd_riak:delete(vcard_xupdate, {LUser, LServer})}.
-import(_LServer, #vcard_xupdate{} = R) ->
- ejabberd_riak:put(R, vcard_xupdate_schema()).
+import(LServer, <<"vcard_xupdate">>, [LUser, Hash, _TimeStamp]) ->
+ ejabberd_riak:put(
+ #vcard_xupdate{us = {LUser, LServer}, hash = Hash},
+ vcard_xupdate_schema()).
%%%===================================================================
%%% Internal functions
diff --git a/src/mod_vcard_xupdate_sql.erl b/src/mod_vcard_xupdate_sql.erl
index 938114b8f..fd2716c33 100644
--- a/src/mod_vcard_xupdate_sql.erl
+++ b/src/mod_vcard_xupdate_sql.erl
@@ -13,8 +13,8 @@
-behaviour(mod_vcard_xupdate).
%% API
--export([init/2, import/2, add_xupdate/3, get_xupdate/2, remove_xupdate/2,
- import/1, export/1]).
+-export([init/2, import/3, add_xupdate/3, get_xupdate/2, remove_xupdate/2,
+ export/1]).
-include("mod_vcard_xupdate.hrl").
-include("ejabberd_sql_pt.hrl").
@@ -62,14 +62,8 @@ export(_Server) ->
[]
end}].
-import(LServer) ->
- [{<<"select username, hash from vcard_xupdate;">>,
- fun([LUser, Hash]) ->
- #vcard_xupdate{us = {LUser, LServer}, hash = Hash}
- end}].
-
-import(_LServer, _) ->
- pass.
+import(_, _, _) ->
+ ok.
%%%===================================================================
%%% Internal functions