--- a/src/rcldb/searchdata.h
+++ b/src/rcldb/searchdata.h
@@ -48,13 +48,15 @@
class SearchDataClause;
/**
- Data structure representing a Recoll user query, for translation
+ A SearchData object represents 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 SearchDataClause objects 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
+ clause type (AND/OR/NEAR etc.), possibly a distance, or are the
+ result of parsing query language input. A clause can also point to
another SearchData representing a subquery.
The content of each clause when added may not be fully parsed yet
@@ -63,28 +65,34 @@
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.
-
- 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"]}
+ This is why the clauses also have an AND/OR/... type. They are an
+ intermediate form between the primary user input and
+ the final Xapian::Query tree.
+
+ For example, 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, const string& stemlang)
- : m_tp(tp), m_haveDates(false), m_maxSize(size_t(-1)),
- m_minSize(size_t(-1)), m_haveWildCards(false), m_stemlang(stemlang)
+ : m_tp(tp), m_stemlang(stemlang)
{
if (m_tp != SCLT_OR && m_tp != SCLT_AND)
m_tp = SCLT_OR;
+ commoninit();
}
SearchData()
- : m_tp(SCLT_AND), m_haveDates(false), m_maxSize(size_t(-1)),
- m_minSize(size_t(-1)), m_haveWildCards(false), m_stemlang("english")
- {
+ : m_tp(SCLT_AND), m_stemlang("english")
+ {
+ commoninit();
}
- ~SearchData() {erase();}
+ ~SearchData()
+ {
+ erase();
+ }
/** Make pristine */
void erase();
@@ -96,7 +104,7 @@
bool haveWildCards() {return m_haveWildCards;}
/** Translate to Xapian query. rcldb knows about the void* */
- bool toNativeQuery(Rcl::Db &db, void *, int maxexp, int maxcl);
+ bool toNativeQuery(Rcl::Db &db, void *);
/** We become the owner of cl and will delete it */
bool addClause(SearchDataClause *cl);
@@ -143,12 +151,26 @@
std::string getDescription() {return m_description;}
void setDescription(const std::string& d) {m_description = d;}
+ /** Return an XML version of the contents, for storage in search history
+ by the GUI */
string asXML();
+
void setTp(SClType tp)
{
m_tp = tp;
}
+
+ void setMaxExpand(int max)
+ {
+ m_softmaxexpand = max;
+ }
+ bool getAutoDiac() {return m_autodiacsens;}
+ bool getAutoCase() {return m_autocasesens;}
+ int getMaxExp() {return m_maxexp;}
+ int getMaxCl() {return m_maxcl;}
+
friend class ::AdvSearch;
+
private:
// Combine type. Only SCLT_AND or SCLT_OR here
SClType m_tp;
@@ -184,10 +206,26 @@
bool m_haveWildCards;
std::string m_stemlang;
+ // Parameters set at the start of ToNativeQuery because they need
+ // an rclconfig. Actually this does not make sense and it would be
+ // simpler to just pass an rclconfig to the constructor;
+ bool m_autodiacsens;
+ bool m_autocasesens;
+ int m_maxexp;
+ int m_maxcl;
+
+ // Parameters which are not part of the main query data but may influence
+ // translation in special cases.
+ // Maximum TermMatch (e.g. wildcard) expansion. This is normally set
+ // from the configuration with a high default, but may be set to a lower
+ // value during "find-as-you-type" operations from the GUI
+ int m_softmaxexpand;
+
bool expandFileTypes(RclConfig *cfg, std::vector<std::string>& exptps);
bool clausesToQuery(Rcl::Db &db, SClType tp,
std::vector<SearchDataClause*>& query,
- string& reason, void *d, int, int);
+ string& reason, void *d);
+ void commoninit();
/* Copyconst and assignment private and forbidden */
SearchData(const SearchData &) {}
@@ -204,7 +242,7 @@
m_modifiers(SDCM_NONE), m_weight(1.0)
{}
virtual ~SearchDataClause() {}
- virtual bool toNativeQuery(Rcl::Db &db, void *, int maxexp, int maxcl) = 0;
+ virtual bool toNativeQuery(Rcl::Db &db, void *) = 0;
bool isFileName() const {return m_tp == SCLT_FILENAME ? true: false;}
virtual std::string getReason() const {return m_reason;}
virtual void getTerms(HighlightData & hldata) const = 0;
@@ -221,6 +259,22 @@
{
return (m_modifiers & SDCM_NOSTEMMING) || m_parentSearch == 0 ?
cstr_null : m_parentSearch->getStemLang();
+ }
+ bool getAutoDiac()
+ {
+ return m_parentSearch ? m_parentSearch->getAutoDiac() : false;
+ }
+ bool getAutoCase()
+ {
+ return m_parentSearch ? m_parentSearch->getAutoCase() : true;
+ }
+ int getMaxExp()
+ {
+ return m_parentSearch ? m_parentSearch->getMaxExp() : 10000;
+ }
+ int getMaxCl()
+ {
+ return m_parentSearch ? m_parentSearch->getMaxCl() : 100000;
}
virtual void setModifiers(Modifier mod)
{
@@ -263,6 +317,7 @@
* "Simple" data clause with user-entered query text. This can include
* multiple phrases and words, but no specified distance.
*/
+class TextSplitQ;
class SearchDataClauseSimple : public SearchDataClause {
public:
SearchDataClauseSimple(SClType tp, const std::string& txt,
@@ -278,7 +333,7 @@
}
/** Translate to Xapian query */
- virtual bool toNativeQuery(Rcl::Db &, void *, int maxexp, int maxcl);
+ virtual bool toNativeQuery(Rcl::Db &, void *);
virtual void getTerms(HighlightData& hldata) const
{
@@ -296,6 +351,21 @@
std::string m_text; // Raw user entry text.
std::string m_field; // Field specification if any
HighlightData m_hldata;
+ int m_curcl;
+
+ bool processUserString(Rcl::Db &db, const string &iq, int mods,
+ std::string &ermsg,
+ void* pq, int slack = 0, bool useNear = false);
+ bool expandTerm(Rcl::Db &db, std::string& ermsg, int mods,
+ const std::string& term,
+ std::vector<std::string>& exp,
+ std::string& sterm, const std::string& prefix);
+ // After splitting entry on whitespace: process non-phrase element
+ void processSimpleSpan(Rcl::Db &db, string& ermsg, const string& span,
+ int mods, void *pq);
+ // Process phrase/near element
+ void processPhraseOrNear(Rcl::Db &db, string& ermsg, TextSplitQ *splitData,
+ int mods, void *pq, bool useNear, int slack);
};
/**
@@ -306,10 +376,10 @@
* field, especially for file names, because this makes searches for
* "*xx" much faster (no need to scan the whole main index).
*/
-class SearchDataClauseFilename : public SearchDataClauseSimple {
+class SearchDataClauseFilename : public SearchDataClause {
public:
SearchDataClauseFilename(const std::string& txt)
- : SearchDataClauseSimple(SCLT_FILENAME, txt)
+ : SearchDataClause(SCLT_FILENAME), m_text(txt)
{
// File name searches don't count when looking for wild cards.
m_haveWildCards = false;
@@ -319,7 +389,14 @@
{
}
- virtual bool toNativeQuery(Rcl::Db &, void *, int maxexp, int maxcl);
+ virtual void getTerms(HighlightData&) const
+ {
+ }
+
+ virtual bool toNativeQuery(Rcl::Db &, void *);
+
+protected:
+ std::string m_text;
};
/**
@@ -338,7 +415,7 @@
{
}
- virtual bool toNativeQuery(Rcl::Db &, void *, int maxexp, int maxcl);
+ virtual bool toNativeQuery(Rcl::Db &, void *);
virtual int getslack() const
{
return m_slack;
@@ -354,9 +431,9 @@
: SearchDataClause(tp), m_sub(sub)
{
}
- virtual bool toNativeQuery(Rcl::Db &db, void *p, int maxexp, int maxcl)
- {
- bool ret = m_sub->toNativeQuery(db, p, maxexp, maxcl);
+ virtual bool toNativeQuery(Rcl::Db &db, void *p)
+ {
+ bool ret = m_sub->toNativeQuery(db, p);
if (!ret)
m_reason = m_sub->getReason();
return ret;