Introduce a database for the repository

Many things are already implemented, but it's by far not complete yet.
Fill DB directly after downloading the XML
Reduce parser concurrent memory usage

It doesn't make sense to first parse the whole repository into memory,
just to insert module by module into the DB and throw everything away.
Using callbacks, the already inserted modules can be cleaned up earlier.
In the future, this could also trigger module deletions on certain tags.
Remove outdated waitForFirstLoadFinished()
Reset last update check when recreating DB
Add support for partial repository downloads

The complete repository XML can specify a URL pattern and the current
version, which are saved to the DB. On the next refresh, the URL for the
partial/incremental file is calculated from this information.

Partial XMLs are expected to include all data required to update the DB
from the stored version to the current version. This currently happens on
module level, i.e. the complete data for all changed modules is included.
Removed packages can also be indicated via a new tag.

A partial XML has to include the partial="true" attribute on the
<repository> tag. If this attribute is not present, the XML will be
handled as a full XML, i.e. all old modules will be deleted from the DB.
This can be useful to refresh the DB in case of bigger changes.

There is currently no fallback to the original URL in case loading the
partial XML failed. If implemented, it should distinguish between
temporary errors and situations where the stored version is simply too
old. HTTP status code 410 (Gone) would be good to indicate the latter, but
requires more specialized server-side handling than a 404 (Not Found).
The official repository currently symlinks older XMLs to the full XML.
Store download messages in local instead of member variable
Notify download listeners only if there have been changes
Update latest version on release type preference change
Cache RepoLoader in RepoDb class
Enclose the whole repository load in a transaction

This results in huge performance gains during the initial load, probably
because it writes all changes to the disk just once in the end, not after
every module.