define new searchdataclausepath to replace the old dir: filtering mechanism. ORing dirs now works
This commit is contained in:
@@ -64,10 +64,11 @@ void WasaQuery::describe(string &desc) const
|
||||
desc += "NULL";
|
||||
break;
|
||||
case OP_LEAF:
|
||||
if (m_exclude)
|
||||
desc += "NOT (";
|
||||
desc += fieldspec + m_value;
|
||||
break;
|
||||
case OP_EXCL:
|
||||
desc += string("NOT (" ) + fieldspec + m_value + ") ";
|
||||
if (m_exclude)
|
||||
desc += ")";
|
||||
break;
|
||||
case OP_OR:
|
||||
case OP_AND:
|
||||
@@ -429,11 +430,12 @@ StringToWasaQuery::Internal::stringToQuery(const string& str, string& reason)
|
||||
}
|
||||
}
|
||||
|
||||
nclause->m_op = WasaQuery::OP_LEAF;
|
||||
// +- indicator ?
|
||||
if (checkSubMatch(SMI_PM, match, reason) && match[0] == '-') {
|
||||
nclause->m_op = WasaQuery::OP_EXCL;
|
||||
nclause->m_exclude = true;
|
||||
} else {
|
||||
nclause->m_op = WasaQuery::OP_LEAF;
|
||||
nclause->m_exclude = false;
|
||||
}
|
||||
|
||||
if (prev_or) {
|
||||
|
||||
@@ -48,7 +48,7 @@ using std::vector;
|
||||
class WasaQuery {
|
||||
public:
|
||||
/** Type of this element: leaf or AND/OR chain */
|
||||
enum Op {OP_NULL, OP_LEAF, OP_EXCL, OP_OR, OP_AND};
|
||||
enum Op {OP_NULL, OP_LEAF, OP_OR, OP_AND};
|
||||
/** Relation to be searched between field and value. Recoll actually only
|
||||
supports "contain" except for a size field */
|
||||
enum Rel {REL_NULL, REL_EQUALS, REL_CONTAINS, REL_LT, REL_LTE,
|
||||
@@ -63,7 +63,8 @@ public:
|
||||
typedef vector<WasaQuery*> subqlist_t;
|
||||
|
||||
WasaQuery()
|
||||
: m_op(OP_NULL), m_modifiers(0), m_slack(0), m_weight(1.0)
|
||||
: m_op(OP_NULL), m_rel(REL_NULL), m_exclude(false),
|
||||
m_modifiers(0), m_slack(0), m_weight(1.0)
|
||||
{}
|
||||
|
||||
~WasaQuery();
|
||||
@@ -79,6 +80,9 @@ public:
|
||||
/** Relation between field and value: =, :, <,>,<=, >= */
|
||||
WasaQuery::Rel m_rel;
|
||||
|
||||
/* Negating flag */
|
||||
bool m_exclude;
|
||||
|
||||
/* String value. Valid for op == OP_LEAF or EXCL */
|
||||
string m_value;
|
||||
|
||||
|
||||
+51
-61
@@ -64,11 +64,13 @@ static Rcl::SearchData *wasaQueryToRcl(const RclConfig *config,
|
||||
if (!stringicmp("mime", (*it)->m_fieldspec) ||
|
||||
!stringicmp("format", (*it)->m_fieldspec)) {
|
||||
if ((*it)->m_op == WasaQuery::OP_LEAF) {
|
||||
sdata->addFiletype((*it)->m_value);
|
||||
} else if ((*it)->m_op == WasaQuery::OP_EXCL) {
|
||||
sdata->remFiletype((*it)->m_value);
|
||||
if ((*it)->m_exclude) {
|
||||
sdata->remFiletype((*it)->m_value);
|
||||
} else {
|
||||
sdata->addFiletype((*it)->m_value);
|
||||
}
|
||||
} else {
|
||||
reason = "internal error: mime clause neither leaf not excl??";
|
||||
reason = "internal error: mime clause not leaf??";
|
||||
return 0;
|
||||
}
|
||||
continue;
|
||||
@@ -78,10 +80,8 @@ static Rcl::SearchData *wasaQueryToRcl(const RclConfig *config,
|
||||
// categories like "audio", "presentation", etc.
|
||||
if (!stringicmp("rclcat", (*it)->m_fieldspec) ||
|
||||
!stringicmp("type", (*it)->m_fieldspec)) {
|
||||
if ((*it)->m_op != WasaQuery::OP_LEAF &&
|
||||
(*it)->m_op != WasaQuery::OP_EXCL) {
|
||||
reason = "internal error: rclcat/type clause neither leaf"
|
||||
"nor excl??";
|
||||
if ((*it)->m_op != WasaQuery::OP_LEAF) {
|
||||
reason = "internal error: rclcat/type clause not leaf??";
|
||||
return 0;
|
||||
}
|
||||
vector<string> mtypes;
|
||||
@@ -89,10 +89,11 @@ static Rcl::SearchData *wasaQueryToRcl(const RclConfig *config,
|
||||
&& !mtypes.empty()) {
|
||||
for (vector<string>::iterator mit = mtypes.begin();
|
||||
mit != mtypes.end(); mit++) {
|
||||
if ((*it)->m_op == WasaQuery::OP_LEAF)
|
||||
sdata->addFiletype(*mit);
|
||||
else
|
||||
if ((*it)->m_exclude) {
|
||||
sdata->remFiletype(*mit);
|
||||
} else {
|
||||
sdata->addFiletype(*mit);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reason = "Unknown rclcat/type value: no mime types found";
|
||||
@@ -101,14 +102,6 @@ static Rcl::SearchData *wasaQueryToRcl(const RclConfig *config,
|
||||
continue;
|
||||
}
|
||||
|
||||
// Filtering on location
|
||||
if (!stringicmp("dir", (*it)->m_fieldspec)) {
|
||||
string dir = path_tildexpand((*it)->m_value);
|
||||
sdata->addDirSpec(dir, (*it)->m_op == WasaQuery::OP_EXCL,
|
||||
(*it)->m_weight);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle "date" spec
|
||||
if (!stringicmp("date", (*it)->m_fieldspec)) {
|
||||
if ((*it)->m_op != WasaQuery::OP_LEAF) {
|
||||
@@ -181,9 +174,9 @@ static Rcl::SearchData *wasaQueryToRcl(const RclConfig *config,
|
||||
continue;
|
||||
|
||||
case WasaQuery::OP_LEAF: {
|
||||
LOGDEB0(("wasaQueryToRcl: leaf clause [%s]:[%s] slack %d\n",
|
||||
(*it)->m_fieldspec.c_str(), (*it)->m_value.c_str(),
|
||||
(*it)->m_slack));
|
||||
LOGDEB0(("wasaQueryToRcl: leaf clause [%s:%s] slack %d excl %d\n",
|
||||
(*it)->m_fieldspec.c_str(), (*it)->m_value.c_str(),
|
||||
(*it)->m_slack, (*it)->m_exclude));
|
||||
|
||||
// Change terms found in the "autosuffs" list into "ext"
|
||||
// field queries
|
||||
@@ -198,23 +191,45 @@ static Rcl::SearchData *wasaQueryToRcl(const RclConfig *config,
|
||||
}
|
||||
}
|
||||
|
||||
// I'm not sure I understand the phrase/near detection
|
||||
// thereafter anymore, maybe it would be better to have an
|
||||
// explicit flag. Mods can only be set after a double
|
||||
// quote.
|
||||
if (TextSplit::hasVisibleWhite((*it)->m_value) || mods) {
|
||||
Rcl::SClType tp = Rcl::SCLT_PHRASE;
|
||||
if (mods & WasaQuery::WQM_PROX) {
|
||||
tp = Rcl::SCLT_NEAR;
|
||||
if (!stringicmp("dir", (*it)->m_fieldspec)) {
|
||||
// dir filtering special case
|
||||
nclause = new Rcl::SearchDataClausePath((*it)->m_value,
|
||||
(*it)->m_exclude);
|
||||
} else if ((*it)->m_exclude) {
|
||||
if (wasa->m_op != WasaQuery::OP_AND) {
|
||||
LOGERR(("wasaQueryToRcl: excl clause inside OR list!\n"));
|
||||
continue;
|
||||
}
|
||||
nclause = new Rcl::SearchDataClauseDist(tp, (*it)->m_value,
|
||||
(*it)->m_slack,
|
||||
(*it)->m_fieldspec);
|
||||
} else {
|
||||
nclause = new Rcl::SearchDataClauseSimple(Rcl::SCLT_AND,
|
||||
(*it)->m_value,
|
||||
// Note: have to add dquotes which will be translated to
|
||||
// phrase if there are several words in there. Not pretty
|
||||
// but should work. If there is actually a single
|
||||
// word, it will not be taken as a phrase, and
|
||||
// stem-expansion will work normally
|
||||
// Have to do this because searchdata has nothing like and_not
|
||||
nclause = new Rcl::SearchDataClauseSimple(Rcl::SCLT_EXCL,
|
||||
string("\"") +
|
||||
(*it)->m_value + "\"",
|
||||
(*it)->m_fieldspec);
|
||||
} else {
|
||||
// I'm not sure I understand the phrase/near detection
|
||||
// thereafter anymore, maybe it would be better to have an
|
||||
// explicit flag. Mods can only be set after a double
|
||||
// quote.
|
||||
if (TextSplit::hasVisibleWhite((*it)->m_value) || mods) {
|
||||
Rcl::SClType tp = Rcl::SCLT_PHRASE;
|
||||
if (mods & WasaQuery::WQM_PROX) {
|
||||
tp = Rcl::SCLT_NEAR;
|
||||
}
|
||||
nclause = new Rcl::SearchDataClauseDist(tp, (*it)->m_value,
|
||||
(*it)->m_slack,
|
||||
(*it)->m_fieldspec);
|
||||
} else {
|
||||
nclause = new Rcl::SearchDataClauseSimple(Rcl::SCLT_AND,
|
||||
(*it)->m_value,
|
||||
(*it)->m_fieldspec);
|
||||
}
|
||||
}
|
||||
|
||||
if (nclause == 0) {
|
||||
reason = "Out of memory";
|
||||
LOGERR(("wasaQueryToRcl: out of memory\n"));
|
||||
@@ -223,31 +238,6 @@ static Rcl::SearchData *wasaQueryToRcl(const RclConfig *config,
|
||||
}
|
||||
break;
|
||||
|
||||
case WasaQuery::OP_EXCL:
|
||||
LOGDEB2(("wasaQueryToRcl: excl clause [%s]:[%s]\n",
|
||||
(*it)->m_fieldspec.c_str(), (*it)->m_value.c_str()));
|
||||
if (wasa->m_op != WasaQuery::OP_AND) {
|
||||
LOGERR(("wasaQueryToRcl: negative clause inside OR list!\n"));
|
||||
continue;
|
||||
}
|
||||
// Note: have to add dquotes which will be translated to
|
||||
// phrase if there are several words in there. Not pretty
|
||||
// but should work. If there is actually a single
|
||||
// word, it will not be taken as a phrase, and
|
||||
// stem-expansion will work normally
|
||||
// Have to do this because searchdata has nothing like and_not
|
||||
nclause = new Rcl::SearchDataClauseSimple(Rcl::SCLT_EXCL,
|
||||
string("\"") +
|
||||
(*it)->m_value + "\"",
|
||||
(*it)->m_fieldspec);
|
||||
|
||||
if (nclause == 0) {
|
||||
reason = "Out of memory";
|
||||
LOGERR(("wasaQueryToRcl: out of memory\n"));
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case WasaQuery::OP_OR:
|
||||
LOGDEB2(("wasaQueryToRcl: OR clause [%s]:[%s]\n",
|
||||
(*it)->m_fieldspec.c_str(), (*it)->m_value.c_str()));
|
||||
|
||||
Reference in New Issue
Block a user