diff --git a/src/akonadi/akonadilivequeryhelpers.cpp b/src/akonadi/akonadilivequeryhelpers.cpp --- a/src/akonadi/akonadilivequeryhelpers.cpp +++ b/src/akonadi/akonadilivequeryhelpers.cpp @@ -42,8 +42,9 @@ LiveQueryHelpers::CollectionFetchFunction LiveQueryHelpers::fetchAllCollections(StorageInterface::FetchContentTypes contentTypes) const { - return [this, contentTypes] (const Domain::LiveQueryInput::AddFunction &add) { - auto job = m_storage->fetchCollections(Collection::root(), StorageInterface::Recursive, contentTypes); + auto storage = m_storage; + return [storage, contentTypes] (const Domain::LiveQueryInput::AddFunction &add) { + auto job = storage->fetchCollections(Collection::root(), StorageInterface::Recursive, contentTypes); Utils::JobHandler::install(job->kjob(), [job, add] { if (job->kjob()->error()) return; @@ -56,8 +57,9 @@ LiveQueryHelpers::CollectionFetchFunction LiveQueryHelpers::fetchCollections(const Collection &root, StorageInterface::FetchContentTypes contentTypes) const { - return [this, contentTypes, root] (const Domain::LiveQueryInput::AddFunction &add) { - auto job = m_storage->fetchCollections(root, StorageInterface::Recursive, contentTypes); + auto storage = m_storage; + return [storage, contentTypes, root] (const Domain::LiveQueryInput::AddFunction &add) { + auto job = storage->fetchCollections(root, StorageInterface::Recursive, contentTypes); Utils::JobHandler::install(job->kjob(), [root, job, add] { if (job->kjob()->error()) return; @@ -79,11 +81,12 @@ LiveQueryHelpers::CollectionFetchFunction LiveQueryHelpers::searchCollections(const Collection &root, const QString *searchTerm) const { - return [this, searchTerm, root] (const Domain::LiveQueryInput::AddFunction &add) { + auto storage = m_storage; + return [storage, searchTerm, root] (const Domain::LiveQueryInput::AddFunction &add) { if (searchTerm->isEmpty()) return; - auto job = m_storage->searchCollections(*searchTerm); + auto job = storage->searchCollections(*searchTerm); Utils::JobHandler::install(job->kjob(), [root, job, add] { if (job->kjob()->error()) return; @@ -107,20 +110,22 @@ LiveQueryHelpers::ItemFetchFunction LiveQueryHelpers::fetchItems(StorageInterface::FetchContentTypes contentTypes) const { - return [this, contentTypes] (const Domain::LiveQueryInput::AddFunction &add) { - auto job = m_storage->fetchCollections(Akonadi::Collection::root(), - StorageInterface::Recursive, - contentTypes); - Utils::JobHandler::install(job->kjob(), [this, job, add] { + auto serializer = m_serializer; + auto storage = m_storage; + return [serializer, storage, contentTypes] (const Domain::LiveQueryInput::AddFunction &add) { + auto job = storage->fetchCollections(Akonadi::Collection::root(), + StorageInterface::Recursive, + contentTypes); + Utils::JobHandler::install(job->kjob(), [serializer, storage, job, add] { if (job->kjob()->error() != KJob::NoError) return; foreach (const auto &collection, job->collections()) { - if (!m_serializer->isSelectedCollection(collection)) + if (!serializer->isSelectedCollection(collection)) continue; - auto job = m_storage->fetchItems(collection); - Utils::JobHandler::install(job->kjob(), [this, job, add] { + auto job = storage->fetchItems(collection); + Utils::JobHandler::install(job->kjob(), [job, add] { if (job->kjob()->error() != KJob::NoError) return; @@ -134,9 +139,10 @@ LiveQueryHelpers::ItemFetchFunction LiveQueryHelpers::fetchItems(const Tag &tag) const { - return [this, tag] (const Domain::LiveQueryInput::AddFunction &add) { - auto job = m_storage->fetchTagItems(tag); - Utils::JobHandler::install(job->kjob(), [this, job, add] { + auto storage = m_storage; + return [storage, tag] (const Domain::LiveQueryInput::AddFunction &add) { + auto job = storage->fetchTagItems(tag); + Utils::JobHandler::install(job->kjob(), [job, add] { if (job->kjob()->error() != KJob::NoError) return; @@ -148,17 +154,18 @@ LiveQueryHelpers::ItemFetchFunction LiveQueryHelpers::fetchSiblings(const Item &item) const { - return [this, item] (const Domain::LiveQueryInput::AddFunction &add) { - auto job = m_storage->fetchItem(item); - Utils::JobHandler::install(job->kjob(), [this, job, add] { + auto storage = m_storage; + return [storage, item] (const Domain::LiveQueryInput::AddFunction &add) { + auto job = storage->fetchItem(item); + Utils::JobHandler::install(job->kjob(), [storage, job, add] { if (job->kjob()->error() != KJob::NoError) return; Q_ASSERT(job->items().size() == 1); auto item = job->items()[0]; Q_ASSERT(item.parentCollection().isValid()); - auto job = m_storage->fetchItems(item.parentCollection()); - Utils::JobHandler::install(job->kjob(), [this, job, add] { + auto job = storage->fetchItems(item.parentCollection()); + Utils::JobHandler::install(job->kjob(), [job, add] { if (job->kjob()->error() != KJob::NoError) return; @@ -171,9 +178,10 @@ LiveQueryHelpers::TagFetchFunction LiveQueryHelpers::fetchTags() const { - return [this] (const Domain::LiveQueryInput::AddFunction &add) { - auto job = m_storage->fetchTags(); - Utils::JobHandler::install(job->kjob(), [this, job, add] { + auto storage = m_storage; + return [storage] (const Domain::LiveQueryInput::AddFunction &add) { + auto job = storage->fetchTags(); + Utils::JobHandler::install(job->kjob(), [job, add] { foreach (const auto &tag, job->tags()) add(tag); }); diff --git a/tests/units/akonadi/akonadilivequeryhelperstest.cpp b/tests/units/akonadi/akonadilivequeryhelperstest.cpp --- a/tests/units/akonadi/akonadilivequeryhelperstest.cpp +++ b/tests/units/akonadi/akonadilivequeryhelperstest.cpp @@ -150,6 +150,20 @@ expected.sort(); QCOMPARE(result, expected); + + // WHEN (should not crash when the helpers object is deleted) + helpers.clear(); + collections.clear(); + fetch(add); + TestHelpers::waitForEmptyJobQueue(); + + // THEN + result.clear(); + std::transform(collections.constBegin(), collections.constEnd(), + std::back_inserter(result), + std::bind(&Akonadi::Collection::displayName, _1)); + result.sort(); + QCOMPARE(result, expected); } void shouldFetchCollectionsForRootAndType_data() @@ -262,6 +276,20 @@ expected.sort(); QCOMPARE(result, expected); + + // WHEN (should not crash when the helpers object is deleted) + helpers.clear(); + collections.clear(); + fetch(add); + TestHelpers::waitForEmptyJobQueue(); + + // THEN + result.clear(); + std::transform(collections.constBegin(), collections.constEnd(), + std::back_inserter(result), + std::bind(&Akonadi::Collection::displayName, _1)); + result.sort(); + QCOMPARE(result, expected); } void shouldSearchCollectionsForRootAndTerm_data() @@ -392,6 +420,20 @@ expected.sort(); QCOMPARE(result, expected); + + // WHEN (should not crash when the helpers object is deleted) + helpers.clear(); + collections.clear(); + fetch(add); + TestHelpers::waitForEmptyJobQueue(); + + // THEN + result.clear(); + std::transform(collections.constBegin(), collections.constEnd(), + std::back_inserter(result), + std::bind(&Akonadi::Collection::displayName, _1)); + result.sort(); + QCOMPARE(result, expected); } void shouldFetchItemsByContentTypes_data() @@ -462,6 +504,20 @@ expected.sort(); QCOMPARE(result, expected); + + // WHEN (should not crash when the helpers object is deleted) + helpers.clear(); + items.clear(); + fetch(add); + TestHelpers::waitForEmptyJobQueue(); + + // THEN + result.clear(); + std::transform(items.constBegin(), items.constEnd(), + std::back_inserter(result), + titleFromItem); + result.sort(); + QCOMPARE(result, expected); } void shouldFetchItemsByTag_data() @@ -530,6 +586,20 @@ expected.sort(); QCOMPARE(result, expected); + + // WHEN (should not crash when the helpers object is deleted) + helpers.clear(); + items.clear(); + fetch(add); + TestHelpers::waitForEmptyJobQueue(); + + // THEN + result.clear(); + std::transform(items.constBegin(), items.constEnd(), + std::back_inserter(result), + titleFromItem); + result.sort(); + QCOMPARE(result, expected); } void shouldFetchSiblings_data() @@ -593,6 +663,20 @@ expected.sort(); QCOMPARE(result, expected); + + // WHEN (should not crash when the helpers object is deleted) + helpers.clear(); + items.clear(); + fetch(add); + TestHelpers::waitForEmptyJobQueue(); + + // THEN + result.clear(); + std::transform(items.constBegin(), items.constEnd(), + std::back_inserter(result), + titleFromItem); + result.sort(); + QCOMPARE(result, expected); } void shouldFetchTags() @@ -626,6 +710,20 @@ auto expected = QStringList({"42", "43"}); expected.sort(); QCOMPARE(result, expected); + + // WHEN (should not crash when the helpers object is deleted) + helpers.clear(); + tags.clear(); + fetch(add); + TestHelpers::waitForEmptyJobQueue(); + + // THEN + result.clear(); + std::transform(tags.constBegin(), tags.constEnd(), + std::back_inserter(result), + std::bind(&Akonadi::Tag::name, _1)); + result.sort(); + QCOMPARE(result, expected); } };