--- a/src/rcldb/rcldb.cpp
+++ b/src/rcldb/rcldb.cpp
@@ -1,5 +1,5 @@
#ifndef lint
-static char rcsid[] = "@(#$Id: rcldb.cpp,v 1.60 2006-04-05 06:26:56 dockes Exp $ (C) 2004 J.F.Dockes";
+static char rcsid[] = "@(#$Id: rcldb.cpp,v 1.61 2006-04-05 12:50:42 dockes Exp $ (C) 2004 J.F.Dockes";
#endif
/*
* This program is free software; you can redistribute it and/or modify
@@ -67,13 +67,26 @@
// when building the abstract
#define MA_EXTRACT_WIDTH 4
+// Truncate longer path and uniquize with hash . The goal for this is
+// to avoid xapian max term length limitations, not to gain space (we
+// gain very little even with very short maxlens like 30)
+#define PATHHASHLEN 150
+
+// Synthetic abstract marker (to discriminate from abstract actually
+// found in doc)
+const static string rclSyntAbs = "?!#@";
+
// Data for a xapian database. There could actually be 2 different
// ones for indexing or query as there is not much in common.
class Native {
public:
- bool isopen;
- bool iswritable;
- string basedir;
+ bool m_isopen;
+ bool m_iswritable;
+ Db::OpenMode m_mode;
+ string m_basedir;
+
+ // List of directories for additional databases to query
+ list<string> m_extraDbs;
// Indexing
Xapian::WritableDatabase wdb;
@@ -92,7 +105,9 @@
Xapian::docid docid,
const list<string>& terms);
- Native() : isopen(false), iswritable(false), enquire(0) { }
+ Native()
+ : m_isopen(false), m_iswritable(false), m_mode(Db::DbRO), enquire(0)
+ { }
~Native() {
delete enquire;
}
@@ -112,27 +127,28 @@
};
Db::Db()
-{
- ndb = new Native;
- m_qOpts = 0;
+ : m_qOpts(0)
+{
+ m_ndb = new Native;
}
Db::~Db()
{
LOGDEB1(("Db::~Db\n"));
- if (ndb == 0)
+ if (m_ndb == 0)
return;
- LOGDEB(("Db::~Db: isopen %d iswritable %d\n", ndb->isopen,
- ndb->iswritable));
- if (ndb->isopen == false)
+ LOGDEB(("Db::~Db: isopen %d m_iswritable %d\n", m_ndb->m_isopen,
+ m_ndb->m_iswritable));
+ if (m_ndb->m_isopen == false)
return;
const char *ermsg = "Unknown error";
try {
LOGDEB(("Db::~Db: closing native database\n"));
- if (ndb->iswritable == true) {
- ndb->wdb.flush();
- }
- delete ndb;
+ if (m_ndb->m_iswritable == true) {
+ m_ndb->wdb.flush();
+ }
+ delete m_ndb;
+ m_ndb = 0;
return;
} catch (const Xapian::Error &e) {
ermsg = e.get_msg().c_str();
@@ -148,15 +164,15 @@
bool Db::open(const string& dir, OpenMode mode, int qops)
{
- if (ndb == 0)
- return false;
- LOGDEB(("Db::open: isopen %d iswritable %d\n", ndb->isopen,
- ndb->iswritable));
- m_qOpts = qops;
-
- if (ndb->isopen) {
- LOGERR(("Db::open: already open\n"));
- return false;
+ if (m_ndb == 0)
+ return false;
+ LOGDEB(("Db::open: m_isopen %d m_iswritable %d\n", m_ndb->m_isopen,
+ m_ndb->m_iswritable));
+
+ if (m_ndb->m_isopen) {
+ // We used to return an error here but I see no reason to
+ if (!close())
+ return false;
}
const char *ermsg = "Unknown";
try {
@@ -166,23 +182,46 @@
{
int action = (mode == DbUpd) ? Xapian::DB_CREATE_OR_OPEN :
Xapian::DB_CREATE_OR_OVERWRITE;
- ndb->wdb = Xapian::WritableDatabase(dir, action);
+ m_ndb->wdb = Xapian::WritableDatabase(dir, action);
LOGDEB(("Db::open: lastdocid: %d\n",
- ndb->wdb.get_lastdocid()));
- ndb->updated.resize(ndb->wdb.get_lastdocid() + 1);
- for (unsigned int i = 0; i < ndb->updated.size(); i++)
- ndb->updated[i] = false;
- ndb->iswritable = true;
+ m_ndb->wdb.get_lastdocid()));
+ m_ndb->updated.resize(m_ndb->wdb.get_lastdocid() + 1);
+ for (unsigned int i = 0; i < m_ndb->updated.size(); i++)
+ m_ndb->updated[i] = false;
+ m_ndb->m_iswritable = true;
}
break;
case DbRO:
default:
- ndb->iswritable = false;
- ndb->db = Xapian::Database(dir);
+ m_ndb->m_iswritable = false;
+ m_ndb->db = Xapian::Database(dir);
+ for (list<string>::iterator it = m_ndb->m_extraDbs.begin();
+ it != m_ndb->m_extraDbs.end(); it++) {
+ string aerr;
+ LOGDEB(("Db::Open: adding query db [%s]\n", it->c_str()));
+ aerr.clear();
+ try {
+ // Make this non-fatal
+ m_ndb->db.add_database(Xapian::Database(*it));
+ } catch (const Xapian::Error &e) {
+ aerr = e.get_msg().c_str();
+ } catch (const string &s) {
+ aerr = s.c_str();
+ } catch (const char *s) {
+ aerr = s;
+ } catch (...) {
+ aerr = "Caught unknown exception";
+ }
+ if (!aerr.empty())
+ LOGERR(("Db::Open: error while trying to add database "
+ "from [%s]: %s\n", it->c_str(), aerr.c_str()));
+ }
break;
}
- ndb->isopen = true;
- ndb->basedir = dir;
+ m_qOpts = qops;
+ m_ndb->m_mode = mode;
+ m_ndb->m_isopen = true;
+ m_ndb->m_basedir = dir;
return true;
} catch (const Xapian::Error &e) {
ermsg = e.get_msg().c_str();
@@ -201,21 +240,21 @@
// Note: xapian has no close call, we delete and recreate the db
bool Db::close()
{
- if (ndb == 0)
- return false;
- LOGDEB(("Db::close(): isopen %d iswritable %d\n", ndb->isopen,
- ndb->iswritable));
- if (ndb->isopen == false)
+ if (m_ndb == 0)
+ return false;
+ LOGDEB(("Db::close(): m_isopen %d m_iswritable %d\n", m_ndb->m_isopen,
+ m_ndb->m_iswritable));
+ if (m_ndb->m_isopen == false)
return true;
const char *ermsg = "Unknown";
try {
- if (ndb->iswritable == true) {
- ndb->wdb.flush();
+ if (m_ndb->m_iswritable == true) {
+ m_ndb->wdb.flush();
LOGDEB(("Rcl:Db: Called xapian flush\n"));
}
- delete ndb;
- ndb = new Native;
- if (ndb)
+ delete m_ndb;
+ m_ndb = new Native;
+ if (m_ndb)
return true;
} catch (const Xapian::Error &e) {
ermsg = e.get_msg().c_str();
@@ -229,12 +268,77 @@
LOGERR(("Db:close: exception while deleting db: %s\n", ermsg));
return false;
}
+bool Db::reOpen()
+{
+ if (m_ndb->m_isopen) {
+ if (!close())
+ return false;
+ if (!open(m_ndb->m_basedir, m_ndb->m_mode, m_qOpts)) {
+ return false;
+ }
+ }
+ return true;
+}
+bool Db::addQueryDb(const string &dir)
+{
+ LOGDEB(("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;
+ if (find(m_ndb->m_extraDbs.begin(), m_ndb->m_extraDbs.end(), dir) ==
+ m_ndb->m_extraDbs.end()) {
+ m_ndb->m_extraDbs.push_back(dir);
+ }
+ return reOpen();
+}
+
+bool Db::rmQueryDb(const string &dir)
+{
+ if (!m_ndb)
+ return false;
+ if (m_ndb->m_iswritable)
+ return false;
+ if (dir.empty()) {
+ m_ndb->m_extraDbs.clear();
+ } else {
+ list<string>::iterator it = find(m_ndb->m_extraDbs.begin(),
+ m_ndb->m_extraDbs.end(), dir);
+ if (it != m_ndb->m_extraDbs.end()) {
+ m_ndb->m_extraDbs.erase(it);
+ }
+ }
+ return reOpen();
+}
+bool Db::testDbDir(const string &dir)
+{
+ string aerr;
+ LOGDEB(("Db::testDbDir: [%s]\n", dir.c_str()));
+ try {
+ Xapian::Database db(dir);
+ } catch (const Xapian::Error &e) {
+ aerr = e.get_msg().c_str();
+ } catch (const string &s) {
+ aerr = s.c_str();
+ } catch (const char *s) {
+ aerr = s;
+ } catch (...) {
+ aerr = "Caught unknown exception";
+ }
+ if (!aerr.empty()) {
+ LOGERR(("Db::Open: error while trying to open database "
+ "from [%s]: %s\n", dir.c_str(), aerr.c_str()));
+ return false;
+ }
+ return true;
+}
bool Db::isopen()
{
- if (ndb == 0)
- return false;
- return ndb->isopen;
+ if (m_ndb == 0)
+ return false;
+ return m_ndb->m_isopen;
}
// A small class to hold state while splitting text
@@ -335,7 +439,7 @@
return output;
}
-// remove some chars and replace them with spaces
+// Remove some chars and replace them with spaces
static string stripchars(const string &str, string delims)
{
string out;
@@ -357,13 +461,6 @@
return out;
}
-// Truncate longer path and uniquize with hash . The goal for this is
-// to avoid xapian max term length limitations, not to gain space (we
-// gain very little even with very short maxlens like 30)
-#define PATHHASHLEN 150
-
-const static string rclSyntAbs = "?!#@";
-
// Add document in internal form to the database: index the terms in
// the title abstract and body and add special terms for file name,
// date, mime type ... , create the document data record (more
@@ -372,7 +469,7 @@
const struct stat *stp)
{
LOGDEB1(("Db::add: fn %s\n", fn.c_str()));
- if (ndb == 0)
+ if (m_ndb == 0)
return false;
Doc doc = idoc;
@@ -513,10 +610,10 @@
// Add db entry or update existing entry:
try {
Xapian::docid did =
- ndb->wdb.replace_document(uniterm.empty() ? pathterm : uniterm,
+ m_ndb->wdb.replace_document(uniterm.empty() ? pathterm : uniterm,
newdocument);
- if (did < ndb->updated.size()) {
- ndb->updated[did] = true;
+ if (did < m_ndb->updated.size()) {
+ m_ndb->updated[did] = true;
LOGDEB(("Db::add: docid %d updated [%s , %s]\n", did, fnc,
doc.ipath.c_str()));
} else {
@@ -526,7 +623,7 @@
} catch (...) {
// FIXME: is this ever actually needed?
try {
- ndb->wdb.add_document(newdocument);
+ m_ndb->wdb.add_document(newdocument);
LOGDEB(("Db::add: %s added (failed re-seek for duplicate)\n",
fnc));
} catch (...) {
@@ -540,7 +637,7 @@
// Test if given filename has changed since last indexed:
bool Db::needUpdate(const string &filename, const struct stat *stp)
{
- if (ndb == 0)
+ if (m_ndb == 0)
return false;
// If no document exist with this path, we do need update
@@ -556,16 +653,16 @@
// file changed)
Xapian::PostingIterator doc;
try {
- if (!ndb->wdb.term_exists(pathterm)) {
+ if (!m_ndb->wdb.term_exists(pathterm)) {
LOGDEB1(("Db::needUpdate: no such path: %s\n", pathterm.c_str()));
return true;
}
- Xapian::PostingIterator docid0 = ndb->wdb.postlist_begin(pathterm);
+ Xapian::PostingIterator docid0 = m_ndb->wdb.postlist_begin(pathterm);
for (Xapian::PostingIterator docid = docid0;
- docid != ndb->wdb.postlist_end(pathterm); docid++) {
-
- Xapian::Document doc = ndb->wdb.get_document(*docid);
+ docid != m_ndb->wdb.postlist_end(pathterm); docid++) {
+
+ Xapian::Document doc = m_ndb->wdb.get_document(*docid);
// Check the date once. no need to look at the others if
// the db needs updating. Note that the fmtime used to be
@@ -590,8 +687,8 @@
}
// Db is up to date. Make a note that this document exists.
- if (*docid < ndb->updated.size())
- ndb->updated[*docid] = true;
+ if (*docid < m_ndb->updated.size())
+ m_ndb->updated[*docid] = true;
}
return false;
} catch (const Xapian::Error &e) {
@@ -627,12 +724,12 @@
bool Db::deleteStemDb(const string& lang)
{
LOGDEB(("Db::deleteStemDb(%s)\n", lang.c_str()));
- if (ndb == 0)
- return false;
- if (ndb->isopen == false)
- return false;
-
- string dir = stemdbname(ndb->basedir, lang);
+ if (m_ndb == 0)
+ return false;
+ if (m_ndb->m_isopen == false)
+ return false;
+
+ string dir = stemdbname(m_ndb->m_basedir, lang);
if (wipedir(dir) == 0 && rmdir(dir.c_str()) == 0)
return true;
return false;
@@ -647,9 +744,9 @@
bool Db::createStemDb(const string& lang)
{
LOGDEB(("Db::createStemDb(%s)\n", lang.c_str()));
- if (ndb == 0)
- return false;
- if (ndb->isopen == false)
+ if (m_ndb == 0)
+ return false;
+ if (m_ndb->m_isopen == false)
return false;
// First build the in-memory stem database:
@@ -667,8 +764,8 @@
try {
Xapian::Stem stemmer(lang);
Xapian::TermIterator it;
- for (it = ndb->wdb.allterms_begin();
- it != ndb->wdb.allterms_end(); it++) {
+ for (it = m_ndb->wdb.allterms_begin();
+ it != m_ndb->wdb.allterms_end(); it++) {
// If it has any non-lowercase 7bit char, cant be stemmable
string::iterator sit = (*it).begin(), eit = sit + (*it).length();
if ((sit = find_if(sit, eit, p_notlowerorutf)) != eit) {
@@ -707,7 +804,7 @@
}
};
// Create xapian database for stem relations
- string stemdbdir = stemdbname(ndb->basedir, lang);
+ string stemdbdir = stemdbname(m_ndb->m_basedir, lang);
// We want to get rid of the db dir in case of error. This gets disarmed
// just before success return.
DirWiper wiper(stemdbdir);
@@ -781,10 +878,10 @@
{
list<string> dirs;
LOGDEB(("Db::getStemLang\n"));
- if (ndb == 0)
+ if (m_ndb == 0)
return dirs;
string pattern = stemdirstem + "*";
- dirs = path_dirglob(ndb->basedir, pattern);
+ dirs = path_dirglob(m_ndb->m_basedir, pattern);
for (list<string>::iterator it = dirs.begin(); it != dirs.end(); it++) {
*it = path_basename(*it);
*it = it->substr(stemdirstem.length(), string::npos);
@@ -801,11 +898,11 @@
bool Db::purge()
{
LOGDEB(("Db::purge\n"));
- if (ndb == 0)
- return false;
- LOGDEB(("Db::purge: isopen %d iswritable %d\n", ndb->isopen,
- ndb->iswritable));
- if (ndb->isopen == false || ndb->iswritable == false)
+ if (m_ndb == 0)
+ return false;
+ LOGDEB(("Db::purge: m_isopen %d m_iswritable %d\n", m_ndb->m_isopen,
+ m_ndb->m_iswritable));
+ if (m_ndb->m_isopen == false || m_ndb->m_iswritable == false)
return false;
// There seems to be problems with the document delete code, when
@@ -816,14 +913,14 @@
// trying to delete an unexistant document ?
// Flushing before trying the deletes seeems to work around the problem
try {
- ndb->wdb.flush();
+ m_ndb->wdb.flush();
} catch (...) {
LOGDEB(("Db::purge: 1st flush failed\n"));
}
- for (Xapian::docid docid = 1; docid < ndb->updated.size(); ++docid) {
- if (!ndb->updated[docid]) {
+ for (Xapian::docid docid = 1; docid < m_ndb->updated.size(); ++docid) {
+ if (!m_ndb->updated[docid]) {
try {
- ndb->wdb.delete_document(docid);
+ m_ndb->wdb.delete_document(docid);
LOGDEB(("Db::purge: deleted document #%d\n", docid));
} catch (const Xapian::DocNotFoundError &) {
LOGDEB(("Db::purge: document #%d not found\n", docid));
@@ -831,7 +928,7 @@
}
}
try {
- ndb->wdb.flush();
+ m_ndb->wdb.flush();
} catch (...) {
LOGDEB(("Db::purge: 2nd flush failed\n"));
}
@@ -841,7 +938,7 @@
/**
* Expand term to list of all terms which stem to the same term.
*/
-static list<string> stemexpand(Native *ndb, string term, const string& lang)
+static list<string> stemexpand(Native *m_ndb, string term, const string& lang)
{
list<string> explist;
try {
@@ -849,7 +946,7 @@
string stem = stemmer.stem_word(term);
LOGDEB(("stemexpand: [%s] stem-> [%s]\n", term.c_str(), stem.c_str()));
// Try to fetch the doc from the stem db
- string stemdbdir = stemdbname(ndb->basedir, lang);
+ string stemdbdir = stemdbname(m_ndb->m_basedir, lang);
Xapian::Database sdb(stemdbdir);
LOGDEB1(("stemexpand: %s lastdocid: %d\n",
stemdbdir.c_str(), sdb.get_lastdocid()));
@@ -925,7 +1022,7 @@
// phrase terms (no stem expansion in this case)
static void stringToXapianQueries(const string &iq,
const string& stemlang,
- Native *ndb,
+ Native *m_ndb,
list<Xapian::Query> &pqueries,
Db::QueryOpts opts = Db::QO_NONE)
{
@@ -973,7 +1070,7 @@
dumb_string(term, term1);
// Possibly perform stem compression/expansion
if (!nostemexp && (opts & Db::QO_STEM)) {
- exp = stemexpand(ndb, term1, stemlang);
+ exp = stemexpand(m_ndb, term1, stemlang);
} else {
exp.push_back(term1);
}
@@ -1001,18 +1098,18 @@
{
LOGDEB(("Db::setQuery: q: [%s], opts 0x%x, stemlang %s\n",
iqstring.c_str(), (unsigned int)opts, stemlang.c_str()));
- if (!ndb)
+ if (!m_ndb)
return false;
m_asdata.erase();
- dbindices.clear();
+ m_dbindices.clear();
list<Xapian::Query> pqueries;
- stringToXapianQueries(iqstring, stemlang, ndb, pqueries, opts);
- ndb->query = Xapian::Query(Xapian::Query::OP_OR, pqueries.begin(),
+ stringToXapianQueries(iqstring, stemlang, m_ndb, pqueries, opts);
+ m_ndb->query = Xapian::Query(Xapian::Query::OP_OR, pqueries.begin(),
pqueries.end());
- delete ndb->enquire;
- ndb->enquire = new Xapian::Enquire(ndb->db);
- ndb->enquire->set_query(ndb->query);
- ndb->mset = Xapian::MSet();
+ delete m_ndb->enquire;
+ m_ndb->enquire = new Xapian::Enquire(m_ndb->db);
+ m_ndb->enquire->set_query(m_ndb->query);
+ m_ndb->mset = Xapian::MSet();
return true;
}
@@ -1035,9 +1132,9 @@
LOGDEB((" restricted to: %s\n", sdata.topdir.c_str()));
m_asdata = sdata;
- dbindices.clear();
-
- if (!ndb)
+ m_dbindices.clear();
+
+ if (!m_ndb)
return false;
list<Xapian::Query> pqueries;
Xapian::Query xq;
@@ -1062,10 +1159,10 @@
LOGDEB((" pattern: [%s]\n", pattern.c_str()));
// Match pattern against all file names in the db
- Xapian::TermIterator it = ndb->db.allterms_begin();
+ Xapian::TermIterator it = m_ndb->db.allterms_begin();
it.skip_to("XSFN");
list<string> names;
- for (;it != ndb->db.allterms_end(); it++) {
+ for (;it != m_ndb->db.allterms_end(); it++) {
if ((*it).find("XSFN") != 0)
break;
string fn = (*it).substr(4);
@@ -1089,7 +1186,7 @@
}
if (!sdata.allwords.empty()) {
- stringToXapianQueries(sdata.allwords, stemlang, ndb, pqueries, opts);
+ stringToXapianQueries(sdata.allwords, stemlang, m_ndb, pqueries, opts);
if (!pqueries.empty()) {
Xapian::Query nq =
Xapian::Query(Xapian::Query::OP_AND, pqueries.begin(),
@@ -1101,7 +1198,7 @@
}
if (!sdata.orwords.empty()) {
- stringToXapianQueries(sdata.orwords, stemlang, ndb, pqueries, opts);
+ stringToXapianQueries(sdata.orwords, stemlang, m_ndb, pqueries, opts);
if (!pqueries.empty()) {
Xapian::Query nq =
Xapian::Query(Xapian::Query::OP_OR, pqueries.begin(),
@@ -1114,7 +1211,7 @@
// We do no stem expansion on 'No' words. Should we ?
if (!sdata.nowords.empty()) {
- stringToXapianQueries(sdata.nowords, stemlang, ndb, pqueries);
+ stringToXapianQueries(sdata.nowords, stemlang, m_ndb, pqueries);
if (!pqueries.empty()) {
Xapian::Query nq;
nq = Xapian::Query(Xapian::Query::OP_OR, pqueries.begin(),
@@ -1128,7 +1225,7 @@
if (!sdata.phrase.empty()) {
Xapian::Query nq;
string s = string("\"") + sdata.phrase + string("\"");
- stringToXapianQueries(s, stemlang, ndb, pqueries);
+ stringToXapianQueries(s, stemlang, m_ndb, pqueries);
if (!pqueries.empty()) {
// There should be a single list element phrase query.
xq = xq.empty() ? *pqueries.begin() :
@@ -1149,13 +1246,13 @@
xq = xq.empty() ? tq : Xapian::Query(Xapian::Query::OP_FILTER, xq, tq);
}
- ndb->query = xq;
- delete ndb->enquire;
- ndb->enquire = new Xapian::Enquire(ndb->db);
- ndb->enquire->set_query(ndb->query);
- ndb->mset = Xapian::MSet();
+ m_ndb->query = xq;
+ delete m_ndb->enquire;
+ m_ndb->enquire = new Xapian::Enquire(m_ndb->db);
+ m_ndb->enquire->set_query(m_ndb->query);
+ m_ndb->mset = Xapian::MSet();
// Get the query description and trim the "Xapian::Query"
- sdata.description = ndb->query.get_description();
+ sdata.description = m_ndb->query.get_description();
if (sdata.description.find("Xapian::Query") == 0)
sdata.description = sdata.description.substr(strlen("Xapian::Query"));
LOGDEB(("Db::SetQuery: Q: %s\n", sdata.description.c_str()));
@@ -1164,32 +1261,33 @@
bool Db::getQueryTerms(list<string>& terms)
{
- if (!ndb)
+ if (!m_ndb)
return false;
terms.clear();
Xapian::TermIterator it;
- for (it = ndb->query.get_terms_begin(); it != ndb->query.get_terms_end();
+ for (it = m_ndb->query.get_terms_begin(); it != m_ndb->query.get_terms_end();
it++) {
terms.push_back(*it);
}
return true;
}
+// Mset size
static const int qquantum = 30;
int Db::getResCnt()
{
- if (!ndb || !ndb->enquire) {
+ if (!m_ndb || !m_ndb->enquire) {
LOGERR(("Db::getResCnt: no query opened\n"));
return -1;
}
- if (ndb->mset.size() <= 0) {
+ if (m_ndb->mset.size() <= 0) {
try {
- ndb->mset = ndb->enquire->get_mset(0, qquantum);
+ m_ndb->mset = m_ndb->enquire->get_mset(0, qquantum);
} catch (const Xapian::DatabaseModifiedError &error) {
- ndb->db.reopen();
- ndb->mset = ndb->enquire->get_mset(0, qquantum);
+ m_ndb->db.reopen();
+ m_ndb->mset = m_ndb->enquire->get_mset(0, qquantum);
} catch (const Xapian::Error & error) {
LOGERR(("enquire->get_mset: exception: %s\n",
error.get_msg().c_str()));
@@ -1197,15 +1295,8 @@
}
}
- return ndb->mset.get_matches_lower_bound();
-}
-
-// This class (friend to RclDb) exists so that we can have functions that
-// access private RclDb data and have Xapian-specific parameters (so that we
-// don't want them to appear in the public rcldb.h).
-class DbPops {
- public:
-};
+ return m_ndb->mset.get_matches_lower_bound();
+}
bool Native::dbDataToRclDoc(std::string &data, Doc &doc,
int qopts,
@@ -1252,7 +1343,7 @@
bool Db::getDoc(int exti, Doc &doc, int *percent)
{
LOGDEB1(("Db::getDoc: exti %d\n", exti));
- if (!ndb || !ndb->enquire) {
+ if (!m_ndb || !m_ndb->enquire) {
LOGERR(("Db::getDoc: no query opened\n"));
return false;
}
@@ -1264,85 +1355,85 @@
int xapi;
if (postqfilter) {
// There is a postquery filter, does this fall in already known area ?
- if (exti >= (int)dbindices.size()) {
+ if (exti >= (int)m_dbindices.size()) {
// Have to fetch xapian docs and filter until we get
// enough or fail
- dbindices.reserve(exti+1);
+ m_dbindices.reserve(exti+1);
// First xapian doc we fetch is the one after last stored
- int first = dbindices.size() > 0 ? dbindices.back() + 1 : 0;
+ int first = m_dbindices.size() > 0 ? m_dbindices.back() + 1 : 0;
// Loop until we get enough docs
- while (exti >= (int)dbindices.size()) {
+ while (exti >= (int)m_dbindices.size()) {
LOGDEB(("Db::getDoc: fetching %d starting at %d\n",
qquantum, first));
try {
- ndb->mset = ndb->enquire->get_mset(first, qquantum);
+ m_ndb->mset = m_ndb->enquire->get_mset(first, qquantum);
} catch (const Xapian::DatabaseModifiedError &error) {
- ndb->db.reopen();
- ndb->mset = ndb->enquire->get_mset(first, qquantum);
+ m_ndb->db.reopen();
+ m_ndb->mset = m_ndb->enquire->get_mset(first, qquantum);
} catch (const Xapian::Error & error) {
LOGERR(("enquire->get_mset: exception: %s\n",
error.get_msg().c_str()));
abort();
}
- if (ndb->mset.empty()) {
+ if (m_ndb->mset.empty()) {
LOGDEB(("Db::getDoc: got empty mset\n"));
return false;
}
- first = ndb->mset.get_firstitem();
- for (unsigned int i = 0; i < ndb->mset.size() ; i++) {
+ first = m_ndb->mset.get_firstitem();
+ for (unsigned int i = 0; i < m_ndb->mset.size() ; i++) {
LOGDEB(("Db::getDoc: [%d]\n", i));
- Xapian::Document xdoc = ndb->mset[i].get_document();
- if (ndb->filterMatch(this, xdoc)) {
- dbindices.push_back(first + i);
+ Xapian::Document xdoc = m_ndb->mset[i].get_document();
+ if (m_ndb->filterMatch(this, xdoc)) {
+ m_dbindices.push_back(first + i);
}
}
- first = first + ndb->mset.size();
+ first = first + m_ndb->mset.size();
}
}
- xapi = dbindices[exti];
+ xapi = m_dbindices[exti];
} else {
xapi = exti;
}
// From there on, we work with a xapian enquire item number. Fetch it
- int first = ndb->mset.get_firstitem();
- int last = first + ndb->mset.size() -1;
+ int first = m_ndb->mset.get_firstitem();
+ int last = first + m_ndb->mset.size() -1;
if (!(xapi >= first && xapi <= last)) {
LOGDEB(("Fetching for first %d, count %d\n", xapi, qquantum));
try {
- ndb->mset = ndb->enquire->get_mset(xapi, qquantum);
+ m_ndb->mset = m_ndb->enquire->get_mset(xapi, qquantum);
} catch (const Xapian::DatabaseModifiedError &error) {
- ndb->db.reopen();
- ndb->mset = ndb->enquire->get_mset(xapi, qquantum);
+ m_ndb->db.reopen();
+ m_ndb->mset = m_ndb->enquire->get_mset(xapi, qquantum);
} catch (const Xapian::Error & error) {
LOGERR(("enquire->get_mset: exception: %s\n",
error.get_msg().c_str()));
abort();
}
- if (ndb->mset.empty())
+ if (m_ndb->mset.empty())
return false;
- first = ndb->mset.get_firstitem();
- last = first + ndb->mset.size() -1;
+ first = m_ndb->mset.get_firstitem();
+ last = first + m_ndb->mset.size() -1;
}
LOGDEB1(("Db::getDoc: Qry [%s] win [%d-%d] Estimated results: %d",
- ndb->query.get_description().c_str(),
+ m_ndb->query.get_description().c_str(),
first, last,
- ndb->mset.get_matches_lower_bound()));
-
- Xapian::Document xdoc = ndb->mset[xapi-first].get_document();
- Xapian::docid docid = *(ndb->mset[xapi-first]);
+ m_ndb->mset.get_matches_lower_bound()));
+
+ Xapian::Document xdoc = m_ndb->mset[xapi-first].get_document();
+ Xapian::docid docid = *(m_ndb->mset[xapi-first]);
if (percent)
- *percent = ndb->mset.convert_to_percent(ndb->mset[xapi-first]);
+ *percent = m_ndb->mset.convert_to_percent(m_ndb->mset[xapi-first]);
// Parse xapian document's data and populate doc fields
string data = xdoc.get_data();
list<string> terms;
getQueryTerms(terms);
- return ndb->dbDataToRclDoc(data, doc, m_qOpts, docid, terms);
+ return m_ndb->dbDataToRclDoc(data, doc, m_qOpts, docid, terms);
}
// Retrieve document defined by file name and internal path. Very inefficient,
@@ -1352,7 +1443,7 @@
{
LOGDEB(("Db:getDoc: [%s] (%d) [%s]\n", fn.c_str(), fn.length(),
ipath.c_str()));
- if (ndb == 0)
+ if (m_ndb == 0)
return false;
// Initialize what we can in any case. If this is history, caller
@@ -1369,7 +1460,7 @@
// with the appropriate ipath. This is very inefficient.
const char *ermsg = "";
try {
- if (!ndb->db.term_exists(pathterm)) {
+ if (!m_ndb->db.term_exists(pathterm)) {
// Document found in history no longer in the database.
// We return true (because their might be other ok docs further)
// but indicate the error with pc = -1
@@ -1380,13 +1471,13 @@
return true;
}
for (Xapian::PostingIterator docid =
- ndb->db.postlist_begin(pathterm);
- docid != ndb->db.postlist_end(pathterm); docid++) {
-
- Xapian::Document xdoc = ndb->db.get_document(*docid);
+ m_ndb->db.postlist_begin(pathterm);
+ docid != m_ndb->db.postlist_end(pathterm); docid++) {
+
+ Xapian::Document xdoc = m_ndb->db.get_document(*docid);
string data = xdoc.get_data();
list<string> terms;
- if (ndb->dbDataToRclDoc(data, doc, QO_NONE, *docid, terms)
+ if (m_ndb->dbDataToRclDoc(data, doc, QO_NONE, *docid, terms)
&& doc.ipath == ipath)
return true;
}