|
@@ -17,29 +17,31 @@
|
|
|
-module(emqx_placeholder).
|
|
-module(emqx_placeholder).
|
|
|
|
|
|
|
|
%% preprocess and process template string with place holders
|
|
%% preprocess and process template string with place holders
|
|
|
--export([ preproc_tmpl/1
|
|
|
|
|
- , preproc_tmpl/2
|
|
|
|
|
- , proc_tmpl/2
|
|
|
|
|
- , proc_tmpl/3
|
|
|
|
|
- , preproc_cmd/1
|
|
|
|
|
- , proc_cmd/2
|
|
|
|
|
- , proc_cmd/3
|
|
|
|
|
- , preproc_sql/1
|
|
|
|
|
- , preproc_sql/2
|
|
|
|
|
- , proc_sql/2
|
|
|
|
|
- , proc_sql_param_str/2
|
|
|
|
|
- , proc_cql_param_str/2
|
|
|
|
|
- , preproc_tmpl_deep/1
|
|
|
|
|
- , preproc_tmpl_deep/2
|
|
|
|
|
- , proc_tmpl_deep/2
|
|
|
|
|
- , proc_tmpl_deep/3
|
|
|
|
|
-
|
|
|
|
|
- , bin/1
|
|
|
|
|
- , sql_data/1
|
|
|
|
|
- ]).
|
|
|
|
|
|
|
+-export([
|
|
|
|
|
+ preproc_tmpl/1,
|
|
|
|
|
+ preproc_tmpl/2,
|
|
|
|
|
+ proc_tmpl/2,
|
|
|
|
|
+ proc_tmpl/3,
|
|
|
|
|
+ preproc_cmd/1,
|
|
|
|
|
+ proc_cmd/2,
|
|
|
|
|
+ proc_cmd/3,
|
|
|
|
|
+ preproc_sql/1,
|
|
|
|
|
+ preproc_sql/2,
|
|
|
|
|
+ proc_sql/2,
|
|
|
|
|
+ proc_sql_param_str/2,
|
|
|
|
|
+ proc_cql_param_str/2,
|
|
|
|
|
+ preproc_tmpl_deep/1,
|
|
|
|
|
+ preproc_tmpl_deep/2,
|
|
|
|
|
+ proc_tmpl_deep/2,
|
|
|
|
|
+ proc_tmpl_deep/3,
|
|
|
|
|
+
|
|
|
|
|
+ bin/1,
|
|
|
|
|
+ sql_data/1
|
|
|
|
|
+]).
|
|
|
|
|
|
|
|
-define(EX_PLACE_HOLDER, "(\\$\\{[a-zA-Z0-9\\._]+\\})").
|
|
-define(EX_PLACE_HOLDER, "(\\$\\{[a-zA-Z0-9\\._]+\\})").
|
|
|
--define(EX_WITHE_CHARS, "\\s"). %% Space and CRLF
|
|
|
|
|
|
|
+%% Space and CRLF
|
|
|
|
|
+-define(EX_WITHE_CHARS, "\\s").
|
|
|
|
|
|
|
|
-type tmpl_token() :: list({var, binary()} | {str, binary()}).
|
|
-type tmpl_token() :: list({var, binary()} | {str, binary()}).
|
|
|
|
|
|
|
@@ -48,26 +50,32 @@
|
|
|
-type prepare_statement_key() :: binary().
|
|
-type prepare_statement_key() :: binary().
|
|
|
|
|
|
|
|
-type var_trans() ::
|
|
-type var_trans() ::
|
|
|
- fun((FoundValue :: term()) -> binary()) |
|
|
|
|
|
- fun((Placeholder :: term(), FoundValue :: term()) -> binary()).
|
|
|
|
|
|
|
+ fun((FoundValue :: term()) -> binary())
|
|
|
|
|
+ | fun((Placeholder :: term(), FoundValue :: term()) -> binary()).
|
|
|
|
|
|
|
|
-type preproc_tmpl_opts() :: #{placeholders => list(binary())}.
|
|
-type preproc_tmpl_opts() :: #{placeholders => list(binary())}.
|
|
|
|
|
|
|
|
--type preproc_sql_opts() :: #{placeholders => list(binary()),
|
|
|
|
|
- replace_with => '?' | '$n'}.
|
|
|
|
|
|
|
+-type preproc_sql_opts() :: #{
|
|
|
|
|
+ placeholders => list(binary()),
|
|
|
|
|
+ replace_with => '?' | '$n'
|
|
|
|
|
+}.
|
|
|
|
|
|
|
|
--type preproc_deep_opts() :: #{placeholders => list(binary()),
|
|
|
|
|
- process_keys => boolean()}.
|
|
|
|
|
|
|
+-type preproc_deep_opts() :: #{
|
|
|
|
|
+ placeholders => list(binary()),
|
|
|
|
|
+ process_keys => boolean()
|
|
|
|
|
+}.
|
|
|
|
|
|
|
|
--type proc_tmpl_opts() :: #{return => rawlist | full_binary,
|
|
|
|
|
- var_trans => var_trans()}.
|
|
|
|
|
|
|
+-type proc_tmpl_opts() :: #{
|
|
|
|
|
+ return => rawlist | full_binary,
|
|
|
|
|
+ var_trans => var_trans()
|
|
|
|
|
+}.
|
|
|
|
|
|
|
|
-type deep_template() ::
|
|
-type deep_template() ::
|
|
|
- #{deep_template() => deep_template()} |
|
|
|
|
|
- {tuple, [deep_template()]} |
|
|
|
|
|
- [deep_template()] |
|
|
|
|
|
- {tmpl, tmpl_token()} |
|
|
|
|
|
- {value, term()}.
|
|
|
|
|
|
|
+ #{deep_template() => deep_template()}
|
|
|
|
|
+ | {tuple, [deep_template()]}
|
|
|
|
|
+ | [deep_template()]
|
|
|
|
|
+ | {tmpl, tmpl_token()}
|
|
|
|
|
+ | {value, term()}.
|
|
|
|
|
|
|
|
%%------------------------------------------------------------------------------
|
|
%%------------------------------------------------------------------------------
|
|
|
%% APIs
|
|
%% APIs
|
|
@@ -83,7 +91,6 @@ preproc_tmpl(Str, Opts) ->
|
|
|
Tokens = re:split(Str, RE, [{return, binary}, group, trim]),
|
|
Tokens = re:split(Str, RE, [{return, binary}, group, trim]),
|
|
|
do_preproc_tmpl(Tokens, []).
|
|
do_preproc_tmpl(Tokens, []).
|
|
|
|
|
|
|
|
-
|
|
|
|
|
-spec proc_tmpl(tmpl_token(), map()) -> binary().
|
|
-spec proc_tmpl(tmpl_token(), map()) -> binary().
|
|
|
proc_tmpl(Tokens, Data) ->
|
|
proc_tmpl(Tokens, Data) ->
|
|
|
proc_tmpl(Tokens, Data, #{return => full_binary}).
|
|
proc_tmpl(Tokens, Data, #{return => full_binary}).
|
|
@@ -92,24 +99,27 @@ proc_tmpl(Tokens, Data) ->
|
|
|
proc_tmpl(Tokens, Data, Opts = #{return := full_binary}) ->
|
|
proc_tmpl(Tokens, Data, Opts = #{return := full_binary}) ->
|
|
|
Trans = maps:get(var_trans, Opts, fun emqx_plugin_libs_rule:bin/1),
|
|
Trans = maps:get(var_trans, Opts, fun emqx_plugin_libs_rule:bin/1),
|
|
|
list_to_binary(
|
|
list_to_binary(
|
|
|
- proc_tmpl(Tokens, Data, #{return => rawlist, var_trans => Trans}));
|
|
|
|
|
-
|
|
|
|
|
|
|
+ proc_tmpl(Tokens, Data, #{return => rawlist, var_trans => Trans})
|
|
|
|
|
+ );
|
|
|
proc_tmpl(Tokens, Data, Opts = #{return := rawlist}) ->
|
|
proc_tmpl(Tokens, Data, Opts = #{return := rawlist}) ->
|
|
|
Trans = maps:get(var_trans, Opts, undefined),
|
|
Trans = maps:get(var_trans, Opts, undefined),
|
|
|
lists:map(
|
|
lists:map(
|
|
|
- fun ({str, Str}) -> Str;
|
|
|
|
|
|
|
+ fun
|
|
|
|
|
+ ({str, Str}) ->
|
|
|
|
|
+ Str;
|
|
|
({var, Phld}) when is_function(Trans, 1) ->
|
|
({var, Phld}) when is_function(Trans, 1) ->
|
|
|
Trans(get_phld_var(Phld, Data));
|
|
Trans(get_phld_var(Phld, Data));
|
|
|
({var, Phld}) when is_function(Trans, 2) ->
|
|
({var, Phld}) when is_function(Trans, 2) ->
|
|
|
Trans(Phld, get_phld_var(Phld, Data));
|
|
Trans(Phld, get_phld_var(Phld, Data));
|
|
|
({var, Phld}) ->
|
|
({var, Phld}) ->
|
|
|
get_phld_var(Phld, Data)
|
|
get_phld_var(Phld, Data)
|
|
|
- end, Tokens).
|
|
|
|
|
-
|
|
|
|
|
|
|
+ end,
|
|
|
|
|
+ Tokens
|
|
|
|
|
+ ).
|
|
|
|
|
|
|
|
-spec preproc_cmd(binary()) -> tmpl_cmd().
|
|
-spec preproc_cmd(binary()) -> tmpl_cmd().
|
|
|
preproc_cmd(Str) ->
|
|
preproc_cmd(Str) ->
|
|
|
- SubStrList = re:split(Str, ?EX_WITHE_CHARS, [{return,binary},trim]),
|
|
|
|
|
|
|
+ SubStrList = re:split(Str, ?EX_WITHE_CHARS, [{return, binary}, trim]),
|
|
|
[preproc_tmpl(SubStr) || SubStr <- SubStrList].
|
|
[preproc_tmpl(SubStr) || SubStr <- SubStrList].
|
|
|
|
|
|
|
|
-spec proc_cmd([tmpl_token()], map()) -> binary() | list().
|
|
-spec proc_cmd([tmpl_token()], map()) -> binary() | list().
|
|
@@ -119,17 +129,15 @@ proc_cmd(Tokens, Data) ->
|
|
|
proc_cmd(Tokens, Data, Opts) ->
|
|
proc_cmd(Tokens, Data, Opts) ->
|
|
|
[proc_tmpl(Tks, Data, Opts) || Tks <- Tokens].
|
|
[proc_tmpl(Tks, Data, Opts) || Tks <- Tokens].
|
|
|
|
|
|
|
|
-
|
|
|
|
|
%% preprocess SQL with place holders
|
|
%% preprocess SQL with place holders
|
|
|
--spec preproc_sql(Sql::binary()) -> {prepare_statement_key(), tmpl_token()}.
|
|
|
|
|
|
|
+-spec preproc_sql(Sql :: binary()) -> {prepare_statement_key(), tmpl_token()}.
|
|
|
preproc_sql(Sql) ->
|
|
preproc_sql(Sql) ->
|
|
|
preproc_sql(Sql, '?').
|
|
preproc_sql(Sql, '?').
|
|
|
|
|
|
|
|
-spec preproc_sql(binary(), '?' | '$n' | preproc_sql_opts()) ->
|
|
-spec preproc_sql(binary(), '?' | '$n' | preproc_sql_opts()) ->
|
|
|
- {prepare_statement_key(), tmpl_token()}.
|
|
|
|
|
|
|
+ {prepare_statement_key(), tmpl_token()}.
|
|
|
preproc_sql(Sql, ReplaceWith) when is_atom(ReplaceWith) ->
|
|
preproc_sql(Sql, ReplaceWith) when is_atom(ReplaceWith) ->
|
|
|
preproc_sql(Sql, #{replace_with => ReplaceWith});
|
|
preproc_sql(Sql, #{replace_with => ReplaceWith});
|
|
|
-
|
|
|
|
|
preproc_sql(Sql, Opts) ->
|
|
preproc_sql(Sql, Opts) ->
|
|
|
RE = preproc_var_re(Opts),
|
|
RE = preproc_var_re(Opts),
|
|
|
ReplaceWith = maps:get(replace_with, Opts, '?'),
|
|
ReplaceWith = maps:get(replace_with, Opts, '?'),
|
|
@@ -141,22 +149,18 @@ preproc_sql(Sql, Opts) ->
|
|
|
{Sql, []}
|
|
{Sql, []}
|
|
|
end.
|
|
end.
|
|
|
|
|
|
|
|
-
|
|
|
|
|
-spec proc_sql(tmpl_token(), map()) -> list().
|
|
-spec proc_sql(tmpl_token(), map()) -> list().
|
|
|
proc_sql(Tokens, Data) ->
|
|
proc_sql(Tokens, Data) ->
|
|
|
proc_tmpl(Tokens, Data, #{return => rawlist, var_trans => fun sql_data/1}).
|
|
proc_tmpl(Tokens, Data, #{return => rawlist, var_trans => fun sql_data/1}).
|
|
|
|
|
|
|
|
-
|
|
|
|
|
-spec proc_sql_param_str(tmpl_token(), map()) -> binary().
|
|
-spec proc_sql_param_str(tmpl_token(), map()) -> binary().
|
|
|
proc_sql_param_str(Tokens, Data) ->
|
|
proc_sql_param_str(Tokens, Data) ->
|
|
|
proc_param_str(Tokens, Data, fun quote_sql/1).
|
|
proc_param_str(Tokens, Data, fun quote_sql/1).
|
|
|
|
|
|
|
|
-
|
|
|
|
|
-spec proc_cql_param_str(tmpl_token(), map()) -> binary().
|
|
-spec proc_cql_param_str(tmpl_token(), map()) -> binary().
|
|
|
proc_cql_param_str(Tokens, Data) ->
|
|
proc_cql_param_str(Tokens, Data) ->
|
|
|
proc_param_str(Tokens, Data, fun quote_cql/1).
|
|
proc_param_str(Tokens, Data, fun quote_cql/1).
|
|
|
|
|
|
|
|
-
|
|
|
|
|
-spec preproc_tmpl_deep(term()) -> deep_template().
|
|
-spec preproc_tmpl_deep(term()) -> deep_template().
|
|
|
preproc_tmpl_deep(Data) ->
|
|
preproc_tmpl_deep(Data) ->
|
|
|
preproc_tmpl_deep(Data, #{process_keys => true}).
|
|
preproc_tmpl_deep(Data, #{process_keys => true}).
|
|
@@ -164,26 +168,22 @@ preproc_tmpl_deep(Data) ->
|
|
|
-spec preproc_tmpl_deep(term(), preproc_deep_opts()) -> deep_template().
|
|
-spec preproc_tmpl_deep(term(), preproc_deep_opts()) -> deep_template().
|
|
|
preproc_tmpl_deep(List, Opts) when is_list(List) ->
|
|
preproc_tmpl_deep(List, Opts) when is_list(List) ->
|
|
|
[preproc_tmpl_deep(El, Opts) || El <- List];
|
|
[preproc_tmpl_deep(El, Opts) || El <- List];
|
|
|
-
|
|
|
|
|
preproc_tmpl_deep(Map, Opts) when is_map(Map) ->
|
|
preproc_tmpl_deep(Map, Opts) when is_map(Map) ->
|
|
|
maps:from_list(
|
|
maps:from_list(
|
|
|
- lists:map(
|
|
|
|
|
- fun({K, V}) ->
|
|
|
|
|
- {preproc_tmpl_deep_map_key(K, Opts),
|
|
|
|
|
- preproc_tmpl_deep(V, Opts)}
|
|
|
|
|
- end,
|
|
|
|
|
- maps:to_list(Map)));
|
|
|
|
|
-
|
|
|
|
|
|
|
+ lists:map(
|
|
|
|
|
+ fun({K, V}) ->
|
|
|
|
|
+ {preproc_tmpl_deep_map_key(K, Opts), preproc_tmpl_deep(V, Opts)}
|
|
|
|
|
+ end,
|
|
|
|
|
+ maps:to_list(Map)
|
|
|
|
|
+ )
|
|
|
|
|
+ );
|
|
|
preproc_tmpl_deep(Binary, Opts) when is_binary(Binary) ->
|
|
preproc_tmpl_deep(Binary, Opts) when is_binary(Binary) ->
|
|
|
{tmpl, preproc_tmpl(Binary, Opts)};
|
|
{tmpl, preproc_tmpl(Binary, Opts)};
|
|
|
-
|
|
|
|
|
preproc_tmpl_deep(Tuple, Opts) when is_tuple(Tuple) ->
|
|
preproc_tmpl_deep(Tuple, Opts) when is_tuple(Tuple) ->
|
|
|
{tuple, preproc_tmpl_deep(tuple_to_list(Tuple), Opts)};
|
|
{tuple, preproc_tmpl_deep(tuple_to_list(Tuple), Opts)};
|
|
|
-
|
|
|
|
|
preproc_tmpl_deep(Other, _Opts) ->
|
|
preproc_tmpl_deep(Other, _Opts) ->
|
|
|
{value, Other}.
|
|
{value, Other}.
|
|
|
|
|
|
|
|
-
|
|
|
|
|
-spec proc_tmpl_deep(deep_template(), map()) -> term().
|
|
-spec proc_tmpl_deep(deep_template(), map()) -> term().
|
|
|
proc_tmpl_deep(DeepTmpl, Data) ->
|
|
proc_tmpl_deep(DeepTmpl, Data) ->
|
|
|
proc_tmpl_deep(DeepTmpl, Data, #{return => full_binary}).
|
|
proc_tmpl_deep(DeepTmpl, Data, #{return => full_binary}).
|
|
@@ -191,24 +191,22 @@ proc_tmpl_deep(DeepTmpl, Data) ->
|
|
|
-spec proc_tmpl_deep(deep_template(), map(), proc_tmpl_opts()) -> term().
|
|
-spec proc_tmpl_deep(deep_template(), map(), proc_tmpl_opts()) -> term().
|
|
|
proc_tmpl_deep(List, Data, Opts) when is_list(List) ->
|
|
proc_tmpl_deep(List, Data, Opts) when is_list(List) ->
|
|
|
[proc_tmpl_deep(El, Data, Opts) || El <- List];
|
|
[proc_tmpl_deep(El, Data, Opts) || El <- List];
|
|
|
-
|
|
|
|
|
proc_tmpl_deep(Map, Data, Opts) when is_map(Map) ->
|
|
proc_tmpl_deep(Map, Data, Opts) when is_map(Map) ->
|
|
|
maps:from_list(
|
|
maps:from_list(
|
|
|
- lists:map(
|
|
|
|
|
- fun({K, V}) ->
|
|
|
|
|
- {proc_tmpl_deep(K, Data, Opts),
|
|
|
|
|
- proc_tmpl_deep(V, Data, Opts)}
|
|
|
|
|
- end,
|
|
|
|
|
- maps:to_list(Map)));
|
|
|
|
|
-
|
|
|
|
|
-proc_tmpl_deep({value, Value}, _Data, _Opts) -> Value;
|
|
|
|
|
-
|
|
|
|
|
-proc_tmpl_deep({tmpl, Tokens}, Data, Opts) -> proc_tmpl(Tokens, Data, Opts);
|
|
|
|
|
-
|
|
|
|
|
|
|
+ lists:map(
|
|
|
|
|
+ fun({K, V}) ->
|
|
|
|
|
+ {proc_tmpl_deep(K, Data, Opts), proc_tmpl_deep(V, Data, Opts)}
|
|
|
|
|
+ end,
|
|
|
|
|
+ maps:to_list(Map)
|
|
|
|
|
+ )
|
|
|
|
|
+ );
|
|
|
|
|
+proc_tmpl_deep({value, Value}, _Data, _Opts) ->
|
|
|
|
|
+ Value;
|
|
|
|
|
+proc_tmpl_deep({tmpl, Tokens}, Data, Opts) ->
|
|
|
|
|
+ proc_tmpl(Tokens, Data, Opts);
|
|
|
proc_tmpl_deep({tuple, Elements}, Data, Opts) ->
|
|
proc_tmpl_deep({tuple, Elements}, Data, Opts) ->
|
|
|
list_to_tuple([proc_tmpl_deep(El, Data, Opts) || El <- Elements]).
|
|
list_to_tuple([proc_tmpl_deep(El, Data, Opts) || El <- Elements]).
|
|
|
|
|
|
|
|
-
|
|
|
|
|
-spec sql_data(term()) -> term().
|
|
-spec sql_data(term()) -> term().
|
|
|
sql_data(undefined) -> null;
|
|
sql_data(undefined) -> null;
|
|
|
sql_data(List) when is_list(List) -> List;
|
|
sql_data(List) when is_list(List) -> List;
|
|
@@ -218,7 +216,6 @@ sql_data(Bool) when is_boolean(Bool) -> Bool;
|
|
|
sql_data(Atom) when is_atom(Atom) -> atom_to_binary(Atom, utf8);
|
|
sql_data(Atom) when is_atom(Atom) -> atom_to_binary(Atom, utf8);
|
|
|
sql_data(Map) when is_map(Map) -> emqx_json:encode(Map).
|
|
sql_data(Map) when is_map(Map) -> emqx_json:encode(Map).
|
|
|
|
|
|
|
|
-
|
|
|
|
|
-spec bin(term()) -> binary().
|
|
-spec bin(term()) -> binary().
|
|
|
bin(Val) -> emqx_plugin_libs_rule:bin(Val).
|
|
bin(Val) -> emqx_plugin_libs_rule:bin(Val).
|
|
|
|
|
|
|
@@ -228,7 +225,8 @@ bin(Val) -> emqx_plugin_libs_rule:bin(Val).
|
|
|
|
|
|
|
|
proc_param_str(Tokens, Data, Quote) ->
|
|
proc_param_str(Tokens, Data, Quote) ->
|
|
|
iolist_to_binary(
|
|
iolist_to_binary(
|
|
|
- proc_tmpl(Tokens, Data, #{return => rawlist, var_trans => Quote})).
|
|
|
|
|
|
|
+ proc_tmpl(Tokens, Data, #{return => rawlist, var_trans => Quote})
|
|
|
|
|
+ ).
|
|
|
|
|
|
|
|
%% backward compatibility for hot upgrading from =< e4.2.1
|
|
%% backward compatibility for hot upgrading from =< e4.2.1
|
|
|
get_phld_var(Fun, Data) when is_function(Fun) ->
|
|
get_phld_var(Fun, Data) when is_function(Fun) ->
|
|
@@ -248,23 +246,24 @@ do_preproc_tmpl([], Acc) ->
|
|
|
lists:reverse(Acc);
|
|
lists:reverse(Acc);
|
|
|
do_preproc_tmpl([[Str, Phld] | Tokens], Acc) ->
|
|
do_preproc_tmpl([[Str, Phld] | Tokens], Acc) ->
|
|
|
do_preproc_tmpl(
|
|
do_preproc_tmpl(
|
|
|
- Tokens,
|
|
|
|
|
- put_head(
|
|
|
|
|
- var,
|
|
|
|
|
- parse_nested(unwrap(Phld)),
|
|
|
|
|
- put_head(str, Str, Acc)));
|
|
|
|
|
|
|
+ Tokens,
|
|
|
|
|
+ put_head(
|
|
|
|
|
+ var,
|
|
|
|
|
+ parse_nested(unwrap(Phld)),
|
|
|
|
|
+ put_head(str, Str, Acc)
|
|
|
|
|
+ )
|
|
|
|
|
+ );
|
|
|
do_preproc_tmpl([[Str] | Tokens], Acc) ->
|
|
do_preproc_tmpl([[Str] | Tokens], Acc) ->
|
|
|
do_preproc_tmpl(
|
|
do_preproc_tmpl(
|
|
|
- Tokens,
|
|
|
|
|
- put_head(str, Str, Acc)).
|
|
|
|
|
|
|
+ Tokens,
|
|
|
|
|
+ put_head(str, Str, Acc)
|
|
|
|
|
+ ).
|
|
|
|
|
|
|
|
put_head(_Type, <<>>, List) -> List;
|
|
put_head(_Type, <<>>, List) -> List;
|
|
|
-put_head(Type, Term, List) ->
|
|
|
|
|
- [{Type, Term} | List].
|
|
|
|
|
|
|
+put_head(Type, Term, List) -> [{Type, Term} | List].
|
|
|
|
|
|
|
|
preproc_tmpl_deep_map_key(Key, #{process_keys := true} = Opts) ->
|
|
preproc_tmpl_deep_map_key(Key, #{process_keys := true} = Opts) ->
|
|
|
preproc_tmpl_deep(Key, Opts);
|
|
preproc_tmpl_deep(Key, Opts);
|
|
|
-
|
|
|
|
|
preproc_tmpl_deep_map_key(Key, _) ->
|
|
preproc_tmpl_deep_map_key(Key, _) ->
|
|
|
{value, Key}.
|
|
{value, Key}.
|
|
|
|
|
|
|
@@ -274,12 +273,16 @@ replace_with(Tmpl, RE, '$n') ->
|
|
|
Parts = re:split(Tmpl, RE, [{return, binary}, trim, group]),
|
|
Parts = re:split(Tmpl, RE, [{return, binary}, trim, group]),
|
|
|
{Res, _} =
|
|
{Res, _} =
|
|
|
lists:foldl(
|
|
lists:foldl(
|
|
|
- fun([Tkn, _Phld], {Acc, Seq}) ->
|
|
|
|
|
- Seq1 = erlang:integer_to_binary(Seq),
|
|
|
|
|
- {<<Acc/binary, Tkn/binary, "$", Seq1/binary>>, Seq + 1};
|
|
|
|
|
|
|
+ fun
|
|
|
|
|
+ ([Tkn, _Phld], {Acc, Seq}) ->
|
|
|
|
|
+ Seq1 = erlang:integer_to_binary(Seq),
|
|
|
|
|
+ {<<Acc/binary, Tkn/binary, "$", Seq1/binary>>, Seq + 1};
|
|
|
([Tkn], {Acc, Seq}) ->
|
|
([Tkn], {Acc, Seq}) ->
|
|
|
{<<Acc/binary, Tkn/binary>>, Seq}
|
|
{<<Acc/binary, Tkn/binary>>, Seq}
|
|
|
- end, {<<>>, 1}, Parts),
|
|
|
|
|
|
|
+ end,
|
|
|
|
|
+ {<<>>, 1},
|
|
|
|
|
+ Parts
|
|
|
|
|
+ ),
|
|
|
Res.
|
|
Res.
|
|
|
|
|
|
|
|
parse_nested(Attr) ->
|
|
parse_nested(Attr) ->
|
|
@@ -289,7 +292,7 @@ parse_nested(Attr) ->
|
|
|
end.
|
|
end.
|
|
|
|
|
|
|
|
unwrap(<<"${", Val/binary>>) ->
|
|
unwrap(<<"${", Val/binary>>) ->
|
|
|
- binary:part(Val, {0, byte_size(Val)-1}).
|
|
|
|
|
|
|
+ binary:part(Val, {0, byte_size(Val) - 1}).
|
|
|
|
|
|
|
|
quote_sql(Str) ->
|
|
quote_sql(Str) ->
|
|
|
quote(Str, <<"\\\\'">>).
|
|
quote(Str, <<"\\\\'">>).
|
|
@@ -301,7 +304,8 @@ quote(Str, ReplaceWith) when
|
|
|
is_list(Str);
|
|
is_list(Str);
|
|
|
is_binary(Str);
|
|
is_binary(Str);
|
|
|
is_atom(Str);
|
|
is_atom(Str);
|
|
|
- is_map(Str) ->
|
|
|
|
|
|
|
+ is_map(Str)
|
|
|
|
|
+->
|
|
|
[$', escape_apo(bin(Str), ReplaceWith), $'];
|
|
[$', escape_apo(bin(Str), ReplaceWith), $'];
|
|
|
quote(Val, _) ->
|
|
quote(Val, _) ->
|
|
|
bin(Val).
|
|
bin(Val).
|