From 0ea0ba3004282636c95bc86c3aac8755fcf7f8b1 Mon Sep 17 00:00:00 2001 From: Alexey Shchepin Date: Wed, 4 May 2016 21:01:05 +0300 Subject: [PATCH] Update more SQL queries --- src/ejabberd_auth_mnesia.erl | 23 ++++-- src/ejabberd_auth_riak.erl | 13 ++-- src/ejabberd_auth_sql.erl | 49 ++++++------ src/ejabberd_sm_sql.erl | 80 +++++++++---------- src/ejabberd_sql.erl | 4 + src/ejabberd_sql_pt.erl | 24 +++--- src/ejd2sql.erl | 19 ++++- src/mod_announce_sql.erl | 65 ++++++++-------- src/mod_caps_sql.erl | 40 +++++----- src/mod_irc_sql.erl | 55 ++++++-------- src/mod_last_sql.erl | 15 ++-- src/mod_mam_sql.erl | 33 ++++---- src/mod_muc_sql.erl | 139 ++++++++++++++-------------------- src/mod_privacy_sql.erl | 63 ++++++++------- src/mod_private_sql.erl | 8 +- src/mod_roster_sql.erl | 41 +++------- src/mod_shared_roster_sql.erl | 129 +++++++++++++++---------------- src/mod_vcard_sql.erl | 76 ++++++------------- src/mod_vcard_xupdate_sql.erl | 43 +++++------ src/sql_queries.erl | 57 +++++++------- 20 files changed, 458 insertions(+), 518 deletions(-) diff --git a/src/ejabberd_auth_mnesia.erl b/src/ejabberd_auth_mnesia.erl index 9029404d6..58e22c79c 100644 --- a/src/ejabberd_auth_mnesia.erl +++ b/src/ejabberd_auth_mnesia.erl @@ -25,6 +25,8 @@ -module(ejabberd_auth_mnesia). +-compile([{parse_transform, ejabberd_sql_pt}]). + -behaviour(ejabberd_config). -author('alexey@process-one.net'). @@ -43,6 +45,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). +-include("ejabberd_sql_pt.hrl"). -record(passwd, {us = {<<"">>, <<"">>} :: {binary(), binary()} | '$1', password = <<"">> :: binary() | scram() | '_'}). @@ -473,12 +476,22 @@ is_password_scram_valid(Password, Scram) -> export(_Server) -> [{passwd, fun(Host, #passwd{us = {LUser, LServer}, password = Password}) + when LServer == Host, + is_binary(Password) -> + [?SQL("delete from users where username=%(LUser)s;"), + ?SQL("insert into users(username, password) " + "values (%(LUser)s, %(Password)s);")]; + (Host, #passwd{us = {LUser, LServer}, password = #scram{} = Scram}) when LServer == Host -> - Username = ejabberd_sql:escape(LUser), - Pass = ejabberd_sql:escape(Password), - [[<<"delete from users where username='">>, Username, <<"';">>], - [<<"insert into users(username, password) " - "values ('">>, Username, <<"', '">>, Pass, <<"');">>]]; + StoredKey = Scram#scram.storedkey, + ServerKey = Scram#scram.serverkey, + Salt = Scram#scram.salt, + IterationCount = Scram#scram.iterationcount, + [?SQL("delete from users where username=%(LUser)s;"), + ?SQL("insert into users(username, password, serverkey, salt, " + "iterationcount) " + "values (%(LUser)s, %(StoredKey)s, %(ServerKey)s," + " %(Salt)s, %(IterationCount)d);")]; (_Host, _R) -> [] end}]. diff --git a/src/ejabberd_auth_riak.erl b/src/ejabberd_auth_riak.erl index c48b94410..c74f1b28e 100644 --- a/src/ejabberd_auth_riak.erl +++ b/src/ejabberd_auth_riak.erl @@ -25,6 +25,8 @@ -module(ejabberd_auth_riak). +-compile([{parse_transform, ejabberd_sql_pt}]). + -author('alexey@process-one.net'). -behaviour(ejabberd_auth). @@ -42,6 +44,7 @@ -export([passwd_schema/0]). -include("ejabberd.hrl"). +-include("ejabberd_sql_pt.hrl"). -record(passwd, {us = {<<"">>, <<"">>} :: {binary(), binary()} | '$1', password = <<"">> :: binary() | scram() | '_'}). @@ -290,12 +293,10 @@ is_password_scram_valid(Password, Scram) -> export(_Server) -> [{passwd, fun(Host, #passwd{us = {LUser, LServer}, password = Password}) - when LServer == Host -> - Username = ejabberd_sql:escape(LUser), - Pass = ejabberd_sql:escape(Password), - [[<<"delete from users where username='">>, Username, <<"';">>], - [<<"insert into users(username, password) " - "values ('">>, Username, <<"', '">>, Pass, <<"');">>]]; + when LServer == Host -> + [?SQL("delete from users where username=%(LUser)s;"), + ?SQL("insert into users(username, password) " + "values (%(LUser)s, %(Password)s);")]; (_Host, _R) -> [] end}]. diff --git a/src/ejabberd_auth_sql.erl b/src/ejabberd_auth_sql.erl index 000b4a4f4..17e3e517b 100644 --- a/src/ejabberd_auth_sql.erl +++ b/src/ejabberd_auth_sql.erl @@ -25,6 +25,8 @@ -module(ejabberd_auth_sql). +-compile([{parse_transform, ejabberd_sql_pt}]). + -behaviour(ejabberd_config). -author('alexey@process-one.net'). @@ -43,6 +45,7 @@ -include("ejabberd.hrl"). -include("logger.hrl"). +-include("ejabberd_sql_pt.hrl"). -define(SALT_LENGTH, 16). @@ -425,19 +428,15 @@ is_password_scram_valid(Password, Scram) -> -define(BATCH_SIZE, 1000). -set_password_scram_t(Username, +set_password_scram_t(LUser, StoredKey, ServerKey, Salt, IterationCount) -> - sql_queries:update_t(<<"users">>, - [<<"username">>, - <<"password">>, - <<"serverkey">>, - <<"salt">>, - <<"iterationcount">>], - [Username, StoredKey, - ServerKey, Salt, - IterationCount], - [<<"username='">>, Username, - <<"'">>]). + ?SQL_UPSERT_T( + "users", + ["!username=%(LUser)s", + "password=%(StoredKey)s", + "serverkey=%(ServerKey)s", + "salt=%(Salt)s", + "iterationcount=%(IterationCount)d"]). convert_to_scram(Server) -> LServer = jid:nameprep(Server), @@ -447,24 +446,24 @@ convert_to_scram(Server) -> {error, {incorrect_server_name, Server}}; true -> F = fun () -> + BatchSize = ?BATCH_SIZE, case ejabberd_sql:sql_query_t( - [<<"select username, password from users where " - "iterationcount=0 limit ">>, - integer_to_binary(?BATCH_SIZE), - <<";">>]) of - {selected, [<<"username">>, <<"password">>], []} -> + ?SQL("select @(username)s, @(password)s" + " from users" + " where iterationcount=0" + " limit %(BatchSize)d")) of + {selected, []} -> ok; - {selected, [<<"username">>, <<"password">>], Rs} -> + {selected, Rs} -> lists:foreach( - fun([LUser, Password]) -> - Username = ejabberd_sql:escape(LUser), + fun({LUser, Password}) -> Scram = password_to_scram(Password), set_password_scram_t( - Username, - ejabberd_sql:escape(Scram#scram.storedkey), - ejabberd_sql:escape(Scram#scram.serverkey), - ejabberd_sql:escape(Scram#scram.salt), - integer_to_binary(Scram#scram.iterationcount) + LUser, + Scram#scram.storedkey, + Scram#scram.serverkey, + Scram#scram.salt, + Scram#scram.iterationcount ) end, Rs), continue; diff --git a/src/ejabberd_sm_sql.erl b/src/ejabberd_sm_sql.erl index 3d4e224d4..8871bbca4 100644 --- a/src/ejabberd_sm_sql.erl +++ b/src/ejabberd_sm_sql.erl @@ -8,6 +8,8 @@ %%%------------------------------------------------------------------- -module(ejabberd_sm_sql). +-compile([{parse_transform, ejabberd_sql_pt}]). + -behaviour(ejabberd_sm). %% API @@ -23,18 +25,19 @@ -include("ejabberd_sm.hrl"). -include("logger.hrl"). -include("jlib.hrl"). +-include("ejabberd_sql_pt.hrl"). %%%=================================================================== %%% API %%%=================================================================== -spec init() -> ok | {error, any()}. init() -> - Node = ejabberd_sql:escape(jlib:atom_to_binary(node())), + Node = jlib:atom_to_binary(node()), ?INFO_MSG("Cleaning SQL SM table...", []), lists:foldl( fun(Host, ok) -> case ejabberd_sql:sql_query( - Host, [<<"delete from sm where node='">>, Node, <<"'">>]) of + Host, ?SQL("delete from sm where node=%(Node)s")) of {updated, _} -> ok; Err -> @@ -47,20 +50,19 @@ init() -> set_session(#session{sid = {Now, Pid}, usr = {U, LServer, R}, priority = Priority, info = Info}) -> - Username = ejabberd_sql:escape(U), - Resource = ejabberd_sql:escape(R), - InfoS = ejabberd_sql:encode_term(Info), + InfoS = jlib:term_to_expr(Info), PrioS = enc_priority(Priority), TS = now_to_timestamp(Now), PidS = list_to_binary(erlang:pid_to_list(Pid)), - Node = ejabberd_sql:escape(jlib:atom_to_binary(node(Pid))), - case sql_queries:update( - LServer, - <<"sm">>, - [<<"usec">>, <<"pid">>, <<"node">>, <<"username">>, - <<"resource">>, <<"priority">>, <<"info">>], - [TS, PidS, Node, Username, Resource, PrioS, InfoS], - [<<"usec='">>, TS, <<"' and pid='">>, PidS, <<"'">>]) of + Node = jlib:atom_to_binary(node(Pid)), + case ?SQL_UPSERT(LServer, "sm", + ["!usec=%(TS)d", + "!pid=%(PidS)s", + "node=%(Node)s", + "username=%(U)s", + "resource=%(R)s", + "priority=%(PrioS)s", + "info=%(InfoS)s"]) of ok -> ok; Err -> @@ -72,14 +74,16 @@ delete_session(_LUser, LServer, _LResource, {Now, Pid}) -> PidS = list_to_binary(erlang:pid_to_list(Pid)), case ejabberd_sql:sql_query( LServer, - [<<"select usec, pid, username, resource, priority, info ">>, - <<"from sm where usec='">>, TS, <<"' and pid='">>,PidS, <<"'">>]) of - {selected, _, [Row]} -> - ejabberd_sql:sql_query( - LServer, [<<"delete from sm where usec='">>, - TS, <<"' and pid='">>, PidS, <<"'">>]), + ?SQL("select @(usec)d, @(pid)s, @(username)s," + " @(resource)s, @(priority)s, @(info)s " + "from sm where usec=%(TS)d and pid=%(PidS)s")) of + {selected, [Row]} -> + ejabberd_sql:sql_query( + LServer, + ?SQL("delete from sm" + " where usec=%(TS)d and pid=%(PidS)s")), {ok, row_to_session(LServer, Row)}; - {selected, _, []} -> + {selected, []} -> {error, notfound}; Err -> ?ERROR_MSG("failed to delete from 'sm' table: ~p", [Err]), @@ -94,9 +98,10 @@ get_sessions() -> get_sessions(LServer) -> case ejabberd_sql:sql_query( - LServer, [<<"select usec, pid, username, ">>, - <<"resource, priority, info from sm">>]) of - {selected, _, Rows} -> + LServer, + ?SQL("select @(usec)d, @(pid)s, @(username)s," + " @(resource)s, @(priority)s, @(info)s from sm")) of + {selected, Rows} -> [row_to_session(LServer, Row) || Row <- Rows]; Err -> ?ERROR_MSG("failed to select from 'sm' table: ~p", [Err]), @@ -104,12 +109,12 @@ get_sessions(LServer) -> end. get_sessions(LUser, LServer) -> - Username = ejabberd_sql:escape(LUser), case ejabberd_sql:sql_query( - LServer, [<<"select usec, pid, username, ">>, - <<"resource, priority, info from sm where ">>, - <<"username='">>, Username, <<"'">>]) of - {selected, _, Rows} -> + LServer, + ?SQL("select @(usec)d, @(pid)s, @(username)s," + " @(resource)s, @(priority)s, @(info)s from sm" + " where username=%(LUser)s")) of + {selected, Rows} -> [row_to_session(LServer, Row) || Row <- Rows]; Err -> ?ERROR_MSG("failed to select from 'sm' table: ~p", [Err]), @@ -117,14 +122,12 @@ get_sessions(LUser, LServer) -> end. get_sessions(LUser, LServer, LResource) -> - Username = ejabberd_sql:escape(LUser), - Resource = ejabberd_sql:escape(LResource), case ejabberd_sql:sql_query( - LServer, [<<"select usec, pid, username, ">>, - <<"resource, priority, info from sm where ">>, - <<"username='">>, Username, <<"' and resource='">>, - Resource, <<"'">>]) of - {selected, _, Rows} -> + LServer, + ?SQL("select @(usec)d, @(pid)s, @(username)s," + " @(resource)s, @(priority)s, @(info)s from sm" + " where username=%(LUser)s and resource=%(LResource)s")) of + {selected, Rows} -> [row_to_session(LServer, Row) || Row <- Rows]; Err -> ?ERROR_MSG("failed to select from 'sm' table: ~p", [Err]), @@ -135,10 +138,9 @@ get_sessions(LUser, LServer, LResource) -> %%% Internal functions %%%=================================================================== now_to_timestamp({MSec, Sec, USec}) -> - jlib:integer_to_binary((MSec * 1000000 + Sec) * 1000000 + USec). + (MSec * 1000000 + Sec) * 1000000 + USec. -timestamp_to_now(TS) -> - I = jlib:binary_to_integer(TS), +timestamp_to_now(I) -> Head = I div 1000000, USec = I rem 1000000, MSec = Head div 1000000, @@ -158,7 +160,7 @@ enc_priority(undefined) -> enc_priority(Int) when is_integer(Int) -> jlib:integer_to_binary(Int). -row_to_session(LServer, [USec, PidS, User, Resource, PrioS, InfoS]) -> +row_to_session(LServer, {USec, PidS, User, Resource, PrioS, InfoS}) -> Now = timestamp_to_now(USec), Pid = erlang:list_to_pid(binary_to_list(PidS)), Priority = dec_priority(PrioS), diff --git a/src/ejabberd_sql.erl b/src/ejabberd_sql.erl index 850a7752c..09bd31973 100644 --- a/src/ejabberd_sql.erl +++ b/src/ejabberd_sql.erl @@ -39,6 +39,7 @@ sql_query_t/1, sql_transaction/2, sql_bloc/2, + sql_query_to_iolist/1, escape/1, escape_like/1, escape_like_arg/1, @@ -668,6 +669,9 @@ sql_query_format_res({selected, _, Rows}, SQLQuery) -> sql_query_format_res(Res, _SQLQuery) -> Res. +sql_query_to_iolist(SQLQuery) -> + generic_sql_query_format(SQLQuery). + %% Generate the OTP callback return tuple depending on the driver result. abort_on_driver_error({error, <<"query timed out">>} = Reply, diff --git a/src/ejabberd_sql_pt.erl b/src/ejabberd_sql_pt.erl index 47e4a07c7..e51b7f928 100644 --- a/src/ejabberd_sql_pt.erl +++ b/src/ejabberd_sql_pt.erl @@ -305,20 +305,24 @@ parse_upsert(Fields) -> "a constant string"}) end end, {[], 0}, Fields), - %io:format("asd ~p~n", [{Fields, Fs}]), + %io:format("upsert ~p~n", [{Fields, Fs}]), Fs. +%% key | {Update} parse_upsert_field([$! | S], ParamPos, Loc) -> {Name, ParseState} = parse_upsert_field1(S, [], ParamPos, Loc), - {Name, true, ParseState}; + {Name, key, ParseState}; +parse_upsert_field([$- | S], ParamPos, Loc) -> + {Name, ParseState} = parse_upsert_field1(S, [], ParamPos, Loc), + {Name, {false}, ParseState}; parse_upsert_field(S, ParamPos, Loc) -> {Name, ParseState} = parse_upsert_field1(S, [], ParamPos, Loc), - {Name, false, ParseState}. + {Name, {true}, ParseState}. parse_upsert_field1([], _Acc, _ParamPos, Loc) -> throw({error, Loc, "?SQL_UPSERT fields must have the " - "following form: \"[!]name=value\""}); + "following form: \"[!-]name=value\""}); parse_upsert_field1([$= | S], Acc, ParamPos, Loc) -> {lists:reverse(Acc), parse(S, ParamPos, Loc)}; parse_upsert_field1([C | S], Acc, ParamPos, Loc) -> @@ -376,9 +380,9 @@ make_sql_upsert_generic(Table, ParseRes) -> make_sql_upsert_update(Table, ParseRes) -> WPairs = lists:flatmap( - fun({_Field, false, _ST}) -> + fun({_Field, {_}, _ST}) -> []; - ({Field, true, ST}) -> + ({Field, key, ST}) -> [ST#state{ 'query' = [{str, Field}, {str, "="}] ++ ST#state.'query' }] @@ -386,9 +390,11 @@ make_sql_upsert_update(Table, ParseRes) -> Where = join_states(WPairs, " AND "), SPairs = lists:flatmap( - fun({_Field, true, _ST}) -> + fun({_Field, key, _ST}) -> []; - ({Field, false, ST}) -> + ({_Field, {false}, _ST}) -> + []; + ({Field, {true}, ST}) -> [ST#state{ 'query' = [{str, Field}, {str, "="}] ++ ST#state.'query' }] @@ -462,7 +468,7 @@ check_upsert(ParseRes, Pos) -> Set = lists:filter( fun({_Field, Match, _ST}) -> - not Match + Match /= key end, ParseRes), case Set of [] -> diff --git a/src/ejd2sql.erl b/src/ejd2sql.erl index 0457f6be2..2d19100a9 100644 --- a/src/ejd2sql.erl +++ b/src/ejd2sql.erl @@ -28,6 +28,7 @@ -author('alexey@process-one.net'). -include("logger.hrl"). +-include("ejabberd_sql_pt.hrl"). -export([export/2, export/3, import_file/2, import/2, import/3, delete/1]). @@ -76,7 +77,12 @@ export(Server, Output, Module) -> IO = prepare_output(Output), lists:foreach( fun({Table, ConvertFun}) -> - export(LServer, Table, IO, ConvertFun) + case export(LServer, Table, IO, ConvertFun) of + {atomic, ok} -> ok; + {aborted, Reason} -> + ?ERROR_MSG("Failed export for module ~p: ~p", + [Module, Reason]) + end end, Module:export(Server)), close_output(Output, IO). @@ -150,7 +156,8 @@ export(LServer, Table, IO, ConvertFun) -> case ConvertFun(LServer, R) of [] -> Acc; - SQL -> + SQL1 -> + SQL = format_queries(SQL1), if N < (?MAX_RECORDS_PER_TRANSACTION) - 1 -> {N + 1, [SQL | SQLs]}; true -> @@ -313,3 +320,11 @@ flatten1([H|T], Acc) -> flatten1(T, [[H, $\n]|Acc]); flatten1([], Acc) -> Acc. + +format_queries(SQLs) -> + lists:map( + fun(#sql_query{} = SQL) -> + ejabberd_sql:sql_query_to_iolist(SQL); + (SQL) -> + SQL + end, SQLs). diff --git a/src/mod_announce_sql.erl b/src/mod_announce_sql.erl index 692c8fae4..762c97ad6 100644 --- a/src/mod_announce_sql.erl +++ b/src/mod_announce_sql.erl @@ -9,6 +9,8 @@ -module(mod_announce_sql). -behaviour(mod_announce). +-compile([{parse_transform, ejabberd_sql_pt}]). + %% API -export([init/2, set_motd_users/2, set_motd/2, delete_motd/1, get_motd/1, is_motd_user/2, set_motd_user/2, import/1, @@ -16,6 +18,7 @@ -include("jlib.hrl"). -include("mod_announce.hrl"). +-include("ejabberd_sql_pt.hrl"). %%%=================================================================== %%% API @@ -27,37 +30,35 @@ set_motd_users(LServer, USRs) -> F = fun() -> lists:foreach( fun({U, _S, _R}) -> - Username = ejabberd_sql:escape(U), - sql_queries:update_t( - <<"motd">>, - [<<"username">>, <<"xml">>], - [Username, <<"">>], - [<<"username='">>, Username, <<"'">>]) + ?SQL_UPSERT_T( + "motd", + ["!username=%(U)s", + "xml=''"]) end, USRs) end, ejabberd_sql:sql_transaction(LServer, F). set_motd(LServer, Packet) -> - XML = ejabberd_sql:escape(fxml:element_to_binary(Packet)), + XML = fxml:element_to_binary(Packet), F = fun() -> - sql_queries:update_t( - <<"motd">>, - [<<"username">>, <<"xml">>], - [<<"">>, XML], - [<<"username=''">>]) + ?SQL_UPSERT_T( + "motd", + ["!username=''", + "xml=%(XML)s"]) end, ejabberd_sql:sql_transaction(LServer, F). delete_motd(LServer) -> F = fun() -> - ejabberd_sql:sql_query_t([<<"delete from motd;">>]) + ejabberd_sql:sql_query_t(?SQL("delete from motd")) end, ejabberd_sql:sql_transaction(LServer, F). get_motd(LServer) -> case catch ejabberd_sql:sql_query( - LServer, [<<"select xml from motd where username='';">>]) of - {selected, [<<"xml">>], [[XML]]} -> + LServer, + ?SQL("select @(xml)s from motd where username=''")) of + {selected, [{XML}]} -> case fxml_stream:parse_element(XML) of {error, _} -> error; @@ -69,46 +70,40 @@ get_motd(LServer) -> end. is_motd_user(LUser, LServer) -> - Username = ejabberd_sql:escape(LUser), case catch ejabberd_sql:sql_query( - LServer, - [<<"select username from motd " - "where username='">>, Username, <<"';">>]) of - {selected, [<<"username">>], [_|_]} -> + LServer, + ?SQL("select @(username)s from motd" + " where username=%(LUser)s")) of + {selected, [_|_]} -> true; _ -> false end. set_motd_user(LUser, LServer) -> - Username = ejabberd_sql:escape(LUser), F = fun() -> - sql_queries:update_t( - <<"motd">>, - [<<"username">>, <<"xml">>], - [Username, <<"">>], - [<<"username='">>, Username, <<"'">>]) - end, + ?SQL_UPSERT_T( + "motd", + ["!username=%(LUser)s", + "xml=''"]) + end, ejabberd_sql:sql_transaction(LServer, F). export(_Server) -> [{motd, fun(Host, #motd{server = LServer, packet = El}) when LServer == Host -> - [[<<"delete from motd where username='';">>], - [<<"insert into motd(username, xml) values ('', '">>, - ejabberd_sql:escape(fxml:element_to_binary(El)), - <<"');">>]]; + XML = fxml:element_to_binary(El), + [?SQL("delete from motd where username='';"), + ?SQL("insert into motd(username, xml) values ('', %(XML)s);")]; (_Host, _R) -> [] end}, {motd_users, fun(Host, #motd_users{us = {LUser, LServer}}) when LServer == Host, LUser /= <<"">> -> - Username = ejabberd_sql:escape(LUser), - [[<<"delete from motd where username='">>, Username, <<"';">>], - [<<"insert into motd(username, xml) values ('">>, - Username, <<"', '');">>]]; + [?SQL("delete from motd where username=%(LUser)s;"), + ?SQL("insert into motd(username, xml) values (%(LUser)s, '');")]; (_Host, _R) -> [] end}]. diff --git a/src/mod_caps_sql.erl b/src/mod_caps_sql.erl index 9f587db35..5faff98b6 100644 --- a/src/mod_caps_sql.erl +++ b/src/mod_caps_sql.erl @@ -9,10 +9,13 @@ -module(mod_caps_sql). -behaviour(mod_caps). +-compile([{parse_transform, ejabberd_sql_pt}]). + %% API -export([init/2, caps_read/2, caps_write/3, export/1]). -include("mod_caps.hrl"). +-include("ejabberd_sql_pt.hrl"). %%%=================================================================== %%% API @@ -21,21 +24,19 @@ init(_Host, _Opts) -> ok. caps_read(LServer, {Node, SubNode}) -> - SNode = ejabberd_sql:escape(Node), - SSubNode = ejabberd_sql:escape(SubNode), case ejabberd_sql:sql_query( - LServer, [<<"select feature from caps_features where ">>, - <<"node='">>, SNode, <<"' and subnode='">>, - SSubNode, <<"';">>]) of - {selected, [<<"feature">>], [[H]|_] = Fs} -> - case catch jlib:binary_to_integer(H) of - Int when is_integer(Int), Int>=0 -> - {ok, Int}; - _ -> - {ok, lists:flatten(Fs)} - end; - _ -> - error + LServer, + ?SQL("select @(feature)s from caps_features where" + " node=%(Node)s and subnode=%(SubNode)s")) of + {selected, [{H}|_] = Fs} -> + case catch jlib:binary_to_integer(H) of + Int when is_integer(Int), Int>=0 -> + {ok, Int}; + _ -> + {ok, [F || {F} <- Fs]} + end; + _ -> + error end. caps_write(LServer, NodePair, Features) -> @@ -56,16 +57,13 @@ export(_Server) -> %%% Internal functions %%%=================================================================== sql_write_features_t({Node, SubNode}, Features) -> - SNode = ejabberd_sql:escape(Node), - SSubNode = ejabberd_sql:escape(SubNode), NewFeatures = if is_integer(Features) -> [jlib:integer_to_binary(Features)]; true -> Features end, - [[<<"delete from caps_features where node='">>, - SNode, <<"' and subnode='">>, SSubNode, <<"';">>]| - [[<<"insert into caps_features(node, subnode, feature) ">>, - <<"values ('">>, SNode, <<"', '">>, SSubNode, <<"', '">>, - ejabberd_sql:escape(F), <<"');">>] || F <- NewFeatures]]. + [?SQL("delete from caps_features where node=%(Node)s" + " and subnode=%(SubNode)s;") | + [?SQL("insert into caps_features(node, subnode, feature)" + " values (%(Node)s, %(SubNode)s, %(F)s);") || F <- NewFeatures]]. diff --git a/src/mod_irc_sql.erl b/src/mod_irc_sql.erl index 9a97d5728..8aa428e54 100644 --- a/src/mod_irc_sql.erl +++ b/src/mod_irc_sql.erl @@ -8,6 +8,8 @@ %%%------------------------------------------------------------------- -module(mod_irc_sql). +-compile([{parse_transform, ejabberd_sql_pt}]). + -behaviour(mod_irc). %% API @@ -15,6 +17,7 @@ -include("jlib.hrl"). -include("mod_irc.hrl"). +-include("ejabberd_sql_pt.hrl"). %%%=================================================================== %%% API @@ -23,31 +26,26 @@ init(_Host, _Opts) -> ok. get_data(LServer, Host, From) -> - LJID = jid:tolower(jid:remove_resource(From)), - SJID = ejabberd_sql:escape(jid:to_string(LJID)), - SHost = ejabberd_sql:escape(Host), + SJID = jid:to_string(jid:tolower(jid:remove_resource(From))), case catch ejabberd_sql:sql_query( - LServer, - [<<"select data from irc_custom where jid='">>, - SJID, <<"' and host='">>, SHost, - <<"';">>]) of - {selected, [<<"data">>], [[SData]]} -> - mod_irc:data_to_binary(From, ejabberd_sql:decode_term(SData)); - {'EXIT', _} -> error; - {selected, _, _} -> empty + LServer, + ?SQL("select @(data)s from irc_custom" + " where jid=%(SJID)s and host=%(Host)s")) of + {selected, [{SData}]} -> + mod_irc:data_to_binary(From, ejabberd_sql:decode_term(SData)); + {'EXIT', _} -> error; + {selected, _} -> empty end. set_data(LServer, Host, From, Data) -> - LJID = jid:tolower(jid:remove_resource(From)), - SJID = ejabberd_sql:escape(jid:to_string(LJID)), - SHost = ejabberd_sql:escape(Host), - SData = ejabberd_sql:encode_term(Data), + SJID = jid:to_string(jid:tolower(jid:remove_resource(From))), + SData = jlib:term_to_expr(Data), F = fun () -> - sql_queries:update_t(<<"irc_custom">>, - [<<"jid">>, <<"host">>, <<"data">>], - [SJID, SHost, SData], - [<<"jid='">>, SJID, <<"' and host='">>, - SHost, <<"'">>]), + ?SQL_UPSERT_T( + "irc_custom", + ["!jid=%(SJID)s", + "!host=%(Host)s", + "data=%(SData)s"]), ok end, ejabberd_sql:sql_transaction(LServer, F). @@ -58,17 +56,12 @@ export(_Server) -> data = Data}) -> case str:suffix(Host, IRCHost) of true -> - SJID = ejabberd_sql:escape( - jid:to_string( - jid:make(U, S, <<"">>))), - SIRCHost = ejabberd_sql:escape(IRCHost), - SData = ejabberd_sql:encode_term(Data), - [[<<"delete from irc_custom where jid='">>, SJID, - <<"' and host='">>, SIRCHost, <<"';">>], - [<<"insert into irc_custom(jid, host, " - "data) values ('">>, - SJID, <<"', '">>, SIRCHost, <<"', '">>, SData, - <<"');">>]]; + SJID = jid:to_string(jid:make(U, S, <<"">>)), + SData = jlib:term_to_expr(Data), + [?SQL("delete from irc_custom" + " where jid=%(SJID)s and host=%(IRCHost)s;"), + ?SQL("insert into irc_custom(jid, host, data)" + " values (%(SJID)s, %(IRCHost)s, %(SData)s);")]; false -> [] end diff --git a/src/mod_last_sql.erl b/src/mod_last_sql.erl index 5f67b14fc..13b028c6f 100644 --- a/src/mod_last_sql.erl +++ b/src/mod_last_sql.erl @@ -9,12 +9,15 @@ -module(mod_last_sql). -behaviour(mod_last). +-compile([{parse_transform, ejabberd_sql_pt}]). + %% API -export([init/2, get_last/2, store_last_info/4, remove_user/2, import/1, import/2, export/1]). -include("mod_last.hrl"). -include("logger.hrl"). +-include("ejabberd_sql_pt.hrl"). %%%=================================================================== %%% API @@ -48,15 +51,9 @@ export(_Server) -> fun(Host, #last_activity{us = {LUser, LServer}, timestamp = TimeStamp, status = Status}) when LServer == Host -> - Username = ejabberd_sql:escape(LUser), - Seconds = - ejabberd_sql:escape(jlib:integer_to_binary(TimeStamp)), - State = ejabberd_sql:escape(Status), - [[<<"delete from last where username='">>, Username, <<"';">>], - [<<"insert into last(username, seconds, " - "state) values ('">>, - Username, <<"', '">>, Seconds, <<"', '">>, State, - <<"');">>]]; + [?SQL("delete from last where username=%(LUser)s;"), + ?SQL("insert into last(username, seconds, state)" + " values (%(LUser)s, %(TimeStamp)d, %(Status)s);")]; (_Host, _R) -> [] end}]. diff --git a/src/mod_mam_sql.erl b/src/mod_mam_sql.erl index 69fdf3238..d88806499 100644 --- a/src/mod_mam_sql.erl +++ b/src/mod_mam_sql.erl @@ -8,6 +8,8 @@ %%%------------------------------------------------------------------- -module(mod_mam_sql). +-compile([{parse_transform, ejabberd_sql_pt}]). + -behaviour(mod_mam). %% API @@ -18,6 +20,7 @@ -include("jlib.hrl"). -include("mod_mam.hrl"). -include("logger.hrl"). +-include("ejabberd_sql_pt.hrl"). %%%=================================================================== %%% API @@ -26,13 +29,12 @@ init(_Host, _Opts) -> ok. remove_user(LUser, LServer) -> - SUser = ejabberd_sql:escape(LUser), ejabberd_sql:sql_query( LServer, - [<<"delete from archive where username='">>, SUser, <<"';">>]), + ?SQL("delete from archive where username=%(LUser)s")), ejabberd_sql:sql_query( LServer, - [<<"delete from archive_prefs where username='">>, SUser, <<"';">>]). + ?SQL("delete from archive_prefs where username=%(LUser)s")). remove_room(LServer, LName, LHost) -> LUser = jid:to_string({LName, LHost, <<>>}), @@ -55,7 +57,7 @@ extended_fields() -> store(Pkt, LServer, {LUser, LHost}, Type, Peer, Nick, _Dir) -> TSinteger = p1_time_compat:system_time(micro_seconds), - ID = TS = jlib:integer_to_binary(TSinteger), + ID = jlib:integer_to_binary(TSinteger), SUser = case Type of chat -> LUser; groupchat -> jid:to_string({LUser, LHost, <<>>}) @@ -67,18 +69,19 @@ store(Pkt, LServer, {LUser, LHost}, Type, Peer, Nick, _Dir) -> jid:tolower(Peer)), XML = fxml:element_to_binary(Pkt), Body = fxml:get_subtag_cdata(Pkt, <<"body">>), + SType = jlib:atom_to_binary(Type), case ejabberd_sql:sql_query( - LServer, - [<<"insert into archive (username, timestamp, " - "peer, bare_peer, xml, txt, kind, nick) values (">>, - <<"'">>, ejabberd_sql:escape(SUser), <<"', ">>, - <<"'">>, TS, <<"', ">>, - <<"'">>, ejabberd_sql:escape(LPeer), <<"', ">>, - <<"'">>, ejabberd_sql:escape(BarePeer), <<"', ">>, - <<"'">>, ejabberd_sql:escape(XML), <<"', ">>, - <<"'">>, ejabberd_sql:escape(Body), <<"', ">>, - <<"'">>, jlib:atom_to_binary(Type), <<"', ">>, - <<"'">>, ejabberd_sql:escape(Nick), <<"');">>]) of + LServer, + ?SQL("insert into archive (username, timestamp," + " peer, bare_peer, xml, txt, kind, nick) values (" + "%(SUser)s, " + "%(TSinteger)d, " + "%(LPeer)s, " + "%(BarePeer)s, " + "%(XML)s, " + "%(Body)s, " + "%(SType)s, " + "%(Nick)s)")) of {updated, _} -> {ok, ID}; Err -> diff --git a/src/mod_muc_sql.erl b/src/mod_muc_sql.erl index 55628d43e..ff7ec1ebb 100644 --- a/src/mod_muc_sql.erl +++ b/src/mod_muc_sql.erl @@ -8,6 +8,8 @@ %%%------------------------------------------------------------------- -module(mod_muc_sql). +-compile([{parse_transform, ejabberd_sql_pt}]). + -behaviour(mod_muc). %% API @@ -18,6 +20,7 @@ -include("jlib.hrl"). -include("mod_muc.hrl"). -include("logger.hrl"). +-include("ejabberd_sql_pt.hrl"). %%%=================================================================== %%% API @@ -26,61 +29,54 @@ init(_Host, _Opts) -> ok. store_room(LServer, Host, Name, Opts) -> - SName = ejabberd_sql:escape(Name), - SHost = ejabberd_sql:escape(Host), - SOpts = ejabberd_sql:encode_term(Opts), + SOpts = jlib:term_to_expr(Opts), F = fun () -> - sql_queries:update_t(<<"muc_room">>, - [<<"name">>, <<"host">>, <<"opts">>], - [SName, SHost, SOpts], - [<<"name='">>, SName, <<"' and host='">>, - SHost, <<"'">>]) + ?SQL_UPSERT_T( + "muc_room", + ["!name=%(Name)s", + "!host=%(Host)s", + "opts=%(SOpts)s"]) end, ejabberd_sql:sql_transaction(LServer, F). restore_room(LServer, Host, Name) -> - SName = ejabberd_sql:escape(Name), - SHost = ejabberd_sql:escape(Host), - case catch ejabberd_sql:sql_query(LServer, - [<<"select opts from muc_room where name='">>, - SName, <<"' and host='">>, SHost, - <<"';">>]) of - {selected, [<<"opts">>], [[Opts]]} -> + case catch ejabberd_sql:sql_query( + LServer, + ?SQL("select @(opts)s from muc_room where name=%(Name)s" + " and host=%(Host)s")) of + {selected, [{Opts}]} -> mod_muc:opts_to_binary(ejabberd_sql:decode_term(Opts)); _ -> error end. forget_room(LServer, Host, Name) -> - SName = ejabberd_sql:escape(Name), - SHost = ejabberd_sql:escape(Host), F = fun () -> - ejabberd_sql:sql_query_t([<<"delete from muc_room where name='">>, - SName, <<"' and host='">>, SHost, - <<"';">>]) + ejabberd_sql:sql_query_t( + ?SQL("delete from muc_room where name=%(Name)s" + " and host=%(Host)s")) end, ejabberd_sql:sql_transaction(LServer, F). can_use_nick(LServer, Host, JID, Nick) -> SJID = jid:to_string(jid:tolower(jid:remove_resource(JID))), - SNick = ejabberd_sql:escape(Nick), - SHost = ejabberd_sql:escape(Host), - case catch ejabberd_sql:sql_query(LServer, - [<<"select jid from muc_registered ">>, - <<"where nick='">>, SNick, - <<"' and host='">>, SHost, <<"';">>]) of - {selected, [<<"jid">>], [[SJID1]]} -> SJID == SJID1; + case catch ejabberd_sql:sql_query( + LServer, + ?SQL("select @(jid)s from muc_registered " + "where nick=%(Nick)s" + " and host=%(Host)s")) of + {selected, [{SJID1}]} -> SJID == SJID1; _ -> true end. get_rooms(LServer, Host) -> - SHost = ejabberd_sql:escape(Host), - case catch ejabberd_sql:sql_query(LServer, - [<<"select name, opts from muc_room ">>, - <<"where host='">>, SHost, <<"';">>]) of - {selected, [<<"name">>, <<"opts">>], RoomOpts} -> + case catch ejabberd_sql:sql_query( + LServer, + ?SQL("select @(name)s, @(opts)s from muc_room" + " where host=%(Host)s")) of + {selected, RoomOpts} -> lists:map( - fun([Room, Opts]) -> + fun({Room, Opts}) -> #muc_room{name_host = {Room, Host}, opts = mod_muc:opts_to_binary( ejabberd_sql:decode_term(Opts))} @@ -91,49 +87,38 @@ get_rooms(LServer, Host) -> end. get_nick(LServer, Host, From) -> - SJID = ejabberd_sql:escape(jid:to_string(jid:tolower(jid:remove_resource(From)))), - SHost = ejabberd_sql:escape(Host), - case catch ejabberd_sql:sql_query(LServer, - [<<"select nick from muc_registered where " - "jid='">>, - SJID, <<"' and host='">>, SHost, - <<"';">>]) of - {selected, [<<"nick">>], [[Nick]]} -> Nick; + SJID = jid:to_string(jid:tolower(jid:remove_resource(From))), + case catch ejabberd_sql:sql_query( + LServer, + ?SQL("select @(nick)s from muc_registered where" + " jid=%(SJID)s and host=%(Host)s")) of + {selected, [{Nick}]} -> Nick; _ -> error end. set_nick(LServer, Host, From, Nick) -> JID = jid:to_string(jid:tolower(jid:remove_resource(From))), - SJID = ejabberd_sql:escape(JID), - SNick = ejabberd_sql:escape(Nick), - SHost = ejabberd_sql:escape(Host), F = fun () -> case Nick of <<"">> -> ejabberd_sql:sql_query_t( - [<<"delete from muc_registered where ">>, - <<"jid='">>, SJID, - <<"' and host='">>, Host, - <<"';">>]), + ?SQL("delete from muc_registered where" + " jid=%(JID)s and host=%(Host)s")), ok; _ -> Allow = case ejabberd_sql:sql_query_t( - [<<"select jid from muc_registered ">>, - <<"where nick='">>, - SNick, - <<"' and host='">>, - SHost, <<"';">>]) of - {selected, [<<"jid">>], [[J]]} -> J == JID; + ?SQL("select @(jid)s from muc_registered" + " where nick=%(Nick)s" + " and host=%(Host)s")) of + {selected, [{J}]} -> J == JID; _ -> true end, if Allow -> - sql_queries:update_t(<<"muc_registered">>, - [<<"jid">>, <<"host">>, - <<"nick">>], - [SJID, SHost, SNick], - [<<"jid='">>, SJID, - <<"' and host='">>, SHost, - <<"'">>]), + ?SQL_UPSERT_T( + "muc_registered", + ["!jid=%(JID)s", + "!host=%(Host)s", + "nick=%(Nick)s"]), ok; true -> false @@ -147,15 +132,12 @@ export(_Server) -> fun(Host, #muc_room{name_host = {Name, RoomHost}, opts = Opts}) -> case str:suffix(Host, RoomHost) of true -> - SName = ejabberd_sql:escape(Name), - SRoomHost = ejabberd_sql:escape(RoomHost), - SOpts = ejabberd_sql:encode_term(Opts), - [[<<"delete from muc_room where name='">>, SName, - <<"' and host='">>, SRoomHost, <<"';">>], - [<<"insert into muc_room(name, host, opts) ", - "values (">>, - <<"'">>, SName, <<"', '">>, SRoomHost, - <<"', '">>, SOpts, <<"');">>]]; + SOpts = jlib:term_to_expr(Opts), + [?SQL("delete from muc_room where name=%(Name)s" + " and host=%(RoomHost)s;"), + ?SQL("insert into muc_room(name, host, opts) " + "values (" + "%(Name)s, %(RoomHost)s, %(SOpts)s);")]; false -> [] end @@ -165,17 +147,12 @@ export(_Server) -> nick = Nick}) -> case str:suffix(Host, RoomHost) of true -> - SJID = ejabberd_sql:escape( - jid:to_string( - jid:make(U, S, <<"">>))), - SNick = ejabberd_sql:escape(Nick), - SRoomHost = ejabberd_sql:escape(RoomHost), - [[<<"delete from muc_registered where jid='">>, - SJID, <<"' and host='">>, SRoomHost, <<"';">>], - [<<"insert into muc_registered(jid, host, " - "nick) values ('">>, - SJID, <<"', '">>, SRoomHost, <<"', '">>, SNick, - <<"');">>]]; + SJID = jid:to_string(jid:make(U, S, <<"">>)), + [?SQL("delete from muc_registered where" + " jid=%(SJID)s and host=%(RoomHost)s;"), + ?SQL("insert into muc_registered(jid, host, " + "nick) values (" + "%(SJID)s, %(RoomHost)s, %(Nick)s);")]; false -> [] end diff --git a/src/mod_privacy_sql.erl b/src/mod_privacy_sql.erl index 6b996fa8b..6da917e9d 100644 --- a/src/mod_privacy_sql.erl +++ b/src/mod_privacy_sql.erl @@ -8,6 +8,8 @@ %%%------------------------------------------------------------------- -module(mod_privacy_sql). +-compile([{parse_transform, ejabberd_sql_pt}]). + -behaviour(mod_privacy). %% API @@ -29,6 +31,7 @@ -include("jlib.hrl"). -include("mod_privacy.hrl"). -include("logger.hrl"). +-include("ejabberd_sql_pt.hrl"). %%%=================================================================== %%% API @@ -208,38 +211,38 @@ export(Server) -> fun(Host, #privacy{us = {LUser, LServer}, lists = Lists, default = Default}) when LServer == Host -> - Username = ejabberd_sql:escape(LUser), if Default /= none -> - SDefault = ejabberd_sql:escape(Default), - [[<<"delete from privacy_default_list where ">>, - <<"username='">>, Username, <<"';">>], - [<<"insert into privacy_default_list(username, " - "name) ">>, - <<"values ('">>, Username, <<"', '">>, - SDefault, <<"');">>]]; + [?SQL("delete from privacy_default_list where" + " username=%(LUser)s;"), + ?SQL("insert into privacy_default_list(username, name) " + "values (%(LUser)s, %(Default)s);")]; true -> [] end ++ lists:flatmap( fun({Name, List}) -> - SName = ejabberd_sql:escape(Name), RItems = lists:map(fun item_to_raw/1, List), - ID = jlib:integer_to_binary(get_id()), - [[<<"delete from privacy_list where username='">>, - Username, <<"' and name='">>, - SName, <<"';">>], - [<<"insert into privacy_list(username, " - "name, id) values ('">>, - Username, <<"', '">>, SName, - <<"', '">>, ID, <<"');">>], - [<<"delete from privacy_list_data where " - "id='">>, ID, <<"';">>]] ++ - [[<<"insert into privacy_list_data(id, t, " - "value, action, ord, match_all, match_iq, " - "match_message, match_presence_in, " - "match_presence_out) values ('">>, - ID, <<"', '">>, str:join(Items, <<"', '">>), - <<"');">>] || Items <- RItems] + ID = get_id(), + [?SQL("delete from privacy_list where" + " username=%(LUser)s and" + " name=%(Name)s;"), + ?SQL("insert into privacy_list(username, " + "name, id) values (" + "%(LUser)s, %(Name)s, %(ID)d);"), + ?SQL("delete from privacy_list_data where" + " id=%(ID)d;")] ++ + [?SQL("insert into privacy_list_data(id, t, " + "value, action, ord, match_all, match_iq, " + "match_message, match_presence_in, " + "match_presence_out) " + "values (%(ID)d, %(SType)s, %(SValue)s, %(SAction)s," + " %(Order)d, %(MatchAll)b, %(MatchIQ)b," + " %(MatchMessage)b, %(MatchPresenceIn)b," + " %(MatchPresenceOut)b)") + || {SType, SValue, SAction, Order, + MatchAll, MatchIQ, + MatchMessage, MatchPresenceIn, + MatchPresenceOut} <- RItems] end, Lists); (_Host, _R) -> @@ -327,10 +330,8 @@ item_to_raw(#listitem{type = Type, value = Value, match_presence_out = MatchPresenceOut}) -> {SType, SValue} = case Type of none -> {<<"n">>, <<"">>}; - jid -> - {<<"j">>, - ejabberd_sql:escape(jid:to_string(Value))}; - group -> {<<"g">>, ejabberd_sql:escape(Value)}; + jid -> {<<"j">>, jid:to_string(Value)}; + group -> {<<"g">>, Value}; subscription -> case Value of none -> {<<"s">>, <<"none">>}; @@ -368,9 +369,7 @@ sql_get_privacy_list_data(LUser, LServer, Name) -> sql_queries:get_privacy_list_data(LServer, LUser, Name). sql_get_privacy_list_data_t(LUser, Name) -> - Username = ejabberd_sql:escape(LUser), - SName = ejabberd_sql:escape(Name), - sql_queries:get_privacy_list_data_t(Username, SName). + sql_queries:get_privacy_list_data_t(LUser, Name). sql_get_privacy_list_data_by_id(ID, LServer) -> sql_queries:get_privacy_list_data_by_id(LServer, ID). diff --git a/src/mod_private_sql.erl b/src/mod_private_sql.erl index 6ec6c9df1..0e9d1b61e 100644 --- a/src/mod_private_sql.erl +++ b/src/mod_private_sql.erl @@ -71,12 +71,8 @@ export(_Server) -> fun(Host, #private_storage{usns = {LUser, LServer, XMLNS}, xml = Data}) when LServer == Host -> - Username = ejabberd_sql:escape(LUser), - LXMLNS = ejabberd_sql:escape(XMLNS), - SData = - ejabberd_sql:escape(fxml:element_to_binary(Data)), - sql_queries:set_private_data_sql(Username, LXMLNS, - SData); + SData = fxml:element_to_binary(Data), + sql_queries:set_private_data_sql(LUser, XMLNS, SData); (_Host, _R) -> [] end}]. diff --git a/src/mod_roster_sql.erl b/src/mod_roster_sql.erl index 616d0ec60..899978091 100644 --- a/src/mod_roster_sql.erl +++ b/src/mod_roster_sql.erl @@ -8,6 +8,8 @@ %%%------------------------------------------------------------------- -module(mod_roster_sql). +-compile([{parse_transform, ejabberd_sql_pt}]). + -behaviour(mod_roster). %% API @@ -20,6 +22,7 @@ -include("jlib.hrl"). -include("mod_roster.hrl"). +-include("ejabberd_sql_pt.hrl"). %%%=================================================================== %%% API @@ -34,15 +37,13 @@ read_roster_version(LUser, LServer) -> end. write_roster_version(LUser, LServer, InTransaction, Ver) -> - Username = ejabberd_sql:escape(LUser), - EVer = ejabberd_sql:escape(Ver), if InTransaction -> - sql_queries:set_roster_version(Username, EVer); + sql_queries:set_roster_version(LUser, Ver); true -> sql_queries:sql_transaction( LServer, fun () -> - sql_queries:set_roster_version(Username, EVer) + sql_queries:set_roster_version(LUser, Ver) end) end. @@ -167,26 +168,20 @@ read_subscription_and_groups(LUser, LServer, LJID) -> export(_Server) -> [{roster, - fun(Host, #roster{usj = {LUser, LServer, LJID}} = R) + fun(Host, #roster{usj = {_LUser, LServer, _LJID}} = R) when LServer == Host -> - Username = ejabberd_sql:escape(LUser), - SJID = ejabberd_sql:escape(jid:to_string(LJID)), - ItemVals = record_to_string(R), - ItemGroups = groups_to_string(R), - sql_queries:update_roster_sql(Username, SJID, - ItemVals, ItemGroups); + ItemVals = record_to_row(R), + ItemGroups = R#roster.groups, + sql_queries:update_roster_sql(ItemVals, ItemGroups); (_Host, _R) -> [] end}, {roster_version, fun(Host, #roster_version{us = {LUser, LServer}, version = Ver}) when LServer == Host -> - Username = ejabberd_sql:escape(LUser), - SVer = ejabberd_sql:escape(Ver), - [[<<"delete from roster_version where username='">>, - Username, <<"';">>], - [<<"insert into roster_version(username, version) values('">>, - Username, <<"', '">>, SVer, <<"');">>]]; + [?SQL("delete from roster_version where username=%(LUser)s;"), + ?SQL("insert into roster_version(username, version) values(" + " %(LUser)s, %(Ver)s);")]; (_Host, _R) -> [] end}]. @@ -294,15 +289,3 @@ record_to_row( none -> <<"N">> end, {LUser, SJID, Name, SSubscription, SAsk, AskMessage}. - -groups_to_string(#roster{us = {User, _Server}, - jid = JID, groups = Groups}) -> - Username = ejabberd_sql:escape(User), - SJID = - ejabberd_sql:escape(jid:to_string(jid:tolower(JID))), - lists:foldl(fun (<<"">>, Acc) -> Acc; - (Group, Acc) -> - G = ejabberd_sql:escape(Group), - [[Username, SJID, G] | Acc] - end, - [], Groups). diff --git a/src/mod_shared_roster_sql.erl b/src/mod_shared_roster_sql.erl index bd123cd4a..2b186fd0b 100644 --- a/src/mod_shared_roster_sql.erl +++ b/src/mod_shared_roster_sql.erl @@ -8,6 +8,8 @@ %%%------------------------------------------------------------------- -module(mod_shared_roster_sql). +-compile([{parse_transform, ejabberd_sql_pt}]). + -behaviour(mod_shared_roster). %% API @@ -21,6 +23,7 @@ -include("jlib.hrl"). -include("mod_roster.hrl"). -include("mod_shared_roster.hrl"). +-include("ejabberd_sql_pt.hrl"). %%%=================================================================== %%% API @@ -30,38 +33,39 @@ init(_Host, _Opts) -> list_groups(Host) -> case ejabberd_sql:sql_query( - Host, [<<"select name from sr_group;">>]) of - {selected, [<<"name">>], Rs} -> [G || [G] <- Rs]; + Host, + ?SQL("select @(name)s from sr_group")) of + {selected, Rs} -> [G || {G} <- Rs]; _ -> [] end. groups_with_opts(Host) -> - case ejabberd_sql:sql_query(Host, - [<<"select name, opts from sr_group;">>]) + case ejabberd_sql:sql_query( + Host, + ?SQL("select @(name)s, @(opts)s from sr_group")) of - {selected, [<<"name">>, <<"opts">>], Rs} -> + {selected, Rs} -> [{G, mod_shared_roster:opts_to_binary(ejabberd_sql:decode_term(Opts))} - || [G, Opts] <- Rs]; + || {G, Opts} <- Rs]; _ -> [] end. create_group(Host, Group, Opts) -> - SGroup = ejabberd_sql:escape(Group), - SOpts = ejabberd_sql:encode_term(Opts), + SOpts = jlib:term_to_expr(Opts), F = fun () -> - sql_queries:update_t(<<"sr_group">>, - [<<"name">>, <<"opts">>], [SGroup, SOpts], - [<<"name='">>, SGroup, <<"'">>]) + ?SQL_UPSERT_T( + "sr_group", + ["!name=%(Group)s", + "opts=%(SOpts)s"]) end, ejabberd_sql:sql_transaction(Host, F). delete_group(Host, Group) -> - SGroup = ejabberd_sql:escape(Group), F = fun () -> - ejabberd_sql:sql_query_t([<<"delete from sr_group where name='">>, - SGroup, <<"';">>]), - ejabberd_sql:sql_query_t([<<"delete from sr_user where grp='">>, - SGroup, <<"';">>]) + ejabberd_sql:sql_query_t( + ?SQL("delete from sr_group where name=%(Group)s")), + ejabberd_sql:sql_query_t( + ?SQL("delete from sr_user where grp=%(Group)s")) end, case ejabberd_sql:sql_transaction(Host, F) of {atomic,{updated,_}} -> {atomic, ok}; @@ -69,23 +73,21 @@ delete_group(Host, Group) -> end. get_group_opts(Host, Group) -> - SGroup = ejabberd_sql:escape(Group), case catch ejabberd_sql:sql_query( Host, - [<<"select opts from sr_group where name='">>, - SGroup, <<"';">>]) of - {selected, [<<"opts">>], [[SOpts]]} -> + ?SQL("select @(opts)s from sr_group where name=%(Group)s")) of + {selected, [{SOpts}]} -> mod_shared_roster:opts_to_binary(ejabberd_sql:decode_term(SOpts)); _ -> error end. set_group_opts(Host, Group, Opts) -> - SGroup = ejabberd_sql:escape(Group), - SOpts = ejabberd_sql:encode_term(Opts), + SOpts = jlib:term_to_expr(Opts), F = fun () -> - sql_queries:update_t(<<"sr_group">>, - [<<"name">>, <<"opts">>], [SGroup, SOpts], - [<<"name='">>, SGroup, <<"'">>]) + ?SQL_UPSERT_T( + "sr_group", + ["!name=%(Group)s", + "opts=%(SOpts)s"]) end, ejabberd_sql:sql_transaction(Host, F). @@ -93,21 +95,18 @@ get_user_groups(US, Host) -> SJID = make_jid_s(US), case catch ejabberd_sql:sql_query( Host, - [<<"select grp from sr_user where jid='">>, - SJID, <<"';">>]) of - {selected, [<<"grp">>], Rs} -> [G || [G] <- Rs]; + ?SQL("select @(grp)s from sr_user where jid=%(SJID)s")) of + {selected, Rs} -> [G || {G} <- Rs]; _ -> [] end. get_group_explicit_users(Host, Group) -> - SGroup = ejabberd_sql:escape(Group), case catch ejabberd_sql:sql_query( Host, - [<<"select jid from sr_user where grp='">>, - SGroup, <<"';">>]) of - {selected, [<<"jid">>], Rs} -> + ?SQL("select @(jid)s from sr_user where grp=%(Group)s")) of + {selected, Rs} -> lists:map( - fun([JID]) -> + fun({JID}) -> {U, S, _} = jid:tolower(jid:from_string(JID)), {U, S} end, Rs); @@ -119,43 +118,36 @@ get_user_displayed_groups(LUser, LServer, GroupsOpts) -> SJID = make_jid_s(LUser, LServer), case catch ejabberd_sql:sql_query( LServer, - [<<"select grp from sr_user where jid='">>, - SJID, <<"';">>]) of - {selected, [<<"grp">>], Rs} -> + ?SQL("select @(grp)s from sr_user where jid=%(SJID)s")) of + {selected, Rs} -> [{Group, proplists:get_value(Group, GroupsOpts, [])} - || [Group] <- Rs]; + || {Group} <- Rs]; _ -> [] end. is_user_in_group(US, Group, Host) -> SJID = make_jid_s(US), - SGroup = ejabberd_sql:escape(Group), - case catch ejabberd_sql:sql_query(Host, - [<<"select * from sr_user where jid='">>, - SJID, <<"' and grp='">>, SGroup, - <<"';">>]) of - {selected, _, []} -> false; + case catch ejabberd_sql:sql_query( + Host, + ?SQL("select @(jid)s from sr_user where jid=%(SJID)s" + " and grp=%(Group)s")) of + {selected, []} -> false; _ -> true end. add_user_to_group(Host, US, Group) -> SJID = make_jid_s(US), - SGroup = ejabberd_sql:escape(Group), - F = fun () -> - sql_queries:update_t(<<"sr_user">>, - [<<"jid">>, <<"grp">>], [SJID, SGroup], - [<<"jid='">>, SJID, <<"' and grp='">>, - SGroup, <<"'">>]) - end, - ejabberd_sql:sql_transaction(Host, F). + ejabberd_sql:sql_query( + Host, + ?SQL("insert into sr_user(jid, grp) values (" + "%(SJID)s, %(Group)s)")). remove_user_from_group(Host, US, Group) -> SJID = make_jid_s(US), - SGroup = ejabberd_sql:escape(Group), F = fun () -> - ejabberd_sql:sql_query_t([<<"delete from sr_user where jid='">>, - SJID, <<"' and grp='">>, SGroup, - <<"';">>]), + ejabberd_sql:sql_query_t( + ?SQL("delete from sr_user where jid=%(SJID)s and" + " grp=%(Group)s")), ok end, ejabberd_sql:sql_transaction(Host, F). @@ -164,26 +156,23 @@ export(_Server) -> [{sr_group, fun(Host, #sr_group{group_host = {Group, LServer}, opts = Opts}) when LServer == Host -> - SGroup = ejabberd_sql:escape(Group), - SOpts = ejabberd_sql:encode_term(Opts), - [[<<"delete from sr_group where name='">>, Group, <<"';">>], - [<<"insert into sr_group(name, opts) values ('">>, - SGroup, <<"', '">>, SOpts, <<"');">>]]; + SOpts = jlib:term_to_expr(Opts), + [?SQL("delete from sr_group where name=%(Group)s;"), + ?SQL("insert into sr_group(name, opts) values (" + "%(Group)s, %(SOpts)s);")]; (_Host, _R) -> [] end}, {sr_user, fun(Host, #sr_user{us = {U, S}, group_host = {Group, LServer}}) when LServer == Host -> - SGroup = ejabberd_sql:escape(Group), - SJID = ejabberd_sql:escape( - jid:to_string( - jid:tolower( - jid:make(U, S, <<"">>)))), - [[<<"delete from sr_user where jid='">>, SJID, - <<"'and grp='">>, Group, <<"';">>], - [<<"insert into sr_user(jid, grp) values ('">>, - SJID, <<"', '">>, SGroup, <<"');">>]]; + SJID = jid:to_string( + jid:tolower( + jid:make(U, S, <<"">>))), + [?SQL("select @(jid)s from sr_user where jid=%(SJID)s" + " and grp=%(Group)s;"), + ?SQL("insert into sr_user(jid, grp) values (" + "%(SJID)s, %(Group)s);")]; (_Host, _R) -> [] end}]. @@ -207,6 +196,6 @@ import(_, _) -> %%% Internal functions %%%=================================================================== make_jid_s(U, S) -> - ejabberd_sql:escape(jid:to_string(jid:tolower(jid:make(U, S, <<"">>)))). + jid:to_string(jid:tolower(jid:make(U, S, <<"">>))). make_jid_s({U, S}) -> make_jid_s(U, S). diff --git a/src/mod_vcard_sql.erl b/src/mod_vcard_sql.erl index 9fcd5cd5e..6b8e90333 100644 --- a/src/mod_vcard_sql.erl +++ b/src/mod_vcard_sql.erl @@ -113,12 +113,10 @@ export(_Server) -> [{vcard, fun(Host, #vcard{us = {LUser, LServer}, vcard = VCARD}) when LServer == Host -> - Username = ejabberd_sql:escape(LUser), - SVCARD = - ejabberd_sql:escape(fxml:element_to_binary(VCARD)), - [[<<"delete from vcard where username='">>, Username, <<"';">>], - [<<"insert into vcard(username, vcard) values ('">>, - Username, <<"', '">>, SVCARD, <<"');">>]]; + 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);")]; (_Host, _R) -> [] end}, @@ -135,52 +133,26 @@ export(_Server) -> orgname = OrgName, lorgname = LOrgName, orgunit = OrgUnit, lorgunit = LOrgUnit}) when LServer == Host -> - Username = ejabberd_sql:escape(User), - LUsername = ejabberd_sql:escape(LUser), - SFN = ejabberd_sql:escape(FN), - SLFN = ejabberd_sql:escape(LFN), - SFamily = ejabberd_sql:escape(Family), - SLFamily = ejabberd_sql:escape(LFamily), - SGiven = ejabberd_sql:escape(Given), - SLGiven = ejabberd_sql:escape(LGiven), - SMiddle = ejabberd_sql:escape(Middle), - SLMiddle = ejabberd_sql:escape(LMiddle), - SNickname = ejabberd_sql:escape(Nickname), - SLNickname = ejabberd_sql:escape(LNickname), - SBDay = ejabberd_sql:escape(BDay), - SLBDay = ejabberd_sql:escape(LBDay), - SCTRY = ejabberd_sql:escape(CTRY), - SLCTRY = ejabberd_sql:escape(LCTRY), - SLocality = ejabberd_sql:escape(Locality), - SLLocality = ejabberd_sql:escape(LLocality), - SEMail = ejabberd_sql:escape(EMail), - SLEMail = ejabberd_sql:escape(LEMail), - SOrgName = ejabberd_sql:escape(OrgName), - SLOrgName = ejabberd_sql:escape(LOrgName), - SOrgUnit = ejabberd_sql:escape(OrgUnit), - SLOrgUnit = ejabberd_sql:escape(LOrgUnit), - [[<<"delete from vcard_search where lusername='">>, - LUsername, <<"';">>], - [<<"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 (">>, - <<" '">>, Username, <<"', '">>, LUsername, - <<"', '">>, SFN, <<"', '">>, SLFN, - <<"', '">>, SFamily, <<"', '">>, SLFamily, - <<"', '">>, SGiven, <<"', '">>, SLGiven, - <<"', '">>, SMiddle, <<"', '">>, SLMiddle, - <<"', '">>, SNickname, <<"', '">>, SLNickname, - <<"', '">>, SBDay, <<"', '">>, SLBDay, - <<"', '">>, SCTRY, <<"', '">>, SLCTRY, - <<"', '">>, SLocality, <<"', '">>, SLLocality, - <<"', '">>, SEMail, <<"', '">>, SLEMail, - <<"', '">>, SOrgName, <<"', '">>, SLOrgName, - <<"', '">>, SOrgUnit, <<"', '">>, SLOrgUnit, - <<"');">>]]; + [?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);")]; (_Host, _R) -> [] end}]. diff --git a/src/mod_vcard_xupdate_sql.erl b/src/mod_vcard_xupdate_sql.erl index 00bb29501..938114b8f 100644 --- a/src/mod_vcard_xupdate_sql.erl +++ b/src/mod_vcard_xupdate_sql.erl @@ -8,6 +8,8 @@ %%%------------------------------------------------------------------- -module(mod_vcard_xupdate_sql). +-compile([{parse_transform, ejabberd_sql_pt}]). + -behaviour(mod_vcard_xupdate). %% API @@ -15,6 +17,7 @@ import/1, export/1]). -include("mod_vcard_xupdate.hrl"). +-include("ejabberd_sql_pt.hrl"). %%%=================================================================== %%% API @@ -23,46 +26,38 @@ init(_Host, _Opts) -> ok. add_xupdate(LUser, LServer, Hash) -> - Username = ejabberd_sql:escape(LUser), - SHash = ejabberd_sql:escape(Hash), F = fun () -> - sql_queries:update_t(<<"vcard_xupdate">>, - [<<"username">>, <<"hash">>], - [Username, SHash], - [<<"username='">>, Username, <<"'">>]) + ?SQL_UPSERT_T( + "vcard_xupdate", + ["!username=%(LUser)s", + "hash=%(Hash)s"]) end, ejabberd_sql:sql_transaction(LServer, F). get_xupdate(LUser, LServer) -> - Username = ejabberd_sql:escape(LUser), - case ejabberd_sql:sql_query(LServer, - [<<"select hash from vcard_xupdate where " - "username='">>, - Username, <<"';">>]) + case ejabberd_sql:sql_query( + LServer, + ?SQL("select @(hash)s from vcard_xupdate where" + " username=%(LUser)s")) of - {selected, [<<"hash">>], [[Hash]]} -> Hash; - _ -> undefined + {selected, [{Hash}]} -> Hash; + _ -> undefined end. remove_xupdate(LUser, LServer) -> - Username = ejabberd_sql:escape(LUser), F = fun () -> - ejabberd_sql:sql_query_t([<<"delete from vcard_xupdate where username='">>, - Username, <<"';">>]) + ejabberd_sql:sql_query_t( + ?SQL("delete from vcard_xupdate where username=%(LUser)s")) end, ejabberd_sql:sql_transaction(LServer, F). export(_Server) -> [{vcard_xupdate, fun(Host, #vcard_xupdate{us = {LUser, LServer}, hash = Hash}) - when LServer == Host -> - Username = ejabberd_sql:escape(LUser), - SHash = ejabberd_sql:escape(Hash), - [[<<"delete from vcard_xupdate where username='">>, - Username, <<"';">>], - [<<"insert into vcard_xupdate(username, " - "hash) values ('">>, - Username, <<"', '">>, SHash, <<"');">>]]; + when LServer == Host -> + [?SQL("delete from vcard_xupdate where username=%(LUser)s;"), + ?SQL("insert into vcard_xupdate(username, hash) values (" + "%(LUser)s, %(Hash)s);")]; (_Host, _R) -> [] end}]. diff --git a/src/sql_queries.erl b/src/sql_queries.erl index 98530a4cf..e1374a817 100644 --- a/src/sql_queries.erl +++ b/src/sql_queries.erl @@ -42,7 +42,7 @@ get_roster_groups/3, del_user_roster_t/2, get_roster_by_jid/3, get_rostergroup_by_jid/3, del_roster/3, del_roster_sql/2, update_roster/5, - update_roster_sql/4, roster_subscribe/1, + update_roster_sql/2, roster_subscribe/1, get_subscription/3, set_private_data/4, set_private_data_sql/3, get_private_data/3, get_private_data/2, del_user_private_storage/2, @@ -368,24 +368,27 @@ update_roster(_LServer, LUser, SJID, ItemVals, end, ItemGroups). -update_roster_sql(Username, SJID, ItemVals, +update_roster_sql({LUser, SJID, Name, SSubscription, SAsk, AskMessage}, ItemGroups) -> - [[<<"delete from rosterusers where " - "username='">>, - Username, <<"' and jid='">>, SJID, <<"';">>], - [<<"insert into rosterusers( " - " username, jid, nick, " - " subscription, ask, askmessage, " - " server, subscribe, type) " - "values ('">>, - join(ItemVals, <<"', '">>), <<"');">>], - [<<"delete from rostergroups where " - "username='">>, - Username, <<"' and jid='">>, SJID, <<"';">>]] + [?SQL("delete from rosterusers where" + " username=%(LUser)s and jid=%(SJID)s;"), + ?SQL("insert into rosterusers(" + " username, jid, nick," + " subscription, ask, askmessage," + " server, subscribe, type) " + "values (" + "%(LUser)s, " + "%(SJID)s, " + "%(Name)s, " + "%(SSubscription)s, " + "%(SAsk)s, " + "%(AskMessage)s, " + "'N', '', 'item');"), + ?SQL("delete from rostergroups where" + " username=%(LUser)s and jid=%(SJID)s;")] ++ - [[<<"insert into rostergroups( " - " username, jid, grp) values ('">>, - join(ItemGroup, <<"', '">>), <<"');">>] + [?SQL("insert into rostergroups(username, jid, grp) " + "values (%(LUser)s, %(SJID)s, %(ItemGroup)s)") || ItemGroup <- ItemGroups]. roster_subscribe({LUser, SJID, Name, SSubscription, SAsk, AskMessage}) -> @@ -414,13 +417,12 @@ set_private_data(_LServer, LUser, XMLNS, SData) -> "!namespace=%(XMLNS)s", "data=%(SData)s"]). -set_private_data_sql(Username, LXMLNS, SData) -> - [[<<"delete from private_storage where username='">>, - Username, <<"' and namespace='">>, LXMLNS, <<"';">>], - [<<"insert into private_storage(username, " - "namespace, data) values ('">>, - Username, <<"', '">>, LXMLNS, <<"', '">>, SData, - <<"');">>]]. +set_private_data_sql(LUser, XMLNS, SData) -> + [?SQL("delete from private_storage where" + " username=%(LUser)s and namespace=%(XMLNS)s;"), + ?SQL("insert into private_storage(username, " + "namespace, data) values (" + "%(LUser)s, %(XMLNS)s, %(SData)s);")]. get_private_data(LServer, LUser, XMLNS) -> ejabberd_sql:sql_query( @@ -628,9 +630,10 @@ get_roster_version(LServer, LUser) -> " where username = %(LUser)s")). set_roster_version(LUser, Version) -> - update_t(<<"roster_version">>, - [<<"username">>, <<"version">>], [LUser, Version], - [<<"username = '">>, LUser, <<"'">>]). + ?SQL_UPSERT_T( + "roster_version", + ["!username=%(LUser)s", + "version=%(Version)s"]). opt_type(sql_type) -> fun (pgsql) -> pgsql;