[UI] Corrected regression on keyword search filter
This commit is contained in:
@@ -26,37 +26,40 @@ SqlQuery generatePartialQuery(SearchFilter& filter)
|
|||||||
{
|
{
|
||||||
SqlQuery sqlQuery;
|
SqlQuery sqlQuery;
|
||||||
|
|
||||||
WhereClause likeWhereClause;
|
|
||||||
|
|
||||||
// Process name like parameters
|
// Process name like parameters
|
||||||
for (auto nameLikeMatch : filter.nameLikeMatch)
|
for (auto nameLikeMatches : filter.nameLikeMatch)
|
||||||
{
|
{
|
||||||
// Artist
|
WhereClause likeWhereClause;
|
||||||
switch (nameLikeMatch.first)
|
|
||||||
|
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:
|
// Artist
|
||||||
for (const std::string& name : nameLikeMatch.second)
|
switch (nameLikeMatch.first)
|
||||||
likeWhereClause.Or( WhereClause("r.name LIKE ?") ).bind("%%" + name + "%%");
|
{
|
||||||
break;
|
case SearchFilter::Field::Artist:
|
||||||
|
for (const std::string& name : nameLikeMatch.second)
|
||||||
|
likeWhereClause.Or( WhereClause("a.name LIKE ?") ).bind("%%" + name + "%%");
|
||||||
|
break;
|
||||||
|
|
||||||
case SearchFilter::Field::Genre:
|
case SearchFilter::Field::Release:
|
||||||
for (const std::string& name : nameLikeMatch.second)
|
for (const std::string& name : nameLikeMatch.second)
|
||||||
likeWhereClause.Or( WhereClause("g.name LIKE ?") ).bind("%%" + name + "%%");
|
likeWhereClause.Or( WhereClause("r.name LIKE ?") ).bind("%%" + name + "%%");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SearchFilter::Field::Track:
|
case SearchFilter::Field::Genre:
|
||||||
for (const std::string& name : nameLikeMatch.second)
|
for (const std::string& name : nameLikeMatch.second)
|
||||||
likeWhereClause.Or( WhereClause("t.name LIKE ?") ).bind("%%" + name + "%%");
|
likeWhereClause.Or( WhereClause("g.name LIKE ?") ).bind("%%" + name + "%%");
|
||||||
break;
|
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
|
// Process id exact match parameters
|
||||||
|
|
||||||
|
|||||||
@@ -42,17 +42,17 @@ class SearchFilter
|
|||||||
Track, // track
|
Track, // track
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<Field, std::vector<std::string> > NameLikeMatchMap;
|
typedef std::vector<std::map<Field, std::vector<std::string> > > NameLikeMatchType;
|
||||||
typedef std::map<Field, std::vector< Wt::Dbo::dbo_default_traits::IdType> > IdMatchMap;
|
typedef std::map<Field, std::vector< Wt::Dbo::dbo_default_traits::IdType> > IdMatchType;
|
||||||
|
|
||||||
SearchFilter() {}
|
SearchFilter() {}
|
||||||
|
|
||||||
static SearchFilter IdMatch( const IdMatchMap& _idMatch )
|
static SearchFilter IdMatch( const IdMatchType& _idMatch )
|
||||||
{
|
{
|
||||||
return SearchFilter(_idMatch);
|
return SearchFilter(_idMatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SearchFilter NameLikeMatch( const NameLikeMatchMap& _nameLikeMatch )
|
static SearchFilter NameLikeMatch( const NameLikeMatchType& _nameLikeMatch )
|
||||||
{
|
{
|
||||||
return SearchFilter(_nameLikeMatch);
|
return SearchFilter(_nameLikeMatch);
|
||||||
}
|
}
|
||||||
@@ -60,15 +60,15 @@ class SearchFilter
|
|||||||
// The filter is a AND of the following conditions:
|
// 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 ...) ...
|
// ((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 ... ) ...
|
// ((Field1.id = ID1-1 OR Field1.id = ID1-2 ... ) AND ((Field2.id = ID2-1 OR Field2.id = ID2-2 ... ) ...
|
||||||
IdMatchMap idMatch;
|
IdMatchType idMatch;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
SearchFilter(const NameLikeMatchMap& _nameLikeMatch) : nameLikeMatch(_nameLikeMatch) {}
|
SearchFilter(const NameLikeMatchType& _nameLikeMatch) : nameLikeMatch(_nameLikeMatch) {}
|
||||||
SearchFilter(const IdMatchMap& _idMatch) : idMatch(_idMatch) {}
|
SearchFilter(const IdMatchType& _idMatch) : idMatch(_idMatch) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
SqlQuery generatePartialQuery(SearchFilter& filter);
|
SqlQuery generatePartialQuery(SearchFilter& filter);
|
||||||
|
|||||||
@@ -49,10 +49,12 @@ KeywordSearchFilter::getConstraint(Database::SearchFilter& filter)
|
|||||||
// For each part, do a global search on all searchable fields
|
// For each part, do a global search on all searchable fields
|
||||||
for (const std::string& value : values)
|
for (const std::string& value : values)
|
||||||
{
|
{
|
||||||
filter.nameLikeMatch[Database::SearchFilter::Field::Artist].push_back(value);
|
filter.nameLikeMatch.push_back({
|
||||||
filter.nameLikeMatch[Database::SearchFilter::Field::Release].push_back(value);
|
{Database::SearchFilter::Field::Artist, {value}},
|
||||||
filter.nameLikeMatch[Database::SearchFilter::Field::Genre].push_back(value);
|
{Database::SearchFilter::Field::Release, {value}},
|
||||||
filter.nameLikeMatch[Database::SearchFilter::Field::Track].push_back(value);
|
{Database::SearchFilter::Field::Genre, {value}},
|
||||||
|
{Database::SearchFilter::Field::Track, {value}}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,15 +97,15 @@ Audio::Audio(Wt::WContainerWidget *parent)
|
|||||||
std::vector<std::string> keywords;
|
std::vector<std::string> keywords;
|
||||||
boost::algorithm::split(keywords, text, boost::is_any_of(" "), boost::token_compress_on);
|
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::Artist, keywords },
|
||||||
{ SearchFilter::Field::Release, keywords }}),
|
{ SearchFilter::Field::Release, keywords }}}),
|
||||||
3);
|
3);
|
||||||
|
|
||||||
artistSearch->search(SearchFilter::NameLikeMatch({{SearchFilter::Field::Artist, keywords}}),
|
artistSearch->search(SearchFilter::NameLikeMatch({{{SearchFilter::Field::Artist, keywords}}}),
|
||||||
3);
|
3);
|
||||||
|
|
||||||
trackSearch->search(SearchFilter::NameLikeMatch({{SearchFilter::Field::Track, keywords}}),
|
trackSearch->search(SearchFilter::NameLikeMatch({{{SearchFilter::Field::Track, keywords}}}),
|
||||||
3);
|
3);
|
||||||
|
|
||||||
artistSearch->show();
|
artistSearch->show();
|
||||||
|
|||||||
+17
-26
@@ -71,14 +71,12 @@ int main(void)
|
|||||||
{
|
{
|
||||||
Wt::Dbo::Transaction transaction(db.getSession());
|
Wt::Dbo::Transaction transaction(db.getSession());
|
||||||
|
|
||||||
SearchFilter filter;
|
SearchFilter filter = SearchFilter::NameLikeMatch({{{SearchFilter::Field::Track, {"track"}}}});
|
||||||
filter.nameLikeMatch[SearchFilter::Field::Track].push_back("track");
|
|
||||||
std::vector<Track::pointer> res = Track::getByFilter(db.getSession(), filter, -1, -1);
|
std::vector<Track::pointer> res = Track::getByFilter(db.getSession(), filter, -1, -1);
|
||||||
assert(res.size() == 1);
|
assert(res.size() == 1);
|
||||||
assert(res.front().id() == 1);
|
assert(res.front().id() == 1);
|
||||||
|
|
||||||
filter.nameLikeMatch[SearchFilter::Field::Track].clear();
|
filter = SearchFilter::NameLikeMatch({{{SearchFilter::Field::Track,{"not-found"}}}});
|
||||||
filter.nameLikeMatch[SearchFilter::Field::Track].push_back("not-found");
|
|
||||||
res = Track::getByFilter(db.getSession(), filter, -1, -1);
|
res = Track::getByFilter(db.getSession(), filter, -1, -1);
|
||||||
assert(res.size() == 0 );
|
assert(res.size() == 0 );
|
||||||
}
|
}
|
||||||
@@ -87,8 +85,7 @@ int main(void)
|
|||||||
{
|
{
|
||||||
Wt::Dbo::Transaction transaction(db.getSession());
|
Wt::Dbo::Transaction transaction(db.getSession());
|
||||||
|
|
||||||
SearchFilter filter;
|
SearchFilter filter = SearchFilter::NameLikeMatch({{{SearchFilter::Field::Artist, {"artist"}}}});
|
||||||
filter.nameLikeMatch[SearchFilter::Field::Artist].push_back("artist");
|
|
||||||
std::vector<Track::pointer> res = Track::getByFilter(db.getSession(), filter, -1, -1);
|
std::vector<Track::pointer> res = Track::getByFilter(db.getSession(), filter, -1, -1);
|
||||||
assert(res.size() == 1);
|
assert(res.size() == 1);
|
||||||
assert(res.front().id() == 1);
|
assert(res.front().id() == 1);
|
||||||
@@ -98,8 +95,7 @@ int main(void)
|
|||||||
{
|
{
|
||||||
Wt::Dbo::Transaction transaction(db.getSession());
|
Wt::Dbo::Transaction transaction(db.getSession());
|
||||||
|
|
||||||
SearchFilter filter;
|
SearchFilter filter = SearchFilter::IdMatch({{SearchFilter::Field::Artist, {1}}});
|
||||||
filter.idMatch[SearchFilter::Field::Artist].push_back(1);
|
|
||||||
std::vector<Track::pointer> res = Track::getByFilter(db.getSession(), filter, -1, -1);
|
std::vector<Track::pointer> res = Track::getByFilter(db.getSession(), filter, -1, -1);
|
||||||
assert(res.size() == 1);
|
assert(res.size() == 1);
|
||||||
assert(res.front().id() == 1);
|
assert(res.front().id() == 1);
|
||||||
@@ -110,8 +106,8 @@ int main(void)
|
|||||||
Wt::Dbo::Transaction transaction(db.getSession());
|
Wt::Dbo::Transaction transaction(db.getSession());
|
||||||
|
|
||||||
SearchFilter filter;
|
SearchFilter filter;
|
||||||
filter.idMatch[SearchFilter::Field::Artist].push_back(1);
|
filter.idMatch[SearchFilter::Field::Artist] = { 1 };
|
||||||
filter.nameLikeMatch[SearchFilter::Field::Track].push_back("track");
|
filter.nameLikeMatch = {{{ SearchFilter::Field::Track, {"track"} }}};
|
||||||
std::vector<Track::pointer> res = Track::getByFilter(db.getSession(), filter, -1, -1);
|
std::vector<Track::pointer> res = Track::getByFilter(db.getSession(), filter, -1, -1);
|
||||||
assert(res.size() == 1);
|
assert(res.size() == 1);
|
||||||
assert(res.front().id() == 1);
|
assert(res.front().id() == 1);
|
||||||
@@ -122,7 +118,7 @@ int main(void)
|
|||||||
{
|
{
|
||||||
Wt::Dbo::Transaction transaction(db.getSession());
|
Wt::Dbo::Transaction transaction(db.getSession());
|
||||||
|
|
||||||
SearchFilter filter = SearchFilter::NameLikeMatch({{SearchFilter::Field::Genre, {"genre"}}});
|
SearchFilter filter = SearchFilter::NameLikeMatch({{{SearchFilter::Field::Genre, {"genre"}}}});
|
||||||
std::vector<Track::pointer> res = Track::getByFilter(db.getSession(), filter, -1, -1);
|
std::vector<Track::pointer> res = Track::getByFilter(db.getSession(), filter, -1, -1);
|
||||||
assert(res.size() == 1);
|
assert(res.size() == 1);
|
||||||
assert(res.front().id() == 1);
|
assert(res.front().id() == 1);
|
||||||
@@ -133,14 +129,12 @@ int main(void)
|
|||||||
{
|
{
|
||||||
Wt::Dbo::Transaction transaction(db.getSession());
|
Wt::Dbo::Transaction transaction(db.getSession());
|
||||||
|
|
||||||
SearchFilter filter;
|
SearchFilter filter = SearchFilter::NameLikeMatch({{{SearchFilter::Field::Track, { "track" } }}});
|
||||||
filter.nameLikeMatch[SearchFilter::Field::Track].push_back("track");
|
|
||||||
std::vector<Artist::pointer> res = Artist::getByFilter(db.getSession(), filter, -1, -1);
|
std::vector<Artist::pointer> res = Artist::getByFilter(db.getSession(), filter, -1, -1);
|
||||||
assert(res.size() == 1);
|
assert(res.size() == 1);
|
||||||
assert(res.front().id() == 1);
|
assert(res.front().id() == 1);
|
||||||
|
|
||||||
filter.nameLikeMatch[SearchFilter::Field::Track].clear();
|
filter = SearchFilter::NameLikeMatch({{{SearchFilter::Field::Track, {"badtrack"} }}});
|
||||||
filter.nameLikeMatch[SearchFilter::Field::Track].push_back("badtrack");
|
|
||||||
res = Artist::getByFilter(db.getSession(), filter, -1, -1);
|
res = Artist::getByFilter(db.getSession(), filter, -1, -1);
|
||||||
assert(res.size() == 0);
|
assert(res.size() == 0);
|
||||||
}
|
}
|
||||||
@@ -149,8 +143,7 @@ int main(void)
|
|||||||
{
|
{
|
||||||
Wt::Dbo::Transaction transaction(db.getSession());
|
Wt::Dbo::Transaction transaction(db.getSession());
|
||||||
|
|
||||||
SearchFilter filter;
|
SearchFilter filter = SearchFilter::IdMatch({{SearchFilter::Field::Track, {1} }});
|
||||||
filter.idMatch[SearchFilter::Field::Track].push_back(1);
|
|
||||||
std::vector<Artist::pointer> res = Artist::getByFilter(db.getSession(), filter, -1, -1);
|
std::vector<Artist::pointer> res = Artist::getByFilter(db.getSession(), filter, -1, -1);
|
||||||
assert(res.size() == 1);
|
assert(res.size() == 1);
|
||||||
assert(res.front().id() == 1);
|
assert(res.front().id() == 1);
|
||||||
@@ -160,8 +153,7 @@ int main(void)
|
|||||||
{
|
{
|
||||||
Wt::Dbo::Transaction transaction(db.getSession());
|
Wt::Dbo::Transaction transaction(db.getSession());
|
||||||
|
|
||||||
SearchFilter filter;
|
SearchFilter filter = SearchFilter::NameLikeMatch({{{SearchFilter::Field::Artist, {"artist"}}}});
|
||||||
filter.nameLikeMatch[SearchFilter::Field::Artist].push_back("artist");
|
|
||||||
std::vector<Artist::pointer> res = Artist::getByFilter(db.getSession(), filter, -1, -1);
|
std::vector<Artist::pointer> res = Artist::getByFilter(db.getSession(), filter, -1, -1);
|
||||||
assert(res.size() == 1);
|
assert(res.size() == 1);
|
||||||
assert(res.front().id() == 1);
|
assert(res.front().id() == 1);
|
||||||
@@ -171,8 +163,7 @@ int main(void)
|
|||||||
{
|
{
|
||||||
Wt::Dbo::Transaction transaction(db.getSession());
|
Wt::Dbo::Transaction transaction(db.getSession());
|
||||||
|
|
||||||
SearchFilter filter;
|
SearchFilter filter = SearchFilter::NameLikeMatch({{{SearchFilter::Field::Release, {"release"} }}});
|
||||||
filter.nameLikeMatch[SearchFilter::Field::Release].push_back("release");
|
|
||||||
|
|
||||||
std::vector<Release::pointer> res = Release::getByFilter(db.getSession(), filter, -1, -1);
|
std::vector<Release::pointer> res = Release::getByFilter(db.getSession(), filter, -1, -1);
|
||||||
assert(res.size() == 1);
|
assert(res.size() == 1);
|
||||||
@@ -183,7 +174,7 @@ int main(void)
|
|||||||
{
|
{
|
||||||
Wt::Dbo::Transaction transaction(db.getSession());
|
Wt::Dbo::Transaction transaction(db.getSession());
|
||||||
|
|
||||||
SearchFilter filter = SearchFilter::NameLikeMatch({{SearchFilter::Field::Track, {"track"}}});
|
SearchFilter filter = SearchFilter::NameLikeMatch({{{SearchFilter::Field::Track, {"track"}}}});
|
||||||
std::vector<Release::pointer> res = Release::getByFilter(db.getSession(), filter, -1, -1);
|
std::vector<Release::pointer> res = Release::getByFilter(db.getSession(), filter, -1, -1);
|
||||||
assert(res.size() == 1);
|
assert(res.size() == 1);
|
||||||
assert(res.front().id() == 1);
|
assert(res.front().id() == 1);
|
||||||
@@ -194,7 +185,7 @@ int main(void)
|
|||||||
{
|
{
|
||||||
Wt::Dbo::Transaction transaction(db.getSession());
|
Wt::Dbo::Transaction transaction(db.getSession());
|
||||||
|
|
||||||
SearchFilter filter = SearchFilter::NameLikeMatch({{SearchFilter::Field::Genre, {"genre"}}});
|
SearchFilter filter = SearchFilter::NameLikeMatch({{{SearchFilter::Field::Genre, {"genre"}}}});
|
||||||
std::vector<Genre::pointer> res = Genre::getByFilter(db.getSession(), filter, -1, -1);
|
std::vector<Genre::pointer> res = Genre::getByFilter(db.getSession(), filter, -1, -1);
|
||||||
assert(res.size() == 1);
|
assert(res.size() == 1);
|
||||||
assert(res.front().id() == 1);
|
assert(res.front().id() == 1);
|
||||||
@@ -205,7 +196,7 @@ int main(void)
|
|||||||
{
|
{
|
||||||
Wt::Dbo::Transaction transaction(db.getSession());
|
Wt::Dbo::Transaction transaction(db.getSession());
|
||||||
|
|
||||||
SearchFilter filter = SearchFilter::NameLikeMatch({{SearchFilter::Field::Track, {"track"}}});
|
SearchFilter filter = SearchFilter::NameLikeMatch({{{SearchFilter::Field::Track, {"track"}}}});
|
||||||
std::vector<Genre::pointer> res = Genre::getByFilter(db.getSession(), filter, -1, -1);
|
std::vector<Genre::pointer> res = Genre::getByFilter(db.getSession(), filter, -1, -1);
|
||||||
assert(res.size() == 1);
|
assert(res.size() == 1);
|
||||||
assert(res.front().id() == 1);
|
assert(res.front().id() == 1);
|
||||||
@@ -216,8 +207,8 @@ int main(void)
|
|||||||
{
|
{
|
||||||
Wt::Dbo::Transaction transaction(db.getSession());
|
Wt::Dbo::Transaction transaction(db.getSession());
|
||||||
|
|
||||||
SearchFilter filter = SearchFilter::NameLikeMatch({{SearchFilter::Field::Track, {"track"}},
|
SearchFilter filter = SearchFilter::NameLikeMatch({{{SearchFilter::Field::Track, {"track"}},
|
||||||
{SearchFilter::Field::Artist, {"artist"}}});
|
{SearchFilter::Field::Artist, {"artist"}}}});
|
||||||
std::vector<Genre::pointer> res = Genre::getByFilter(db.getSession(), filter, -1, -1);
|
std::vector<Genre::pointer> res = Genre::getByFilter(db.getSession(), filter, -1, -1);
|
||||||
assert(res.size() == 1);
|
assert(res.size() == 1);
|
||||||
assert(res.front().id() == 1);
|
assert(res.front().id() == 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user