added basic facility for result path translation
This commit is contained in:
@@ -95,6 +95,7 @@ void RclConfig::zeroMe() {
|
||||
mimeconf = 0;
|
||||
mimeview = 0;
|
||||
m_fields = 0;
|
||||
m_ptrans = 0;
|
||||
m_stopsuffixes = 0;
|
||||
m_maxsufflen = 0;
|
||||
m_stpsuffstate.init(this, 0, "recoll_noindex");
|
||||
@@ -217,6 +218,8 @@ RclConfig::RclConfig(const string *argcnf)
|
||||
if (!readFieldsConfig(cnferrloc))
|
||||
return;
|
||||
|
||||
m_ptrans = new ConfSimple(path_cat(m_confdir, "ptrans").c_str(), 1);
|
||||
|
||||
m_ok = true;
|
||||
setKeyDir(cstr_null);
|
||||
|
||||
@@ -744,7 +747,7 @@ bool RclConfig::getFieldTraits(const string& _fld, const FieldTraits **ftpp)
|
||||
_fld.c_str(), pit->second.pfx.c_str()));
|
||||
return true;
|
||||
} else {
|
||||
LOGDEB1(("RclConfig::readFieldsConfig: no prefix for field [%s]\n",
|
||||
LOGDEB1(("RclConfig::getFieldTraits: no prefix for field [%s]\n",
|
||||
fld.c_str()));
|
||||
*ftpp = 0;
|
||||
return false;
|
||||
@@ -936,6 +939,41 @@ string RclConfig::getDbDir() const
|
||||
return path_canon(dbdir);
|
||||
}
|
||||
|
||||
void RclConfig::urlrewrite(const string& dbdir, string& url) const
|
||||
{
|
||||
LOGDEB2(("RclConfig::urlrewrite: dbdir [%s] url [%s]\n",
|
||||
dbdir.c_str(), url.c_str()));
|
||||
|
||||
// Do path translations exist for this index ?
|
||||
if (m_ptrans == 0 || !m_ptrans->hasSubKey(dbdir)) {
|
||||
LOGDEB2(("RclConfig::urlrewrite: no paths translations (m_ptrans %p)\n",
|
||||
m_ptrans));
|
||||
return;
|
||||
}
|
||||
|
||||
string path = fileurltolocalpath(url);
|
||||
if (path.empty()) {
|
||||
LOGDEB2(("RclConfig::urlrewrite: not file url\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
// For each translation check if the prefix matches the input path,
|
||||
// replace and return the result if it does.
|
||||
vector<string> opaths = m_ptrans->getNames(dbdir);
|
||||
for (vector<string>::const_iterator it = opaths.begin();
|
||||
it != opaths.end(); it++) {
|
||||
if (it->size() <= path.size() && !path.compare(0, it->size(), *it)) {
|
||||
string npath;
|
||||
// This call always succeeds because the key comes from getNames()
|
||||
if (m_ptrans->get(*it, npath, dbdir)) {
|
||||
path = path.replace(0, it->size(), npath);
|
||||
url = "file://" + path;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool RclConfig::sourceChanged() const
|
||||
{
|
||||
if (m_conf && m_conf->sourceChanged())
|
||||
@@ -948,6 +986,8 @@ bool RclConfig::sourceChanged() const
|
||||
return true;
|
||||
if (m_fields && m_fields->sourceChanged())
|
||||
return true;
|
||||
if (m_ptrans && m_ptrans->sourceChanged())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1179,6 +1219,7 @@ void RclConfig::freeAll()
|
||||
delete mimeconf;
|
||||
delete mimeview;
|
||||
delete m_fields;
|
||||
delete m_ptrans;
|
||||
delete STOPSUFFIXES;
|
||||
// just in case
|
||||
zeroMe();
|
||||
@@ -1204,6 +1245,8 @@ void RclConfig::initFrom(const RclConfig& r)
|
||||
mimeview = new ConfStack<ConfSimple>(*(r.mimeview));
|
||||
if (r.m_fields)
|
||||
m_fields = new ConfStack<ConfSimple>(*(r.m_fields));
|
||||
if (r.m_ptrans)
|
||||
m_ptrans = new ConfSimple(*(r.m_ptrans));
|
||||
m_fldtotraits = r.m_fldtotraits;
|
||||
m_aliastocanon = r.m_aliastocanon;
|
||||
m_storedFields = r.m_storedFields;
|
||||
|
||||
@@ -150,6 +150,8 @@ class RclConfig {
|
||||
string getPidfile() const;
|
||||
/** Get indexing status file name */
|
||||
string getIdxStatusFile() const;
|
||||
/** Do path translation according to the ptrans table */
|
||||
void urlrewrite(const string& dbdir, string& url) const;
|
||||
|
||||
/** Get Web Queue directory name */
|
||||
string getWebQueueDir() const;
|
||||
@@ -279,6 +281,7 @@ class RclConfig {
|
||||
ConfStack<ConfSimple> *mimeconf; // but their content may depend on it.
|
||||
ConfStack<ConfSimple> *mimeview; //
|
||||
ConfStack<ConfSimple> *m_fields;
|
||||
ConfSimple *m_ptrans; // Paths translations
|
||||
map<string, FieldTraits> m_fldtotraits; // Field to field params
|
||||
map<string, string> m_aliastocanon;
|
||||
set<string> m_storedFields;
|
||||
|
||||
+19
-3
@@ -233,8 +233,21 @@ bool Db::Native::dbDataToRclDoc(Xapian::docid docid, std::string &data,
|
||||
if (!parms.ok())
|
||||
return false;
|
||||
|
||||
// Special cases:
|
||||
// Compute what index this comes from, and check for path translations
|
||||
string dbdir = m_rcldb->m_basedir;
|
||||
if (!m_rcldb->m_extraDbs.empty()) {
|
||||
// As per trac.xapian.org/wiki/FAQ/MultiDatabaseDocumentID
|
||||
unsigned int idxi = (docid-1) % (m_rcldb->m_extraDbs.size()+1);
|
||||
// idxi is in [0, extraDbs.size()]. 0 is the base index, 1-n index
|
||||
// into the additional dbs array
|
||||
if (idxi) {
|
||||
dbdir = m_rcldb->m_extraDbs[idxi - 1];
|
||||
}
|
||||
}
|
||||
parms.get(Doc::keyurl, doc.url);
|
||||
m_rcldb->m_config->urlrewrite(dbdir, doc.url);
|
||||
|
||||
// Special cases:
|
||||
parms.get(Doc::keytp, doc.mimetype);
|
||||
parms.get(Doc::keyfmt, doc.fmtime);
|
||||
parms.get(Doc::keydmt, doc.dmtime);
|
||||
@@ -264,6 +277,7 @@ bool Db::Native::dbDataToRclDoc(Xapian::docid docid, std::string &data,
|
||||
if (doc.meta.find(*it) == doc.meta.end())
|
||||
parms.get(*it, doc.meta[*it]);
|
||||
}
|
||||
doc.meta[Doc::keyurl] = doc.url;
|
||||
doc.meta[Doc::keymt] = doc.dmtime.empty() ? doc.fmtime : doc.dmtime;
|
||||
return true;
|
||||
}
|
||||
@@ -579,14 +593,16 @@ int Db::termDocCnt(const string& _term)
|
||||
return res;
|
||||
}
|
||||
|
||||
bool Db::addQueryDb(const string &dir)
|
||||
bool Db::addQueryDb(const string &_dir)
|
||||
{
|
||||
LOGDEB(("Db::addQueryDb: ndb %p iswritable %d db [%s]\n", m_ndb,
|
||||
string dir = _dir;
|
||||
LOGDEB0(("Db::addQueryDb: ndb %p iswritable %d db [%s]\n", m_ndb,
|
||||
(m_ndb)?m_ndb->m_iswritable:0, dir.c_str()));
|
||||
if (!m_ndb)
|
||||
return false;
|
||||
if (m_ndb->m_iswritable)
|
||||
return false;
|
||||
dir = path_canon(dir);
|
||||
if (find(m_extraDbs.begin(), m_extraDbs.end(), dir) == m_extraDbs.end()) {
|
||||
m_extraDbs.push_back(dir);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user