summaryrefslogtreecommitdiff
path: root/lib/database.cc
AgeCommit message (Collapse)Author
2017-02-22lib: fix g_hash_table related read-after-free bugDavid Bremner
The two g_hash_table functions (insert, add) have different behaviour with respect to existing keys. g_hash_table_insert frees the new key, while g_hash_table_add (which is really g_hash_table_replace in disguise) frees the existing key. With this change 'ref' is live until the end of the function (assuming single-threaded access to 'hash'). We can't guarantee it will continue to be live in the future (i.e. there may be a future key duplication) so we copy it with the allocation context passed to parse_references (in practice this is the notmuch_message_t object whose parents we are finding). Thanks to Tomi for the simpler approach to the problem based on reading the fine glib manual.
2016-10-06require xapian >= 1.2.6David Bremner
It seems that no-one tried to compile without Xapian compact support since March of 2015, since that's when I introduced a syntax error in that branch of the ifdef. Given the choice of maintaining this underused branch of code, or bumping the Xapian dependency to a version from 2011, it seems reasonable to do the latter.
2016-09-28lib/database.cc: fix misleading indentationTomi Ollila
Found by gcc 6.1.1 -Wmisleading-indentation option (set by -Wall).
2016-09-21add property: query prefix to search for specific propertiesDaniel Kahn Gillmor
We want to be able to query the properties directly, like: notmuch count property:foo=bar which should return a count of messages where the property with key "foo" has value equal to "bar".
2016-09-21lib: read "property" terms from messages.David Bremner
This is a first step towards providing an API to attach arbitrary (key,value) pairs to messages and retrieve all of the values for a given key.
2016-08-18lib: reword comment about XFOLDER: prefixDavid Bremner
I believe the current one is misleading, because in my experiments Xapian did not add : when prefix and term were both upper case. Indeed, it's hard to see how it could, because prefixes are added at a layer above Xapian in our code. See _notmuch_message_add_term for an example. Also try to explain why this is a good idea. As far as I can ascertain, this is more of an issue for a system trying to work with an unknown set of prefixes. Since notmuch has a fixed set of prefixes, and we can hopefully be trusted not to add XGOLD and XGOLDEN as prefixes, it is harder for problems to arise.
2016-08-09lib: provide _notmuch_database_log_appendDavid Bremner
_notmuch_database_log clears the log buffer each time. Rather than introducing more complicated semantics about for this function, provide a second function that does not clear the buffer. This is mainly a convenience function for callers constructing complex or multi-line log messages. The changes to query.cc are to make sure that the common code path of the new function is tested.
2016-06-29Use the Xapian::DB_RETRY_LOCK flag when availableIstvan Marko
Xapian 1.3 has introduced the DB_RETRY_LOCK flag (Xapian bug 275). Detect it in configure and optionally use it. With this flag commands that need the write lock will wait for their turn instead of aborting when it's not immediately available. Amended by db: allow disabling in configure
2016-06-10lib: fix memory leak of field processor objectsDavid Bremner
The field processor objects need to be deallocated explicitly just like the range processors (or a talloc destructor defined).
2016-06-07lib: document config metadataDavid Bremner
This probably should have been part of 3458e3c89c, but I missed it.
2016-06-05Use https instead of http where possibleDaniel Kahn Gillmor
Many of the external links found in the notmuch source can be resolved using https instead of http. This changeset addresses as many as i could find, without touching the e-mail corpus or expected outputs found in tests.
2016-06-05lib: whitespace cleanupTomi Ollila
Cleaned the following whitespace in lib/* files: lib/index.cc: 1 line: trailing whitespace lib/database.cc 5 lines: 8 spaces at the beginning of line lib/notmuch-private.h: 4 lines: 8 spaces at the beginning of line lib/message.cc: 1 line: trailing whitespace lib/sha1.c: 1 line: empty lines at the end of file lib/query.cc: 2 lines: 8 spaces at the beginning of line lib/gen-version-script.sh: 1 line: trailing whitespace
2016-05-25lib: add support for named queriesDavid Bremner
This relies on the optional presense of xapian field processors, and the library config API.
2016-05-08lib: optionally support single argument date: queriesDavid Bremner
This relies on the FieldProcessor API, which is only present in xapian >= 1.3.
2016-04-12lib: clean up _notmuch_database_split_pathJani Nikula
Make the logic it a bit easier to read. No functional changes.
2016-04-12lib: fix handling of one character long directory names at top levelJani Nikula
The code to skip multiple slashes in _notmuch_database_split_path() skips back one character too much. This is compensated by a +1 in the length parameter to the strndup() call. Mostly this works fine, but if the path is to a file under a top level directory with one character long name, the directory part is mistaken to be part of the file name (slash == path in code). The returned directory name will be the empty string and the basename will be the full path, breaking the indexing logic in notmuch new. Fix the multiple slash skipping to keep the slash variable pointing at the last slash, and adjust strndup() accordingly. The bug was introduced in commit e890b0cf4011fd9fd77ebd87343379e4a778888b Author: Carl Worth <cworth@cworth.org> Date: Sat Dec 19 13:20:26 2009 -0800 database: Store the parent ID for each directory document. just a little over two months after the initial commit in the Notmuch code history, making this the longest living bug in Notmuch to date.
2015-11-23forbid atomic transactions on writable, upgradable databasesSteven Allen
We can't (but currently do) allow upgrades within transactions because upgrades need their own transactions. We don't want to re-use the current transaction because bailing out of an upgrade would mean loosing all previous changes (because our "atomic" transactions don't commit before hand). This gives us two options: 1. Fail at the beginning of upgrade (tell the user to end the transaction, upgrade, and start over). 2. Don't allow the user to start the transaction. I went with the latter because: 1. There is no reason to call `begin_atomic` unless you intend to to write to the database and anyone intending to write to the database should upgrade it first. 2. This means that nothing inside an atomic transaction can ever fail with NOTMUCH_STATUS_UPGRADE_REQUIRED.
2015-10-05lib: migrate notmuch_database_upgrade to new query_search APIDavid Bremner
Here we depend on the error path cleaning up query
2015-10-05lib: add versions of n_q_count_{message,threads} with status returnDavid Bremner
Although I think it's a pretty bad idea to continue using the old API, this allows both a more gentle transition for clients of the library, and allows us to break one monolithic change into a series
2015-10-05lib: move query variable to function scopeDavid Bremner
This is a prelude to deallocating it (if necessary) on the error path.
2015-09-04lib: constify argument to notmuch_database_status_stringDavid Bremner
We don't modify the database struct, so no harm in committing to that.
2015-09-04lib: note remaining uses of deprecated message search APIDavid Bremner
The two remaining cases in the lib seem to require more than a simple replacement of the old call, with the new call plus a check of the return value.
2015-08-14lib: Add "lastmod:" queries for filtering by last modificationAustin Clements
The implementation is essentially the same as the date range search prior to Jani's fancy date parser.
2015-08-13lib: API to retrieve database revision and UUIDAustin Clements
This exposes the committed database revision to library users along with a UUID that can be used to detect when revision numbers are no longer comparable (e.g., because the database has been replaced).
2015-08-13lib: Add per-message last modification trackingAustin Clements
This adds a new document value that stores the revision of the last modification to message metadata, where the revision number increases monotonically with each database commit. An alternative would be to store the wall-clock time of the last modification of each message. In principle this is simpler and has the advantage that any process can determine the current timestamp without support from libnotmuch. However, even assuming a computer's clock never goes backward and ignoring clock skew in networked environments, this has a fatal flaw. Xapian uses (optimistic) snapshot isolation, which means reads can be concurrent with writes. Given this, consider the following time line with a write and two read transactions: write |-X-A--------------| read 1 |---B---| read 2 |---| The write transaction modifies message X and records the wall-clock time of the modification at A. The writer hangs around for a while and later commits its change. Read 1 is concurrent with the write, so it doesn't see the change to X. It does some query and records the wall-clock time of its results at B. Transaction read 2 later starts after the write commits and queries for changes since wall-clock time B (say the reads are performing an incremental backup). Even though read 1 could not see the change to X, read 2 is told (correctly) that X has not changed since B, the time of the last read. In fact, X changed before wall-clock time A, but the change was not visible until *after* wall-clock time B, so read 2 misses the change to X. This is tricky to solve in full-blown snapshot isolation, but because Xapian serializes writes, we can use a simple, monotonically increasing database revision number. Furthermore, maintaining this revision number requires no more IO than a wall-clock time solution because Xapian already maintains statistics on the upper (and lower) bound of each value stream.
2015-06-12lib: reject relative paths in n_d_{create,open}_verboseDavid Bremner
There are many places in the notmuch code where the path is assumed to be absolute. If someone (TM) wants a project, one could remove these assumptions. In the mean time, prevent users from shooting themselves in the foot. Update test suite mark tests for this error as no longer broken, and also convert some tests that used relative paths for nonexistent directories.
2015-06-12lib: add NOTMUCH_STATUS_PATH_ERRORDavid Bremner
The difference with FILE_ERROR is that this is for things that are wrong with the path before looking at the disk. Add some 3 tests; two broken as a reminder to actually use this new code.
2015-05-31cli: change "setup" to "set up" where used as a verbJ. Lewis Muir
The word "setup" is a noun, not a verb. Change occurrences of "setup" where used as a verb to "set up".
2015-03-29lib: eliminate fprintf from _notmuch_message_file_openDavid Bremner
You may wonder why _notmuch_message_file_open_ctx has two parameters. This is because we need sometime to use a ctx which is a notmuch_message_t. While we could get the database from this, there is no easy way in C to tell type we are getting.
2015-03-29lib: replace almost all fprintfs in library with _n_d_logDavid Bremner
This is not supposed to change any functionality from an end user point of view. Note that it will eliminate some output to stderr. The query debugging output is left as is; it doesn't really fit with the current primitive logging model. The remaining "bad" fprintf will need an internal API change.
2015-03-29lib: add a log function with output to a string in notmuch_database_tDavid Bremner
In principle in the future this could do something fancier than asprintf.
2015-03-29lib: add "verbose" versions of notmuch_database_{open,create}David Bremner
The compatibility wrapper ensures that clients calling notmuch_database_open will receive consistent output for now. The changes to notmuch-{new,search} and test/symbol-test are just to make the test suite pass. The use of IGNORE_RESULT is justified by two things. 1) I don't know what else to do. 2) asprintf guarantees the output string is NULL if an error occurs, so at least we are not passing garbage back.
2015-01-24Add indexing for the mimetype termTodd
This adds the indexing support for the "mimetype:" term and removes the broken test flag. The indexing is probablistic in Xapian terms, which gives a better experience to end users. Standard content-types of the form "foo/bar" are automatically interpreted as phrases in Xapian due to the embedded slash. Assume, separate messages with application/pdf and application/x-pdf are indexed, then: - mimetype:application/x-pdf will find only the application/x-pdf - mimetype:application/pdf will find only the application/pdf - mimetype:pdf will find both of the messages
2015-01-24Add the NOTMUCH_FEATURE_INDEXED_MIMETYPES database featureTodd
This feature will exist in all newly created databases, but there is no upgrade provided for it. If this flag exists, it indicates that the database was created after the indexed MIME-types feature was added.
2014-10-25lib: Remove unnecessary thread linking steps when using ghost messagesAustin Clements
Previously, it was necessary to link new messages to children to work around some (though not all) problems with the old metadata-based approach to stored thread IDs. With ghost messages, this is no longer necessary, so don't bother with child linking when ghost messages are in use.
2014-10-25lib: Implement upgrade to ghost messages featureAustin Clements
Somehow this is the first upgrade pass that actually does *any* error checking, so this also adds the bit of necessary infrastructure to handle that.
2014-10-25lib: Implement ghost-based thread linkingAustin Clements
This updates the thread linking code to use ghost messages instead of user metadata to link messages into threads. In contrast with the old approach, this is actually correct. Previously, thread merging updated only the thread IDs of message documents, not thread IDs stored in user metadata. As originally diagnosed by Mark Walters [1] and as demonstrated by the broken T260-thread-order test, this can cause notmuch to fail to link messages even though they're in the same thread. In principle the old approach could have been fixed by updating the user metadata thread IDs as well, but these are not indexed and hence this would have required a full scan of all stored thread IDs. Ghost messages solve this problem naturally by reusing the exact same thread ID and message ID representation and indexing as regular messages. Furthermore, thanks to this greater symmetry, ghost messages are also algorithmically simpler. We continue to support the old user metadata format, so this patch can't delete any code, but when we do remove support for the old format, several functions can simply be deleted. [1] id:8738h7kv2q.fsf@qmul.ac.uk
2014-10-25lib: Update database schema doc for ghost messagesAustin Clements
This describes the structure of ghost mail documents. Ghost messages are not yet implemented.
2014-10-25lib: Add a ghost messages database featureAustin Clements
This will be implemented over the next several patches. The feature is not yet "enabled" (this does not add it to NOTMUCH_FEATURES_CURRENT).
2014-10-11lib: Refactor _notmuch_database_link_messageAustin Clements
This moves the code to retrieve and clear the metadata thread ID out of _notmuch_database_link_message into its own function. This will simplify future changes.
2014-10-11lib: Move message ID compression to _notmuch_message_create_for_message_idAustin Clements
Previously, this was performed by notmuch_database_add_message. This happens to be the only caller currently (which is why this was safe), but we're about to introduce more callers, and it makes more sense to put responsibility for ID compression in the lower-level function rather than requiring each caller to handle it.
2014-10-03lib: Simplify close and codify aborting atomic sectionAustin Clements
In Xapian, closing a database implicitly aborts any outstanding transaction and commits changes. For historical reasons, notmuch_database_close had grown to almost, but not quite duplicate this behavior. Before closing the database, it would explicitly (and unnecessarily) commit it. However, if there was an outstanding transaction (ie atomic section), commit would throw a Xapian exception, which notmuch_database_close would unnecessarily print to stderr, even though notmuch_database_close would ultimately abort the transaction anyway when it called close. This patch simplifies notmuch_database_close to explicitly abort any outstanding transaction and then just call Database::close. This works for both read-only and read/write databases, takes care of committing changes, unifies the exception handling path, and codifies aborting outstanding transactions. This is currently the only way to abort an atomic section (and may remain so, since it would be difficult to roll back things we may have cached from rolled-back modifications).
2014-09-01lib: Fix endless upgrade problemAustin Clements
48db8c8 introduced a disagreement between when notmuch_database_needs_upgrade returned TRUE and when notmuch_database_upgrade actually performed an upgrade. As a result, if a database had a version less than 3, but no new features were required, notmuch new would call notmuch_database_upgrade to perform an upgrade, but notmuch_database_upgrade would return immediately without updating the database version. Hence, the next notmuch new would do the same, and so on. Fix this by ensuring that the upgrade-required logic is identical between the two.
2014-08-30lib: Return an error from operations that require an upgradeAustin Clements
Previously, there was no protection against a caller invoking an operation on an old database version that would effectively corrupt the database by treating it like a newer version. According to notmuch.h, any caller that opens the database in read/write mode is supposed to check if the database needs upgrading and perform an upgrade if it does. This would protect against this, but nobody (even the CLI) actually does this. However, with features, it's easy to protect against incompatible operations on a fine-grained basis. This lightweight change allows callers to safely operate on old database versions, while preventing specific operations that would corrupt the database with an informative error message.
2014-08-30lib: Report progress for combined upgrade operationAustin Clements
Previously, some parts of upgrade didn't report progress and for others it was possible for the progress meter to restart at 0 part way through the upgrade because each stage was reported separately. Fix this by computing the total amount of work that needs to be done up-front and updating completed work monotonically.
2014-08-30lib: Reorganize upgrade around document typesAustin Clements
Rather than potentially making multiple passes over the same type of data in the database, reorganize upgrade around each type of data that may be upgraded. This eliminates code duplication, will make multi-version upgrades faster, and will let us improve progress reporting.
2014-08-30lib: Use database features to drive upgradeAustin Clements
Previously, we had database version information hard-coded in the upgrade code. Slightly re-organize the upgrade process around the set of new database features to be enabled by the upgrade.
2014-08-30lib: Simplify upgrade code using a transactionAustin Clements
Previously, the upgrade was organized as two passes -- an upgrade pass, and a separate cleanup pass -- so the database was always in a valid state. This change substantially simplifies this code by performing the upgrade in a transaction and combining both passes in to one. This 1) eliminates a lot of duplicate code between the passes, 2) speeds up the upgrade process, 3) makes progress reporting more accurate, 4) eliminates the potential for stale data if the upgrade is interrupted during the cleanup pass, and 5) makes it easier to reason about the safety of the upgrade code.
2014-08-30lib: Database version 3: Introduce fine-grained "features"Austin Clements
Previously, our database schema was versioned by a single number. Each database schema change had to occur "atomically" in Notmuch's development history: before some commit, Notmuch used version N, after that commit, it used version N+1. Hence, each new schema version could introduce only one change, the task of developing a schema change fell on a single person, and it all had to happen and be perfect in a single commit series. This made introducing a new schema version hard. We've seen only two schema changes in the history of Notmuch. This commit introduces database schema version 3; hopefully the last schema version we'll need for a while. With this version, we switch from a single version number to "features": a set of named, independent aspects of the database schema. Features should make backwards compatibility easier. For many things, it should be easy to support databases both with and without a feature, which will allow us to make upgrades optional and will enable "unstable" features that can be developed and tested over time. Features also make forwards compatibility easier. The features recorded in a database include "compatibility flags," which can indicate to an older version of Notmuch when it must support a given feature to open the database for read or for write. This lets us replace the old vague "I don't recognize this version, so something might go wrong, but I promise to try my best" warnings upon opening a database with an unknown version with precise errors. If a database is safe to open for read/write despite unknown features, an older version will know that and issue no message at all. If the database is not safe to open for read/write because of unknown features, an older version will know that, too, and can tell the user exactly which required features it lacks support for.
2014-08-16Make parsing of References and In-Reply-To header less error proneMichal Sojka
According to RFC2822 References and In-Reply-To headers are supposed to contain one or more Message-IDs, however older RFC822 allowed almost any content. When both References and In-Reply-To headers ends with something else that a Message-ID (see e.g. [1]), the thread structure presented by notmuch is incorrect. The reason is that notmuch treats this case as if the email contained no "replyto" information (see _notmuch_database_link_message_to_parents). This patch changes the parse_references() function to return the last valid Message-ID encountered rather than NULL resulting from the last hunk of text not being the Message-ID. [1] https://lkml.org/lkml/headers/2014/5/19/864