From a20f9e2ce18df53b6c062c4a1436b7089b1a558f Mon Sep 17 00:00:00 2001 From: Veloman Yunkan Date: Sat, 6 Mar 2021 20:03:41 +0400 Subject: [PATCH] Library::filter() works in two stages 1. Get the subset of books matching the q (title/description) parameter of the search 2. Filter out books not matching the other parameters of the search. Stage 1. currently works in the old way, but will be replaced by Xapian based search in subsequent commits. --- include/library.h | 4 ++++ src/library.cpp | 27 ++++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/include/library.h b/include/library.h index 86dfafaee..b56dab896 100644 --- a/include/library.h +++ b/include/library.h @@ -105,7 +105,11 @@ class Filter { Filter& query(std::string query); Filter& name(std::string name); + bool hasQuery() const; + bool accept(const Book& book) const; + bool acceptByQueryOnly(const Book& book) const; + bool acceptByNonQueryCriteria(const Book& book) const; }; diff --git a/src/library.cpp b/src/library.cpp index c9855bd94..b16c4b9d6 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -236,12 +236,18 @@ std::vector Library::filter(const Filter& filter) { std::vector bookIds; for(auto& pair:m_books) { - auto book = pair.second; - if(filter.accept(book)) { + if(filter.acceptByQueryOnly(pair.second)) { bookIds.push_back(pair.first); } } - return bookIds; + + std::vector result; + for(auto id : bookIds) { + if(filter.acceptByNonQueryCriteria(m_books[id])) { + result.push_back(id); + } + } + return result; } template @@ -495,7 +501,17 @@ Filter& Filter::name(std::string name) #define ACTIVE(X) (activeFilters & (X)) #define FILTER(TAG, TEST) if (ACTIVE(TAG) && !(TEST)) { return false; } +bool Filter::hasQuery() const +{ + return ACTIVE(QUERY); +} + bool Filter::accept(const Book& book) const +{ + return acceptByNonQueryCriteria(book) && acceptByQueryOnly(book); +} + +bool Filter::acceptByNonQueryCriteria(const Book& book) const { auto local = !book.getPath().empty(); FILTER(_LOCAL, local) @@ -538,6 +554,11 @@ bool Filter::accept(const Book& book) const } } } + return true; +} + +bool Filter::acceptByQueryOnly(const Book& book) const +{ if ( ACTIVE(QUERY) && !(matchRegex(book.getTitle(), "\\Q" + _query + "\\E") || matchRegex(book.getDescription(), "\\Q" + _query + "\\E")))