Skip to content

Commit

Permalink
[qtcontacts-sqlite] Regenerate aggregates on database load if require…
Browse files Browse the repository at this point in the history
…d. Contributes to JB#50551

The schema upgrade will result in all aggregates being destroyed.
They need to be regenerated on first load.
  • Loading branch information
Chris Adams committed Sep 16, 2020
1 parent 5844edd commit eb98ed3
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 2 deletions.
8 changes: 6 additions & 2 deletions src/engine/contactsdatabase.cpp
Expand Up @@ -1673,8 +1673,12 @@ static const char *upgradeVersion20[] = {
" WHERE Details.detail = 'Name'",
// delete the old contacts table
"DROP TABLE OldContacts",
// XXXXXXXXXXX TODO: re-generate the aggregates...
// ...
// we need to regenerate aggregates, but cannot do it via a query.
// instead, we do it manually from C++ after the schema upgrade is complete.
// we also need to drop and recreate OOB as it will have stale
// sync data in it.
"DROP TABLE OOB",
createOOBTable,
// rebuild the indexes we dropped
createDetailsRemoveIndex,
createAddressesDetailsContactIdIndex,
Expand Down
54 changes: 54 additions & 0 deletions src/engine/contactsengine.cpp
Expand Up @@ -60,6 +60,7 @@
#include <QContactAbstractRequest>
#include <QContactFetchRequest>
#include <QContactCollectionFetchRequest>
#include <QContactCollectionFilter>

// ---- for schema modification ------
#include <QtContacts/QContactDisplayLabel>
Expand Down Expand Up @@ -2175,11 +2176,64 @@ ContactsDatabase &ContactsEngine::database()
m_database.reset(new ContactsDatabase(this));
if (!m_database->open(dbId, m_nonprivileged, m_autoTest, true)) {
QTCONTACTS_SQLITE_WARNING(QString::fromLatin1("Unable to open synchronous engine database connection"));
} else if (!m_nonprivileged && !regenerateAggregatesIfNeeded()) {
QTCONTACTS_SQLITE_WARNING(QString::fromLatin1("Unable to regenerate aggregates after schema upgrade"));
}
}
return *m_database;
}

bool ContactsEngine::regenerateAggregatesIfNeeded()
{
QContactManager::Error err = QContactManager::NoError;
QContactCollectionFilter aggregatesFilter, localsFilter;
aggregatesFilter.setCollectionId(QContactCollectionId(m_managerUri, QByteArrayLiteral("col-1")));
localsFilter.setCollectionId(QContactCollectionId(m_managerUri, QByteArrayLiteral("col-2")));

const QList<QContactId> aggregateIds = contactIds(aggregatesFilter, QList<QContactSortOrder>(), &err);
if (err != QContactManager::NoError) {
QTCONTACTS_SQLITE_WARNING(QString::fromLatin1("Failed to read aggregate contact ids during attempt to regenerate aggregates"));
return false;
}

if (!aggregateIds.isEmpty()) {
// if we already have aggregates, then aggregates must
// have been regenerated already.
return true;
}

const QList<QContactId> localIds = contactIds(localsFilter, QList<QContactSortOrder>(), &err);
if (err != QContactManager::NoError) {
QTCONTACTS_SQLITE_WARNING(QString::fromLatin1("Failed to read local contact ids during attempt to regenerate aggregates"));
return false;
}

if (localIds.isEmpty()) {
// no local contacts in database to be aggregated.
return true;
}

// We need to regenerate aggregates for our local contacts, due to
// the database schema upgrade from version 20 to version 21.
QList<QContact> localContacts = contacts(
localsFilter,
QList<QContactSortOrder>(),
QContactFetchHint(),
&err);
if (err != QContactManager::NoError) {
QTCONTACTS_SQLITE_WARNING(QString::fromLatin1("Failed to read local contacts during attempt to regenerate aggregates"));
return false;
}

// Simply save them all; this should regenerate aggregates as required.
if (!saveContacts(&localContacts, nullptr, &err)) {
QTCONTACTS_SQLITE_WARNING(QString::fromLatin1("Failed to save local contacts during attempt to regenerate aggregates"));
return false;
}

return true;
}

ContactReader *ContactsEngine::reader() const
{
if (!m_synchronousReader) {
Expand Down
1 change: 1 addition & 0 deletions src/engine/contactsengine.h
Expand Up @@ -214,6 +214,7 @@ private slots:
void _q_displayLabelGroupsChanged();

private:
bool regenerateAggregatesIfNeeded();
QString databaseUuid();
ContactsDatabase &database();

Expand Down

0 comments on commit eb98ed3

Please sign in to comment.