allow multiple directory specs as in dir:/home/me -dir:tmp

This commit is contained in:
Jean-Francois Dockes 2012-08-19 08:27:12 +02:00
parent 6c5272ddaa
commit bce82def6f
5 changed files with 37 additions and 29 deletions

View file

@ -25,7 +25,7 @@
#include "debuglog.h" #include "debuglog.h"
bool subtreelist(RclConfig *config, const string& top, bool subtreelist(RclConfig *config, const string& top,
vector<string>& paths) vector<string>& paths)
{ {
LOGDEB(("subtreelist: top: [%s]\n", top.c_str())); LOGDEB(("subtreelist: top: [%s]\n", top.c_str()));
Rcl::Db rcldb(config); Rcl::Db rcldb(config);
@ -38,7 +38,7 @@ bool subtreelist(RclConfig *config, const string& top,
Rcl::SearchData *sd = new Rcl::SearchData(Rcl::SCLT_OR); Rcl::SearchData *sd = new Rcl::SearchData(Rcl::SCLT_OR);
RefCntr<Rcl::SearchData> rq(sd); RefCntr<Rcl::SearchData> rq(sd);
rq->setTopdir(top); rq->addDirSpec(top);
Rcl::Query query(&rcldb); Rcl::Query query(&rcldb);
query.setQuery(rq); query.setQuery(rq);

View file

@ -417,8 +417,8 @@ void AdvSearch::runSearch()
if (!subtreeCMB->currentText().isEmpty()) { if (!subtreeCMB->currentText().isEmpty()) {
QString current = subtreeCMB->currentText(); QString current = subtreeCMB->currentText();
sdata->setTopdir((const char*)subtreeCMB->currentText().toUtf8(), sdata->addDirSpec((const char*)subtreeCMB->currentText().toUtf8(),
direxclCB->isChecked()); direxclCB->isChecked());
// Keep history clean and sorted. Maybe there would be a // Keep history clean and sorted. Maybe there would be a
// simpler way to do this // simpler way to do this
list<QString> entries; list<QString> entries;

View file

@ -102,8 +102,8 @@ static Rcl::SearchData *wasaQueryToRcl(RclConfig *config, WasaQuery *wasa,
// Filtering on location // Filtering on location
if (!stringicmp("dir", (*it)->m_fieldspec)) { if (!stringicmp("dir", (*it)->m_fieldspec)) {
string dir = path_tildexpand((*it)->m_value); string dir = path_tildexpand((*it)->m_value);
sdata->setTopdir(dir, (*it)->m_op == WasaQuery::OP_EXCL, sdata->addDirSpec(dir, (*it)->m_op == WasaQuery::OP_EXCL,
(*it)->m_weight); (*it)->m_weight);
continue; continue;
} }

View file

@ -320,29 +320,30 @@ bool SearchData::toNativeQuery(Rcl::Db &db, void *d)
// Add the directory filtering clause. This is a phrase of terms // Add the directory filtering clause. This is a phrase of terms
// prefixed with the pathelt prefix XP // prefixed with the pathelt prefix XP
if (!m_topdir.empty()) { for (vector<DirSpec>::const_iterator dit = m_dirspecs.begin();
dit != m_dirspecs.end(); dit++) {
vector<string> vpath; vector<string> vpath;
stringToTokens(m_topdir, vpath, "/"); stringToTokens(dit->dir, vpath, "/");
vector<string> pvpath; vector<string> pvpath;
if (m_topdir[0] == '/') if (dit->dir[0] == '/')
pvpath.push_back(pathelt_prefix); pvpath.push_back(pathelt_prefix);
for (vector<string>::const_iterator it = vpath.begin(); for (vector<string>::const_iterator pit = vpath.begin();
it != vpath.end(); it++){ pit != vpath.end(); pit++){
pvpath.push_back(pathelt_prefix + *it); pvpath.push_back(pathelt_prefix + *pit);
} }
Xapian::Query::op tdop; Xapian::Query::op tdop;
if (m_topdirweight == 1.0) { if (dit->weight == 1.0) {
tdop = m_topdirexcl ? tdop = dit->exclude ?
Xapian::Query::OP_AND_NOT : Xapian::Query::OP_FILTER; Xapian::Query::OP_AND_NOT : Xapian::Query::OP_FILTER;
} else { } else {
tdop = m_topdirexcl ? tdop = dit->exclude ?
Xapian::Query::OP_AND_NOT : Xapian::Query::OP_AND_MAYBE; Xapian::Query::OP_AND_NOT : Xapian::Query::OP_AND_MAYBE;
} }
Xapian::Query tdq = Xapian::Query(Xapian::Query::OP_PHRASE, Xapian::Query tdq = Xapian::Query(Xapian::Query::OP_PHRASE,
pvpath.begin(), pvpath.end()); pvpath.begin(), pvpath.end());
if (m_topdirweight != 1.0) if (dit->weight != 1.0)
tdq = Xapian::Query(Xapian::Query::OP_SCALE_WEIGHT, tdq = Xapian::Query(Xapian::Query::OP_SCALE_WEIGHT,
tdq, m_topdirweight); tdq, dit->weight);
xq = Xapian::Query(tdop, xq, tdq); xq = Xapian::Query(tdop, xq, tdq);
} }
@ -480,8 +481,7 @@ void SearchData::erase() {
delete *it; delete *it;
m_query.clear(); m_query.clear();
m_filetypes.clear(); m_filetypes.clear();
m_topdir.erase(); m_dirspecs.clear();
m_topdirexcl = false;
m_description.erase(); m_description.erase();
m_reason.erase(); m_reason.erase();
m_haveDates = false; m_haveDates = false;

View file

@ -71,8 +71,7 @@ class SearchDataClause;
class SearchData { class SearchData {
public: public:
SearchData(SClType tp) SearchData(SClType tp)
: m_tp(tp), m_topdirexcl(false), m_topdirweight(1.0), : m_tp(tp), m_haveDates(false), m_maxSize(size_t(-1)),
m_haveDates(false), m_maxSize(size_t(-1)),
m_minSize(size_t(-1)), m_haveWildCards(false) m_minSize(size_t(-1)), m_haveWildCards(false)
{ {
if (m_tp != SCLT_OR && m_tp != SCLT_AND) if (m_tp != SCLT_OR && m_tp != SCLT_AND)
@ -105,11 +104,9 @@ public:
bool maybeAddAutoPhrase(Rcl::Db &db, double threshold); bool maybeAddAutoPhrase(Rcl::Db &db, double threshold);
/** Set/get top subdirectory for filtering results */ /** Set/get top subdirectory for filtering results */
void setTopdir(const std::string& t, bool excl = false, float w = 1.0) void addDirSpec(const std::string& t, bool excl = false, float w = 1.0)
{ {
m_topdir = t; m_dirspecs.push_back(DirSpec(t, excl, w));
m_topdirexcl = excl;
m_topdirweight = w;
} }
void setMinSize(size_t size) {m_minSize = size;} void setMinSize(size_t size) {m_minSize = size;}
@ -148,10 +145,21 @@ private:
std::vector<std::string> m_filetypes; std::vector<std::string> m_filetypes;
// Excluded set of file types if not empty // Excluded set of file types if not empty
std::vector<std::string> m_nfiletypes; std::vector<std::string> m_nfiletypes;
// Restrict to subtree.
std::string m_topdir; // Restrict to subtree or exclude one
bool m_topdirexcl; // Invert meaning class DirSpec {
float m_topdirweight; // affect weight instead of filter public:
std::string dir;
bool exclude;
// For positive spec: affect weight instead of filter
float weight;
DirSpec(const std::string&d, bool x, float w)
: dir(d), exclude(x), weight(w)
{
}
};
std::vector<DirSpec> m_dirspecs;
bool m_haveDates; bool m_haveDates;
DateInterval m_dates; // Restrict to date interval DateInterval m_dates; // Restrict to date interval
size_t m_maxSize; size_t m_maxSize;