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

Preliminary export PubSub data from Mnesia tables to SQL file (#1571)

This commit is contained in:
Badlop 2017-08-03 10:52:44 +02:00
parent 6deceeec2e
commit 5dcc97c85a
2 changed files with 99 additions and 2 deletions

View File

@ -58,6 +58,7 @@ modules() ->
mod_offline,
mod_privacy,
mod_private,
mod_pubsub,
mod_roster,
mod_shared_roster,
mod_vcard].
@ -80,8 +81,8 @@ export(Server, Output, Module) ->
case export(LServer, Table, IO, ConvertFun) of
{atomic, ok} -> ok;
{aborted, Reason} ->
?ERROR_MSG("Failed export for module ~p: ~p",
[Module, Reason])
?ERROR_MSG("Failed export for module ~p and table ~p: ~p",
[Module, Table, Reason])
end
end, Module:export(Server)),
close_output(Output, IO).

View File

@ -39,6 +39,8 @@
-protocol({xep, 163, '1.2'}).
-protocol({xep, 248, '0.2'}).
-compile([{parse_transform, ejabberd_sql_pt}]).
-include("ejabberd.hrl").
-include("logger.hrl").
-include("xmpp.hrl").
@ -92,6 +94,11 @@
terminate/2, code_change/3, depends/2]).
-export([send_loop/1, mod_opt_type/1]).
-export([export/1]).
-include("ejabberd_sql_pt.hrl").
-define(PROCNAME, ejabberd_mod_pubsub).
-define(LOOPNAME, ejabberd_mod_pubsub_loop).
@ -3866,6 +3873,95 @@ purge_offline(Host, LJID, Node) ->
Error
end.
%% REVIEW:
%% * this code takes NODEID from Itemid2, and forgets about Nodeidx
%% * this code assumes Payload only contains one xmlelement()
%% * PUBLISHER is taken from Creation
export(_Server) ->
[{pubsub_item,
fun(_Host, #pubsub_item{itemid = {Itemid1, NODEID},
%nodeidx = _Nodeidx,
creation = {{C1, C2, C3}, Cusr},
modification = {{M1, M2, M3}, _Musr},
payload = Payload}) ->
ITEMID = ejabberd_sql:escape(Itemid1),
CREATION = ejabberd_sql:escape(list_to_binary(
string:join([string:right(integer_to_list(I),6,$0)||I<-[C1,C2,C3]],":"))),
MODIFICATION = ejabberd_sql:escape(list_to_binary(
string:join([string:right(integer_to_list(I),6,$0)||I<-[M1,M2,M3]],":"))),
PUBLISHER = ejabberd_sql:escape(jid:encode(Cusr)),
[PayloadEl] = [El || {xmlel,_,_,_} = El <- Payload],
PAYLOAD = ejabberd_sql:escape(fxml:element_to_binary(PayloadEl)),
[?SQL("delete from pubsub_item where itemid=%(ITEMID)s;"),
?SQL("insert into pubsub_item(itemid,nodeid,creation,modification,publisher,payload) \n"
" values (%(ITEMID)s, %(NODEID)d, %(CREATION)s,
%(MODIFICATION)s, %(PUBLISHER)s, %(PAYLOAD)s);")];
(_Host, _R) ->
[]
end},
%% REVIEW:
%% * From the mnesia table, the #pubsub_state.items is not used in ODBC
%% * Right now AFFILIATION is the first letter of Affiliation
%% * Right now SUBSCRIPTIONS expects only one Subscription
%% * Right now SUBSCRIPTIONS letter is the first letter of Subscription
{pubsub_state,
fun(_Host, #pubsub_state{stateid = {Jid, Stateid},
%nodeidx = Nodeidx,
items = _Items,
affiliation = Affiliation,
subscriptions = Subscriptions}) ->
STATEID = list_to_binary(integer_to_list(Stateid)),
JID = ejabberd_sql:escape(jid:encode(Jid)),
NODEID = <<"unknown">>, %% TODO: integer_to_list(Nodeidx),
AFFILIATION = list_to_binary(string:substr(atom_to_list(Affiliation),1,1)),
SUBSCRIPTIONS = list_to_binary(parse_subscriptions(Subscriptions)),
[?SQL("delete from pubsub_state where stateid=%(STATEID)s;"),
?SQL("insert into pubsub_state(stateid,jid,nodeid,affiliation,subscriptions)\n"
" values (%(STATEID)s, %(JID)s, %(NODEID)s, %(AFFILIATION)s, %(SUBSCRIPTIONS)s);")];
(_Host, _R) ->
[]
end},
%% REVIEW:
%% * Parents is not migrated to PARENTs
%% * Probably some option VALs are not correctly represented in mysql
{pubsub_node,
fun(_Host, #pubsub_node{nodeid = {Hostid, Nodeid},
id = Id,
parents = _Parents,
type = Type,
owners = Owners,
options = Options}) ->
HOST = case Hostid of
{U,S,R} -> ejabberd_sql:escape(jlib:jid_to_string({U,S,R}));
_ -> ejabberd_sql:escape(Hostid)
end,
NODE = ejabberd_sql:escape(Nodeid),
PARENT = <<"">>,
IdB = integer_to_binary(Id),
TYPE = ejabberd_sql:escape(<<Type/binary, "_odbc">>),
[?SQL("delete from pubsub_node where nodeid=%(Id)d;"),
?SQL("insert into pubsub_node(host,node,nodeid,parent,type) \n"
" values (%(HOST)s, %(NODE)s, %(Id)d, %(PARENT)s, %(TYPE)s);"),
?SQL("delete from pubsub_node_option where nodeid=%(Id)d;"),
[["insert into pubsub_node_option(nodeid,name,val)\n"
" values (", IdB, ", '", atom_to_list(Name), "', '",
io_lib:format("~p", [Val]), "');\n"] || {Name,Val} <- Options],
?SQL("delete from pubsub_node_owner where nodeid=%(Id)d;"),
[["insert into pubsub_node_owner(nodeid,owner)\n"
" values (", IdB, ", '", jlib:jid_to_string(Usr), "');\n"] || Usr <- Owners],"\n"];
(_Host, _R) ->
[]
end}].
parse_subscriptions([]) ->
"";
parse_subscriptions([{State, Item}]) ->
STATE = case State of
subscribed -> "s"
end,
string:join([STATE, Item],":").
mod_opt_type(access_createnode) -> fun acl:access_rules_validator/1;
mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end;
mod_opt_type(host) -> fun iolist_to_binary/1;