Transformed the search functions into a class.

Deleted unicode tests because they are covered by search tests.
This commit is contained in:
tastytea 2019-08-06 11:20:30 +02:00
parent df59f484c6
commit 92eef4c64d
Signed by: tastytea
GPG Key ID: CFC39497F1B26E07
5 changed files with 80 additions and 80 deletions

View File

@ -21,42 +21,44 @@
#include <string>
#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<vector<string>> parse_expression(string expression);
class Search
{
public:
/*!
* @brief Defines the entries to search.
*
* @since 0.7.0
*/
explicit Search(const vector<Database::entry> &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<Database::entry> 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<Database::entry>
search_tags(const vector<Database::entry> &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<Database::entry>
search_all(const vector<Database::entry> &entries, string expression,
const bool is_re);
const vector<Database::entry> search_all(string expression,
const bool is_re) const;
private:
const vector<Database::entry> _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<vector<string>> 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

View File

@ -85,15 +85,16 @@ int main(const int argc, const char *argv[])
}
if (opts.format != export_format::undefined)
{
vector<Database::entry> entries =
db.retrieve(opts.span[0], opts.span[1]);
vector<Database::entry> 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)

View File

@ -28,7 +28,12 @@ namespace remwharead
using std::find;
using std::find_if;
const vector<vector<string>> parse_expression(string expression)
Search::Search(const vector<Database::entry> &entries)
:_entries(entries)
{}
const vector<vector<string>> Search::parse_expression(string expression)
const
{
vector<vector<string>> 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<DB::entry> search_tags(const vector<DB::entry> &entries,
string expression, const bool is_re)
const vector<DB::entry> Search::search_tags(string expression,
const bool is_re) const
{
vector<vector<string>> searchlist = parse_expression(expression);
vector<DB::entry> result;
for (const vector<string> &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<DB::entry> search_all(const vector<DB::entry> &entries,
string expression, const bool is_re)
const vector<DB::entry> Search::search_all(string expression,
const bool is_re) const
{
vector<vector<string>> searchlist = parse_expression(expression);
vector<DB::entry> result = search_tags(entries, expression, is_re);
vector<DB::entry> result = search_tags(expression, is_re);
for (const vector<string> &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.

View File

@ -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;
}

View File

@ -1,34 +0,0 @@
/* This file is part of remwharead.
* Copyright © 2019 tastytea <tastytea@tastytea.de>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <catch.hpp>
#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("ШОКОЛАД") == "шоколад");
}
}
}