diff options
author | Uwe Klotz <uklotz@mixxx.org> | 2018-11-16 00:07:19 +0100 |
---|---|---|
committer | Uwe Klotz <uklotz@mixxx.org> | 2018-11-16 00:07:19 +0100 |
commit | 3a609d743841d5cebd883b66325cea66909986b6 (patch) | |
tree | 017cf24acbf87063dac599c091b1e8479dc73266 /src/library | |
parent | eb6b8095922ac53f91db583c7d996218bf93f667 (diff) | |
parent | 0ee197c1dda4c0894dc10340d162a705888122f3 (diff) |
Merge branch '2.1' of git@github.com:mixxxdj/mixxx.git into 2.2
# Conflicts:
# src/library/searchqueryparser.cpp
Diffstat (limited to 'src/library')
-rw-r--r-- | src/library/searchquery.cpp | 26 | ||||
-rw-r--r-- | src/library/searchquery.h | 6 | ||||
-rw-r--r-- | src/library/searchqueryparser.cpp | 16 |
3 files changed, 33 insertions, 15 deletions
diff --git a/src/library/searchquery.cpp b/src/library/searchquery.cpp index f0472a807b..78c35355d9 100644 --- a/src/library/searchquery.cpp +++ b/src/library/searchquery.cpp @@ -6,6 +6,7 @@ #include "track/keyutils.h" #include "library/dao/trackschema.h" #include "util/db/sqllikewildcards.h" +#include "util/db/dbconnection.h" QVariant getTrackValueForColumn(const TrackPointer& pTrack, const QString& column) { if (column == LIBRARYTABLE_ARTIST) { @@ -141,6 +142,15 @@ QString NotNode::toSql() const { } } +TextFilterNode::TextFilterNode(const QSqlDatabase& database, + const QStringList& sqlColumns, + const QString& argument) + : m_database(database), + m_sqlColumns(sqlColumns), + m_argument(argument) { + mixxx::DbConnection::makeStringLatinLow(&m_argument); +} + bool TextFilterNode::match(const TrackPointer& pTrack) const { for (const auto& sqlColumn: m_sqlColumns) { QVariant value = getTrackValueForColumn(pTrack, sqlColumn); @@ -148,7 +158,9 @@ bool TextFilterNode::match(const TrackPointer& pTrack) const { continue; } - if (value.toString().contains(m_argument, Qt::CaseInsensitive)) { + QString strValue = value.toString(); + mixxx::DbConnection::makeStringLatinLow(&strValue); + if (strValue.contains(m_argument)) { return true; } } @@ -157,8 +169,16 @@ bool TextFilterNode::match(const TrackPointer& pTrack) const { QString TextFilterNode::toSql() const { FieldEscaper escaper(m_database); - QString escapedArgument = escaper.escapeString(kSqlLikeMatchAll + m_argument + kSqlLikeMatchAll); - + QString argument = m_argument; + if (argument.size() > 0) { + if (argument[argument.size() - 1].isSpace()) { + // LIKE eats a trailing space. This can be avoided by adding a '_' + // as a delimiter that matches any following character. + argument.append('_'); + } + } + QString escapedArgument = escaper.escapeString( + kSqlLikeMatchAll + argument + kSqlLikeMatchAll); QStringList searchClauses; for (const auto& sqlColumn: m_sqlColumns) { searchClauses << QString("%1 LIKE %2").arg(sqlColumn, escapedArgument); diff --git a/src/library/searchquery.h b/src/library/searchquery.h index c36f1ad400..20241dec5a 100644 --- a/src/library/searchquery.h +++ b/src/library/searchquery.h @@ -76,11 +76,7 @@ class TextFilterNode : public QueryNode { public: TextFilterNode(const QSqlDatabase& database, const QStringList& sqlColumns, - const QString& argument) - : m_database(database), - m_sqlColumns(sqlColumns), - m_argument(argument) { - } + const QString& argument); bool match(const TrackPointer& pTrack) const override; QString toSql() const override; diff --git a/src/library/searchqueryparser.cpp b/src/library/searchqueryparser.cpp index 7ab0c83cdd..c8b0a47a30 100644 --- a/src/library/searchqueryparser.cpp +++ b/src/library/searchqueryparser.cpp @@ -136,15 +136,16 @@ void SearchQueryParser::parseTokens(QStringList tokens, } else if (m_textFilterMatcher.indexIn(token) != -1) { QString field = m_textFilterMatcher.cap(1); QString argument = getTextArgument( - m_textFilterMatcher.cap(2), &tokens).trimmed(); + m_textFilterMatcher.cap(2), &tokens); if (!argument.isEmpty()) { if (field == "crate") { pNode = std::make_unique<CrateFilterNode>( - &m_pTrackCollection->crates(), argument); + &m_pTrackCollection->crates(), argument); } else { pNode = std::make_unique<TextFilterNode>( - m_pTrackCollection->database(), m_fieldToSqlColumns[field], argument); + m_pTrackCollection->database(), + m_fieldToSqlColumns[field], argument); } } } else if (m_numericFilterMatcher.indexIn(token) != -1) { @@ -154,7 +155,7 @@ void SearchQueryParser::parseTokens(QStringList tokens, if (!argument.isEmpty()) { pNode = std::make_unique<NumericFilterNode>( - m_fieldToSqlColumns[field], argument); + m_fieldToSqlColumns[field], argument); } } else if (m_specialFilterMatcher.indexIn(token) != -1) { bool fuzzy = token.startsWith(kFuzzyPrefix); @@ -190,6 +191,7 @@ void SearchQueryParser::parseTokens(QStringList tokens, } // Don't trigger on a lone minus sign. if (!token.isEmpty()) { + QString argument = getTextArgument(token, &tokens); // For untagged strings we search the track fields as well // as the crate names the track is in. This allows the user // to use crates like tags @@ -197,14 +199,14 @@ void SearchQueryParser::parseTokens(QStringList tokens, std::unique_ptr<OrNode> gNode = std::make_unique<OrNode>(); gNode->addNode(std::make_unique<CrateFilterNode>( - &m_pTrackCollection->crates(), token)); + &m_pTrackCollection->crates(), argument)); gNode->addNode(std::make_unique<TextFilterNode>( - m_pTrackCollection->database(), queryColumns, token)); + m_pTrackCollection->database(), queryColumns, argument)); pNode = std::move(gNode); } else { pNode = std::make_unique<TextFilterNode>( - m_pTrackCollection->database(), queryColumns, token); + m_pTrackCollection->database(), queryColumns, argument); } } } |