Transformed the search functions into a class.
Deleted unicode tests because they are covered by search tests.
This commit is contained in:
parent
df59f484c6
commit
92eef4c64d
|
@ -21,40 +21,42 @@
|
|||
#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);
|
||||
|
||||
//! Convert str to lowercase. Works with unicode.
|
||||
const string to_lowercase(const string &str);
|
||||
class Search
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* @brief Defines the entries to search.
|
||||
*
|
||||
* @since 0.7.0
|
||||
*/
|
||||
explicit Search(const vector<Database::entry> &entries);
|
||||
|
||||
/*!
|
||||
* @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.
|
||||
*
|
||||
* @since 0.7.0
|
||||
*/
|
||||
const vector<Database::entry>
|
||||
search_tags(const vector<Database::entry> &entries, string expression,
|
||||
const bool is_re);
|
||||
const vector<Database::entry> search_tags(string expression,
|
||||
const bool is_re) const;
|
||||
|
||||
/*!
|
||||
* @brief Search in full text of database entries.
|
||||
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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("ШОКОЛАД") == "шоколад");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue