diff --git a/src/index/recollindex.cpp b/src/index/recollindex.cpp index afd904a2..d2d179c5 100644 --- a/src/index/recollindex.cpp +++ b/src/index/recollindex.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: recollindex.cpp,v 1.36 2008-08-29 09:51:24 dockes Exp $ (C) 2004 J.F.Dockes"; +static char rcsid[] = "@(#$Id: recollindex.cpp,v 1.37 2008-09-30 12:38:28 dockes Exp $ (C) 2004 J.F.Dockes"; #endif /* * This program is free software; you can redistribute it and/or modify @@ -401,6 +401,9 @@ int main(int argc, const char **argv) } else { confindexer = new ConfIndexer(config, &updater); - exit(!confindexer->index(rezero)); + bool status = confindexer->index(rezero); + if (!status) + cerr << "Indexing failed" << endl; + exit(!status); } } diff --git a/src/qtgui/confgui/confguiindex.cpp b/src/qtgui/confgui/confguiindex.cpp index 694dffaa..3e5f73f5 100644 --- a/src/qtgui/confgui/confguiindex.cpp +++ b/src/qtgui/confgui/confguiindex.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: confguiindex.cpp,v 1.12 2008-09-25 06:00:25 dockes Exp $ (C) 2007 J.F.Dockes"; +static char rcsid[] = "@(#$Id: confguiindex.cpp,v 1.13 2008-09-30 12:38:29 dockes Exp $ (C) 2007 J.F.Dockes"; #endif #include @@ -98,7 +98,7 @@ void ConfIndexW::acceptChanges() QTimer::singleShot(0, this, SLOT(reloadPanels())); if (startIndexingAfterConfig) { startIndexingAfterConfig = 0; - startindexing = 1; + start_indexing(true); } } diff --git a/src/qtgui/idxthread.cpp b/src/qtgui/idxthread.cpp index 5b8afe49..f3b231c7 100644 --- a/src/qtgui/idxthread.cpp +++ b/src/qtgui/idxthread.cpp @@ -27,10 +27,11 @@ #include "smallut.h" #include "rclinit.h" -int stopindexing; -int startindexing; -IdxThreadStatus indexingstatus = IDXTS_OK; -string indexingReason; +static int stopindexing; +static int startindexing; +static bool rezero; +static IdxThreadStatus indexingstatus = IDXTS_OK; +static string indexingReason; static int stopidxthread; static QMutex curfile_mutex; @@ -74,13 +75,14 @@ void IdxThread::run() myconf->getConfParam("loglevel", &loglevel); DebugLog::getdbl()->setloglevel(loglevel); ConfIndexer *indexer = new ConfIndexer(myconf, this); - if (indexer->index()) { + if (indexer->index(rezero)) { indexingstatus = IDXTS_OK; indexingReason = ""; } else { indexingstatus = IDXTS_ERROR; indexingReason = "Indexing failed: " + indexer->getReason(); } + rezero = false; delete indexer; } msleep(100); @@ -101,7 +103,15 @@ void stop_idxthread() stopidxthread = 1; idxthread.wait(); } - +void stop_indexing() +{ + stopindexing = 1; +} +void start_indexing(bool raz) +{ + startindexing = 1; + rezero = raz; +} DbIxStatus idxthread_idxStatus() { QMutexLocker locker(&curfile_mutex); @@ -111,3 +121,11 @@ bool idxthread_idxInterrupted() { return idxthread.m_interrupted; } +string idxthread_getReason() +{ + return indexingReason; +} +IdxThreadStatus idxthread_getStatus() +{ + return indexingstatus; +} diff --git a/src/qtgui/idxthread.h b/src/qtgui/idxthread.h index ec290d0f..1e5b4390 100644 --- a/src/qtgui/idxthread.h +++ b/src/qtgui/idxthread.h @@ -16,7 +16,7 @@ */ #ifndef _IDXTHREAD_H_INCLUDED_ #define _IDXTHREAD_H_INCLUDED_ -/* @(#$Id: idxthread.h,v 1.7 2008-01-17 11:15:43 dockes Exp $ (C) 2004 J.F.Dockes */ +/* @(#$Id: idxthread.h,v 1.8 2008-09-30 12:38:29 dockes Exp $ (C) 2004 J.F.Dockes */ #include #include "indexer.h" @@ -27,15 +27,16 @@ class RclConfig; extern void start_idxthread(const RclConfig& cnf); extern void stop_idxthread(); -// Set these to to request action -extern int stopindexing; -extern int startindexing; +// Use these to to request action from thread +extern void start_indexing(bool rezero = false); +extern void stop_indexing(); -// indexingstatus is NULL iff indexing is currently in progress. +// Final status of indexing. indexingstatus is NULL iff indexing is +// currently in progress. enum IdxThreadStatus {IDXTS_NULL = 0, IDXTS_OK = 1, IDXTS_ERROR = 2}; -extern IdxThreadStatus indexingstatus; -// Final indexing status message -extern string indexingReason; +extern IdxThreadStatus idxthread_getStatus(); +extern string idxthread_getReason(); + // Current status of running indexing (phase, file name etc.) extern DbIxStatus idxthread_idxStatus(); // Did last op fail because of stop request ? diff --git a/src/qtgui/main.cpp b/src/qtgui/main.cpp index 81217fbd..cec336ab 100644 --- a/src/qtgui/main.cpp +++ b/src/qtgui/main.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: main.cpp,v 1.69 2008-09-24 05:35:03 dockes Exp $ (C) 2005 J.F.Dockes"; +static char rcsid[] = "@(#$Id: main.cpp,v 1.70 2008-09-30 12:38:29 dockes Exp $ (C) 2005 J.F.Dockes"; #endif /* * This program is free software; you can redistribute it and/or modify @@ -338,12 +338,11 @@ int main(int argc, char **argv) "Ok", "Cancel", 0, 0)) { case 0: // Ok: indexing is going to start. - startindexing = 1; + start_indexing(true); break; case 1: // Cancel needindexconfig = true; - startindexing = 0; break; } } diff --git a/src/qtgui/rclmain_w.cpp b/src/qtgui/rclmain_w.cpp index 9197b836..ec80a691 100644 --- a/src/qtgui/rclmain_w.cpp +++ b/src/qtgui/rclmain_w.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: rclmain_w.cpp,v 1.54 2008-09-29 11:33:55 dockes Exp $ (C) 2005 J.F.Dockes"; +static char rcsid[] = "@(#$Id: rclmain_w.cpp,v 1.55 2008-09-30 12:38:29 dockes Exp $ (C) 2005 J.F.Dockes"; #endif /* * This program is free software; you can redistribute it and/or modify @@ -358,20 +358,20 @@ void RclMain::periodic100() { static int toggle = 0; // Check if indexing thread done - if (indexingstatus != IDXTS_NULL) { + if (idxthread_getStatus() != IDXTS_NULL) { // Indexing is stopped statusBar()->message(""); fileToggleIndexingAction->setText(tr("Update &Index")); fileToggleIndexingAction->setEnabled(TRUE); if (m_idxStatusAck == false) { m_idxStatusAck = true; - if (indexingstatus != IDXTS_OK) { + if (idxthread_getStatus() != IDXTS_OK) { if (idxthread_idxInterrupted()) { QMessageBox::warning(0, "Recoll", tr("Indexing interrupted")); } else { QMessageBox::warning(0, "Recoll", - QString::fromAscii(indexingReason.c_str())); + QString::fromAscii(idxthread_getReason().c_str())); } } // Make sure we reopen the db to get the results. If there @@ -427,12 +427,12 @@ void RclMain::periodic100() void RclMain::toggleIndexing() { - if (indexingstatus == IDXTS_NULL) { + if (idxthread_getStatus() == IDXTS_NULL) { // Indexing in progress - stopindexing = 1; + stop_indexing(); fileToggleIndexingAction->setText(tr("Update &Index")); } else { - startindexing = 1; + start_indexing(false); fileToggleIndexingAction->setText(tr("Stop &Indexing")); } fileToggleIndexingAction->setEnabled(FALSE); @@ -448,11 +448,11 @@ static string urltolocalpath(string url) void RclMain::startSearch(RefCntr sdata) { LOGDEB(("RclMain::startSearch. Indexing %s\n", - indexingstatus == IDXTS_NULL?"on":"off")); + idxthread_getStatus() == IDXTS_NULL?"on":"off")); // The db may have been closed at the end of indexing string reason; // If indexing is being performed, we reopen the db at each query. - if (!maybeOpenDb(reason, indexingstatus == IDXTS_NULL)) { + if (!maybeOpenDb(reason, idxthread_getStatus() == IDXTS_NULL)) { QMessageBox::critical(0, "Recoll", QString(reason.c_str())); return; } diff --git a/src/rcldb/rcldb.cpp b/src/rcldb/rcldb.cpp index e17183c2..f3291779 100644 --- a/src/rcldb/rcldb.cpp +++ b/src/rcldb/rcldb.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: rcldb.cpp,v 1.146 2008-09-29 08:59:20 dockes Exp $ (C) 2004 J.F.Dockes"; +static char rcsid[] = "@(#$Id: rcldb.cpp,v 1.147 2008-09-30 12:38:29 dockes Exp $ (C) 2004 J.F.Dockes"; #endif /* * This program is free software; you can redistribute it and/or modify @@ -67,6 +67,10 @@ enum value_slot { VALUE_SIG = 10 // Doc sig as chosen by app (ex: mtime+size }; +// Recoll index format version is stored in user metadata. When this change, +// we can't open the db and will have to reindex. +static const string RCL_IDX_VERSION_KEY("RCL_IDX_VERSION_KEY"); +static const string RCL_IDX_VERSION("1"); // This is the word position offset at which we index the body text // (abstract, keywords, etc.. are stored before this) @@ -514,10 +518,11 @@ bool Db::open(const string& dir, const string &stops, OpenMode mode, Xapian::DB_CREATE_OR_OVERWRITE; m_ndb->wdb = Xapian::WritableDatabase(dir, action); m_ndb->m_iswritable = true; - // We open a readonly object in addition to the r/w - // one because some operations are faster when - // performed through a Database (no forced flushes on - // allterms_begin(), ie, used in subDocs() + // We open a readonly object in all cases (possibly in + // addition to the r/w one) because some operations + // are faster when performed through a Database: no + // forced flushes on allterms_begin(), ie, used in + // subDocs() m_ndb->db = Xapian::Database(dir); LOGDEB(("Db::open: lastdocid: %d\n", m_ndb->wdb.get_lastdocid())); @@ -548,6 +553,19 @@ bool Db::open(const string& dir, const string &stops, OpenMode mode, } break; } + // Check index format version. Must not try to check a just created or + // truncated db + if (mode != DbTrunc && m_ndb->db.get_doccount()>0) { + Xapian::Database cdb = m_ndb->m_iswritable ? m_ndb->wdb: m_ndb->db; + string version = cdb.get_metadata(RCL_IDX_VERSION_KEY); + if (version.compare(RCL_IDX_VERSION)) { + m_ndb->m_noversionwrite = true; + LOGERR(("Rcl::Db::open: file index [%s], software [%s]\n", + version.c_str(), RCL_IDX_VERSION.c_str())); + throw Xapian::DatabaseError("Recoll index version mismatch", + "", ""); + } + } m_mode = mode; m_ndb->m_isopen = true; m_basedir = dir; @@ -577,8 +595,11 @@ bool Db::i_close(bool final) string ermsg; try { bool w = m_ndb->m_iswritable; - if (w) + if (w) { + if (!m_ndb->m_noversionwrite) + m_ndb->wdb.set_metadata(RCL_IDX_VERSION_KEY, RCL_IDX_VERSION); LOGDEB(("Rcl::Db:close: xapian will close. May take some time\n")); + } // Used to do a flush here. Cant see why it should be necessary. deleteZ(m_ndb); if (w) diff --git a/src/rcldb/rcldb_p.h b/src/rcldb/rcldb_p.h index bf73915d..c2db458d 100644 --- a/src/rcldb/rcldb_p.h +++ b/src/rcldb/rcldb_p.h @@ -4,7 +4,7 @@ #include "xapian.h" namespace Rcl { -/* @(#$Id: rcldb_p.h,v 1.5 2008-09-16 08:18:30 dockes Exp $ (C) 2007 J.F.Dockes */ +/* @(#$Id: rcldb_p.h,v 1.6 2008-09-30 12:38:29 dockes Exp $ (C) 2007 J.F.Dockes */ // Generic Xapian exception catching code. We do this quite often, // and I have no idea how to do this except for a macro @@ -30,10 +30,10 @@ class Query; // common. class Db::Native { public: - Db *m_db; + Db *m_db; bool m_isopen; bool m_iswritable; - + bool m_noversionwrite; //Set if open failed because of version mismatch! // Indexing Xapian::WritableDatabase wdb; @@ -41,7 +41,7 @@ class Db::Native { Xapian::Database db; Native(Db *db) - : m_db(db), m_isopen(false), m_iswritable(false) + : m_db(db), m_isopen(false), m_iswritable(false),m_noversionwrite(false) { } ~Native() {