shared: LooqsQuery: Fix logic of implicit AND booleans. Add 'limit:' support
Add implicit AND booleans at the end. This fixes a number of issues in LooqsQuery: (1) A query like a b c p:(something) would fail, because a b c get merged into one word. This happens at the end. lonewords are special and do not become a token immediatly. So previous logic to add implicit ANDs does not apply. (2) Negations were also broken with lonewords. (3) The TokenType enum fields were too narrow to be useful for the bitmask Independent of that, add support for 'limit:'
This commit is contained in:
parent
821bed6706
commit
a6ddcef0c0
@ -220,19 +220,8 @@ LooqsQuery LooqsQuery::build(QString expression, TokenType loneWordsTokenType, b
|
|||||||
{
|
{
|
||||||
throw LooqsGeneralException("Can't have two negations following each other");
|
throw LooqsGeneralException("Can't have two negations following each other");
|
||||||
}
|
}
|
||||||
if(!previousWasBool())
|
|
||||||
{
|
|
||||||
result.addToken(Token(BOOL_AND)); // Implicit and, our default operation
|
|
||||||
}
|
|
||||||
result.addToken(Token(NEGATION));
|
result.addToken(Token(NEGATION));
|
||||||
}
|
}
|
||||||
if(!result.tokens.isEmpty() && !previousWasBool() && !previousWas(NEGATION) && !previousWas(BRACKET_OPEN) &&
|
|
||||||
bracket != ")")
|
|
||||||
{
|
|
||||||
// the current token isn't a negation, isn't a boolean. Thus, implicit AND is required
|
|
||||||
result.addToken(Token(BOOL_AND));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(bracket != "")
|
if(bracket != "")
|
||||||
{
|
{
|
||||||
if(bracket == "(")
|
if(bracket == "(")
|
||||||
@ -259,7 +248,7 @@ LooqsQuery LooqsQuery::build(QString expression, TokenType loneWordsTokenType, b
|
|||||||
|
|
||||||
if(filtername != "")
|
if(filtername != "")
|
||||||
{
|
{
|
||||||
TokenType tokenType;
|
TokenType tokenType = WORD;
|
||||||
QString value = m.captured("innerargs");
|
QString value = m.captured("innerargs");
|
||||||
if(value == "")
|
if(value == "")
|
||||||
{
|
{
|
||||||
@ -294,21 +283,21 @@ LooqsQuery LooqsQuery::build(QString expression, TokenType loneWordsTokenType, b
|
|||||||
{
|
{
|
||||||
tokenType = FILTER_CONTENT_PAGE;
|
tokenType = FILTER_CONTENT_PAGE;
|
||||||
}
|
}
|
||||||
else if(filtername ==
|
// TODO: given this is not really a "filter", this feels slightly misplaced here
|
||||||
"sort") // TODO: given this is not really a "filter", this feels slightly misplaced here
|
else if(filtername == "sort")
|
||||||
{
|
{
|
||||||
if(!result.sortConditions.empty())
|
if(!result.sortConditions.empty())
|
||||||
{
|
{
|
||||||
throw LooqsGeneralException("Two sort statements are illegal");
|
throw LooqsGeneralException("Two sort statements are illegal");
|
||||||
}
|
}
|
||||||
// TODO: hack, since we are not a "filter", we must remove a preceeding (implicit) boolean
|
|
||||||
if((result.tokens.last().type & BOOL) == BOOL)
|
|
||||||
{
|
|
||||||
result.tokens.pop_back();
|
|
||||||
}
|
|
||||||
result.sortConditions = createSortConditions(value);
|
result.sortConditions = createSortConditions(value);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
else if(filtername == "limit")
|
||||||
|
{
|
||||||
|
result.limit = value.toInt();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw LooqsGeneralException("Unknown filter provided!");
|
throw LooqsGeneralException("Unknown filter provided!");
|
||||||
@ -326,6 +315,26 @@ LooqsQuery LooqsQuery::build(QString expression, TokenType loneWordsTokenType, b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add our default implicit AND boolean condition where appropriate */
|
||||||
|
QVector<Token> newTokens;
|
||||||
|
|
||||||
|
TokenType prevType = BOOL_AND;
|
||||||
|
int needsBoolean = FILTER_CONTENT | FILTER_PATH | NEGATION;
|
||||||
|
for(Token &t : result.tokens)
|
||||||
|
{
|
||||||
|
if(t.type == BRACKET_OPEN || t.type & needsBoolean)
|
||||||
|
{
|
||||||
|
if(!((prevType & BOOL) == BOOL) && !((prevType & NEGATION) == NEGATION) &&
|
||||||
|
!((prevType & BRACKET_OPEN) == BRACKET_OPEN))
|
||||||
|
{
|
||||||
|
newTokens.append(Token(BOOL_AND));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prevType = t.type;
|
||||||
|
newTokens.append(t);
|
||||||
|
}
|
||||||
|
result.tokens = newTokens;
|
||||||
|
|
||||||
bool contentsearch = result.hasContentSearch();
|
bool contentsearch = result.hasContentSearch();
|
||||||
bool sortsForContent = std::any_of(result.sortConditions.begin(), result.sortConditions.end(),
|
bool sortsForContent = std::any_of(result.sortConditions.begin(), result.sortConditions.end(),
|
||||||
[](SortCondition c) { return c.field == CONTENT_TEXT; });
|
[](SortCondition c) { return c.field == CONTENT_TEXT; });
|
||||||
|
@ -40,6 +40,7 @@ class LooqsQuery
|
|||||||
/* Helper field to determine quertype as well as to quickly check what kind of filters etc.
|
/* Helper field to determine quertype as well as to quickly check what kind of filters etc.
|
||||||
* are being used in this query*/
|
* are being used in this query*/
|
||||||
int tokensMask = 0;
|
int tokensMask = 0;
|
||||||
|
int limit = -1;
|
||||||
QVector<Token> tokens;
|
QVector<Token> tokens;
|
||||||
QVector<SortCondition> sortConditions;
|
QVector<SortCondition> sortConditions;
|
||||||
void addToken(Token t);
|
void addToken(Token t);
|
||||||
@ -52,6 +53,14 @@ class LooqsQuery
|
|||||||
{
|
{
|
||||||
return tokensMask;
|
return tokensMask;
|
||||||
}
|
}
|
||||||
|
int getLimit() const
|
||||||
|
{
|
||||||
|
return limit;
|
||||||
|
}
|
||||||
|
void setLimit(int limit)
|
||||||
|
{
|
||||||
|
this->limit = limit;
|
||||||
|
}
|
||||||
bool hasContentSearch();
|
bool hasContentSearch();
|
||||||
bool hasPathSearch();
|
bool hasPathSearch();
|
||||||
|
|
||||||
|
@ -4,24 +4,25 @@
|
|||||||
|
|
||||||
enum TokenType
|
enum TokenType
|
||||||
{
|
{
|
||||||
WORD,
|
WORD = 8,
|
||||||
NEGATION = 2,
|
NEGATION = 16,
|
||||||
BOOL = 4,
|
BOOL = 32,
|
||||||
BOOL_AND,
|
BOOL_AND,
|
||||||
BOOL_OR,
|
BOOL_OR,
|
||||||
GROUP = 8,
|
GROUP = 64,
|
||||||
BRACKET_OPEN,
|
BRACKET_OPEN,
|
||||||
BRACKET_CLOSE,
|
BRACKET_CLOSE,
|
||||||
SORT = 16,
|
SORT = 128,
|
||||||
FILTER_PATH = 32,
|
FILTER_PATH = 256,
|
||||||
FILTER_PATH_MTIME,
|
FILTER_PATH_MTIME,
|
||||||
FILTER_PATH_CONTAINS,
|
FILTER_PATH_CONTAINS,
|
||||||
FILTER_PATH_SIZE,
|
FILTER_PATH_SIZE,
|
||||||
FILTER_PATH_ENDS,
|
FILTER_PATH_ENDS,
|
||||||
FILTER_PATH_STARTS,
|
FILTER_PATH_STARTS,
|
||||||
FILTER_CONTENT = 64,
|
FILTER_CONTENT = 512,
|
||||||
FILTER_CONTENT_CONTAINS,
|
FILTER_CONTENT_CONTAINS,
|
||||||
FILTER_CONTENT_PAGE,
|
FILTER_CONTENT_PAGE,
|
||||||
|
LIMIT = 1024
|
||||||
};
|
};
|
||||||
|
|
||||||
class Token
|
class Token
|
||||||
|
Loading…
Reference in New Issue
Block a user