diff options
Diffstat (limited to 'src/mod_vcard_sql.erl')
-rw-r--r-- | src/mod_vcard_sql.erl | 253 |
1 files changed, 171 insertions, 82 deletions
diff --git a/src/mod_vcard_sql.erl b/src/mod_vcard_sql.erl index b8234bf9c..6b604161f 100644 --- a/src/mod_vcard_sql.erl +++ b/src/mod_vcard_sql.erl @@ -1,25 +1,42 @@ %%%------------------------------------------------------------------- -%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net> -%%% @copyright (C) 2016, Evgeny Khramtsov -%%% @doc -%%% -%%% @end +%%% File : mod_vcard_sql.erl +%%% Author : Evgeny Khramtsov <ekhramtsov@process-one.net> %%% Created : 13 Apr 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net> -%%%------------------------------------------------------------------- +%%% +%%% +%%% ejabberd, Copyright (C) 2002-2019 ProcessOne +%%% +%%% This program is free software; you can redistribute it and/or +%%% modify it under the terms of the GNU General Public License as +%%% published by the Free Software Foundation; either version 2 of the +%%% License, or (at your option) any later version. +%%% +%%% This program is distributed in the hope that it will be useful, +%%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%%% General Public License for more details. +%%% +%%% You should have received a copy of the GNU General Public License along +%%% with this program; if not, write to the Free Software Foundation, Inc., +%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +%%% +%%%---------------------------------------------------------------------- + -module(mod_vcard_sql). --compile([{parse_transform, ejabberd_sql_pt}]). -behaviour(mod_vcard). %% API --export([init/2, get_vcard/2, set_vcard/4, search/4, remove_user/2, - import/1, import/2, export/1]). +-export([init/2, stop/1, get_vcard/2, set_vcard/4, search/4, remove_user/2, + search_fields/1, search_reported/1, import/3, export/1]). +-export([is_search_supported/1]). --include("jlib.hrl"). +-include("xmpp.hrl"). -include("mod_vcard.hrl"). -include("logger.hrl"). -include("ejabberd_sql_pt.hrl"). +-include("translate.hrl"). %%%=================================================================== %%% API @@ -27,14 +44,23 @@ init(_Host, _Opts) -> ok. +stop(_Host) -> + ok. + +is_search_supported(_LServer) -> + true. + get_vcard(LUser, LServer) -> - case catch sql_queries:get_vcard(LServer, LUser) of + case ejabberd_sql:sql_query( + LServer, + ?SQL("select @(vcard)s from vcard" + " where username=%(LUser)s and %(LServer)H")) of {selected, [{SVCARD}]} -> case fxml_stream:parse_element(SVCARD) of {error, _Reason} -> error; - VCARD -> [VCARD] + VCARD -> {ok, [VCARD]} end; - {selected, []} -> []; + {selected, []} -> {ok, []}; _ -> error end. @@ -63,13 +89,40 @@ set_vcard(LUser, LServer, VCARD, orgunit = OrgUnit, lorgunit = LOrgUnit}) -> SVCARD = fxml:element_to_binary(VCARD), - sql_queries:set_vcard(LServer, LUser, BDay, CTRY, - EMail, FN, Family, Given, LBDay, - LCTRY, LEMail, LFN, LFamily, - LGiven, LLocality, LMiddle, - LNickname, LOrgName, LOrgUnit, - Locality, Middle, Nickname, OrgName, - OrgUnit, SVCARD, User). + ejabberd_sql:sql_transaction( + LServer, + fun() -> + ?SQL_UPSERT(LServer, "vcard", + ["!username=%(LUser)s", + "!server_host=%(LServer)s", + "vcard=%(SVCARD)s"]), + ?SQL_UPSERT(LServer, "vcard_search", + ["username=%(User)s", + "!lusername=%(LUser)s", + "!server_host=%(LServer)s", + "fn=%(FN)s", + "lfn=%(LFN)s", + "family=%(Family)s", + "lfamily=%(LFamily)s", + "given=%(Given)s", + "lgiven=%(LGiven)s", + "middle=%(Middle)s", + "lmiddle=%(LMiddle)s", + "nickname=%(Nickname)s", + "lnickname=%(LNickname)s", + "bday=%(BDay)s", + "lbday=%(LBDay)s", + "ctry=%(CTRY)s", + "lctry=%(LCTRY)s", + "locality=%(Locality)s", + "llocality=%(LLocality)s", + "email=%(EMail)s", + "lemail=%(LEMail)s", + "orgname=%(OrgName)s", + "lorgname=%(LOrgName)s", + "orgunit=%(OrgUnit)s", + "lorgunit=%(LOrgUnit)s"]) + end). search(LServer, Data, AllowReturnAll, MaxMatch) -> MatchSpec = make_matchspec(LServer, Data), @@ -79,7 +132,7 @@ search(LServer, Data, AllowReturnAll, MaxMatch) -> infinity -> <<"">>; Val -> - [<<" LIMIT ">>, jlib:integer_to_binary(Val)] + [<<" LIMIT ">>, integer_to_binary(Val)] end, case catch ejabberd_sql:sql_query( LServer, @@ -93,20 +146,50 @@ search(LServer, Data, AllowReturnAll, MaxMatch) -> <<"middle">>, <<"nickname">>, <<"bday">>, <<"ctry">>, <<"locality">>, <<"email">>, <<"orgname">>, <<"orgunit">>], Rs} when is_list(Rs) -> - Rs; + [row_to_item(LServer, R) || R <- Rs]; Error -> ?ERROR_MSG("~p", [Error]), [] end end. +search_fields(_LServer) -> + [{?T("User"), <<"user">>}, + {?T("Full Name"), <<"fn">>}, + {?T("Name"), <<"first">>}, + {?T("Middle Name"), <<"middle">>}, + {?T("Family Name"), <<"last">>}, + {?T("Nickname"), <<"nick">>}, + {?T("Birthday"), <<"bday">>}, + {?T("Country"), <<"ctry">>}, + {?T("City"), <<"locality">>}, + {?T("Email"), <<"email">>}, + {?T("Organization Name"), <<"orgname">>}, + {?T("Organization Unit"), <<"orgunit">>}]. + +search_reported(_LServer) -> + [{?T("Jabber ID"), <<"jid">>}, + {?T("Full Name"), <<"fn">>}, + {?T("Name"), <<"first">>}, + {?T("Middle Name"), <<"middle">>}, + {?T("Family Name"), <<"last">>}, + {?T("Nickname"), <<"nick">>}, + {?T("Birthday"), <<"bday">>}, + {?T("Country"), <<"ctry">>}, + {?T("City"), <<"locality">>}, + {?T("Email"), <<"email">>}, + {?T("Organization Name"), <<"orgname">>}, + {?T("Organization Unit"), <<"orgunit">>}]. + remove_user(LUser, LServer) -> ejabberd_sql:sql_transaction( LServer, fun() -> ejabberd_sql:sql_query_t( - ?SQL("delete from vcard where username=%(LUser)s")), + ?SQL("delete from vcard" + " where username=%(LUser)s and %(LServer)H")), ejabberd_sql:sql_query_t( - ?SQL("delete from vcard_search where lusername=%(LUser)s")) + ?SQL("delete from vcard_search" + " where lusername=%(LUser)s and %(LServer)H")) end). export(_Server) -> @@ -114,9 +197,12 @@ export(_Server) -> fun(Host, #vcard{us = {LUser, LServer}, vcard = VCARD}) when LServer == Host -> SVCARD = fxml:element_to_binary(VCARD), - [?SQL("delete from vcard where username=%(LUser)s;"), - ?SQL("insert into vcard(username, vcard) values (" - "%(LUser)s, %(SVCARD)s);")]; + [?SQL("delete from vcard" + " where username=%(LUser)s and %(LServer)H;"), + ?SQL_INSERT("vcard", + ["username=%(LUser)s", + "server_host=%(LServer)s", + "vcard=%(SVCARD)s"])]; (_Host, _R) -> [] end}, @@ -133,61 +219,40 @@ export(_Server) -> orgname = OrgName, lorgname = LOrgName, orgunit = OrgUnit, lorgunit = LOrgUnit}) when LServer == Host -> - [?SQL("delete from vcard_search where lusername=%(LUser)s;"), - ?SQL("insert into vcard_search(username," - " lusername, fn, lfn, family, lfamily," - " given, lgiven, middle, lmiddle," - " nickname, lnickname, bday, lbday," - " ctry, lctry, locality, llocality," - " email, lemail, orgname, lorgname," - " orgunit, lorgunit) values (" - " %(LUser)s, %(User)s," - " %(FN)s, %(LFN)s," - " %(Family)s, %(LFamily)s," - " %(Given)s, %(LGiven)s," - " %(Middle)s, %(LMiddle)s," - " %(Nickname)s, %(LNickname)s," - " %(BDay)s, %(LBDay)s," - " %(CTRY)s, %(LCTRY)s," - " %(Locality)s, %(LLocality)s," - " %(EMail)s, %(LEMail)s," - " %(OrgName)s, %(LOrgName)s," - " %(OrgUnit)s, %(LOrgUnit)s);")]; + [?SQL("delete from vcard_search" + " where lusername=%(LUser)s and %(LServer)H;"), + ?SQL_INSERT("vcard_search", + ["username=%(User)s", + "lusername=%(LUser)s", + "server_host=%(LServer)s", + "fn=%(FN)s", + "lfn=%(LFN)s", + "family=%(Family)s", + "lfamily=%(LFamily)s", + "given=%(Given)s", + "lgiven=%(LGiven)s", + "middle=%(Middle)s", + "lmiddle=%(LMiddle)s", + "nickname=%(Nickname)s", + "lnickname=%(LNickname)s", + "bday=%(BDay)s", + "lbday=%(LBDay)s", + "ctry=%(CTRY)s", + "lctry=%(LCTRY)s", + "locality=%(Locality)s", + "llocality=%(LLocality)s", + "email=%(EMail)s", + "lemail=%(LEMail)s", + "orgname=%(OrgName)s", + "lorgname=%(LOrgName)s", + "orgunit=%(OrgUnit)s", + "lorgunit=%(LOrgUnit)s"])]; (_Host, _R) -> [] 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 @@ -195,10 +260,19 @@ import(_, _) -> make_matchspec(LServer, Data) -> filter_fields(Data, <<"">>, LServer). -filter_fields([], Match, _LServer) -> - case Match of - <<"">> -> <<"">>; - _ -> [<<" where ">>, Match] +filter_fields([], Match, LServer) -> + case ejabberd_sql:use_new_schema() of + true -> + SServer = ejabberd_sql:escape(LServer), + case Match of + <<"">> -> [<<"where server_host='">>, SServer, <<"'">>]; + _ -> [<<" where server_host='">>, SServer, <<"' and ">>, Match] + end; + false -> + case Match of + <<"">> -> <<"">>; + _ -> [<<" where ">>, Match] + end end; filter_fields([{SVar, [Val]} | Ds], Match, LServer) when is_binary(Val) and (Val /= <<"">>) -> @@ -240,3 +314,18 @@ make_val(Match, Field, Val) -> <<"">> -> Condition; _ -> [Match, <<" and ">>, Condition] end. + +row_to_item(LServer, [Username, FN, Family, Given, Middle, Nickname, BDay, + CTRY, Locality, EMail, OrgName, OrgUnit]) -> + [{<<"jid">>, <<Username/binary, $@, LServer/binary>>}, + {<<"fn">>, FN}, + {<<"last">>, Family}, + {<<"first">>, Given}, + {<<"middle">>, Middle}, + {<<"nick">>, Nickname}, + {<<"bday">>, BDay}, + {<<"ctry">>, CTRY}, + {<<"locality">>, Locality}, + {<<"email">>, EMail}, + {<<"orgname">>, OrgName}, + {<<"orgunit">>, OrgUnit}]. |