From a6c06964e1d961a4de3daf5b1cc9ccb4ad6ba90c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chmielowski?= Date: Wed, 5 Dec 2018 13:11:52 +0100 Subject: [PATCH] Add list types to sql_pt --- src/ejabberd_sql.erl | 17 +++++++++++------ src/ejabberd_sql_pt.erl | 27 +++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/ejabberd_sql.erl b/src/ejabberd_sql.erl index 3d3741548..9e088f211 100644 --- a/src/ejabberd_sql.erl +++ b/src/ejabberd_sql.erl @@ -37,12 +37,12 @@ sql_query_t/1, sql_transaction/2, sql_bloc/2, - abort/1, - restart/1, - use_new_schema/0, - sql_query_to_iolist/1, + abort/1, + restart/1, + use_new_schema/0, + sql_query_to_iolist/1, escape/1, - standard_escape/1, + standard_escape/1, escape_like/1, escape_like_arg/1, escape_like_arg_circumflex/1, @@ -55,7 +55,8 @@ freetds_config/0, odbcinst_config/0, init_mssql/1, - keep_alive/2]). + keep_alive/2, + to_list/2]). %% gen_fsm callbacks -export([init/1, handle_event/3, handle_sync_event/4, @@ -258,6 +259,10 @@ to_bool(true) -> true; to_bool(1) -> true; to_bool(_) -> false. +to_list(EscapeFun, Val) -> + Escaped = lists:join(<<",">>, lists:map(EscapeFun, Val)), + [<<"(">>, Escaped, <<")">>]. + encode_term(Term) -> escape(list_to_binary( erl_prettypr:format(erl_syntax:abstract(Term), diff --git a/src/ejabberd_sql_pt.erl b/src/ejabberd_sql_pt.erl index eb7905bf0..1f6134d07 100644 --- a/src/ejabberd_sql_pt.erl +++ b/src/ejabberd_sql_pt.erl @@ -306,6 +306,20 @@ parse1([$%, $( | S], Acc, State) -> false -> append_string("0=0", State3) end; + {list, InternalType} -> + Convert = erl_syntax:application( + erl_syntax:atom(ejabberd_sql), + erl_syntax:atom(to_list), + [erl_syntax:record_access( + erl_syntax:variable(?ESCAPE_VAR), + erl_syntax:atom(?ESCAPE_RECORD), + erl_syntax:atom(InternalType)), + erl_syntax:variable(Name)]), + State2#state{'query' = [{var, Var} | State2#state.'query'], + args = [Convert | State2#state.args], + params = [Var | State2#state.params], + param_pos = State2#state.param_pos + 1, + used_vars = [Name | State2#state.used_vars]}; _ -> Convert = erl_syntax:application( @@ -335,6 +349,19 @@ parse_name(S, IsArg, State) -> parse_name([], _Acc, _Depth, _IsArg, State) -> throw({error, State#state.loc, "expected ')', found end of string"}); +parse_name([$), $l, T | S], Acc, 0, true, State) -> + Type = case T of + $d -> {list, integer}; + $s -> {list, string}; + $b -> {list, boolean}; + _ -> + throw({error, State#state.loc, + ["unknown type specifier 'l", T, "'"]}) + end, + {lists:reverse(Acc), Type, S, State}; +parse_name([$), $l, T | _], _Acc, 0, false, State) -> + throw({error, State#state.loc, + ["list type 'l", T, "' is not allowed for outputs"]}); parse_name([$), T | S], Acc, 0, IsArg, State) -> Type = case T of