]> granicus.if.org Git - ejabberd/commitdiff
Add list types to sql_pt
authorPaweł Chmielowski <pchmielowski@process-one.net>
Wed, 5 Dec 2018 12:11:52 +0000 (13:11 +0100)
committerPaweł Chmielowski <pchmielowski@process-one.net>
Wed, 5 Dec 2018 12:11:52 +0000 (13:11 +0100)
src/ejabberd_sql.erl
src/ejabberd_sql_pt.erl

index 3d3741548892dcda4f15e50c1a21e08b4b60f1ca..9e088f211ff0effd618482ae2d7729ed27212b78 100644 (file)
         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),
index eb7905bf0807acfb03f2e3d32724957d510c7b09..1f6134d072540d4534778296b00825cb3fee81d9 100644 (file)
@@ -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