diff --git a/src/ejabberd_sql.erl b/src/ejabberd_sql.erl index 22151b697..5bf371654 100644 --- a/src/ejabberd_sql.erl +++ b/src/ejabberd_sql.erl @@ -45,6 +45,7 @@ escape_like_arg/1, escape_like_arg_circumflex/1, to_string_literal/2, + to_string_literal_t/1, to_bool/1, sqlite_db/1, sqlite_file/1, @@ -263,6 +264,10 @@ to_string_literal(sqlite, S) -> to_string_literal(pgsql, S) -> <<"E'", (escape(S))/binary, "'">>. +to_string_literal_t(S) -> + State = get(?STATE_KEY), + to_string_literal(State#state.db_type, S). + encode_term(Term) -> escape(list_to_binary( erl_prettypr:format(erl_syntax:abstract(Term), diff --git a/src/mod_vcard_sql.erl b/src/mod_vcard_sql.erl index 6b604161f..5c195fbf8 100644 --- a/src/mod_vcard_sql.erl +++ b/src/mod_vcard_sql.erl @@ -263,10 +263,11 @@ make_matchspec(LServer, Data) -> filter_fields([], Match, LServer) -> case ejabberd_sql:use_new_schema() of true -> - SServer = ejabberd_sql:escape(LServer), + SQLType = ejabberd_option:sql_type(LServer), + SServer = ejabberd_sql:to_string_literal(SQLType, LServer), case Match of - <<"">> -> [<<"where server_host='">>, SServer, <<"'">>]; - _ -> [<<" where server_host='">>, SServer, <<"' and ">>, Match] + <<"">> -> [<<"where server_host=">>, SServer]; + _ -> [<<" where server_host=">>, SServer, <<" and ">>, Match] end; false -> case Match of @@ -278,26 +279,26 @@ filter_fields([{SVar, [Val]} | Ds], Match, LServer) when is_binary(Val) and (Val /= <<"">>) -> LVal = mod_vcard:string2lower(Val), NewMatch = case SVar of - <<"user">> -> make_val(Match, <<"lusername">>, LVal); - <<"fn">> -> make_val(Match, <<"lfn">>, LVal); - <<"last">> -> make_val(Match, <<"lfamily">>, LVal); - <<"first">> -> make_val(Match, <<"lgiven">>, LVal); - <<"middle">> -> make_val(Match, <<"lmiddle">>, LVal); - <<"nick">> -> make_val(Match, <<"lnickname">>, LVal); - <<"bday">> -> make_val(Match, <<"lbday">>, LVal); - <<"ctry">> -> make_val(Match, <<"lctry">>, LVal); + <<"user">> -> make_val(LServer, Match, <<"lusername">>, LVal); + <<"fn">> -> make_val(LServer, Match, <<"lfn">>, LVal); + <<"last">> -> make_val(LServer, Match, <<"lfamily">>, LVal); + <<"first">> -> make_val(LServer, Match, <<"lgiven">>, LVal); + <<"middle">> -> make_val(LServer, Match, <<"lmiddle">>, LVal); + <<"nick">> -> make_val(LServer, Match, <<"lnickname">>, LVal); + <<"bday">> -> make_val(LServer, Match, <<"lbday">>, LVal); + <<"ctry">> -> make_val(LServer, Match, <<"lctry">>, LVal); <<"locality">> -> - make_val(Match, <<"llocality">>, LVal); - <<"email">> -> make_val(Match, <<"lemail">>, LVal); - <<"orgname">> -> make_val(Match, <<"lorgname">>, LVal); - <<"orgunit">> -> make_val(Match, <<"lorgunit">>, LVal); + make_val(LServer, Match, <<"llocality">>, LVal); + <<"email">> -> make_val(LServer, Match, <<"lemail">>, LVal); + <<"orgname">> -> make_val(LServer, Match, <<"lorgname">>, LVal); + <<"orgunit">> -> make_val(LServer, Match, <<"lorgunit">>, LVal); _ -> Match end, filter_fields(Ds, NewMatch, LServer); filter_fields([_ | Ds], Match, LServer) -> filter_fields(Ds, Match, LServer). -make_val(Match, Field, Val) -> +make_val(LServer, Match, Field, Val) -> Condition = case str:suffix(<<"*">>, Val) of true -> Val1 = str:substr(Val, 1, byte_size(Val) - 1), @@ -307,8 +308,9 @@ make_val(Match, Field, Val) -> "%">>, [Field, <<" LIKE '">>, SVal, <<"' ESCAPE '^'">>]; _ -> - SVal = ejabberd_sql:escape(Val), - [Field, <<" = '">>, SVal, <<"'">>] + SQLType = ejabberd_option:sql_type(LServer), + SVal = ejabberd_sql:to_string_literal(SQLType, Val), + [Field, <<" = ">>, SVal] end, case Match of <<"">> -> Condition; diff --git a/src/node_flat_sql.erl b/src/node_flat_sql.erl index 15d9fd770..76b1c8ccc 100644 --- a/src/node_flat_sql.erl +++ b/src/node_flat_sql.erl @@ -838,7 +838,7 @@ del_items(_, []) -> del_items(Nidx, [ItemId]) -> del_item(Nidx, ItemId); del_items(Nidx, ItemIds) -> - I = str:join([[<<"'">>, ejabberd_sql:escape(X), <<"'">>] || X <- ItemIds], <<",">>), + I = str:join([ejabberd_sql:to_string_literal_t(X) || X <- ItemIds], <<",">>), SNidx = misc:i2l(Nidx), catch ejabberd_sql:sql_query_t([<<"delete from pubsub_item where itemid in (">>, diff --git a/src/pubsub_db_sql.erl b/src/pubsub_db_sql.erl index 4df6a8695..558b696cb 100644 --- a/src/pubsub_db_sql.erl +++ b/src/pubsub_db_sql.erl @@ -40,13 +40,12 @@ %% -spec read_subscription(SubID :: string()) -> {ok, #pubsub_subscription{}} | notfound. read_subscription(SubID) -> case - ejabberd_sql:sql_query_t([<<"select opt_name, opt_value from pubsub_subscr" - "iption_opt where subid = '">>, - ejabberd_sql:escape(SubID), <<"'">>]) + ejabberd_sql:sql_query_t( + ?SQL("select @(opt_name)s, @(opt_value)s from pubsub_subscription_opt where subid = %(SubID)s")) of - {selected, [<<"opt_name">>, <<"opt_value">>], []} -> + {selected, []} -> notfound; - {selected, [<<"opt_name">>, <<"opt_value">>], Options} -> + {selected, Options} -> {ok, #pubsub_subscription{subid = SubID, options = lists:map(fun subscription_opt_from_sql/1, Options)}} @@ -57,48 +56,47 @@ delete_subscription(SubID) -> %% -spec update_subscription(#pubsub_subscription{}) -> ok . %% -spec add_subscription(#pubsub_subscription{}) -> ok. %% -------------- Internal utilities ----------------------- - ejabberd_sql:sql_query_t([<<"delete from pubsub_subscription_opt " - "where subid = '">>, - ejabberd_sql:escape(SubID), <<"'">>]), + ejabberd_sql:sql_query_t( + ?SQL("delete from pubsub_subscription_opt " + "where subid = %(SubID)s")), ok. update_subscription(#pubsub_subscription{subid = SubId} = Sub) -> delete_subscription(SubId), add_subscription(Sub). add_subscription(#pubsub_subscription{subid = SubId, options = Opts}) -> - EscapedSubId = ejabberd_sql:escape(SubId), - lists:foreach(fun (Opt) -> - {OdbcOptName, OdbcOptValue} = subscription_opt_to_sql(Opt), - ejabberd_sql:sql_query_t([<<"insert into pubsub_subscription_opt(subid, " - "opt_name, opt_value)values ('">>, - EscapedSubId, <<"','">>, - OdbcOptName, <<"','">>, - OdbcOptValue, <<"')">>]) - end, - Opts), + lists:foreach( + fun(Opt) -> + {OdbcOptName, OdbcOptValue} = subscription_opt_to_sql(Opt), + ejabberd_sql:sql_query_t( + ?SQL("insert into pubsub_subscription_opt(subid, " + "opt_name, opt_value) values " + "(%(SubId)s, %(OdbcOptName)s, %(OdbcOptValue)s)")) + end, + Opts), ok. -subscription_opt_from_sql([<<"DELIVER">>, Value]) -> +subscription_opt_from_sql({<<"DELIVER">>, Value}) -> {deliver, sql_to_boolean(Value)}; -subscription_opt_from_sql([<<"DIGEST">>, Value]) -> +subscription_opt_from_sql({<<"DIGEST">>, Value}) -> {digest, sql_to_boolean(Value)}; -subscription_opt_from_sql([<<"DIGEST_FREQUENCY">>, Value]) -> +subscription_opt_from_sql({<<"DIGEST_FREQUENCY">>, Value}) -> {digest_frequency, sql_to_integer(Value)}; -subscription_opt_from_sql([<<"EXPIRE">>, Value]) -> +subscription_opt_from_sql({<<"EXPIRE">>, Value}) -> {expire, sql_to_timestamp(Value)}; -subscription_opt_from_sql([<<"INCLUDE_BODY">>, Value]) -> +subscription_opt_from_sql({<<"INCLUDE_BODY">>, Value}) -> {include_body, sql_to_boolean(Value)}; %%TODO: might be > than 1 show_values value??. %% need to use compact all in only 1 opt. -subscription_opt_from_sql([<<"SHOW_VALUES">>, Value]) -> +subscription_opt_from_sql({<<"SHOW_VALUES">>, Value}) -> {show_values, Value}; -subscription_opt_from_sql([<<"SUBSCRIPTION_TYPE">>, Value]) -> +subscription_opt_from_sql({<<"SUBSCRIPTION_TYPE">>, Value}) -> {subscription_type, case Value of <<"items">> -> items; <<"nodes">> -> nodes end}; -subscription_opt_from_sql([<<"SUBSCRIPTION_DEPTH">>, Value]) -> +subscription_opt_from_sql({<<"SUBSCRIPTION_DEPTH">>, Value}) -> {subscription_depth, case Value of <<"all">> -> all;