mirror of
https://git.notmuchmail.org/git/notmuch
synced 2024-12-22 17:34:54 +01:00
lib: Rename set/get_timestamp to set/get_directory_mtime.
I've been suitably scolded by Keith for doing a premature generalization that ended up just making the documentation more convoluted. Fix that.
This commit is contained in:
parent
ba12bf1f26
commit
50ae83a17f
3 changed files with 66 additions and 71 deletions
|
@ -37,7 +37,7 @@ typedef struct {
|
|||
|
||||
/* Here's the current schema for our database:
|
||||
*
|
||||
* We currently have two different types of documents: mail and timestamps.
|
||||
* We currently have two different types of documents: mail and directory.
|
||||
*
|
||||
* Mail document
|
||||
* -------------
|
||||
|
@ -75,21 +75,19 @@ typedef struct {
|
|||
* user in searching. But the database doesn't really care itself
|
||||
* about any of these.
|
||||
*
|
||||
* Timestamp document
|
||||
* Directory document
|
||||
* ------------------
|
||||
* A timestamp document is used by a client of the notmuch library to
|
||||
* A directory document is used by a client of the notmuch library to
|
||||
* maintain data necessary to allow for efficient polling of mail
|
||||
* directories. The notmuch library does no interpretation of
|
||||
* timestamps, but merely allows the user to store and retrieve
|
||||
* timestamps as name/value pairs.
|
||||
* directories.
|
||||
*
|
||||
* The timestamp document is indexed with a single prefixed term:
|
||||
* The directory document is indexed with a single prefixed term:
|
||||
*
|
||||
* timestamp: The user's key value (likely a directory name)
|
||||
* directory: The directory path (an absolute path)
|
||||
*
|
||||
* and has a single value:
|
||||
*
|
||||
* TIMESTAMP: The time_t value from the user.
|
||||
* TIMESTAMP: The mtime of the directory (at last scan)
|
||||
*/
|
||||
|
||||
/* With these prefix values we follow the conventions published here:
|
||||
|
@ -111,7 +109,8 @@ prefix_t BOOLEAN_PREFIX_INTERNAL[] = {
|
|||
{ "type", "T" },
|
||||
{ "reference", "XREFERENCE" },
|
||||
{ "replyto", "XREPLYTO" },
|
||||
{ "timestamp", "XTIMESTAMP" },
|
||||
/* XXX: Need a flag day to rename XTIMESTAMP. */
|
||||
{ "directory", "XTIMESTAMP" },
|
||||
};
|
||||
|
||||
prefix_t BOOLEAN_PREFIX_EXTERNAL[] = {
|
||||
|
@ -561,30 +560,29 @@ notmuch_database_get_path (notmuch_database_t *notmuch)
|
|||
}
|
||||
|
||||
static notmuch_private_status_t
|
||||
find_timestamp_document (notmuch_database_t *notmuch, const char *db_key,
|
||||
find_directory_document (notmuch_database_t *notmuch, const char *db_path,
|
||||
Xapian::Document *doc, unsigned int *doc_id)
|
||||
{
|
||||
return find_unique_document (notmuch, "timestamp", db_key, doc, doc_id);
|
||||
return find_unique_document (notmuch, "directory", db_path, 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.
|
||||
/* We allow the user to use arbitrarily long paths for directories. But
|
||||
* we have a term-length limit. So if we exceed that, we'll use the
|
||||
* SHA-1 of the path for the database term.
|
||||
*
|
||||
* Caution: This function returns a newly allocated string which the
|
||||
* caller should free() when finished.
|
||||
* Note: This function may return the original value of 'path'. If it
|
||||
* does not, then the caller is responsible to free() the returned
|
||||
* value.
|
||||
*/
|
||||
static char *
|
||||
timestamp_db_key (const char *key)
|
||||
static const char *
|
||||
directory_db_path (const char *path)
|
||||
{
|
||||
int term_len = strlen (_find_prefix ("timestamp")) + strlen (key);
|
||||
int term_len = strlen (_find_prefix ("directory")) + strlen (path);
|
||||
|
||||
if (term_len > NOTMUCH_TERM_MAX)
|
||||
return notmuch_sha1_of_string (key);
|
||||
return notmuch_sha1_of_string (path);
|
||||
else
|
||||
return strdup (key);
|
||||
return path;
|
||||
}
|
||||
|
||||
/* Given a legal 'path' for the database, return the relative path.
|
||||
|
@ -622,15 +620,16 @@ _notmuch_database_relative_path (notmuch_database_t *notmuch,
|
|||
}
|
||||
|
||||
notmuch_status_t
|
||||
notmuch_database_set_timestamp (notmuch_database_t *notmuch,
|
||||
const char *key, time_t timestamp)
|
||||
notmuch_database_set_directory_mtime (notmuch_database_t *notmuch,
|
||||
const char *path,
|
||||
time_t mtime)
|
||||
{
|
||||
Xapian::Document doc;
|
||||
Xapian::WritableDatabase *db;
|
||||
unsigned int doc_id;
|
||||
notmuch_private_status_t status;
|
||||
notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS;
|
||||
char *db_key = NULL;
|
||||
const char *db_path = NULL;
|
||||
|
||||
if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_ONLY) {
|
||||
fprintf (stderr, "Attempted to update a read-only database.\n");
|
||||
|
@ -638,17 +637,17 @@ notmuch_database_set_timestamp (notmuch_database_t *notmuch,
|
|||
}
|
||||
|
||||
db = static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db);
|
||||
db_key = timestamp_db_key (key);
|
||||
db_path = directory_db_path (path);
|
||||
|
||||
try {
|
||||
status = find_timestamp_document (notmuch, db_key, &doc, &doc_id);
|
||||
status = find_directory_document (notmuch, db_path, &doc, &doc_id);
|
||||
|
||||
doc.add_value (NOTMUCH_VALUE_TIMESTAMP,
|
||||
Xapian::sortable_serialise (timestamp));
|
||||
Xapian::sortable_serialise (mtime));
|
||||
|
||||
if (status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND) {
|
||||
char *term = talloc_asprintf (NULL, "%s%s",
|
||||
_find_prefix ("timestamp"), db_key);
|
||||
_find_prefix ("directory"), db_path);
|
||||
doc.add_term (term);
|
||||
talloc_free (term);
|
||||
|
||||
|
@ -658,31 +657,32 @@ notmuch_database_set_timestamp (notmuch_database_t *notmuch,
|
|||
}
|
||||
|
||||
} catch (const Xapian::Error &error) {
|
||||
fprintf (stderr, "A Xapian exception occurred setting timestamp: %s.\n",
|
||||
fprintf (stderr, "A Xapian exception occurred setting directory mtime: %s.\n",
|
||||
error.get_msg().c_str());
|
||||
notmuch->exception_reported = TRUE;
|
||||
ret = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
|
||||
}
|
||||
|
||||
if (db_key)
|
||||
free (db_key);
|
||||
if (db_path != path)
|
||||
free ((char *) db_path);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
time_t
|
||||
notmuch_database_get_timestamp (notmuch_database_t *notmuch, const char *key)
|
||||
notmuch_database_get_directory_mtime (notmuch_database_t *notmuch,
|
||||
const char *path)
|
||||
{
|
||||
Xapian::Document doc;
|
||||
unsigned int doc_id;
|
||||
notmuch_private_status_t status;
|
||||
char *db_key = NULL;
|
||||
const char *db_path = NULL;
|
||||
time_t ret = 0;
|
||||
|
||||
db_key = timestamp_db_key (key);
|
||||
db_path = directory_db_path (path);
|
||||
|
||||
try {
|
||||
status = find_timestamp_document (notmuch, db_key, &doc, &doc_id);
|
||||
status = find_directory_document (notmuch, db_path, &doc, &doc_id);
|
||||
|
||||
if (status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND)
|
||||
goto DONE;
|
||||
|
@ -694,8 +694,8 @@ notmuch_database_get_timestamp (notmuch_database_t *notmuch, const char *key)
|
|||
}
|
||||
|
||||
DONE:
|
||||
if (db_key)
|
||||
free (db_key);
|
||||
if (db_path != path)
|
||||
free ((char *) db_path);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -178,56 +178,51 @@ notmuch_database_close (notmuch_database_t *database);
|
|||
const char *
|
||||
notmuch_database_get_path (notmuch_database_t *database);
|
||||
|
||||
/* Store a timestamp within the database.
|
||||
/* Store an mtime within the database for 'path'.
|
||||
*
|
||||
* 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:
|
||||
* The intention is for the caller to use the mtime 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'.
|
||||
* o Call notmuch_database_set_directory_mtime
|
||||
*
|
||||
* 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.
|
||||
* future, the client can call notmuch_database_get_directory_mtime
|
||||
* 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.
|
||||
* Note: The notmuch_database_get_directory_mtime 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_SUCCESS: mtime successfully stored in database.
|
||||
*
|
||||
* NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception
|
||||
* occurred. Timestamp not stored.
|
||||
* occurred, mtime not stored.
|
||||
*/
|
||||
notmuch_status_t
|
||||
notmuch_database_set_timestamp (notmuch_database_t *database,
|
||||
const char *key, time_t timestamp);
|
||||
notmuch_database_set_directory_mtime (notmuch_database_t *database,
|
||||
const char *path,
|
||||
time_t mtime);
|
||||
|
||||
/* Retrieve a timestamp from the database.
|
||||
/* Retrieve the mtime from the database for 'path'.
|
||||
*
|
||||
* Returns the timestamp value previously stored by calling
|
||||
* notmuch_database_set_timestamp with the same value for 'key'.
|
||||
* Returns the mtime value previously stored by calling
|
||||
* notmuch_database_set_directory_mtime with the same 'path'.
|
||||
*
|
||||
* Returns 0 if no timestamp is stored for 'key' or if any error
|
||||
* occurred querying the database.
|
||||
* Returns 0 if no mtime is stored for 'path' or if any error occurred
|
||||
* querying the database.
|
||||
*/
|
||||
time_t
|
||||
notmuch_database_get_timestamp (notmuch_database_t *database,
|
||||
const char *key);
|
||||
notmuch_database_get_directory_mtime (notmuch_database_t *database,
|
||||
const char *path);
|
||||
|
||||
/* Add a new message to the given notmuch database.
|
||||
*
|
||||
|
|
|
@ -146,7 +146,7 @@ add_files_recursive (notmuch_database_t *notmuch,
|
|||
|
||||
path_mtime = st->st_mtime;
|
||||
|
||||
path_dbtime = notmuch_database_get_timestamp (notmuch, path);
|
||||
path_dbtime = notmuch_database_get_directory_mtime (notmuch, path);
|
||||
num_entries = scandir (path, &namelist, 0, ino_cmp);
|
||||
|
||||
if (num_entries == -1) {
|
||||
|
@ -277,7 +277,7 @@ add_files_recursive (notmuch_database_t *notmuch,
|
|||
next = NULL;
|
||||
}
|
||||
|
||||
status = notmuch_database_set_timestamp (notmuch, path, path_mtime);
|
||||
status = notmuch_database_set_directory_mtime (notmuch, path, path_mtime);
|
||||
if (status && ret == NOTMUCH_STATUS_SUCCESS)
|
||||
ret = status;
|
||||
|
||||
|
|
Loading…
Reference in a new issue