aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Carl Worth <cworth@cworth.org>2009-10-28 16:50:14 -0700
committerGravatar Carl Worth <cworth@cworth.org>2009-10-28 16:51:56 -0700
commita1135f0b7e67db7056a4ef02d61b8ad0ec46e88b (patch)
tree1ecece326675b8364b406c224838674c5b211d29
parentfbf55bfe2fdcdf3773ba37a9921875530e94c7b3 (diff)
Fix add_message and get_filename to strip/re-add the database path.
We now store only a relative path inside the database so the database is not nicely relocatable.
-rw-r--r--database.cc19
-rw-r--r--message.cc54
-rw-r--r--notmuch-private.h2
-rw-r--r--notmuch.c24
-rw-r--r--notmuch.h18
5 files changed, 89 insertions, 28 deletions
diff --git a/database.cc b/database.cc
index d7cd26c7..3e00aa59 100644
--- a/database.cc
+++ b/database.cc
@@ -487,6 +487,9 @@ notmuch_database_open (const char *path)
notmuch = talloc (NULL, notmuch_database_t);
notmuch->path = talloc_strdup (notmuch, path);
+ if (notmuch->path[strlen (notmuch->path) - 1] == '/')
+ notmuch->path[strlen (notmuch->path) - 1] = '\0';
+
try {
notmuch->xapian_db = new Xapian::WritableDatabase (xapian_path,
Xapian::DB_CREATE_OR_OPEN);
@@ -856,9 +859,10 @@ notmuch_database_add_message (notmuch_database_t *notmuch,
notmuch_message_file_t *message_file;
notmuch_message_t *message;
notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS;
+ notmuch_private_status_t private_status;
const char *date, *header;
- const char *from, *to, *subject, *old_filename;
+ const char *from, *to, *subject;
char *message_id;
if (message_ret)
@@ -932,21 +936,20 @@ notmuch_database_add_message (notmuch_database_t *notmuch,
message = _notmuch_message_create_for_message_id (NULL,
notmuch,
message_id,
- &ret);
+ &private_status);
talloc_free (message_id);
if (message == NULL)
goto DONE;
- /* Has a message previously been added with the same ID? */
- old_filename = notmuch_message_get_filename (message);
- if (old_filename && strlen (old_filename)) {
- ret = NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID;
- goto DONE;
- } else {
+ /* Is this a newly created message object? */
+ if (private_status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND) {
_notmuch_message_set_filename (message, filename);
_notmuch_message_add_term (message, "type", "mail");
+ } else {
+ ret = NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID;
+ goto DONE;
}
ret = _notmuch_database_link_message (notmuch, message, message_file);
diff --git a/message.cc b/message.cc
index 75e752c8..169b20c1 100644
--- a/message.cc
+++ b/message.cc
@@ -146,7 +146,8 @@ _notmuch_message_create (const void *talloc_owner,
* If there is already a document with message ID 'message_id' in the
* database, then the returned message can be used to query/modify the
* document. Otherwise, a new document will be inserted into the
- * database before this function returns.
+ * database before this function returns, (and *status will be set
+ * to NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND).
*
* If an error occurs, this function will return NULL and *status
* will be set as appropriate. (The status pointer argument must
@@ -156,15 +157,14 @@ notmuch_message_t *
_notmuch_message_create_for_message_id (const void *talloc_owner,
notmuch_database_t *notmuch,
const char *message_id,
- notmuch_status_t *status)
+ notmuch_private_status_t *status_ret)
{
- notmuch_private_status_t private_status;
notmuch_message_t *message;
Xapian::Document doc;
unsigned int doc_id;
char *term;
- *status = NOTMUCH_STATUS_SUCCESS;
+ *status_ret = NOTMUCH_PRIVATE_STATUS_SUCCESS;
message = notmuch_database_find_message (notmuch, message_id);
if (message)
@@ -173,7 +173,7 @@ _notmuch_message_create_for_message_id (const void *talloc_owner,
term = talloc_asprintf (NULL, "%s%s",
_find_prefix ("id"), message_id);
if (term == NULL) {
- *status = NOTMUCH_STATUS_OUT_OF_MEMORY;
+ *status_ret = NOTMUCH_PRIVATE_STATUS_OUT_OF_MEMORY;
return NULL;
}
@@ -185,15 +185,17 @@ _notmuch_message_create_for_message_id (const void *talloc_owner,
doc_id = notmuch->xapian_db->add_document (doc);
} catch (const Xapian::Error &error) {
- *status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
+ *status_ret = NOTMUCH_PRIVATE_STATUS_XAPIAN_EXCEPTION;
return NULL;
}
message = _notmuch_message_create (talloc_owner, notmuch,
- doc_id, &private_status);
+ doc_id, status_ret);
- *status = COERCE_STATUS (private_status,
- "Failed to find dcocument after inserting it.");
+ /* We want to inform the caller that we had to create a new
+ * document. */
+ if (*status_ret == NOTMUCH_PRIVATE_STATUS_SUCCESS)
+ *status_ret = NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND;
return message;
}
@@ -297,21 +299,49 @@ void
_notmuch_message_set_filename (notmuch_message_t *message,
const char *filename)
{
- if (message->filename)
+ const char *s;
+ const char *db_path;
+ unsigned int db_path_len;
+
+ if (message->filename) {
talloc_free (message->filename);
- message->doc.set_data (filename);
+ message->filename = NULL;
+ }
+
+ if (filename == NULL)
+ INTERNAL_ERROR ("Message filename cannot be NULL.");
+
+ s = filename;
+
+ db_path = notmuch_database_get_path (message->notmuch);
+ db_path_len = strlen (db_path);
+
+ if (*s == '/' && strncmp (s, db_path, db_path_len) == 0
+ && strlen (s) > db_path_len)
+ {
+ s += db_path_len + 1;
+ }
+
+ message->doc.set_data (s);
}
const char *
notmuch_message_get_filename (notmuch_message_t *message)
{
std::string filename_str;
+ const char *db_path;
if (message->filename)
return message->filename;
filename_str = message->doc.get_data ();
- message->filename = talloc_strdup (message, filename_str.c_str ());
+ db_path = notmuch_database_get_path (message->notmuch);
+
+ if (filename_str[0] != '/')
+ message->filename = talloc_asprintf (message, "%s/%s", db_path,
+ filename_str.c_str ());
+ else
+ message->filename = talloc_strdup (message, filename_str.c_str ());
return message->filename;
}
diff --git a/notmuch-private.h b/notmuch-private.h
index 440860ba..da36c300 100644
--- a/notmuch-private.h
+++ b/notmuch-private.h
@@ -172,7 +172,7 @@ notmuch_message_t *
_notmuch_message_create_for_message_id (const void *talloc_owner,
notmuch_database_t *notmuch,
const char *message_id,
- notmuch_status_t *status);
+ notmuch_private_status_t *status);
const char *
_notmuch_message_get_subject (notmuch_message_t *message);
diff --git a/notmuch.c b/notmuch.c
index 5a0ca5c9..757f09d7 100644
--- a/notmuch.c
+++ b/notmuch.c
@@ -531,6 +531,30 @@ setup_command (unused (int argc), unused (char *argv[]))
free (default_path);
}
+ /* Coerce th directory into an absolute directory name. */
+ if (*mail_directory != '/') {
+ char *cwd, *absolute_mail_directory;
+
+ cwd = getcwd (NULL, 0);
+ if (cwd == NULL) {
+ fprintf (stderr, "Out of memory.\n");
+ exit (1);
+ }
+
+ if (asprintf (&absolute_mail_directory, "%s/%s",
+ cwd, mail_directory) < 0)
+ {
+ fprintf (stderr, "Out of memory.\n");
+ exit (1);
+ }
+
+ free (cwd);
+ free (mail_directory);
+ mail_directory = absolute_mail_directory;
+
+ printf ("Abs: %s\n", mail_directory);
+ }
+
notmuch = notmuch_database_create (mail_directory);
if (notmuch == NULL) {
fprintf (stderr, "Failed to create new notmuch database at %s\n",
diff --git a/notmuch.h b/notmuch.h
index f4e59ab2..165fe852 100644
--- a/notmuch.h
+++ b/notmuch.h
@@ -246,11 +246,14 @@ notmuch_database_get_timestamp (notmuch_database_t *database,
/* Add a new message to the given notmuch database.
*
* Here,'filename' should be a path relative to the the path of
- * 'database' (see notmuch_database_get_path). The file should be a
- * single mail message (not a multi-message mbox) that is expected to
- * remain at its current location, (since the notmuch database will
- * reference the filename, and will not copy the entire contents of
- * the file.
+ * 'database' (see notmuch_database_get_path), or else should be an
+ * absolute filename with initial components that match the path of
+ * 'database'.
+ *
+ * The file should be a single mail message (not a multi-message mbox)
+ * that is expected to remain at its current location, (since the
+ * notmuch database will reference the filename, and will not copy the
+ * entire contents of the file.
*
* If 'message' is not NULL, then, on successful return '*message'
* will be initialized to a message object that can be used for things
@@ -605,8 +608,9 @@ notmuch_message_get_thread_id (notmuch_message_t *message);
/* Get the filename for the email corresponding to 'message'.
*
- * The returned filename is relative to the base of the database from
- * which 'message' was obtained. See notmuch_database_get_path() .
+ * The returned filename is an absolute filename, (the initial
+ * component will match notmuch_database_get_path() ).
+ *
* The returned string belongs to the message so should not be
* modified or freed by the caller (nor should it be referenced after
* the message is destroyed). */