return "Unbalanced number of calls to notmuch_database_begin_atomic/end_atomic";
case NOTMUCH_STATUS_UNSUPPORTED_OPERATION:
return "Unsupported operation";
+ case NOTMUCH_STATUS_UPGRADE_REQUIRED:
+ return "Operation requires a database upgrade";
default:
case NOTMUCH_STATUS_LAST_STATUS:
return "Unknown error status value";
{
notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;
- try {
- if (notmuch->xapian_db != NULL &&
- notmuch->mode == NOTMUCH_DATABASE_MODE_READ_WRITE)
- (static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db))->flush ();
- } catch (const Xapian::Error &error) {
- status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
- if (! notmuch->exception_reported) {
- fprintf (stderr, "Error: A Xapian exception occurred flushing database: %s\n",
- error.get_msg().c_str());
- }
- }
-
/* Many Xapian objects (and thus notmuch objects) hold references to
* the database, so merely deleting the database may not suffice to
* close it. Thus, we explicitly close it here. */
if (notmuch->xapian_db != NULL) {
try {
+ /* If there's an outstanding transaction, it's unclear if
+ * closing the Xapian database commits everything up to
+ * that transaction, or may discard committed (but
+ * unflushed) transactions. To be certain, explicitly
+ * cancel any outstanding transaction before closing. */
+ if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_WRITE &&
+ notmuch->atomic_nesting)
+ (static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db))
+ ->cancel_transaction ();
+
+ /* Close the database. This implicitly flushes
+ * outstanding changes. */
notmuch->xapian_db->close();
} catch (const Xapian::Error &error) {
- /* don't clobber previous error status */
- if (status == NOTMUCH_STATUS_SUCCESS)
- status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
+ status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
+ if (! notmuch->exception_reported) {
+ fprintf (stderr, "Error: A Xapian exception occurred closing database: %s\n",
+ error.get_msg().c_str());
+ }
}
}
target_features = notmuch->features | NOTMUCH_FEATURES_CURRENT;
new_features = NOTMUCH_FEATURES_CURRENT & ~notmuch->features;
- if (! new_features)
+ if (! notmuch_database_needs_upgrade (notmuch))
return NOTMUCH_STATUS_SUCCESS;
if (progress_notify) {
timer_is_active = TRUE;
}
+ /* Figure out how much total work we need to do. */
+ if (new_features &
+ (NOTMUCH_FEATURE_FILE_TERMS | NOTMUCH_FEATURE_BOOL_FOLDER)) {
+ notmuch_query_t *query = notmuch_query_create (notmuch, "");
+ total += notmuch_query_count_messages (query);
+ notmuch_query_destroy (query);
+ }
+ if (new_features & NOTMUCH_FEATURE_DIRECTORY_DOCS) {
+ t_end = db->allterms_end ("XTIMESTAMP");
+ for (t = db->allterms_begin ("XTIMESTAMP"); t != t_end; t++)
+ ++total;
+ }
+
/* Perform the upgrade in a transaction. */
db->begin_transaction (true);
notmuch_message_t *message;
char *filename;
- total = notmuch_query_count_messages (query);
-
for (messages = notmuch_query_search_messages (query);
notmuch_messages_valid (messages);
notmuch_messages_move_to_next (messages))
db->delete_document (*p);
}
+
+ ++count;
}
}
if (message_ret == NULL)
return NOTMUCH_STATUS_NULL_POINTER;
+ if (! (notmuch->features & NOTMUCH_FEATURE_FILE_TERMS))
+ return NOTMUCH_STATUS_UPGRADE_REQUIRED;
+
/* return NULL on any failure */
*message_ret = NULL;