diff --git a/src/database/SearchFilter.cpp b/src/database/SearchFilter.cpp index 18632b21..e5bcca35 100644 --- a/src/database/SearchFilter.cpp +++ b/src/database/SearchFilter.cpp @@ -26,37 +26,40 @@ SqlQuery generatePartialQuery(SearchFilter& filter) { SqlQuery sqlQuery; - WhereClause likeWhereClause; - // Process name like parameters - for (auto nameLikeMatch : filter.nameLikeMatch) + for (auto nameLikeMatches : filter.nameLikeMatch) { - // Artist - switch (nameLikeMatch.first) + WhereClause likeWhereClause; + + for (auto nameLikeMatch : nameLikeMatches) { - case SearchFilter::Field::Artist: - for (const std::string& name : nameLikeMatch.second) - likeWhereClause.Or( WhereClause("a.name LIKE ?") ).bind("%%" + name + "%%"); - break; - case SearchFilter::Field::Release: - for (const std::string& name : nameLikeMatch.second) - likeWhereClause.Or( WhereClause("r.name LIKE ?") ).bind("%%" + name + "%%"); - break; + // Artist + switch (nameLikeMatch.first) + { + case SearchFilter::Field::Artist: + for (const std::string& name : nameLikeMatch.second) + likeWhereClause.Or( WhereClause("a.name LIKE ?") ).bind("%%" + name + "%%"); + break; - case SearchFilter::Field::Genre: - for (const std::string& name : nameLikeMatch.second) - likeWhereClause.Or( WhereClause("g.name LIKE ?") ).bind("%%" + name + "%%"); - break; + case SearchFilter::Field::Release: + for (const std::string& name : nameLikeMatch.second) + likeWhereClause.Or( WhereClause("r.name LIKE ?") ).bind("%%" + name + "%%"); + break; - case SearchFilter::Field::Track: - for (const std::string& name : nameLikeMatch.second) - likeWhereClause.Or( WhereClause("t.name LIKE ?") ).bind("%%" + name + "%%"); - break; + case SearchFilter::Field::Genre: + for (const std::string& name : nameLikeMatch.second) + likeWhereClause.Or( WhereClause("g.name LIKE ?") ).bind("%%" + name + "%%"); + break; + + case SearchFilter::Field::Track: + for (const std::string& name : nameLikeMatch.second) + likeWhereClause.Or( WhereClause("t.name LIKE ?") ).bind("%%" + name + "%%"); + break; + } } - + sqlQuery.where().And( likeWhereClause ); } - sqlQuery.where().And( likeWhereClause ); // Process id exact match parameters diff --git a/src/database/SearchFilter.hpp b/src/database/SearchFilter.hpp index 93bc0472..10c27d2d 100644 --- a/src/database/SearchFilter.hpp +++ b/src/database/SearchFilter.hpp @@ -42,17 +42,17 @@ class SearchFilter Track, // track }; - typedef std::map > NameLikeMatchMap; - typedef std::map > IdMatchMap; + typedef std::vector > > NameLikeMatchType; + typedef std::map > IdMatchType; SearchFilter() {} - static SearchFilter IdMatch( const IdMatchMap& _idMatch ) + static SearchFilter IdMatch( const IdMatchType& _idMatch ) { return SearchFilter(_idMatch); } - static SearchFilter NameLikeMatch( const NameLikeMatchMap& _nameLikeMatch ) + static SearchFilter NameLikeMatch( const NameLikeMatchType& _nameLikeMatch ) { return SearchFilter(_nameLikeMatch); } @@ -60,15 +60,15 @@ class SearchFilter // The filter is a AND of the following conditions: // ((Field1.name LIKE STR1-1 OR Field1.name LIKE STR1-2 ...) OR (Field2.name LIKE STR2-1 OR Field2.name LIKE STR2-2 ...) ... - NameLikeMatchMap nameLikeMatch; + NameLikeMatchType nameLikeMatch; // ((Field1.id = ID1-1 OR Field1.id = ID1-2 ... ) AND ((Field2.id = ID2-1 OR Field2.id = ID2-2 ... ) ... - IdMatchMap idMatch; + IdMatchType idMatch; private: - SearchFilter(const NameLikeMatchMap& _nameLikeMatch) : nameLikeMatch(_nameLikeMatch) {} - SearchFilter(const IdMatchMap& _idMatch) : idMatch(_idMatch) {} + SearchFilter(const NameLikeMatchType& _nameLikeMatch) : nameLikeMatch(_nameLikeMatch) {} + SearchFilter(const IdMatchType& _idMatch) : idMatch(_idMatch) {} }; SqlQuery generatePartialQuery(SearchFilter& filter); diff --git a/src/ui/audio/desktop/KeywordSearchFilter.cpp b/src/ui/audio/desktop/KeywordSearchFilter.cpp index 1ce24444..6b4d4355 100644 --- a/src/ui/audio/desktop/KeywordSearchFilter.cpp +++ b/src/ui/audio/desktop/KeywordSearchFilter.cpp @@ -49,10 +49,12 @@ KeywordSearchFilter::getConstraint(Database::SearchFilter& filter) // For each part, do a global search on all searchable fields for (const std::string& value : values) { - filter.nameLikeMatch[Database::SearchFilter::Field::Artist].push_back(value); - filter.nameLikeMatch[Database::SearchFilter::Field::Release].push_back(value); - filter.nameLikeMatch[Database::SearchFilter::Field::Genre].push_back(value); - filter.nameLikeMatch[Database::SearchFilter::Field::Track].push_back(value); + filter.nameLikeMatch.push_back({ + {Database::SearchFilter::Field::Artist, {value}}, + {Database::SearchFilter::Field::Release, {value}}, + {Database::SearchFilter::Field::Genre, {value}}, + {Database::SearchFilter::Field::Track, {value}} + }); } } } diff --git a/src/ui/audio/mobile/MobileAudio.cpp b/src/ui/audio/mobile/MobileAudio.cpp index b5c38fd8..ccc02fd1 100644 --- a/src/ui/audio/mobile/MobileAudio.cpp +++ b/src/ui/audio/mobile/MobileAudio.cpp @@ -97,15 +97,15 @@ Audio::Audio(Wt::WContainerWidget *parent) std::vector keywords; boost::algorithm::split(keywords, text, boost::is_any_of(" "), boost::token_compress_on); - releaseSearch->search(SearchFilter::NameLikeMatch( { + releaseSearch->search(SearchFilter::NameLikeMatch( {{ { SearchFilter::Field::Artist, keywords }, - { SearchFilter::Field::Release, keywords }}), + { SearchFilter::Field::Release, keywords }}}), 3); - artistSearch->search(SearchFilter::NameLikeMatch({{SearchFilter::Field::Artist, keywords}}), + artistSearch->search(SearchFilter::NameLikeMatch({{{SearchFilter::Field::Artist, keywords}}}), 3); - trackSearch->search(SearchFilter::NameLikeMatch({{SearchFilter::Field::Track, keywords}}), + trackSearch->search(SearchFilter::NameLikeMatch({{{SearchFilter::Field::Track, keywords}}}), 3); artistSearch->show(); diff --git a/test/CheckDbBasics.cpp b/test/CheckDbBasics.cpp index db07c0c6..e1fbfaa9 100644 --- a/test/CheckDbBasics.cpp +++ b/test/CheckDbBasics.cpp @@ -71,14 +71,12 @@ int main(void) { Wt::Dbo::Transaction transaction(db.getSession()); - SearchFilter filter; - filter.nameLikeMatch[SearchFilter::Field::Track].push_back("track"); + SearchFilter filter = SearchFilter::NameLikeMatch({{{SearchFilter::Field::Track, {"track"}}}}); std::vector res = Track::getByFilter(db.getSession(), filter, -1, -1); assert(res.size() == 1); assert(res.front().id() == 1); - filter.nameLikeMatch[SearchFilter::Field::Track].clear(); - filter.nameLikeMatch[SearchFilter::Field::Track].push_back("not-found"); + filter = SearchFilter::NameLikeMatch({{{SearchFilter::Field::Track,{"not-found"}}}}); res = Track::getByFilter(db.getSession(), filter, -1, -1); assert(res.size() == 0 ); } @@ -87,8 +85,7 @@ int main(void) { Wt::Dbo::Transaction transaction(db.getSession()); - SearchFilter filter; - filter.nameLikeMatch[SearchFilter::Field::Artist].push_back("artist"); + SearchFilter filter = SearchFilter::NameLikeMatch({{{SearchFilter::Field::Artist, {"artist"}}}}); std::vector res = Track::getByFilter(db.getSession(), filter, -1, -1); assert(res.size() == 1); assert(res.front().id() == 1); @@ -98,8 +95,7 @@ int main(void) { Wt::Dbo::Transaction transaction(db.getSession()); - SearchFilter filter; - filter.idMatch[SearchFilter::Field::Artist].push_back(1); + SearchFilter filter = SearchFilter::IdMatch({{SearchFilter::Field::Artist, {1}}}); std::vector res = Track::getByFilter(db.getSession(), filter, -1, -1); assert(res.size() == 1); assert(res.front().id() == 1); @@ -110,8 +106,8 @@ int main(void) Wt::Dbo::Transaction transaction(db.getSession()); SearchFilter filter; - filter.idMatch[SearchFilter::Field::Artist].push_back(1); - filter.nameLikeMatch[SearchFilter::Field::Track].push_back("track"); + filter.idMatch[SearchFilter::Field::Artist] = { 1 }; + filter.nameLikeMatch = {{{ SearchFilter::Field::Track, {"track"} }}}; std::vector res = Track::getByFilter(db.getSession(), filter, -1, -1); assert(res.size() == 1); assert(res.front().id() == 1); @@ -122,7 +118,7 @@ int main(void) { Wt::Dbo::Transaction transaction(db.getSession()); - SearchFilter filter = SearchFilter::NameLikeMatch({{SearchFilter::Field::Genre, {"genre"}}}); + SearchFilter filter = SearchFilter::NameLikeMatch({{{SearchFilter::Field::Genre, {"genre"}}}}); std::vector res = Track::getByFilter(db.getSession(), filter, -1, -1); assert(res.size() == 1); assert(res.front().id() == 1); @@ -133,14 +129,12 @@ int main(void) { Wt::Dbo::Transaction transaction(db.getSession()); - SearchFilter filter; - filter.nameLikeMatch[SearchFilter::Field::Track].push_back("track"); + SearchFilter filter = SearchFilter::NameLikeMatch({{{SearchFilter::Field::Track, { "track" } }}}); std::vector res = Artist::getByFilter(db.getSession(), filter, -1, -1); assert(res.size() == 1); assert(res.front().id() == 1); - filter.nameLikeMatch[SearchFilter::Field::Track].clear(); - filter.nameLikeMatch[SearchFilter::Field::Track].push_back("badtrack"); + filter = SearchFilter::NameLikeMatch({{{SearchFilter::Field::Track, {"badtrack"} }}}); res = Artist::getByFilter(db.getSession(), filter, -1, -1); assert(res.size() == 0); } @@ -149,8 +143,7 @@ int main(void) { Wt::Dbo::Transaction transaction(db.getSession()); - SearchFilter filter; - filter.idMatch[SearchFilter::Field::Track].push_back(1); + SearchFilter filter = SearchFilter::IdMatch({{SearchFilter::Field::Track, {1} }}); std::vector res = Artist::getByFilter(db.getSession(), filter, -1, -1); assert(res.size() == 1); assert(res.front().id() == 1); @@ -160,8 +153,7 @@ int main(void) { Wt::Dbo::Transaction transaction(db.getSession()); - SearchFilter filter; - filter.nameLikeMatch[SearchFilter::Field::Artist].push_back("artist"); + SearchFilter filter = SearchFilter::NameLikeMatch({{{SearchFilter::Field::Artist, {"artist"}}}}); std::vector res = Artist::getByFilter(db.getSession(), filter, -1, -1); assert(res.size() == 1); assert(res.front().id() == 1); @@ -171,8 +163,7 @@ int main(void) { Wt::Dbo::Transaction transaction(db.getSession()); - SearchFilter filter; - filter.nameLikeMatch[SearchFilter::Field::Release].push_back("release"); + SearchFilter filter = SearchFilter::NameLikeMatch({{{SearchFilter::Field::Release, {"release"} }}}); std::vector res = Release::getByFilter(db.getSession(), filter, -1, -1); assert(res.size() == 1); @@ -183,7 +174,7 @@ int main(void) { Wt::Dbo::Transaction transaction(db.getSession()); - SearchFilter filter = SearchFilter::NameLikeMatch({{SearchFilter::Field::Track, {"track"}}}); + SearchFilter filter = SearchFilter::NameLikeMatch({{{SearchFilter::Field::Track, {"track"}}}}); std::vector res = Release::getByFilter(db.getSession(), filter, -1, -1); assert(res.size() == 1); assert(res.front().id() == 1); @@ -194,7 +185,7 @@ int main(void) { Wt::Dbo::Transaction transaction(db.getSession()); - SearchFilter filter = SearchFilter::NameLikeMatch({{SearchFilter::Field::Genre, {"genre"}}}); + SearchFilter filter = SearchFilter::NameLikeMatch({{{SearchFilter::Field::Genre, {"genre"}}}}); std::vector res = Genre::getByFilter(db.getSession(), filter, -1, -1); assert(res.size() == 1); assert(res.front().id() == 1); @@ -205,7 +196,7 @@ int main(void) { Wt::Dbo::Transaction transaction(db.getSession()); - SearchFilter filter = SearchFilter::NameLikeMatch({{SearchFilter::Field::Track, {"track"}}}); + SearchFilter filter = SearchFilter::NameLikeMatch({{{SearchFilter::Field::Track, {"track"}}}}); std::vector res = Genre::getByFilter(db.getSession(), filter, -1, -1); assert(res.size() == 1); assert(res.front().id() == 1); @@ -216,8 +207,8 @@ int main(void) { Wt::Dbo::Transaction transaction(db.getSession()); - SearchFilter filter = SearchFilter::NameLikeMatch({{SearchFilter::Field::Track, {"track"}}, - {SearchFilter::Field::Artist, {"artist"}}}); + SearchFilter filter = SearchFilter::NameLikeMatch({{{SearchFilter::Field::Track, {"track"}}, + {SearchFilter::Field::Artist, {"artist"}}}}); std::vector res = Genre::getByFilter(db.getSession(), filter, -1, -1); assert(res.size() == 1); assert(res.front().id() == 1);