]> git.notmuchmail.org Git - notmuch/blobdiff - lib/database.cc
compact: catch Xapian::Error consistently
[notmuch] / lib / database.cc
index 3dfea0f4f9e27b48de199ed539f0d58e8614b684..3530cb650afba31748ea6fe9a15221fd8943ba16 100644 (file)
@@ -805,35 +805,39 @@ notmuch_database_close (notmuch_database_t *notmuch)
 }
 
 #if HAVE_XAPIAN_COMPACT
-static int unlink_cb (const char *path,
-                     unused (const struct stat *sb),
-                     unused (int type),
-                     unused (struct FTW *ftw))
+static int
+unlink_cb (const char *path,
+          unused (const struct stat *sb),
+          unused (int type),
+          unused (struct FTW *ftw))
 {
-    return remove(path);
+    return remove (path);
 }
 
-static int rmtree (const char *path)
+static int
+rmtree (const char *path)
 {
-    return nftw(path, unlink_cb, 64, FTW_DEPTH | FTW_PHYS);
+    return nftw (path, unlink_cb, 64, FTW_DEPTH | FTW_PHYS);
 }
 
 class NotmuchCompactor : public Xapian::Compactor
 {
     notmuch_compact_status_cb_t status_cb;
+    void *status_closure;
 
 public:
-    NotmuchCompactor(notmuch_compact_status_cb_t cb) : status_cb(cb) { }
+    NotmuchCompactor(notmuch_compact_status_cb_t cb, void *closure) :
+       status_cb (cb), status_closure (closure) { }
 
     virtual void
     set_status (const std::string &table, const std::string &status)
     {
-       charmsg;
+       char *msg;
 
        if (status_cb == NULL)
            return;
 
-       if (status.length() == 0)
+       if (status.length () == 0)
            msg = talloc_asprintf (NULL, "compacting table %s", table.c_str());
        else
            msg = talloc_asprintf (NULL, "     %s", status.c_str());
@@ -842,8 +846,8 @@ public:
            return;
        }
 
-       status_cb(msg);
-       talloc_free(msg);
+       status_cb (msg, status_closure);
+       talloc_free (msg);
     }
 };
 
@@ -859,18 +863,22 @@ public:
  * compaction process to protect data integrity.
  */
 notmuch_status_t
-notmuch_database_compact (const char* path,
-                         const char* backup_path,
-                         notmuch_compact_status_cb_t status_cb)
+notmuch_database_compact (const char *path,
+                         const char *backup_path,
+                         notmuch_compact_status_cb_t status_cb,
+                         void *closure)
 {
-    void *local = talloc_new (NULL);
+    void *local;
     char *notmuch_path, *xapian_path, *compact_xapian_path;
-    char *old_xapian_path = NULL;
     notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS;
     notmuch_database_t *notmuch = NULL;
     struct stat statbuf;
 
-    ret = notmuch_database_open(path, NOTMUCH_DATABASE_MODE_READ_WRITE, &notmuch);
+    local = talloc_new (NULL);
+    if (! local)
+       return NOTMUCH_STATUS_OUT_OF_MEMORY;
+
+    ret = notmuch_database_open (path, NOTMUCH_DATABASE_MODE_READ_WRITE, &notmuch);
     if (ret) {
        goto DONE;
     }
@@ -891,63 +899,61 @@ notmuch_database_compact (const char* path,
     }
 
     if (backup_path != NULL) {
-       if (! (old_xapian_path = talloc_asprintf (local, "%s/xapian.old", backup_path))) {
-           ret = NOTMUCH_STATUS_OUT_OF_MEMORY;
-           goto DONE;
-       }
-
-       if (stat(old_xapian_path, &statbuf) != -1) {
-           fprintf (stderr, "Backup path already exists: %s\n", old_xapian_path);
+       if (stat (backup_path, &statbuf) != -1) {
+           fprintf (stderr, "Backup path already exists: %s\n", backup_path);
            ret = NOTMUCH_STATUS_FILE_ERROR;
            goto DONE;
        }
        if (errno != ENOENT) {
            fprintf (stderr, "Unknown error while stat()ing backup path: %s\n",
-                    strerror(errno));
+                    strerror (errno));
            goto DONE;
        }
     }
 
     try {
-       NotmuchCompactor compactor(status_cb);
-
-       compactor.set_renumber(false);
-       compactor.add_source(xapian_path);
-       compactor.set_destdir(compact_xapian_path);
-       compactor.compact();
-    } catch (Xapian::InvalidArgumentError e) {
-       fprintf (stderr, "Error while compacting: %s\n", e.get_msg().c_str());
+       NotmuchCompactor compactor (status_cb, closure);
+
+       compactor.set_renumber (false);
+       compactor.add_source (xapian_path);
+       compactor.set_destdir (compact_xapian_path);
+       compactor.compact ();
+    } catch (const Xapian::Error &error) {
+       fprintf (stderr, "Error while compacting: %s\n", error.get_msg().c_str());
        ret = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
        goto DONE;
     }
 
-    if (old_xapian_path != NULL) {
-       if (rename(xapian_path, old_xapian_path)) {
+    if (backup_path) {
+       if (rename (xapian_path, backup_path)) {
            fprintf (stderr, "Error moving old database out of the way\n");
            ret = NOTMUCH_STATUS_FILE_ERROR;
            goto DONE;
        }
     } else {
-       rmtree(xapian_path);
+       rmtree (xapian_path);
     }
 
-    if (rename(compact_xapian_path, xapian_path)) {
+    if (rename (compact_xapian_path, xapian_path)) {
        fprintf (stderr, "Error moving compacted database\n");
        ret = NOTMUCH_STATUS_FILE_ERROR;
        goto DONE;
     }
 
-    notmuch_database_close(notmuch);
+  DONE:
+    if (notmuch)
+       notmuch_database_destroy (notmuch);
+
+    talloc_free (local);
 
-DONE:
-    talloc_free(local);
     return ret;
 }
 #else
 notmuch_status_t
-notmuch_database_compact (unused (const char* path),
-                         unused (const char* backup_path),
-                         unused (notmuch_compact_status_cb_t status_cb))
+notmuch_database_compact (unused (const char *path),
+                         unused (const char *backup_path),
+                         unused (notmuch_compact_status_cb_t status_cb),
+                         unused (void *closure))
 {
     fprintf (stderr, "notmuch was compiled against a xapian version lacking compaction support.\n");
     return NOTMUCH_STATUS_UNSUPPORTED_OPERATION;
@@ -1534,7 +1540,7 @@ _notmuch_database_generate_doc_id (notmuch_database_t *notmuch)
     notmuch->last_doc_id++;
 
     if (notmuch->last_doc_id == 0)
-       INTERNAL_ERROR ("Xapian document IDs are exhausted.\n");        
+       INTERNAL_ERROR ("Xapian document IDs are exhausted.\n");
 
     return notmuch->last_doc_id;
 }