File indexing completed on 2024-05-19 05:16:11

0001 /*
0002     SPDX-FileCopyrightText: 2010 Stephen Kelly <steveire@gmail.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "entitytreecreatejob.h"
0008 
0009 #include <Akonadi/CollectionCreateJob>
0010 #include <Akonadi/ItemCreateJob>
0011 
0012 #include <QVariant>
0013 
0014 #include "migration_debug.h"
0015 
0016 using namespace Akonadi;
0017 
0018 static const char collectionIdMappingProperty[] = "collectionIdMappingProperty";
0019 
0020 EntityTreeCreateJob::EntityTreeCreateJob(const QList<Akonadi::Collection::List> &collections, const Akonadi::Item::List &items, QObject *parent)
0021     : Akonadi::TransactionSequence(parent)
0022     , m_collections(collections)
0023     , m_items(items)
0024 {
0025 }
0026 
0027 void EntityTreeCreateJob::doStart()
0028 {
0029     if (!m_collections.isEmpty()) {
0030         createNextLevelOfCollections();
0031     }
0032     createReadyItems();
0033 }
0034 
0035 void EntityTreeCreateJob::createNextLevelOfCollections()
0036 {
0037     CollectionCreateJob *job = nullptr;
0038 
0039     const Collection::List colList = m_collections.takeFirst();
0040     for (const Collection &collection : colList) {
0041         ++m_pendingJobs;
0042         job = new CollectionCreateJob(collection, this);
0043         job->setProperty(collectionIdMappingProperty, collection.id());
0044         connect(job, &CollectionCreateJob::result, this, &EntityTreeCreateJob::collectionCreateJobDone);
0045     }
0046 }
0047 
0048 void EntityTreeCreateJob::createReadyItems()
0049 {
0050     Item::List::iterator it;
0051     for (it = m_items.begin(); it != m_items.end();) {
0052         Collection parentCollection = (*it).parentCollection();
0053         if (parentCollection.isValid()) {
0054             (void)new ItemCreateJob(*it, parentCollection, this);
0055             it = m_items.erase(it);
0056         } else {
0057             ++it;
0058         }
0059     }
0060     if (m_items.isEmpty() && m_collections.isEmpty()) {
0061         commit();
0062     }
0063 }
0064 
0065 void EntityTreeCreateJob::collectionCreateJobDone(KJob *job)
0066 {
0067     Q_ASSERT(m_pendingJobs > 0);
0068     --m_pendingJobs;
0069     auto collectionCreateJob = qobject_cast<CollectionCreateJob *>(job);
0070     Collection createdCollection = collectionCreateJob->collection();
0071 
0072     if (job->error()) {
0073         qCDebug(MIGRATION_LOG) << job->errorString();
0074         return;
0075     }
0076 
0077     const Collection::Id creationId = job->property(collectionIdMappingProperty).toLongLong();
0078 
0079     Item::List::iterator it;
0080     const Item::List::iterator end = m_items.end();
0081     for (it = m_items.begin(); it != end; ++it) {
0082         qCDebug(MIGRATION_LOG) << "updating items";
0083         if (it->parentCollection().id() == creationId) {
0084             it->setParentCollection(createdCollection);
0085         }
0086     }
0087 
0088     createReadyItems();
0089 
0090     if (!m_collections.isEmpty()) {
0091         Collection::List::iterator col_it;
0092         const Collection::List::iterator col_end = m_collections[0].end();
0093         for (col_it = m_collections[0].begin(); col_it != col_end; ++col_it) {
0094             if (col_it->parentCollection().id() == creationId) {
0095                 col_it->setParentCollection(createdCollection);
0096             }
0097         }
0098         if (m_pendingJobs == 0) {
0099             createNextLevelOfCollections();
0100         }
0101     }
0102 
0103     if (m_items.isEmpty() && m_collections.isEmpty()) {
0104         commit();
0105     }
0106 }
0107 
0108 #include "moc_entitytreecreatejob.cpp"