Commit a283882e authored by chriadam's avatar chriadam

[qtcontacts-sqlite] Properly emit changes to display label groups. Contributes to JB#45836

Previously we emitted asynchronously before the transaction was
committed.  This commit ensures that we emit only if the transaction
is committed successfully by the writer thread, ensuring that there
is no race between readers attempting to access the updated
display label groups list, and the completion of the write.
parent 737cd106
...@@ -160,6 +160,12 @@ void ContactNotifier::relationshipsRemoved(const QSet<QContactId> &contactIds) ...@@ -160,6 +160,12 @@ void ContactNotifier::relationshipsRemoved(const QSet<QContactId> &contactIds)
} }
} }
void ContactNotifier::displayLabelGroupsChanged()
{
QDBusMessage message = createSignal("displayLabelGroupsChanged", m_nonprivileged);
QDBusConnection::sessionBus().send(message);
}
bool ContactNotifier::connect(const char *name, const char *signature, QObject *receiver, const char *slot) bool ContactNotifier::connect(const char *name, const char *signature, QObject *receiver, const char *slot)
{ {
static QDBusConnection connection(QDBusConnection::sessionBus()); static QDBusConnection connection(QDBusConnection::sessionBus());
......
...@@ -55,6 +55,7 @@ public: ...@@ -55,6 +55,7 @@ public:
void selfContactIdChanged(QContactId oldId, QContactId newId); void selfContactIdChanged(QContactId oldId, QContactId newId);
void relationshipsAdded(const QSet<QContactId> &contactIds); void relationshipsAdded(const QSet<QContactId> &contactIds);
void relationshipsRemoved(const QSet<QContactId> &contactIds); void relationshipsRemoved(const QSet<QContactId> &contactIds);
void displayLabelGroupsChanged();
bool connect(const char *name, const char *signature, QObject *receiver, const char *slot); bool connect(const char *name, const char *signature, QObject *receiver, const char *slot);
}; };
......
...@@ -1924,6 +1924,7 @@ static bool executeDisplayLabelGroupLocalizationStatements(QSqlDatabase &databas ...@@ -1924,6 +1924,7 @@ static bool executeDisplayLabelGroupLocalizationStatements(QSqlDatabase &databas
} }
// for every single contact in our database, read the data required to generate the display label group data. // for every single contact in our database, read the data required to generate the display label group data.
bool emitDisplayLabelGroupChange = false;
QVariantList contactIds; QVariantList contactIds;
QVariantList displayLabelGroups; QVariantList displayLabelGroups;
QVariantList displayLabelGroupSortOrders; QVariantList displayLabelGroupSortOrders;
...@@ -1959,7 +1960,7 @@ static bool executeDisplayLabelGroupLocalizationStatements(QSqlDatabase &databas ...@@ -1959,7 +1960,7 @@ static bool executeDisplayLabelGroupLocalizationStatements(QSqlDatabase &databas
c.saveDetail(&n); c.saveDetail(&n);
c.saveDetail(&dl); c.saveDetail(&dl);
const QString dlg = cdb->determineDisplayLabelGroup(c); const QString dlg = cdb->determineDisplayLabelGroup(c, &emitDisplayLabelGroupChange);
displayLabelGroups.append(dlg); displayLabelGroups.append(dlg);
displayLabelGroupSortOrders.append(cdb->displayLabelGroupSortValue(dlg)); displayLabelGroupSortOrders.append(cdb->displayLabelGroupSortValue(dlg));
} }
...@@ -3473,7 +3474,7 @@ QString ContactsDatabase::displayLabelGroupPreferredProperty() const ...@@ -3473,7 +3474,7 @@ QString ContactsDatabase::displayLabelGroupPreferredProperty() const
return retn; return retn;
} }
QString ContactsDatabase::determineDisplayLabelGroup(const QContact &c) QString ContactsDatabase::determineDisplayLabelGroup(const QContact &c, bool *emitDisplayLabelGroupChange)
{ {
// Read system setting to determine whether display label group // Read system setting to determine whether display label group
// should be generated from last name, first name, or display label. // should be generated from last name, first name, or display label.
...@@ -3532,19 +3533,17 @@ QString ContactsDatabase::determineDisplayLabelGroup(const QContact &c) ...@@ -3532,19 +3533,17 @@ QString ContactsDatabase::determineDisplayLabelGroup(const QContact &c)
} }
} }
if (!group.isEmpty() && !m_knownDisplayLabelGroupsSortValues.contains(group)) { if (emitDisplayLabelGroupChange && !group.isEmpty() && !m_knownDisplayLabelGroupsSortValues.contains(group)) {
// We are about to write a contact to the database which has a // We are about to write a contact to the database which has a
// display label group which previously was not known / observed. // display label group which previously was not known / observed.
// Calculate the sort value for the display label group, // Calculate the sort value for the display label group,
// and add it to our map of displayLabelGroup->sortValue. // and add it to our map of displayLabelGroup->sortValue.
// Note: this should be thread-safe since we only call this method within writes. // Note: this should be thread-safe since we only call this method within writes.
*emitDisplayLabelGroupChange = true;
m_knownDisplayLabelGroupsSortValues.insert( m_knownDisplayLabelGroupsSortValues.insert(
group, ::displayLabelGroupSortValue( group, ::displayLabelGroupSortValue(
group, group,
m_knownDisplayLabelGroupsSortValues)); m_knownDisplayLabelGroupsSortValues));
// and invoke engine->_q_displayLabelGroupsChanged() asynchronously.
QMetaObject::invokeMethod(m_engine, "_q_displayLabelGroupsChanged", Qt::QueuedConnection);
} }
return group; return group;
......
...@@ -159,7 +159,7 @@ public: ...@@ -159,7 +159,7 @@ public:
void regenerateDisplayLabelGroups(); void regenerateDisplayLabelGroups();
QString displayLabelGroupPreferredProperty() const; QString displayLabelGroupPreferredProperty() const;
QString determineDisplayLabelGroup(const QContact &c); QString determineDisplayLabelGroup(const QContact &c, bool *emitDisplayLabelGroupChange = Q_NULLPTR);
QStringList displayLabelGroups() const; QStringList displayLabelGroups() const;
int displayLabelGroupSortValue(const QString &group) const; int displayLabelGroupSortValue(const QString &group) const;
......
...@@ -898,6 +898,7 @@ QContactManager::Error ContactsEngine::open() ...@@ -898,6 +898,7 @@ QContactManager::Error ContactsEngine::open()
m_notifier->connect("selfContactIdChanged", "uu", this, SLOT(_q_selfContactIdChanged(quint32,quint32))); m_notifier->connect("selfContactIdChanged", "uu", this, SLOT(_q_selfContactIdChanged(quint32,quint32)));
m_notifier->connect("relationshipsAdded", "au", this, SLOT(_q_relationshipsAdded(QVector<quint32>))); m_notifier->connect("relationshipsAdded", "au", this, SLOT(_q_relationshipsAdded(QVector<quint32>)));
m_notifier->connect("relationshipsRemoved", "au", this, SLOT(_q_relationshipsRemoved(QVector<quint32>))); m_notifier->connect("relationshipsRemoved", "au", this, SLOT(_q_relationshipsRemoved(QVector<quint32>)));
m_notifier->connect("displayLabelGroupsChanged", "", this, SLOT(_q_displayLabelGroupsChanged()));
} }
} else { } else {
QTCONTACTS_SQLITE_WARNING(QString::fromLatin1("Unable to open asynchronous engine database connection")); QTCONTACTS_SQLITE_WARNING(QString::fromLatin1("Unable to open asynchronous engine database connection"));
......
...@@ -139,6 +139,7 @@ ContactWriter::ContactWriter(ContactsEngine &engine, ContactsDatabase &database, ...@@ -139,6 +139,7 @@ ContactWriter::ContactWriter(ContactsEngine &engine, ContactsDatabase &database,
, m_database(database) , m_database(database)
, m_notifier(notifier) , m_notifier(notifier)
, m_reader(reader) , m_reader(reader)
, m_displayLabelGroupsChanged(false)
{ {
Q_ASSERT(notifier); Q_ASSERT(notifier);
Q_ASSERT(reader); Q_ASSERT(reader);
...@@ -177,6 +178,10 @@ bool ContactWriter::commitTransaction() ...@@ -177,6 +178,10 @@ bool ContactWriter::commitTransaction()
return false; return false;
} }
if (m_displayLabelGroupsChanged) {
m_notifier->displayLabelGroupsChanged();
m_displayLabelGroupsChanged = false;
}
if (!m_addedIds.isEmpty()) { if (!m_addedIds.isEmpty()) {
m_notifier->contactsAdded(m_addedIds.toList()); m_notifier->contactsAdded(m_addedIds.toList());
m_addedIds.clear(); m_addedIds.clear();
...@@ -218,6 +223,7 @@ void ContactWriter::rollbackTransaction() ...@@ -218,6 +223,7 @@ void ContactWriter::rollbackTransaction()
m_presenceChangedIds.clear(); m_presenceChangedIds.clear();
m_changedIds.clear(); m_changedIds.clear();
m_addedIds.clear(); m_addedIds.clear();
m_displayLabelGroupsChanged = false;
} }
QContactManager::Error ContactWriter::setIdentity(ContactsDatabase::Identity identity, QContactId contactId) QContactManager::Error ContactWriter::setIdentity(ContactsDatabase::Identity identity, QContactId contactId)
...@@ -5591,7 +5597,7 @@ ContactsDatabase::Query ContactWriter::bindContactDetails(const QContact &contac ...@@ -5591,7 +5597,7 @@ ContactsDatabase::Query ContactWriter::bindContactDetails(const QContact &contac
QContactDisplayLabel label = contact.detail<QContactDisplayLabel>(); QContactDisplayLabel label = contact.detail<QContactDisplayLabel>();
const QString displayLabel = label.label().trimmed(); const QString displayLabel = label.label().trimmed();
query.bindValue(0, displayLabel); query.bindValue(0, displayLabel);
const QString displayLabelGroup = m_database.determineDisplayLabelGroup(contact); const QString displayLabelGroup = m_database.determineDisplayLabelGroup(contact, &m_displayLabelGroupsChanged);
query.bindValue(1, displayLabelGroup); query.bindValue(1, displayLabelGroup);
const int displayLabelGroupSortOrder = m_database.displayLabelGroupSortValue(displayLabelGroup); const int displayLabelGroupSortOrder = m_database.displayLabelGroupSortValue(displayLabelGroup);
query.bindValue(2, displayLabelGroupSortOrder); query.bindValue(2, displayLabelGroupSortOrder);
......
...@@ -172,6 +172,7 @@ private: ...@@ -172,6 +172,7 @@ private:
ContactNotifier *m_notifier; ContactNotifier *m_notifier;
ContactReader *m_reader; ContactReader *m_reader;
bool m_displayLabelGroupsChanged;
QSet<QContactId> m_addedIds; QSet<QContactId> m_addedIds;
QSet<QContactId> m_removedIds; QSet<QContactId> m_removedIds;
QSet<QContactId> m_changedIds; QSet<QContactId> m_changedIds;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment