defined data structure to pass around the search term description used for highlighting and other
This commit is contained in:
+52
-81
@@ -498,23 +498,12 @@ bool SearchData::fileNameOnly()
|
||||
return true;
|
||||
}
|
||||
|
||||
// Extract all terms and term groups
|
||||
bool SearchData::getTerms(vector<string>& terms,
|
||||
vector<vector<string> >& groups,
|
||||
vector<int>& gslks) const
|
||||
// Extract all term data
|
||||
void SearchData::getTerms(HighlightData &hld) const
|
||||
{
|
||||
for (qlist_cit_t it = m_query.begin(); it != m_query.end(); it++)
|
||||
(*it)->getTerms(terms, groups, gslks);
|
||||
return true;
|
||||
}
|
||||
// Extract user terms
|
||||
void SearchData::getUTerms(vector<string>& terms) const
|
||||
{
|
||||
for (qlist_cit_t it = m_query.begin(); it != m_query.end(); it++)
|
||||
(*it)->getUTerms(terms);
|
||||
sort(terms.begin(), terms.end());
|
||||
vector<string>::iterator it = unique(terms.begin(), terms.end());
|
||||
terms.erase(it, terms.end());
|
||||
(*it)->getTerms(hld);
|
||||
return;
|
||||
}
|
||||
|
||||
// Splitter callback for breaking a user string into simple terms and
|
||||
@@ -590,10 +579,10 @@ private:
|
||||
// translating.
|
||||
class StringToXapianQ {
|
||||
public:
|
||||
StringToXapianQ(Db& db, const string& field,
|
||||
StringToXapianQ(Db& db, HighlightData& hld, const string& field,
|
||||
const string &stmlng, bool boostUser)
|
||||
: m_db(db), m_field(field), m_stemlang(stmlng),
|
||||
m_doBoostUserTerms(boostUser)
|
||||
: m_db(db), m_field(field), m_stemlang(stmlng),
|
||||
m_doBoostUserTerms(boostUser), m_hld(hld)
|
||||
{ }
|
||||
|
||||
bool processUserString(const string &iq,
|
||||
@@ -601,20 +590,6 @@ public:
|
||||
vector<Xapian::Query> &pqueries,
|
||||
const StopList &stops,
|
||||
int slack = 0, bool useNear = false);
|
||||
// After processing the string: return search terms and term
|
||||
// groups (ie: for highlighting)
|
||||
bool getTerms(vector<string>& terms, vector<vector<string> >& groups)
|
||||
{
|
||||
terms.insert(terms.end(), m_terms.begin(), m_terms.end());
|
||||
groups.insert(groups.end(), m_groups.begin(), m_groups.end());
|
||||
return true;
|
||||
}
|
||||
bool getUTerms(vector<string>& terms)
|
||||
{
|
||||
terms.insert(terms.end(), m_uterms.begin(), m_uterms.end());
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
void expandTerm(bool dont, const string& term, vector<string>& exp,
|
||||
string& sterm, const string& prefix);
|
||||
@@ -630,10 +605,7 @@ private:
|
||||
const string& m_field;
|
||||
const string& m_stemlang;
|
||||
bool m_doBoostUserTerms;
|
||||
// Single terms and phrases resulting from breaking up text;
|
||||
vector<string> m_uterms;
|
||||
vector<string> m_terms;
|
||||
vector<vector<string> > m_groups;
|
||||
HighlightData& m_hld;
|
||||
};
|
||||
|
||||
#if 1
|
||||
@@ -647,7 +619,7 @@ static void listVector(const string& what, const vector<string>&l)
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Expand stem and wildcards
|
||||
/** Take simple term and expand stem and wildcards
|
||||
*
|
||||
* @param nostemexp don't perform stem expansion. This is mainly used to
|
||||
* prevent stem expansion inside phrases (because the user probably
|
||||
@@ -680,9 +652,11 @@ void StringToXapianQ::expandTerm(bool nostemexp,
|
||||
nostemexp = true;
|
||||
}
|
||||
|
||||
if (!haswild)
|
||||
m_hld.uterms.insert(term);
|
||||
|
||||
if (nostemexp && !haswild) {
|
||||
sterm = term;
|
||||
m_uterms.push_back(sterm);
|
||||
exp.resize(1);
|
||||
exp[0] = prefix + term;
|
||||
} else {
|
||||
@@ -692,7 +666,6 @@ void StringToXapianQ::expandTerm(bool nostemexp,
|
||||
m_field);
|
||||
} else {
|
||||
sterm = term;
|
||||
m_uterms.push_back(sterm);
|
||||
m_db.termMatch(Rcl::Db::ET_STEM, m_stemlang, term, res, -1,
|
||||
m_field);
|
||||
}
|
||||
@@ -701,7 +674,6 @@ void StringToXapianQ::expandTerm(bool nostemexp,
|
||||
exp.push_back(it->term);
|
||||
}
|
||||
}
|
||||
//listVector("ExpandTerm:uterms now: ", m_uterms);
|
||||
}
|
||||
|
||||
// Do distribution of string vectors: a,b c,d -> a,c a,d b,c b,d
|
||||
@@ -753,12 +725,15 @@ void StringToXapianQ::processSimpleSpan(const string& span, bool nostemexp,
|
||||
}
|
||||
|
||||
expandTerm(nostemexp, span, exp, sterm, prefix);
|
||||
|
||||
// m_terms is used for highlighting, we don't want prefixes in there.
|
||||
|
||||
// Set up the highlight data. No prefix should go in there
|
||||
for (vector<string>::const_iterator it = exp.begin();
|
||||
it != exp.end(); it++) {
|
||||
m_terms.push_back(it->substr(prefix.size()));
|
||||
m_hld.groups.push_back(vector<string>(1, it->substr(prefix.size())));
|
||||
m_hld.slacks.push_back(0);
|
||||
m_hld.grpsugidx.push_back(m_hld.ugroups.size() - 1);
|
||||
}
|
||||
|
||||
// Push either term or OR of stem-expanded set
|
||||
Xapian::Query xq(Xapian::Query::OP_OR, exp.begin(), exp.end());
|
||||
|
||||
@@ -786,7 +761,9 @@ void StringToXapianQ::processPhraseOrNear(TextSplitQ *splitData,
|
||||
Xapian::Query::op op = useNear ? Xapian::Query::OP_NEAR :
|
||||
Xapian::Query::OP_PHRASE;
|
||||
vector<Xapian::Query> orqueries;
|
||||
#ifdef XAPIAN_NEAR_EXPAND_SINGLE_BUF
|
||||
bool hadmultiple = false;
|
||||
#endif
|
||||
vector<vector<string> >groups;
|
||||
|
||||
string prefix;
|
||||
@@ -805,15 +782,19 @@ void StringToXapianQ::processPhraseOrNear(TextSplitQ *splitData,
|
||||
for (vector<string>::iterator it = splitData->terms.begin();
|
||||
it != splitData->terms.end(); it++, nxit++) {
|
||||
LOGDEB0(("ProcessPhrase: processing [%s]\n", it->c_str()));
|
||||
// Adjust when we do stem expansion. Not inside phrases, and
|
||||
// some versions of xapian will accept only one OR clause
|
||||
// inside NEAR, all others must be leafs.
|
||||
bool nostemexp = *nxit || (op == Xapian::Query::OP_PHRASE) || hadmultiple;
|
||||
// Adjust when we do stem expansion. Not if disabled by
|
||||
// caller, not inside phrases, and some versions of xapian
|
||||
// will accept only one OR clause inside NEAR.
|
||||
bool nostemexp = *nxit || (op == Xapian::Query::OP_PHRASE)
|
||||
#ifdef XAPIAN_NEAR_EXPAND_SINGLE_BUF
|
||||
|| hadmultiple
|
||||
#endif // single OR inside NEAR
|
||||
;
|
||||
|
||||
string sterm;
|
||||
vector<string> exp;
|
||||
expandTerm(nostemexp, *it, exp, sterm, prefix);
|
||||
LOGDEB0(("ProcessPhrase: exp size %d\n", exp.size()));
|
||||
LOGDEB0(("ProcessPhraseOrNear: exp size %d\n", exp.size()));
|
||||
listVector("", exp);
|
||||
// groups is used for highlighting, we don't want prefixes in there.
|
||||
vector<string> noprefs;
|
||||
@@ -850,7 +831,13 @@ void StringToXapianQ::processPhraseOrNear(TextSplitQ *splitData,
|
||||
vector<vector<string> > allcombs;
|
||||
vector<string> comb;
|
||||
multiply_groups(groups.begin(), groups.end(), comb, allcombs);
|
||||
m_groups.insert(m_groups.end(), allcombs.begin(), allcombs.end());
|
||||
|
||||
// Insert the search groups and slacks in the highlight data, with
|
||||
// a reference to the user entry that generated them:
|
||||
m_hld.groups.insert(m_hld.groups.end(), allcombs.begin(), allcombs.end());
|
||||
m_hld.slacks.insert(m_hld.slacks.end(), allcombs.size(), slack);
|
||||
m_hld.grpsugidx.insert(m_hld.grpsugidx.end(), allcombs.size(),
|
||||
m_hld.ugroups.size() - 1);
|
||||
}
|
||||
|
||||
// Trim string beginning with ^ or ending with $ and convert to flags
|
||||
@@ -875,7 +862,16 @@ static int stringToMods(string& s)
|
||||
* We just separate words and phrases, and do wildcard and stem expansion,
|
||||
*
|
||||
* This is used to process data entered into an OR/AND/NEAR/PHRASE field of
|
||||
* the GUI.
|
||||
* the GUI (in the case of NEAR/PHRASE, clausedist adds dquotes to the user
|
||||
* entry).
|
||||
*
|
||||
* This appears awful, and it would seem that the split into
|
||||
* terms/phrases should be performed in the upper layer so that we
|
||||
* only receive pure term or near/phrase pure elements here, but in
|
||||
* fact there are things that would appear like terms to naive code,
|
||||
* and which will actually may be turned into phrases (ie: tom:jerry),
|
||||
* in a manner which intimately depends on the index implementation,
|
||||
* so that it makes sense to process this here.
|
||||
*
|
||||
* The final list contains one query for each term or phrase
|
||||
* - Elements corresponding to a stem-expanded part are an OP_OR
|
||||
@@ -895,9 +891,6 @@ bool StringToXapianQ::processUserString(const string &iq,
|
||||
{
|
||||
LOGDEB(("StringToXapianQ:: query string: [%s], slack %d, near %d\n", iq.c_str(), slack, useNear));
|
||||
ermsg.erase();
|
||||
m_uterms.clear();
|
||||
m_terms.clear();
|
||||
m_groups.clear();
|
||||
|
||||
// Simple whitespace-split input into user-level words and
|
||||
// double-quoted phrases: word1 word2 "this is a phrase".
|
||||
@@ -952,10 +945,12 @@ bool StringToXapianQ::processUserString(const string &iq,
|
||||
case 0:
|
||||
continue;// ??
|
||||
case 1:
|
||||
m_hld.ugroups.push_back(vector<string>(1, *it));
|
||||
processSimpleSpan(splitter.terms.front(),
|
||||
splitter.nostemexps.front(), pqueries);
|
||||
break;
|
||||
default:
|
||||
m_hld.ugroups.push_back(vector<string>(1, *it));
|
||||
processPhraseOrNear(&splitter, pqueries, useNear, slack, mods);
|
||||
}
|
||||
}
|
||||
@@ -984,8 +979,6 @@ bool SearchDataClauseSimple::toNativeQuery(Rcl::Db &db, void *p,
|
||||
LOGDEB2(("SearchDataClauseSimple::toNativeQuery: stemlang [%s]\n",
|
||||
stemlang.c_str()));
|
||||
|
||||
m_terms.clear();
|
||||
m_groups.clear();
|
||||
Xapian::Query *qp = (Xapian::Query *)p;
|
||||
*qp = Xapian::Query();
|
||||
|
||||
@@ -1007,16 +1000,14 @@ bool SearchDataClauseSimple::toNativeQuery(Rcl::Db &db, void *p,
|
||||
(m_parentSearch && !m_parentSearch->haveWildCards()) ||
|
||||
(m_parentSearch == 0 && !m_haveWildCards);
|
||||
|
||||
StringToXapianQ tr(db, m_field, l_stemlang, doBoostUserTerm);
|
||||
StringToXapianQ tr(db, m_hldata, m_field, l_stemlang, doBoostUserTerm);
|
||||
if (!tr.processUserString(m_text, m_reason, pqueries, db.getStopList()))
|
||||
return false;
|
||||
if (pqueries.empty()) {
|
||||
LOGERR(("SearchDataClauseSimple: resolved to null query\n"));
|
||||
return true;
|
||||
}
|
||||
tr.getTerms(m_terms, m_groups);
|
||||
tr.getUTerms(m_uterms);
|
||||
//listVector("SearchDataClauseSimple: Uterms: ", m_uterms);
|
||||
|
||||
*qp = Xapian::Query(op, pqueries.begin(), pqueries.end());
|
||||
if (m_weight != 1.0) {
|
||||
*qp = Xapian::Query(Xapian::Query::OP_SCALE_WEIGHT, *qp, m_weight);
|
||||
@@ -1056,8 +1047,6 @@ bool SearchDataClauseDist::toNativeQuery(Rcl::Db &db, void *p,
|
||||
const string& l_stemlang = (m_modifiers&SDCM_NOSTEMMING)? cstr_null:
|
||||
stemlang;
|
||||
LOGDEB(("SearchDataClauseDist::toNativeQuery\n"));
|
||||
m_terms.clear();
|
||||
m_groups.clear();
|
||||
|
||||
Xapian::Query *qp = (Xapian::Query *)p;
|
||||
*qp = Xapian::Query();
|
||||
@@ -1080,7 +1069,7 @@ bool SearchDataClauseDist::toNativeQuery(Rcl::Db &db, void *p,
|
||||
}
|
||||
string s = cstr_dquote + m_text + cstr_dquote;
|
||||
bool useNear = (m_tp == SCLT_NEAR);
|
||||
StringToXapianQ tr(db, m_field, l_stemlang, doBoostUserTerm);
|
||||
StringToXapianQ tr(db, m_hldata, m_field, l_stemlang, doBoostUserTerm);
|
||||
if (!tr.processUserString(s, m_reason, pqueries, db.getStopList(),
|
||||
m_slack, useNear))
|
||||
return false;
|
||||
@@ -1088,8 +1077,7 @@ bool SearchDataClauseDist::toNativeQuery(Rcl::Db &db, void *p,
|
||||
LOGERR(("SearchDataClauseDist: resolved to null query\n"));
|
||||
return true;
|
||||
}
|
||||
tr.getTerms(m_terms, m_groups);
|
||||
tr.getUTerms(m_uterms);
|
||||
|
||||
*qp = *pqueries.begin();
|
||||
if (m_weight != 1.0) {
|
||||
*qp = Xapian::Query(Xapian::Query::OP_SCALE_WEIGHT, *qp, m_weight);
|
||||
@@ -1097,21 +1085,4 @@ bool SearchDataClauseDist::toNativeQuery(Rcl::Db &db, void *p,
|
||||
return true;
|
||||
}
|
||||
|
||||
// Translate subquery
|
||||
bool SearchDataClauseSub::toNativeQuery(Rcl::Db &db, void *p, const string&)
|
||||
{
|
||||
return m_sub->toNativeQuery(db, p);
|
||||
}
|
||||
|
||||
bool SearchDataClauseSub::getTerms(vector<string>& terms,
|
||||
vector<vector<string> >& groups,
|
||||
vector<int>& gslks) const
|
||||
{
|
||||
return m_sub.getconstptr()->getTerms(terms, groups, gslks);
|
||||
}
|
||||
void SearchDataClauseSub::getUTerms(vector<string>& terms) const
|
||||
{
|
||||
m_sub.getconstptr()->getUTerms(terms);
|
||||
}
|
||||
|
||||
} // Namespace Rcl
|
||||
|
||||
+136
-108
@@ -31,14 +31,11 @@
|
||||
#include "refcntr.h"
|
||||
#include "smallut.h"
|
||||
#include "cstr.h"
|
||||
#include "hldata.h"
|
||||
|
||||
class RclConfig;
|
||||
|
||||
#ifndef NO_NAMESPACES
|
||||
using std::vector;
|
||||
using std::string;
|
||||
namespace Rcl {
|
||||
#endif // NO_NAMESPACES
|
||||
|
||||
/** Search clause types */
|
||||
enum SClType {
|
||||
@@ -50,33 +47,33 @@ enum SClType {
|
||||
class SearchDataClause;
|
||||
|
||||
/**
|
||||
Data structure representing a Recoll user query, for translation
|
||||
into a Xapian query tree. This could probably better called a 'question'.
|
||||
Data structure representing a Recoll user query, for translation
|
||||
into a Xapian query tree. This could probably better called a 'question'.
|
||||
|
||||
This is a list of search clauses combined through either OR or AND.
|
||||
This is a list of search clauses combined through either OR or AND.
|
||||
|
||||
Clauses either reflect user entry in a query field: some text, a
|
||||
clause type (AND/OR/NEAR etc.), possibly a distance, or points to
|
||||
another SearchData representing a subquery.
|
||||
Clauses either reflect user entry in a query field: some text, a
|
||||
clause type (AND/OR/NEAR etc.), possibly a distance, or points to
|
||||
another SearchData representing a subquery.
|
||||
|
||||
The content of each clause when added may not be fully parsed yet
|
||||
(may come directly from a gui field). It will be parsed and may be
|
||||
translated to several queries in the Xapian sense, for exemple
|
||||
several terms and phrases as would result from
|
||||
["this is a phrase" term1 term2] .
|
||||
The content of each clause when added may not be fully parsed yet
|
||||
(may come directly from a gui field). It will be parsed and may be
|
||||
translated to several queries in the Xapian sense, for exemple
|
||||
several terms and phrases as would result from
|
||||
["this is a phrase" term1 term2] .
|
||||
|
||||
This is why the clauses also have an AND/OR/... type.
|
||||
This is why the clauses also have an AND/OR/... type.
|
||||
|
||||
A phrase clause could be added either explicitly or using double quotes:
|
||||
{SCLT_PHRASE, [this is a phrase]} or as {SCLT_XXX, ["this is a phrase"]}
|
||||
A phrase clause could be added either explicitly or using double quotes:
|
||||
{SCLT_PHRASE, [this is a phrase]} or as {SCLT_XXX, ["this is a phrase"]}
|
||||
|
||||
*/
|
||||
*/
|
||||
class SearchData {
|
||||
public:
|
||||
SearchData(SClType tp)
|
||||
: m_tp(tp), m_topdirexcl(false), m_topdirweight(1.0),
|
||||
m_haveDates(false), m_maxSize(size_t(-1)),
|
||||
m_minSize(size_t(-1)), m_haveWildCards(false)
|
||||
: m_tp(tp), m_topdirexcl(false), m_topdirweight(1.0),
|
||||
m_haveDates(false), m_maxSize(size_t(-1)),
|
||||
m_minSize(size_t(-1)), m_haveWildCards(false)
|
||||
{
|
||||
if (m_tp != SCLT_OR && m_tp != SCLT_AND)
|
||||
m_tp = SCLT_OR;
|
||||
@@ -108,7 +105,7 @@ public:
|
||||
bool maybeAddAutoPhrase(Rcl::Db &db, double threshold);
|
||||
|
||||
/** Set/get top subdirectory for filtering results */
|
||||
void setTopdir(const string& t, bool excl = false, float w = 1.0)
|
||||
void setTopdir(const std::string& t, bool excl = false, float w = 1.0)
|
||||
{
|
||||
m_topdir = t;
|
||||
m_topdirexcl = excl;
|
||||
@@ -122,38 +119,37 @@ public:
|
||||
void setDateSpan(DateInterval *dip) {m_dates = *dip; m_haveDates = true;}
|
||||
|
||||
/** Add file type for filtering results */
|
||||
void addFiletype(const string& ft) {m_filetypes.push_back(ft);}
|
||||
void addFiletype(const std::string& ft) {m_filetypes.push_back(ft);}
|
||||
/** Add file type to not wanted list */
|
||||
void remFiletype(const string& ft) {m_nfiletypes.push_back(ft);}
|
||||
void remFiletype(const std::string& ft) {m_nfiletypes.push_back(ft);}
|
||||
|
||||
void setStemlang(const string& lang = "english") {m_stemlang = lang;}
|
||||
void setStemlang(const std::string& lang = "english") {m_stemlang = lang;}
|
||||
|
||||
/** Retrieve error description */
|
||||
string getReason() {return m_reason;}
|
||||
std::string getReason() {return m_reason;}
|
||||
|
||||
/** Get terms and phrase/near groups. Used in the GUI for highlighting
|
||||
* The groups and gslks vectors are parallel and hold the phrases/near
|
||||
* string groups and their associated slacks (distance in excess of group
|
||||
* size)
|
||||
/** Return term expansion data. Mostly used by caller for highlighting
|
||||
*/
|
||||
bool getTerms(vector<string>& terms,
|
||||
vector<vector<string> >& groups, vector<int>& gslks) const;
|
||||
/** Get user-input terms (before expansion etc.) */
|
||||
void getUTerms(vector<string>& terms) const;
|
||||
void getTerms(HighlightData& hldata) const;
|
||||
|
||||
/**
|
||||
* Get/set the description field which is retrieved from xapian after
|
||||
* initializing the query. It is stored here for usage in the GUI.
|
||||
*/
|
||||
string getDescription() {return m_description;}
|
||||
void setDescription(const string& d) {m_description = d;}
|
||||
std::string getDescription() {return m_description;}
|
||||
void setDescription(const std::string& d) {m_description = d;}
|
||||
|
||||
private:
|
||||
SClType m_tp; // Only SCLT_AND or SCLT_OR here
|
||||
vector<SearchDataClause*> m_query;
|
||||
vector<string> m_filetypes; // Restrict to filetypes if set.
|
||||
vector<string> m_nfiletypes; // Unwanted file types
|
||||
string m_topdir; // Restrict to subtree.
|
||||
// Combine type. Only SCLT_AND or SCLT_OR here
|
||||
SClType m_tp;
|
||||
// Complex query descriptor
|
||||
std::vector<SearchDataClause*> m_query;
|
||||
// Restricted set of filetypes if not empty.
|
||||
std::vector<std::string> m_filetypes;
|
||||
// Excluded set of file types if not empty
|
||||
std::vector<std::string> m_nfiletypes;
|
||||
// Restrict to subtree.
|
||||
std::string m_topdir;
|
||||
bool m_topdirexcl; // Invert meaning
|
||||
float m_topdirweight; // affect weight instead of filter
|
||||
bool m_haveDates;
|
||||
@@ -162,11 +158,11 @@ private:
|
||||
size_t m_minSize;
|
||||
// Printable expanded version of the complete query, retrieved/set
|
||||
// from rcldb after the Xapian::setQuery() call
|
||||
string m_description;
|
||||
string m_reason;
|
||||
std::string m_description;
|
||||
std::string m_reason;
|
||||
bool m_haveWildCards;
|
||||
string m_stemlang;
|
||||
bool expandFileTypes(RclConfig *cfg, vector<string>& exptps);
|
||||
std::string m_stemlang;
|
||||
bool expandFileTypes(RclConfig *cfg, std::vector<std::string>& exptps);
|
||||
/* Copyconst and assignment private and forbidden */
|
||||
SearchData(const SearchData &) {}
|
||||
SearchData& operator=(const SearchData&) {return *this;};
|
||||
@@ -178,39 +174,56 @@ public:
|
||||
SDCM_ANCHOREND=4};
|
||||
|
||||
SearchDataClause(SClType tp)
|
||||
: m_tp(tp), m_parentSearch(0), m_haveWildCards(0),
|
||||
m_modifiers(SDCM_NONE), m_weight(1.0)
|
||||
: m_tp(tp), m_parentSearch(0), m_haveWildCards(0),
|
||||
m_modifiers(SDCM_NONE), m_weight(1.0)
|
||||
{}
|
||||
virtual ~SearchDataClause() {}
|
||||
virtual bool toNativeQuery(Rcl::Db &db, void *, const string&) = 0;
|
||||
virtual bool toNativeQuery(Rcl::Db &db, void *, const std::string&) = 0;
|
||||
bool isFileName() const {return m_tp == SCLT_FILENAME ? true: false;}
|
||||
virtual string getReason() const {return m_reason;}
|
||||
virtual bool getTerms(vector<string>&, vector<vector<string> >&,
|
||||
vector<int>&) const = 0;
|
||||
virtual void getUTerms(vector<string>&) const = 0;
|
||||
virtual std::string getReason() const {return m_reason;}
|
||||
virtual void getTerms(HighlightData & hldata) const = 0;
|
||||
|
||||
SClType getTp() {return m_tp;}
|
||||
void setParent(SearchData *p) {m_parentSearch = p;}
|
||||
virtual void setModifiers(Modifier mod) {m_modifiers = mod;}
|
||||
virtual int getModifiers() {return m_modifiers;}
|
||||
virtual void addModifier(Modifier mod) {
|
||||
SClType getTp()
|
||||
{
|
||||
return m_tp;
|
||||
}
|
||||
void setParent(SearchData *p)
|
||||
{
|
||||
m_parentSearch = p;
|
||||
}
|
||||
virtual void setModifiers(Modifier mod)
|
||||
{
|
||||
m_modifiers = mod;
|
||||
}
|
||||
virtual int getModifiers()
|
||||
{
|
||||
return m_modifiers;
|
||||
}
|
||||
virtual void addModifier(Modifier mod)
|
||||
{
|
||||
int imod = getModifiers();
|
||||
imod |= mod;
|
||||
setModifiers(Modifier(imod));
|
||||
}
|
||||
virtual void setWeight(float w) {m_weight = w;}
|
||||
virtual void setWeight(float w)
|
||||
{
|
||||
m_weight = w;
|
||||
}
|
||||
friend class SearchData;
|
||||
|
||||
protected:
|
||||
string m_reason;
|
||||
std::string m_reason;
|
||||
SClType m_tp;
|
||||
SearchData *m_parentSearch;
|
||||
bool m_haveWildCards;
|
||||
Modifier m_modifiers;
|
||||
float m_weight;
|
||||
private:
|
||||
SearchDataClause(const SearchDataClause&) {}
|
||||
SearchDataClause& operator=(const SearchDataClause&) {
|
||||
SearchDataClause(const SearchDataClause&)
|
||||
{
|
||||
}
|
||||
SearchDataClause& operator=(const SearchDataClause&)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
@@ -221,45 +234,37 @@ private:
|
||||
*/
|
||||
class SearchDataClauseSimple : public SearchDataClause {
|
||||
public:
|
||||
SearchDataClauseSimple(SClType tp, const string& txt,
|
||||
const string& fld = string())
|
||||
: SearchDataClause(tp), m_text(txt), m_field(fld), m_slack(0) {
|
||||
m_haveWildCards = (txt.find_first_of(cstr_minwilds) != string::npos);
|
||||
SearchDataClauseSimple(SClType tp, const std::string& txt,
|
||||
const std::string& fld = std::string())
|
||||
: SearchDataClause(tp), m_text(txt), m_field(fld)
|
||||
{
|
||||
m_haveWildCards =
|
||||
(txt.find_first_of(cstr_minwilds) != std::string::npos);
|
||||
}
|
||||
|
||||
virtual ~SearchDataClauseSimple() {}
|
||||
virtual ~SearchDataClauseSimple()
|
||||
{
|
||||
}
|
||||
|
||||
/** Translate to Xapian query */
|
||||
virtual bool toNativeQuery(Rcl::Db &db, void *, const string& stemlang);
|
||||
virtual bool toNativeQuery(Rcl::Db &, void *, const std::string& stemlang);
|
||||
|
||||
/** Retrieve query terms and term groups. This is used for highlighting */
|
||||
virtual bool getTerms(vector<string>& terms, /* Single terms */
|
||||
vector<vector<string> >& groups, /* Prox grps */
|
||||
vector<int>& gslks) const /* Prox slacks */
|
||||
virtual void getTerms(HighlightData& hldata) const
|
||||
{
|
||||
terms.insert(terms.end(), m_terms.begin(), m_terms.end());
|
||||
groups.insert(groups.end(), m_groups.begin(), m_groups.end());
|
||||
gslks.insert(gslks.end(), m_groups.size(), m_slack);
|
||||
return true;
|
||||
hldata.append(m_hldata);
|
||||
}
|
||||
virtual void getUTerms(vector<string>& terms) const
|
||||
virtual const std::string& gettext()
|
||||
{
|
||||
terms.insert(terms.end(), m_uterms.begin(), m_uterms.end());
|
||||
return m_text;
|
||||
}
|
||||
virtual const std::string& getfield()
|
||||
{
|
||||
return m_field;
|
||||
}
|
||||
virtual const string& gettext() {return m_text;}
|
||||
virtual const string& getfield() {return m_field;}
|
||||
protected:
|
||||
string m_text; // Raw user entry text.
|
||||
string m_field; // Field specification if any
|
||||
// Single terms and phrases resulting from breaking up m_text;
|
||||
// valid after toNativeQuery() call
|
||||
vector<string> m_terms;
|
||||
vector<vector<string> > m_groups;
|
||||
// User terms before expansion
|
||||
vector<string> m_uterms;
|
||||
// Declare m_slack here. Always 0, but allows getTerms to work for
|
||||
// SearchDataClauseDist
|
||||
int m_slack;
|
||||
std::string m_text; // Raw user entry text.
|
||||
std::string m_field; // Field specification if any
|
||||
HighlightData m_hldata;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -272,29 +277,39 @@ protected:
|
||||
*/
|
||||
class SearchDataClauseFilename : public SearchDataClauseSimple {
|
||||
public:
|
||||
SearchDataClauseFilename(const string& txt)
|
||||
: SearchDataClauseSimple(SCLT_FILENAME, txt) {
|
||||
SearchDataClauseFilename(const std::string& txt)
|
||||
: SearchDataClauseSimple(SCLT_FILENAME, txt)
|
||||
{
|
||||
// File name searches don't count when looking for wild cards.
|
||||
m_haveWildCards = false;
|
||||
}
|
||||
virtual ~SearchDataClauseFilename() {}
|
||||
virtual bool toNativeQuery(Rcl::Db &db, void *, const string& stemlang);
|
||||
|
||||
virtual ~SearchDataClauseFilename()
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool toNativeQuery(Rcl::Db &, void *, const std::string& stemlang);
|
||||
};
|
||||
|
||||
/**
|
||||
* A clause coming from a NEAR or PHRASE entry field. There is only one
|
||||
* string group, and a specified distance, which applies to it.
|
||||
* std::string group, and a specified distance, which applies to it.
|
||||
*/
|
||||
class SearchDataClauseDist : public SearchDataClauseSimple {
|
||||
public:
|
||||
SearchDataClauseDist(SClType tp, const string& txt, int slack,
|
||||
const string& fld = string())
|
||||
: SearchDataClauseSimple(tp, txt, fld) {m_slack = slack;}
|
||||
virtual ~SearchDataClauseDist() {}
|
||||
SearchDataClauseDist(SClType tp, const std::string& txt, int slack,
|
||||
const std::string& fld = std::string())
|
||||
: SearchDataClauseSimple(tp, txt, fld), m_slack(slack)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool toNativeQuery(Rcl::Db &db, void *, const string& stemlang);
|
||||
virtual ~SearchDataClauseDist()
|
||||
{
|
||||
}
|
||||
|
||||
// m_slack is declared in SearchDataClauseSimple
|
||||
virtual bool toNativeQuery(Rcl::Db &, void *, const std::string& stemlang);
|
||||
private:
|
||||
int m_slack;
|
||||
};
|
||||
|
||||
/** Subquery */
|
||||
@@ -302,15 +317,28 @@ class SearchDataClauseSub : public SearchDataClause {
|
||||
public:
|
||||
// We take charge of the SearchData * and will delete it.
|
||||
SearchDataClauseSub(SClType tp, RefCntr<SearchData> sub)
|
||||
: SearchDataClause(tp), m_sub(sub) {}
|
||||
virtual ~SearchDataClauseSub() {}
|
||||
virtual bool toNativeQuery(Rcl::Db &db, void *, const string& stemlang);
|
||||
virtual bool getTerms(vector<string>&, vector<vector<string> >&,
|
||||
vector<int>&) const;
|
||||
virtual void getUTerms(vector<string>&) const;
|
||||
: SearchDataClause(tp), m_sub(sub)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~SearchDataClauseSub()
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool toNativeQuery(Rcl::Db &db, void *p, const std::string&)
|
||||
{
|
||||
return m_sub->toNativeQuery(db, p);
|
||||
}
|
||||
|
||||
virtual void getTerms(HighlightData& hldata) const
|
||||
{
|
||||
m_sub.getconstptr()->getTerms(hldata);
|
||||
}
|
||||
|
||||
protected:
|
||||
RefCntr<SearchData> m_sub;
|
||||
};
|
||||
|
||||
} // Namespace Rcl
|
||||
|
||||
#endif /* _SEARCHDATA_H_INCLUDED_ */
|
||||
|
||||
Reference in New Issue
Block a user