mirror of
https://git.notmuchmail.org/git/notmuch
synced 2024-11-24 20:08:10 +01:00
Add notmuch_database_set_timestamp and notmuch_database_get_timestamp
These will be very helpful to implement an efficient "notmuch new" command which imports new mail messages that have appeared.
This commit is contained in:
parent
668f20bdfb
commit
68a10091d6
5 changed files with 158 additions and 9 deletions
95
database.cc
95
database.cc
|
@ -484,6 +484,101 @@ notmuch_database_get_path (notmuch_database_t *notmuch)
|
|||
return notmuch->path;
|
||||
}
|
||||
|
||||
notmuch_private_status_t
|
||||
find_timestamp_document (notmuch_database_t *notmuch, const char *db_key,
|
||||
Xapian::Document *doc, unsigned int *doc_id)
|
||||
{
|
||||
return find_unique_document (notmuch, "timestamp", db_key, doc, doc_id);
|
||||
}
|
||||
|
||||
/* We allow the user to use arbitrarily long keys for timestamps,
|
||||
* (they're for filesystem paths after all, which have no limit we
|
||||
* know about). But we have a term-length limit. So if we exceed that,
|
||||
* we'll use the SHA-1 of the user's key as the actual key for
|
||||
* constructing a database term.
|
||||
*
|
||||
* Caution: This function returns a newly allocated string which the
|
||||
* caller should free() when finished.
|
||||
*/
|
||||
static char *
|
||||
timestamp_db_key (const char *key)
|
||||
{
|
||||
if (strlen (key) + 1 > NOTMUCH_TERM_MAX) {
|
||||
return notmuch_sha1_of_string (key);
|
||||
} else {
|
||||
return strdup (key);
|
||||
}
|
||||
}
|
||||
|
||||
notmuch_status_t
|
||||
notmuch_database_set_timestamp (notmuch_database_t *notmuch,
|
||||
const char *key, time_t timestamp)
|
||||
{
|
||||
Xapian::Document doc;
|
||||
unsigned int doc_id;
|
||||
notmuch_private_status_t status;
|
||||
notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS;
|
||||
char *db_key = NULL;
|
||||
|
||||
db_key = timestamp_db_key (key);
|
||||
|
||||
try {
|
||||
status = find_timestamp_document (notmuch, db_key, &doc, &doc_id);
|
||||
|
||||
doc.add_value (0, Xapian::sortable_serialise (timestamp));
|
||||
|
||||
if (status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND) {
|
||||
char *term = talloc_asprintf (NULL, "%s%s",
|
||||
_find_prefix ("timestamp"), db_key);
|
||||
doc.add_term (term);
|
||||
talloc_free (term);
|
||||
|
||||
notmuch->xapian_db->add_document (doc);
|
||||
} else {
|
||||
notmuch->xapian_db->replace_document (doc_id, doc);
|
||||
}
|
||||
|
||||
} catch (Xapian::Error &error) {
|
||||
fprintf (stderr, "A Xapian exception occurred: %s.\n",
|
||||
error.get_msg().c_str());
|
||||
ret = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
||||
}
|
||||
|
||||
if (db_key)
|
||||
free (db_key);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
time_t
|
||||
notmuch_database_get_timestamp (notmuch_database_t *notmuch, const char *key)
|
||||
{
|
||||
Xapian::Document doc;
|
||||
unsigned int doc_id;
|
||||
notmuch_private_status_t status;
|
||||
char *db_key = NULL;
|
||||
time_t ret = 0;
|
||||
|
||||
db_key = timestamp_db_key (key);
|
||||
|
||||
try {
|
||||
status = find_timestamp_document (notmuch, db_key, &doc, &doc_id);
|
||||
|
||||
if (status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND)
|
||||
goto DONE;
|
||||
|
||||
ret = Xapian::sortable_unserialise (doc.get_value (0));
|
||||
} catch (Xapian::Error &error) {
|
||||
goto DONE;
|
||||
}
|
||||
|
||||
DONE:
|
||||
if (db_key)
|
||||
free (db_key);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
notmuch_status_t
|
||||
notmuch_database_add_message (notmuch_database_t *notmuch,
|
||||
const char *filename)
|
||||
|
|
|
@ -82,7 +82,8 @@ prefix_t BOOLEAN_PREFIX[] = {
|
|||
{ "attachment_extension", "O" },
|
||||
{ "msgid", "Q" },
|
||||
{ "thread", "H" },
|
||||
{ "ref", "R" }
|
||||
{ "ref", "R" },
|
||||
{ "timestamp", "KTS" },
|
||||
};
|
||||
|
||||
const char *
|
||||
|
|
|
@ -21,15 +21,15 @@
|
|||
#ifndef NOTMUCH_PRIVATE_H
|
||||
#define NOTMUCH_PRIVATE_H
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE /* For getline */
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
|
||||
#include "notmuch.h"
|
||||
|
||||
NOTMUCH_BEGIN_DECLS
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE /* For getline */
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/types.h>
|
||||
|
|
|
@ -18,11 +18,12 @@
|
|||
* Author: Carl Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#include "notmuch.h"
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE /* for getline */
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
|
||||
#include "notmuch.h"
|
||||
|
||||
/* This is separate from notmuch-private.h because we're trying to
|
||||
* keep notmuch.c from looking into any internals, (which helps us
|
||||
|
@ -30,7 +31,6 @@
|
|||
*/
|
||||
#include "xutil.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
|
53
notmuch.h
53
notmuch.h
|
@ -31,6 +31,8 @@
|
|||
|
||||
NOTMUCH_BEGIN_DECLS
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
@ -172,6 +174,57 @@ notmuch_database_default_path (void);
|
|||
const char *
|
||||
notmuch_database_get_path (notmuch_database_t *database);
|
||||
|
||||
/* Store a timestamp within the database.
|
||||
*
|
||||
* The Notmuch database will not interpret this key nor the timestamp
|
||||
* values at all. It will merely store them together and return the
|
||||
* timestamp when notmuch_database_get_timestamp is called with the
|
||||
* same value for 'key'.
|
||||
*
|
||||
* The intention is for the caller to use the timestamp to allow
|
||||
* efficient identification of new messages to be added to the
|
||||
* database. The recommended usage is as follows:
|
||||
*
|
||||
* o Read the mtime of a directory from the filesystem
|
||||
*
|
||||
* o Call add_message for all mail files in the directory
|
||||
*
|
||||
* o Call notmuch_database_set_timestamp with the path of the
|
||||
* directory as 'key' and the originally read mtime as 'value'.
|
||||
*
|
||||
* Then, when wanting to check for updates to the directory in the
|
||||
* future, the client can call notmuch_database_get_timestamp and know
|
||||
* that it only needs to add files if the mtime of the directory and
|
||||
* files are newer than the stored timestamp.
|
||||
*
|
||||
* Note: The notmuch_database_get_timestamp function does not allow
|
||||
* the caller to distinguish a timestamp of 0 from a non-existent
|
||||
* timestamp. So don't store a timestamp of 0 unless you are
|
||||
* comfortable with that.
|
||||
*
|
||||
* Return value:
|
||||
*
|
||||
* NOTMUCH_STATUS_SUCCESS: Timestamp successfully stored in database.
|
||||
*
|
||||
* NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception
|
||||
* occurred. Timestamp not stored.
|
||||
*/
|
||||
notmuch_status_t
|
||||
notmuch_database_set_timestamp (notmuch_database_t *database,
|
||||
const char *key, time_t timestamp);
|
||||
|
||||
/* Retrieve a timestamp from the database.
|
||||
*
|
||||
* Returns the timestamp value previously stored by calling
|
||||
* notmuch_database_set_timestamp with the same value for 'key'.
|
||||
*
|
||||
* Returns 0 if no timestamp is stored for 'key' or if any error
|
||||
* occurred querying the database.
|
||||
*/
|
||||
time_t
|
||||
notmuch_database_get_timestamp (notmuch_database_t *database,
|
||||
const char *key);
|
||||
|
||||
/* Add a new message to the given notmuch database.
|
||||
*
|
||||
* Here,'filename' should be a path relative to the the path of
|
||||
|
|
Loading…
Reference in a new issue