summaryrefslogtreecommitdiffstats
path: root/src/library
diff options
context:
space:
mode:
authorUwe Klotz <uklotz@mixxx.org>2018-11-16 00:07:19 +0100
committerUwe Klotz <uklotz@mixxx.org>2018-11-16 00:07:19 +0100
commit3a609d743841d5cebd883b66325cea66909986b6 (patch)
tree017cf24acbf87063dac599c091b1e8479dc73266 /src/library
parenteb6b8095922ac53f91db583c7d996218bf93f667 (diff)
parent0ee197c1dda4c0894dc10340d162a705888122f3 (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.cpp26
-rw-r--r--src/library/searchquery.h6
-rw-r--r--src/library/searchqueryparser.cpp16
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);
}
}
}