summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Nosov <Michael.Nosov@harman.com>2018-06-11 19:41:26 +0300
committerMichael Nosov <Michael.Nosov@harman.com>2018-08-03 08:56:47 +0000
commit4e6eabe6120d69ff0c615f26344cdeea231611c9 (patch)
treec32f9f57e56c4cfc2a83e078386fdbd2b820c8ec
parent86aaab6e00d6a1a20cb98b5c3d3235757bde8d25 (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.cpp49
-rw-r--r--tests/tst_qmailstore/tst_qmailstore.cpp82
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()