--- /dev/null
+Return-Path: <schnouki@schnouki.net>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+ by olra.theworths.org (Postfix) with ESMTP id 3AAAA429E25\r
+ for <notmuch@notmuchmail.org>; Tue, 13 Dec 2011 09:12:11 -0800 (PST)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -0.1\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-0.1 tagged_above=-999 required=5\r
+ tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1]\r
+ autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+ by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+ with ESMTP id cNxkHsTdUanm for <notmuch@notmuchmail.org>;\r
+ Tue, 13 Dec 2011 09:12:09 -0800 (PST)\r
+Received: from ks3536.kimsufi.com (schnouki.net [87.98.217.222])\r
+ by olra.theworths.org (Postfix) with ESMTP id 0C4A0429E29\r
+ for <notmuch@notmuchmail.org>; Tue, 13 Dec 2011 09:12:09 -0800 (PST)\r
+Received: from thor.loria.fr (thor.loria.fr [152.81.12.250])\r
+ by ks3536.kimsufi.com (Postfix) with ESMTPSA id 41AAF6A002A;\r
+ Tue, 13 Dec 2011 18:12:08 +0100 (CET)\r
+DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=schnouki.net;\r
+ s=key-schnouki; t=1323796328;\r
+ bh=EtHcMD+7gqtNXmtfU4FRCK6w1Rq9oohRWUpyVSw04Bs=;\r
+ h=From:To:Subject:Date:Message-Id:In-Reply-To:References;\r
+ b=L/kg4l4zxHSnDdZvgM1h/4rNe5e7f3RGBjadOvS6Ui8c49fZxlm6d71cQFmauApd+\r
+ 9M30B/f7nYhd4b0tFTcF1GqDj3JQN14nxaNVf5doMVX30UnclojQ8tjuENpP+0jvVW\r
+ 8JGY7xevU8Sjc4NqPUsxB/JNtRIfYrRqWxszoZlk=\r
+From: Thomas Jost <schnouki@schnouki.net>\r
+To: notmuch@notmuchmail.org\r
+Subject: [PATCH 2/5] lib: Add a MTIME value to every mail document\r
+Date: Tue, 13 Dec 2011 18:11:42 +0100\r
+Message-Id: <1323796305-28789-3-git-send-email-schnouki@schnouki.net>\r
+X-Mailer: git-send-email 1.7.8\r
+In-Reply-To: <1323796305-28789-1-git-send-email-schnouki@schnouki.net>\r
+References: <1323796305-28789-1-git-send-email-schnouki@schnouki.net>\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+ <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Tue, 13 Dec 2011 17:12:11 -0000\r
+\r
+This is a time_t value, similar to the message date (TIMESTAMP). It is first set\r
+when the message is added to the database, and is then updated every time a tag\r
+is added or removed. It can thus be used for doing incremental dumps of the\r
+database or for synchronizing it between several computers.\r
+\r
+This value can be read freely (with notmuch_message_get_mtime()) but for now it\r
+can't be set to an arbitrary value: it can only be set to "now" when updated.\r
+There's no specific reason for this except that I don't really see a real use\r
+case for setting it to an arbitrary value.\r
+---\r
+ lib/database.cc | 7 ++++++-\r
+ lib/message.cc | 32 ++++++++++++++++++++++++++++++++\r
+ lib/notmuch-private.h | 6 +++++-\r
+ lib/notmuch.h | 4 ++++\r
+ 4 files changed, 47 insertions(+), 2 deletions(-)\r
+\r
+diff --git a/lib/database.cc b/lib/database.cc\r
+index 2025189..6dc6f73 100644\r
+--- a/lib/database.cc\r
++++ b/lib/database.cc\r
+@@ -81,7 +81,7 @@ typedef struct {\r
+ * STRING is the name of a file within that\r
+ * directory for this mail message.\r
+ *\r
+- * A mail document also has four values:\r
++ * A mail document also has five values:\r
+ *\r
+ * TIMESTAMP: The time_t value corresponding to the message's\r
+ * Date header.\r
+@@ -92,6 +92,9 @@ typedef struct {\r
+ *\r
+ * SUBJECT: The value of the "Subject" header\r
+ *\r
++ * MTIME: The time_t value corresponding to the last time\r
++ * a tag was added or removed on the message.\r
++ *\r
+ * In addition, terms from the content of the message are added with\r
+ * "from", "to", "attachment", and "subject" prefixes for use by the\r
+ * user in searching. Similarly, terms from the path of the mail\r
+@@ -1735,6 +1738,8 @@ notmuch_database_add_message (notmuch_database_t *notmuch,\r
+ date = notmuch_message_file_get_header (message_file, "date");\r
+ _notmuch_message_set_header_values (message, date, from, subject);\r
+ \r
++ _notmuch_message_update_mtime (message);\r
++\r
+ _notmuch_message_index_file (message, filename);\r
+ } else {\r
+ ret = NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID;\r
+diff --git a/lib/message.cc b/lib/message.cc\r
+index 0075425..0c98589 100644\r
+--- a/lib/message.cc\r
++++ b/lib/message.cc\r
+@@ -830,6 +830,34 @@ _notmuch_message_set_header_values (notmuch_message_t *message,\r
+ message->doc.add_value (NOTMUCH_VALUE_SUBJECT, subject);\r
+ }\r
+ \r
++/* Get the message mtime, i.e. when it was added or the last time a tag was\r
++ * added/removed. */\r
++time_t\r
++notmuch_message_get_mtime (notmuch_message_t *message)\r
++{\r
++ std::string value;\r
++\r
++ try {\r
++ value = message->doc.get_value (NOTMUCH_VALUE_MTIME);\r
++ } catch (Xapian::Error &error) {\r
++ INTERNAL_ERROR ("Failed to read mtime value from document.");\r
++ return 0;\r
++ }\r
++\r
++ return Xapian::sortable_unserialise (value);\r
++}\r
++\r
++/* Set the message mtime to "now". */\r
++void\r
++_notmuch_message_update_mtime (notmuch_message_t *message)\r
++{\r
++ time_t time_value;\r
++\r
++ time_value = time (NULL);\r
++ message->doc.add_value (NOTMUCH_VALUE_MTIME,\r
++ Xapian::sortable_serialise (time_value));\r
++}\r
++\r
+ /* Synchronize changes made to message->doc out into the database. */\r
+ void\r
+ _notmuch_message_sync (notmuch_message_t *message)\r
+@@ -994,6 +1022,8 @@ notmuch_message_add_tag (notmuch_message_t *message, const char *tag)\r
+ private_status);\r
+ }\r
+ \r
++ _notmuch_message_update_mtime (message);\r
++\r
+ if (! message->frozen)\r
+ _notmuch_message_sync (message);\r
+ \r
+@@ -1022,6 +1052,8 @@ notmuch_message_remove_tag (notmuch_message_t *message, const char *tag)\r
+ private_status);\r
+ }\r
+ \r
++ _notmuch_message_update_mtime (message);\r
++\r
+ if (! message->frozen)\r
+ _notmuch_message_sync (message);\r
+ \r
+diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h\r
+index 60a932f..9859872 100644\r
+--- a/lib/notmuch-private.h\r
++++ b/lib/notmuch-private.h\r
+@@ -95,7 +95,8 @@ typedef enum {\r
+ NOTMUCH_VALUE_TIMESTAMP = 0,\r
+ NOTMUCH_VALUE_MESSAGE_ID,\r
+ NOTMUCH_VALUE_FROM,\r
+- NOTMUCH_VALUE_SUBJECT\r
++ NOTMUCH_VALUE_SUBJECT,\r
++ NOTMUCH_VALUE_MTIME\r
+ } notmuch_value_t;\r
+ \r
+ /* Xapian (with flint backend) complains if we provide a term longer\r
+@@ -276,6 +277,9 @@ _notmuch_message_set_header_values (notmuch_message_t *message,\r
+ const char *from,\r
+ const char *subject);\r
+ void\r
++_notmuch_message_update_mtime (notmuch_message_t *message);\r
++\r
++void\r
+ _notmuch_message_sync (notmuch_message_t *message);\r
+ \r
+ notmuch_status_t\r
+diff --git a/lib/notmuch.h b/lib/notmuch.h\r
+index 9f23a10..643ebce 100644\r
+--- a/lib/notmuch.h\r
++++ b/lib/notmuch.h\r
+@@ -910,6 +910,10 @@ notmuch_message_set_flag (notmuch_message_t *message,\r
+ time_t\r
+ notmuch_message_get_date (notmuch_message_t *message);\r
+ \r
++/* Get the mtime of 'message' as a time_t value. */\r
++time_t\r
++notmuch_message_get_mtime (notmuch_message_t *message);\r
++\r
+ /* Get the value of the specified header from 'message'.\r
+ *\r
+ * The value will be read from the actual message file, not from the\r
+-- \r
+1.7.8\r
+\r