-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Track search: use := and quotes to find exact matches #12063
Conversation
src/library/searchquery.cpp
Outdated
: m_database(database), | ||
m_sqlColumns(sqlColumns), | ||
m_argument(argument) { | ||
m_argument(argument), | ||
m_exactMatch(exactMatch) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bool
is a poor type choice. An enum class StringMatch
with Equals
and Contains
variants would be much more concise, maintainable, and extensible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the hint.
Though this is on hold for now, someone else may adopt it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
And I implemented it in the existing text filter matcher, so the changes are much smaller, no code duplication anymore.
9260d0b
to
fa98937
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
couldn't resist "meinen senf abzugeben" ;)
Thank you.
EXPECT_STREQ( | ||
qPrintable(QString("comment LIKE 'asdf'")), | ||
qPrintable(pQuery->toSql())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this tests implementation details IMO and does not belong in a test IMO. wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are crucial implementation details, sure they need to be tested.
Please elaborate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well it conflates two different levels of abstraction. The first part of the test checks for the behavior. That should be very stable and even if we changed some details about our database these won't change. On the other hand, all the tests that involve toSql
don't only rely on the fact that we use SQL (something that would not be true if we were to transition to aoide) but even how exactly we do the fuzzy matching (using LIKE
) even though there are other implementations as well. Do you see how this introduces coupling? The test should be ensuring the behavior, not the way it works internally.
A little (admittedly childish and simplified) analogy: If I need to put a nail into a wall, I can just use a hammer, I don't care if the hammerhead is made of iron or steel, both do the job (I think, I'm not a carpenter 😅).
Sure if you need to test specific properties of a hammer, that is legitimate to test, but it doesn't belong in the same test as "it puts a nail into a wall".
I'm aware that this is quite theoretical and likely a little controversial the code in question just follows the same pattern as the rest of the file. I'm just saying that the current design is not great and we should question it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
got it. of course, ideally, we'd just test the parser to return certain track ids of a sample library.
src/library/searchqueryparser.cpp
Outdated
QString SearchQueryParser::getTextArgument(QString argument, | ||
QStringList* tokens) const { | ||
QStringList* tokens, | ||
StringMatch* matchMode) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dislike the implicitness of the out parameter. Eg its not fully transparent if the pointer is valid but shouldMatchExactly
is false
. then it'll just not set anything. A caller might expect it to always set it. The result is that if used incorrectly (which is not hard in this case), the caller could be left with an initialized variable.
Imo the better design would be not use an out-parameter in this case and instead just return a struct with both the matchmode and the argument.
QString SearchQueryParser::getTextArgument(QString argument, | |
QStringList* tokens) const { | |
QStringList* tokens, | |
StringMatch* matchMode) const { | |
struct TextArgumentResult { | |
QString argumentValue; | |
StringMatch matchmode; | |
}; | |
TextArgumentResult SearchQueryParser::getTextArgument(QString argument, | |
QStringList* tokens) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Eg its not fully transparent if the pointer is valid but shouldMatchExactly is false. then it'll just not set anything.
For now, I fixed that by setting matchMode at the beginning.
A struct would for me, too, but it requires more refactoring.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not so much imo. PR underway
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Co-authored-by: Swiftb0y <[email protected]>
31f95ef
to
62da287
Compare
Looking good now. |
src/library/searchqueryparser.cpp
Outdated
if (argument.startsWith("=")) { | ||
// strip the '=' from the argument | ||
argument = argument.mid(1); | ||
// TODO(ronso0) should 'tag:"string"' really be equal to 'tag:="string"? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
edit
tag:=string
and tag:="string"
lgtm otherwise. thank you. |
ffcd6c0
to
51c2a38
Compare
fyi the parser could like be simplified even more if the tokenizer recognized the quotes and just consumed the entire thing as one token. That would make |
Tbh I'm not motivated to do more optimization, this has already grown way beyond my initial commit (though I very much appreciate your input!). |
Yes, I'm sorry for blowing up the scope. The previous comment was just a remark and not a request for more changes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, Thank you very much.
remove draft and merge? |
Ready! TODO |
Thank you |
I'd say this deserves a changelog entry to make the change a bit more discoverable for upgraders (if they already read the search documentation they probably won't notice the change..). |
A quick check that has proven to work:
[text property]:="string"
finds only tracks where the property is exactlystring
.title:="Blob"
finds all track titles that exactly "Blob", not "What a Blob" etc.May be extended to include spaces and special chars before and after to find
Blob
and..Blob!
Bug fix or feature? Doesn't change the ui, hence I targeted 2.4
But it reuires a manual update.
Closes #10699