Commit fb024c66 authored by mnosovharman's avatar mnosovharman

[qmf] Fix of update folder when parent folder id is changed. Contributes to JB#41524


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
parent 16e178bf
......@@ -7344,6 +7344,19 @@ QMailStorePrivate::AttemptResult QMailStorePrivate::attemptUpdateFolder(QMailFol
if (folder->parentFolderId().isValid() && folder->parentAccountId().isValid() && !modifiedAccountIds->contains(folder->parentAccountId()))
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("DELETE FROM mailfolderlinks WHERE descendantid = ?",
......@@ -7372,6 +7385,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()) {
......
......@@ -902,6 +902,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()
......
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