aboutsummaryrefslogtreecommitdiff
path: root/src/mod_vcard_sql.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/mod_vcard_sql.erl')
-rw-r--r--src/mod_vcard_sql.erl253
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}].