Switch to side-by-side view

--- 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 @@
     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 @@
 		    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 @@
 	    }
 	    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 @@
     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)