]> git.notmuchmail.org Git - notmuch/blobdiff - database.cc
Add comment documenting our current database schema.
[notmuch] / database.cc
index 928e91ba7585617f9a64c3634b3ef2f39f6a3f0f..b392914190bb2f6247d89af371e0a86d56301938 100644 (file)
@@ -35,6 +35,55 @@ typedef struct {
     const char *prefix;
 } prefix_t;
 
+/* Here's the current schema for our database:
+ *
+ * We currently have two different types of documents: mail and timestamps.
+ *
+ * Mail document
+ * -------------
+ * A mail document is associated with a particular email message file
+ * on disk. It is indexed with the following prefixed terms:
+ *
+ *    Single terms of given prefix:
+ *
+ *     type:   mail
+ *
+ *     id:     Unique ID of mail, (from Message-ID header or generated
+ *             as "notmuch-sha1-<sha1_sum_of_entire_file>.
+ *
+ *    Multiple terms of given prefix:
+ *
+ *     ref:    The message IDs from all In-Reply-To and References
+ *             headers in the message.
+ *
+ *     tag:    Any tags associated with this message by the user.
+ *
+ *     thread: The thread ID of all threads to which the mail belongs
+ *
+ *    A mail document also has two values:
+ *
+ *     TIMESTAMP:      The time_t value corresponding to the message's
+ *                     Date header.
+ *
+ *     MESSAGE_ID:     The unique ID of the mail mess (see "id" above)
+ *
+ * Timestamp document
+ * ------------------
+ * A timestamp 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.
+ *
+ * The timestamp document is indexed with a single prefixed term:
+ *
+ *     timestamp:      The user's key value (likely a directory name)
+ *
+ * and has a single value:
+ *
+ *     TIMETAMPS:      The time_t value from the user.
+ */
+
 /* With these prefix values we follow the conventions published here:
  *
  * http://xapian.org/docs/omega/termprefixes.html
@@ -192,26 +241,34 @@ find_unique_document (notmuch_database_t *notmuch,
     return NOTMUCH_PRIVATE_STATUS_SUCCESS;
 }
 
+/* XXX: Should rewrite this to accept a notmuch_message_t* instead of
+ * a Xapian:Document and then we could just use
+ * notmuch_message_get_thread_ids instead of duplicating its logic
+ * here. */
 static void
 insert_thread_id (GHashTable *thread_ids, Xapian::Document doc)
 {
     string value_string;
-    const char *value, *id, *comma;
-
-    value_string = doc.get_value (NOTMUCH_VALUE_THREAD);
-    value = value_string.c_str();
-    if (strlen (value)) {
-       id = value;
-       while (*id) {
-           comma = strchr (id, ',');
-           if (comma == NULL)
-               comma = id + strlen (id);
-           g_hash_table_insert (thread_ids,
-                                strndup (id, comma - id), NULL);
-           id = comma;
-           if (*id)
-               id++;
-       }
+    Xapian::TermIterator i;
+    const char *prefix_str = _find_prefix ("thread");
+    char prefix;
+
+    assert (strlen (prefix_str) == 1);
+
+    prefix = *prefix_str;
+
+    i = doc.termlist_begin ();
+    i.skip_to (prefix_str);
+
+    while (1) {
+       if (i == doc.termlist_end ())
+           break;
+       value_string = *i;
+       if (value_string.empty () || value_string[0] != prefix)
+           break;
+       g_hash_table_insert (thread_ids,
+                            strdup (value_string.c_str () + 1), NULL);
+       i++;
     }
 }
 
@@ -588,7 +645,8 @@ notmuch_database_set_timestamp (notmuch_database_t *notmuch,
     try {
        status = find_timestamp_document (notmuch, db_key, &doc, &doc_id);
 
-       doc.add_value (0, Xapian::sortable_serialise (timestamp));
+       doc.add_value (NOTMUCH_VALUE_TIMESTAMP,
+                      Xapian::sortable_serialise (timestamp));
 
        if (status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND) {
            char *term = talloc_asprintf (NULL, "%s%s",
@@ -630,7 +688,7 @@ notmuch_database_get_timestamp (notmuch_database_t *notmuch, const char *key)
        if (status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND)
            goto DONE;
 
-       ret =  Xapian::sortable_unserialise (doc.get_value (0));
+       ret =  Xapian::sortable_unserialise (doc.get_value (NOTMUCH_VALUE_TIMESTAMP));
     } catch (Xapian::Error &error) {
        goto DONE;
     }