25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-12-20 17:27:00 +01:00

Make it possible to import without cursor usage

This commit is contained in:
Evgeniy Khramtsov 2013-07-22 10:46:00 +10:00
parent ca6463ed78
commit f75d78d3f5

View File

@ -103,21 +103,24 @@ import_file(Server, FileName) ->
end. end.
import(Server, Output) -> import(Server, Output) ->
import(Server, Output, [{fast, true}]).
import(Server, Output, Opts) ->
LServer = jlib:nameprep(iolist_to_binary(Server)), LServer = jlib:nameprep(iolist_to_binary(Server)),
Modules = modules(), Modules = modules(),
IO = prepare_output(Output, disk_log), IO = prepare_output(Output, disk_log),
lists:foreach( lists:foreach(
fun(Module) -> fun(Module) ->
import(LServer, IO, Module) import(LServer, IO, Opts, Module)
end, Modules), end, Modules),
close_output(Output, IO). close_output(Output, IO).
import(Server, Output, Module) -> import(Server, Output, Opts, Module) ->
LServer = jlib:nameprep(iolist_to_binary(Server)), LServer = jlib:nameprep(iolist_to_binary(Server)),
IO = prepare_output(Output, disk_log), IO = prepare_output(Output, disk_log),
lists:foreach( lists:foreach(
fun({SelectQuery, ConvertFun}) -> fun({SelectQuery, ConvertFun}) ->
import(LServer, SelectQuery, IO, ConvertFun) import(LServer, SelectQuery, IO, ConvertFun, Opts)
end, Module:import(Server)), end, Module:import(Server)),
close_output(Output, IO). close_output(Output, IO).
@ -157,31 +160,32 @@ output(_LServer, Table, Fd, SQLs) ->
file:write(Fd, ["-- \n-- Mnesia table: ", atom_to_list(Table), file:write(Fd, ["-- \n-- Mnesia table: ", atom_to_list(Table),
"\n--\n", SQLs]). "\n--\n", SQLs]).
import(LServer, SelectQuery, IO, ConvertFun) -> import(LServer, SelectQuery, IO, ConvertFun, Opts) ->
F = fun() -> F = case proplists:get_bool(fast, Opts) of
ejabberd_odbc:sql_query_t( true ->
iolist_to_binary( fun() ->
[<<"declare c cursor for ">>, SelectQuery])), case ejabberd_odbc:sql_query_t(SelectQuery) of
fetch(IO, ConvertFun) {selected, _, Rows} ->
lists:foldl(fun process_sql_row/2,
{IO, ConvertFun, undefined}, Rows);
Err ->
erlang:error(Err)
end
end;
false ->
fun() ->
ejabberd_odbc:sql_query_t(
iolist_to_binary(
[<<"declare c cursor for ">>, SelectQuery])),
fetch(IO, ConvertFun, undefined)
end
end, end,
ejabberd_odbc:sql_transaction(LServer, F). ejabberd_odbc:sql_transaction(LServer, F).
fetch(IO, ConvertFun) ->
fetch(IO, ConvertFun, undefined).
fetch(IO, ConvertFun, PrevRow) -> fetch(IO, ConvertFun, PrevRow) ->
case ejabberd_odbc:sql_query_t([<<"fetch c;">>]) of 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]} -> {selected, _, [Row]} ->
case catch ConvertFun(Row) of process_sql_row(Row, {IO, ConvertFun, PrevRow}),
{'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); fetch(IO, ConvertFun, Row);
{selected, _, []} -> {selected, _, []} ->
ok; ok;
@ -189,6 +193,18 @@ fetch(IO, ConvertFun, PrevRow) ->
erlang:error(Err) erlang:error(Err)
end. 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}) -> import_dump(LServer, Mods, #dump{fd = Fd, cont = Cont}) ->
case disk_log:chunk(Fd, Cont) of case disk_log:chunk(Fd, Cont) of
{NewCont, Terms} -> {NewCont, Terms} ->