*
* and has a single value:
*
- * TIMETAMPS: The time_t value from the user.
+ * TIMESTAMP: The time_t value from the user.
*/
/* With these prefix values we follow the conventions published here:
prefix_t BOOLEAN_PREFIX_INTERNAL[] = {
{ "type", "T" },
- { "thread", "G" },
{ "ref", "XREFERENCE" },
{ "timestamp", "XTIMESTAMP" },
+ { "contact", "XCONTACT" }
};
prefix_t BOOLEAN_PREFIX_EXTERNAL[] = {
+ { "thread", "G" },
{ "tag", "K" },
{ "id", "Q" }
};
+prefix_t PROBABILISTIC_PREFIX[]= {
+ { "from", "XFROM" },
+ { "to", "XTO" },
+ { "attachment", "XATTACHMENT" },
+ { "subject", "XSUBJECT"}
+};
+
int
_internal_error (const char *format, ...)
{
va_start (va_args, format);
+ fprintf (stderr, "Internal error: ");
vfprintf (stderr, format, va_args);
exit (1);
if (strcmp (name, BOOLEAN_PREFIX_EXTERNAL[i].name) == 0)
return BOOLEAN_PREFIX_EXTERNAL[i].prefix;
+ for (i = 0; i < ARRAY_SIZE (PROBABILISTIC_PREFIX); i++)
+ if (strcmp (name, PROBABILISTIC_PREFIX[i].name) == 0)
+ return PROBABILISTIC_PREFIX[i].prefix;
+
INTERNAL_ERROR ("No prefix exists for '%s'\n", name);
return "";
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);
notmuch->query_parser = new Xapian::QueryParser;
+ notmuch->term_gen = new Xapian::TermGenerator;
+ notmuch->term_gen->set_stemmer (Xapian::Stem ("english"));
+
notmuch->query_parser->set_default_op (Xapian::Query::OP_AND);
notmuch->query_parser->set_database (*notmuch->xapian_db);
+ notmuch->query_parser->set_stemmer (Xapian::Stem ("english"));
+ notmuch->query_parser->set_stemming_strategy (Xapian::QueryParser::STEM_SOME);
for (i = 0; i < ARRAY_SIZE (BOOLEAN_PREFIX_EXTERNAL); i++) {
prefix_t *prefix = &BOOLEAN_PREFIX_EXTERNAL[i];
notmuch->query_parser->add_boolean_prefix (prefix->name,
prefix->prefix);
}
+
+ for (i = 0; i < ARRAY_SIZE (PROBABILISTIC_PREFIX); i++) {
+ prefix_t *prefix = &PROBABILISTIC_PREFIX[i];
+ notmuch->query_parser->add_prefix (prefix->name, prefix->prefix);
+ }
} catch (const Xapian::Error &error) {
fprintf (stderr, "A Xapian exception occurred: %s\n",
error.get_msg().c_str());
+ notmuch = NULL;
}
DONE:
{
notmuch->xapian_db->flush ();
+ delete notmuch->term_gen;
delete notmuch->query_parser;
delete notmuch->xapian_db;
talloc_free (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)
(char *) NULL);
try {
- /* The first order of business is to find/create a message ID. */
+ /* Before we do any real work, (especially before doing a
+ * potential SHA-1 computation on the entire file's contents),
+ * let's make sure that what we're looking at looks like an
+ * actual email message.
+ */
+ from = notmuch_message_file_get_header (message_file, "from");
+ subject = notmuch_message_file_get_header (message_file, "subject");
+ to = notmuch_message_file_get_header (message_file, "to");
+
+ if (from == NULL &&
+ subject == NULL &&
+ to == NULL)
+ {
+ ret = NOTMUCH_STATUS_FILE_NOT_EMAIL;
+ goto DONE;
+ }
+
+ /* Now that we're sure it's mail, the first order of business
+ * is to find a message ID (or else create one ourselves). */
header = notmuch_message_file_get_header (message_file, "message-id");
if (header) {
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);
date = notmuch_message_file_get_header (message_file, "date");
_notmuch_message_set_date (message, date);
- from = notmuch_message_file_get_header (message_file, "from");
- subject = notmuch_message_file_get_header (message_file, "subject");
- to = notmuch_message_file_get_header (message_file, "to");
+ _notmuch_message_index_file (message, filename);
- if (from == NULL &&
- subject == NULL &&
- to == NULL)
- {
- ret = NOTMUCH_STATUS_FILE_NOT_EMAIL;
- goto DONE;
- } else {
- _notmuch_message_sync (message);
- }
+ _notmuch_message_sync (message);
} catch (const Xapian::Error &error) {
fprintf (stderr, "A Xapian exception occurred: %s.\n",
error.get_msg().c_str());