Improve compatibility with CockroachDB (#3074)

This commit is contained in:
Alexey Shchepin 2019-12-16 06:52:06 +03:00
parent f9120f75b0
commit 24ac62eabd
4 changed files with 50 additions and 45 deletions

View File

@ -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),

View File

@ -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;

View File

@ -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 (">>,

View File

@ -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;