diff options
author | Michael Nosov <Michael.Nosov@harman.com> | 2018-06-11 19:41:26 +0300 |
---|---|---|
committer | Michael Nosov <Michael.Nosov@harman.com> | 2018-08-03 08:56:47 +0000 |
commit | 4e6eabe6120d69ff0c615f26344cdeea231611c9 (patch) | |
tree | c32f9f57e56c4cfc2a83e078386fdbd2b820c8ec | |
parent | 86aaab6e00d6a1a20cb98b5c3d3235757bde8d25 (diff) |
[qmf] Fix of update folder when parent folder id is changed
Scenario:
a) Let's have the following hierarchy:
f0->f1->f2->f3->f4
f5->f6
b) Change parent folder id of 'f2' from 'f1' to 'f6'
c) Query descendant folders of f1.
Expected result: no folders shall be returned
Actual result: folders f3 and f4 are returned
Appropriate test case is also added in tst_qmailstore.cpp
Change-Id: I2546429cd71e9194389bacaeacb4dfcf82eba849
Reviewed-by: Matthew Vogt <matthew.vogt@qinetic.com.au>
Reviewed-by: Christopher Adams <chris.adams@jollamobile.com>
-rw-r--r-- | src/libraries/qmfclient/qmailstore_p.cpp | 49 | ||||
-rw-r--r-- | tests/tst_qmailstore/tst_qmailstore.cpp | 82 |
2 files changed, 131 insertions, 0 deletions
diff --git a/src/libraries/qmfclient/qmailstore_p.cpp b/src/libraries/qmfclient/qmailstore_p.cpp index 889160e7..a1dd8bce 100644 --- a/src/libraries/qmfclient/qmailstore_p.cpp +++ b/src/libraries/qmfclient/qmailstore_p.cpp @@ -6422,6 +6422,19 @@ QMailStorePrivate::AttemptResult QMailStorePrivate::attemptUpdateFolder(QMailFol modifiedAccountIds->append(folder->parentAccountId()); { + //remove existing links from folder's ancestors to folder's descendants + QSqlQuery query(simpleQuery("DELETE FROM mailfolderlinks WHERE " + "descendantid IN (SELECT descendantid FROM mailfolderlinks WHERE id=?) AND " + "id IN (SELECT id FROM mailfolderlinks WHERE descendantid=?)", + QVariantList() << folder->id().toULongLong() + << folder->id().toULongLong(), + "mailfolderlinks delete ancestors->descendants in update")); + if (query.lastError().type() != QSqlError::NoError) + return DatabaseFailure; + + } + + { //remove existing links to this folder QSqlQuery query(simpleQuery(QLatin1String("DELETE FROM mailfolderlinks WHERE descendantid = ?"), QVariantList() << folder->id().toULongLong(), @@ -6449,6 +6462,42 @@ QMailStorePrivate::AttemptResult QMailStorePrivate::attemptUpdateFolder(QMailFol if (query.lastError().type() != QSqlError::NoError) return DatabaseFailure; } + { + // Add links ancestors->descendants + // CROSS JOIN is not supported by QSqlQuery, so need to add new ancestors->descendants combinations manually + QList<quint64> ancestors; + QSqlQuery queryAncestors(simpleQuery("SELECT id FROM mailfolderlinks WHERE descendantid = ?", + QVariantList() << folder->id().toULongLong(), + "mailfolderlinks query list of ancestors")); + while (queryAncestors.next()) + ancestors.append(extractValue<quint64>(queryAncestors.value(0))); + + if (!ancestors.isEmpty()) { + QList<quint64> descendants; + QSqlQuery queryDescendants(simpleQuery("SELECT descendantid FROM mailfolderlinks WHERE id = ?", + QVariantList() << folder->id().toULongLong(), + "mailfolderlinks query list of descendants")); + while (queryDescendants.next()) + descendants.append(extractValue<quint64>(queryDescendants.value(0))); + + if (!descendants.isEmpty()) { + QVariantList ancestorRows; + QVariantList descendantRows; + foreach (quint64 anc, ancestors) { + foreach (quint64 desc, descendants) { + ancestorRows.append(anc); + descendantRows.append(desc); + } + } + QSqlQuery query(batchQuery(QString("INSERT INTO mailfolderlinks VALUES (?,?)"), + QVariantList() << QVariant(ancestorRows) + << QVariant(descendantRows), + "mailfolderlinks insert ancestors-descendants")); + if (query.lastError().type() != QSqlError::NoError) + return DatabaseFailure; + } + } + } } if (commitOnSuccess && !t.commit()) { diff --git a/tests/tst_qmailstore/tst_qmailstore.cpp b/tests/tst_qmailstore/tst_qmailstore.cpp index d44fc565..363a34e2 100644 --- a/tests/tst_qmailstore/tst_qmailstore.cpp +++ b/tests/tst_qmailstore/tst_qmailstore.cpp @@ -852,6 +852,88 @@ void tst_QMailStore::updateFolder() QCOMPARE(folder6.customFields(), folder5.customFields()); QCOMPARE(folder6.customField("answer"), QString("Fido")); QVERIFY(folder6.customField("temporary").isNull()); + + // -------- Test QMailFolder::setParentId -------------- + // Step 1: Setup the following hierarchy + // f0->f1->f2->f3->f4 + // f5->f6 + QMailFolder f0 = QMailFolder("f0", QMailFolderId()); + QVERIFY(QMailStore::instance()->addFolder(&f0)); + QCOMPARE(QMailStore::instance()->lastError(), QMailStore::NoError); + + QMailFolder f1 = QMailFolder("f1", f0.id()); + QVERIFY(QMailStore::instance()->addFolder(&f1)); + QCOMPARE(QMailStore::instance()->lastError(), QMailStore::NoError); + + QMailFolder f2 = QMailFolder("f2", f1.id()); + QVERIFY(QMailStore::instance()->addFolder(&f2)); + QCOMPARE(QMailStore::instance()->lastError(), QMailStore::NoError); + + QMailFolder f3 = QMailFolder("f3", f2.id()); + QVERIFY(QMailStore::instance()->addFolder(&f3)); + QCOMPARE(QMailStore::instance()->lastError(), QMailStore::NoError); + + QMailFolder f4 = QMailFolder("f4", f3.id()); + QVERIFY(QMailStore::instance()->addFolder(&f4)); + QCOMPARE(QMailStore::instance()->lastError(), QMailStore::NoError); + + QMailFolder f5 = QMailFolder("f5", QMailFolderId()); + QVERIFY(QMailStore::instance()->addFolder(&f5)); + QCOMPARE(QMailStore::instance()->lastError(), QMailStore::NoError); + + QMailFolder f6 = QMailFolder("f6", f5.id()); + QVERIFY(QMailStore::instance()->addFolder(&f6)); + QCOMPARE(QMailStore::instance()->lastError(), QMailStore::NoError); + + //Step 2: Move f2 to f6. New folder hierarchy shall be the following + // f0->f1 + // f5->f6->f2->f3->f4 + f2.setParentFolderId(f6.id()); + QMailStore::instance()->updateFolder(&f2); + + //Verify ancestors->descendants connections + QMailFolderKey key; + QMailFolderIdList folderIds; + + key = QMailFolderKey::ancestorFolderIds(f5.id(), QMailDataComparator::Includes); + folderIds = QMailStore::instance()->queryFolders(key); + QCOMPARE(folderIds.count(), 4); + QVERIFY(folderIds.contains(f6.id()) && + folderIds.contains(f2.id()) && + folderIds.contains(f3.id()) && + folderIds.contains(f4.id())); + + key = QMailFolderKey::ancestorFolderIds(f6.id(), QMailDataComparator::Includes); + folderIds = QMailStore::instance()->queryFolders(key); + QCOMPARE(folderIds.count(), 3); + QVERIFY(folderIds.contains(f2.id()) && + folderIds.contains(f3.id()) && + folderIds.contains(f4.id())); + + key = QMailFolderKey::ancestorFolderIds(f2.id(), QMailDataComparator::Includes); + folderIds = QMailStore::instance()->queryFolders(key); + QCOMPARE(folderIds.count(), 2); + QVERIFY(folderIds.contains(f3.id()) && + folderIds.contains(f4.id())); + + key = QMailFolderKey::ancestorFolderIds(f3.id(), QMailDataComparator::Includes); + folderIds = QMailStore::instance()->queryFolders(key); + QCOMPARE(folderIds.count(), 1); + QVERIFY(folderIds.contains(f4.id())); + + key = QMailFolderKey::ancestorFolderIds(f4.id(), QMailDataComparator::Includes); + folderIds = QMailStore::instance()->queryFolders(key); + QCOMPARE(folderIds.count(), 0); + + key = QMailFolderKey::ancestorFolderIds(f0.id(), QMailDataComparator::Includes); + folderIds = QMailStore::instance()->queryFolders(key); + QCOMPARE(folderIds.count(), 1); + QVERIFY(folderIds.contains(f1.id())); + + key = QMailFolderKey::ancestorFolderIds(f1.id(), QMailDataComparator::Includes); + folderIds = QMailStore::instance()->queryFolders(key); + QCOMPARE(folderIds.count(), 0); + // -------- End Test QMailFolder::setParentId -------------- } void tst_QMailStore::updateMessage() |