25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-24 16:23:40 +01:00

Add SQL to Mnesia converter

This commit is contained in:
Evgeniy Khramtsov 2013-07-21 20:24:36 +10:00
parent a2ead99c83
commit d58148fa8d
16 changed files with 510 additions and 36 deletions

View 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.

View 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.

View 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)};

View File

@ -28,10 +28,14 @@
-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
%%%----------------------------------------------------------------------
@ -42,21 +46,24 @@
%%% - 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.

View 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.

View 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.

View 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.

View 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.

View 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.

View File

@ -30,11 +30,11 @@
-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.

View 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.

View 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.

View 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.

View 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.

View 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.

View 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, "