From 92eef4c64d6dad836b5fab66d62bb4d2385c6f94 Mon Sep 17 00:00:00 2001 From: tastytea Date: Tue, 6 Aug 2019 11:20:30 +0200 Subject: [PATCH] Transformed the search functions into a class. Deleted unicode tests because they are covered by search tests. --- include/search.hpp | 83 ++++++++++++++++++++++++++++-------------- src/cli/main.cpp | 9 +++-- src/lib/search.cpp | 25 ++++++++----- tests/test_search.cpp | 9 +++-- tests/test_unicode.cpp | 34 ----------------- 5 files changed, 80 insertions(+), 80 deletions(-) delete mode 100644 tests/test_unicode.cpp diff --git a/include/search.hpp b/include/search.hpp index f8d66e5..9edbadf 100644 --- a/include/search.hpp +++ b/include/search.hpp @@ -21,42 +21,44 @@ #include #include "sqlite.hpp" -//! @file - namespace remwharead { using std::vector; using std::string; /*! - * @brief Split expression in subexpressions. + * @brief Search in database entries. * - * First it splits at `OR` or `||`, then it splits the subexpressions at - * `AND` or `&&`. The first vector contains all tags before the first `OR`. + * @since 0.7.0 * - * @return Vector of `OR`-vectors of `AND`-tags. + * @headerfile search.hpp remwharead/search.hpp */ - const vector> parse_expression(string expression); + class Search + { + public: + /*! + * @brief Defines the entries to search. + * + * @since 0.7.0 + */ + explicit Search(const vector &entries); - //! Convert str to lowercase. Works with unicode. - const string to_lowercase(const string &str); + /*! + * @brief Search in tags of database entries. + * + * Only matches whole tags, *Pill* does not match *Pillow*. + * + * @param expression Search expression. + * @param is_re Is it a regular expression? + * + * @return Vector of matching Database::entry. + * + * @since 0.7.0 + */ + const vector search_tags(string expression, + const bool is_re) const; - /*! - * @brief Search in tags of database entries. - * - * Only matches whole tags, *Pill* does not match *Pillow*. - * - * @param entries Vector of Database::entry to search. - * @param expression Search expression. - * @param is_re Is it a regular expression? - * - * @return Vector of matching Database::entry. - */ - const vector - search_tags(const vector &entries, string expression, - const bool is_re); - - /*! + /*! * @brief Search in full text of database entries. * * Searches in tags, title, description and full text. @@ -66,10 +68,35 @@ namespace remwharead * @param is_re Is it a regular expression? * * @return Vector of matching Database::entry. + * + * @since 0.7.0 */ - const vector - search_all(const vector &entries, string expression, - const bool is_re); + const vector search_all(string expression, + const bool is_re) const; + + private: + const vector _entries; + + /*! + * @brief Split expression into subexpressions. + * + * First it splits at `OR` or `||`, then it splits the subexpressions + * at `AND` or `&&`. The first vector contains all tags before the + * first `OR`. + * + * @return Vector of `OR`-vectors of `AND`-tags. + * + * @since 0.7.0 + */ + const vector> parse_expression(string expression) const; + + /*! + * @brief Convert str to lowercase. Works with unicode. + * + * @since 0.7.0 + */ + const string to_lowercase(const string &str) const; + }; } #endif // REMWHAREAD_SEARCH_HPP diff --git a/src/cli/main.cpp b/src/cli/main.cpp index d69b398..e4c21d2 100644 --- a/src/cli/main.cpp +++ b/src/cli/main.cpp @@ -85,15 +85,16 @@ int main(const int argc, const char *argv[]) } if (opts.format != export_format::undefined) { - vector entries = - db.retrieve(opts.span[0], opts.span[1]); + vector entries; + Search search(db.retrieve(opts.span[0], opts.span[1])); + if (!opts.search_tags.empty()) { - entries = search_tags(entries, opts.search_tags, opts.regex); + entries = search.search_tags(opts.search_tags, opts.regex); } else if (!opts.search_all.empty()) { - entries = search_all(entries, opts.search_all, opts.regex); + entries = search.search_all(opts.search_all, opts.regex); } switch (opts.format) diff --git a/src/lib/search.cpp b/src/lib/search.cpp index 771d61a..6b9cd4b 100644 --- a/src/lib/search.cpp +++ b/src/lib/search.cpp @@ -28,7 +28,12 @@ namespace remwharead using std::find; using std::find_if; - const vector> parse_expression(string expression) + Search::Search(const vector &entries) + :_entries(entries) + {} + + const vector> Search::parse_expression(string expression) + const { vector> searchlist; const regex re_or("(.+?) (OR|\\|\\|) "); @@ -62,7 +67,7 @@ namespace remwharead return searchlist; } - const string to_lowercase(const string &str) + const string Search::to_lowercase(const string &str) const { icu::UnicodeString uni(str.c_str()); string out; @@ -70,15 +75,15 @@ namespace remwharead return out; } - const vector search_tags(const vector &entries, - string expression, const bool is_re) + const vector Search::search_tags(string expression, + const bool is_re) const { vector> searchlist = parse_expression(expression); vector result; for (const vector &tags_or : searchlist) { - for (const DB::entry &entry : entries) + for (const DB::entry &entry : _entries) { // Add entry to result if all tags in an OR-slice match. bool matched = true; @@ -86,7 +91,7 @@ namespace remwharead { const auto it = find_if( entry.tags.begin(), entry.tags.end(), - [&tag, is_re](string s) + [&, is_re](string s) { s = to_lowercase(s); if (is_re) @@ -114,15 +119,15 @@ namespace remwharead return result; } - const vector search_all(const vector &entries, - string expression, const bool is_re) + const vector Search::search_all(string expression, + const bool is_re) const { vector> searchlist = parse_expression(expression); - vector result = search_tags(entries, expression, is_re); + vector result = search_tags(expression, is_re); for (const vector &terms_or : searchlist) { - for (const DB::entry &entry : entries) + for (const DB::entry &entry : _entries) { // Add entry to result if all terms in an OR-slice match title, // description or full text. diff --git a/tests/test_search.cpp b/tests/test_search.cpp index bda47d2..1b39b5c 100644 --- a/tests/test_search.cpp +++ b/tests/test_search.cpp @@ -39,17 +39,18 @@ SCENARIO ("Searching works correctly") entry.datetime = system_clock::time_point(); entry.fulltext = "Full text."; entry.description = "Good description."; + Search search({ entry }); WHEN ("Searching in tags") { try { - if (search_tags({ entry }, "tAg1_ö", false).size() != 1) + if (search.search_tags("tAg1_Ö", false).size() != 1) { search_ok = false; } - if (search_tags({ entry }, "tAg?[0-9]_ö", true).size() != 1) + if (search.search_tags( "tAg?[0-9]_ö", true).size() != 1) { search_ok = false; } @@ -71,12 +72,12 @@ SCENARIO ("Searching works correctly") { try { - if (search_all({ entry }, "DESCRIPT AND good", false).size() != 1) + if (search.search_all("DESCRIPT AND good", false).size() != 1) { search_ok = false; } - if (search_all({ entry }, "^ful{2} T..T\\.$", true).size() != 1) + if (search.search_all("^ful{2} T..T\\.$", true).size() != 1) { search_ok = false; } diff --git a/tests/test_unicode.cpp b/tests/test_unicode.cpp deleted file mode 100644 index f9d7676..0000000 --- a/tests/test_unicode.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* This file is part of remwharead. - * Copyright © 2019 tastytea - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include "search.hpp" - -using namespace remwharead; - -SCENARIO ("Unicode is handled correctly") -{ - WHEN ("In to_lowercase()") - { - THEN ("Results look okay") - { - REQUIRE(to_lowercase("SUPPENGRÜN") == "suppengrün"); - REQUIRE(to_lowercase("SCHEIẞE") == "scheiße"); - REQUIRE(to_lowercase("ШОКОЛАД") == "шоколад"); - } - } -} -