chore(topic_index): add topic validation
This commit is contained in:
parent
33ed53bb6a
commit
558402a68e
|
@ -113,7 +113,7 @@
|
|||
%% @doc Make a search-key for the given topic.
|
||||
-spec make_key(emqx_types:topic(), ID) -> key(ID).
|
||||
make_key(Topic, ID) when is_binary(Topic) ->
|
||||
Words = words(Topic),
|
||||
Words = filter_words(Topic),
|
||||
case emqx_topic:wildcard(Words) of
|
||||
true ->
|
||||
%% it's a wildcard
|
||||
|
@ -171,7 +171,7 @@ matches(Topic, NextF, Opts) ->
|
|||
|
||||
%% @doc Entrypoint of the search for a given topic.
|
||||
search(Topic, NextF, Opts) ->
|
||||
Words = words(Topic),
|
||||
Words = topic_words(Topic),
|
||||
Base = base_init(Words),
|
||||
ORetFirst = proplists:get_bool(return_first, Opts),
|
||||
OUnique = proplists:get_bool(unique, Opts),
|
||||
|
@ -320,18 +320,22 @@ match_add(K, Acc) when is_list(Acc) ->
|
|||
match_add(K, first) ->
|
||||
throw({first, K}).
|
||||
|
||||
-spec words(emqx_types:topic()) -> [word()].
|
||||
words(Topic) when is_binary(Topic) ->
|
||||
-spec filter_words(emqx_types:topic()) -> [word()].
|
||||
filter_words(Topic) when is_binary(Topic) ->
|
||||
% NOTE
|
||||
% This is almost identical to `emqx_topic:words/1`, but it doesn't convert empty
|
||||
% tokens to ''. This is needed to keep ordering of words consistent with what
|
||||
% `match_filter/3` expects.
|
||||
[word(W) || W <- emqx_topic:tokens(Topic)].
|
||||
[word(W, filter) || W <- emqx_topic:tokens(Topic)].
|
||||
|
||||
-spec word(binary()) -> word().
|
||||
word(<<"+">>) -> '+';
|
||||
word(<<"#">>) -> '#';
|
||||
word(Bin) -> Bin.
|
||||
topic_words(Topic) when is_binary(Topic) ->
|
||||
[word(W, topic) || W <- emqx_topic:tokens(Topic)].
|
||||
|
||||
word(<<"+">>, topic) -> error(badarg);
|
||||
word(<<"#">>, topic) -> error(badarg);
|
||||
word(<<"+">>, filter) -> '+';
|
||||
word(<<"#">>, filter) -> '#';
|
||||
word(Bin, _) -> Bin.
|
||||
|
||||
%% match non-wildcard topics
|
||||
match_topics(Topic, {Topic, _} = Key, NextF, Acc) ->
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
%%--------------------------------------------------------------------
|
||||
%% Copyright (c) 2023 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||
%%
|
||||
%% Licensed under the Apache License, Version 2.0 (the "License");
|
||||
%% you may not use this file except in compliance with the License.
|
||||
%% You may obtain a copy of the License at
|
||||
%%
|
||||
%% http://www.apache.org/licenses/LICENSE-2.0
|
||||
%%
|
||||
%% Unless required by applicable law or agreed to in writing, software
|
||||
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
%% See the License for the specific language governing permissions and
|
||||
%% limitations under the License.
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
-module(emqx_trie_search_tests).
|
||||
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
topic_validation_test() ->
|
||||
NextF = fun(_) -> '$end_of_table' end,
|
||||
Call = fun(Topic) ->
|
||||
emqx_trie_search:match(Topic, NextF)
|
||||
end,
|
||||
?assertError(badarg, Call(<<"+">>)),
|
||||
?assertError(badarg, Call(<<"#">>)),
|
||||
?assertError(badarg, Call(<<"a/+/b">>)),
|
||||
?assertError(badarg, Call(<<"a/b/#">>)),
|
||||
?assertEqual(false, Call(<<"a/b/b+">>)),
|
||||
?assertEqual(false, Call(<<"a/b/c#">>)),
|
||||
ok.
|
Loading…
Reference in New Issue