mirror of
https://git.notmuchmail.org/git/notmuch
synced 2024-12-22 09:24:54 +01:00
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.
This commit is contained in:
parent
fbf55bfe2f
commit
a1135f0b7e
5 changed files with 89 additions and 28 deletions
19
database.cc
19
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);
|
||||
|
|
54
message.cc
54
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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
24
notmuch.c
24
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",
|
||||
|
|
18
notmuch.h
18
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). */
|
||||
|
|
Loading…
Reference in a new issue