diff options
-rw-r--r-- | src/libs/installer/genericdatacache.cpp | 38 | ||||
-rw-r--r-- | src/libs/installer/genericdatacache.h | 7 | ||||
-rw-r--r-- | src/libs/installer/metadatajob_p.h | 2 |
3 files changed, 40 insertions, 7 deletions
diff --git a/src/libs/installer/genericdatacache.cpp b/src/libs/installer/genericdatacache.cpp index fd264ce63..d8db99600 100644 --- a/src/libs/installer/genericdatacache.cpp +++ b/src/libs/installer/genericdatacache.cpp @@ -120,6 +120,16 @@ CacheableItem::~CacheableItem() */ /*! + \enum GenericDataCache::RegisterMode + This enum holds the possible values for modes of registering items to cache. + + \value Copy + The contents of the item are copied to the cache. + \value Move + The contents of the item are move to the cache. +*/ + +/*! \fn template <typename T> QInstaller::GenericDataCache<T>::GenericDataCache() Constructs a new empty cache. The cache is invalid until set with a @@ -417,13 +427,14 @@ T *GenericDataCache<T>::itemByPath(const QString &path) const the new \a item replaces a previous item with the same checksum. The cache takes ownership of the object pointed by \a item. The contents of the - item are copied to the cache with a subdirectory name that matches the checksum - of the item. + item are copied or moved to the cache with a subdirectory name that matches the checksum + of the item. The \c mode decides how the contents of the item are registered, either by + copying or moving. Returns \c true on success or \c false if the item could not be registered. */ template <typename T> -bool GenericDataCache<T>::registerItem(T *item, bool replace) +bool GenericDataCache<T>::registerItem(T *item, bool replace, RegisterMode mode) { QMutexLocker _(&m_mutex); if (m_invalidated) { @@ -455,10 +466,27 @@ bool GenericDataCache<T>::registerItem(T *item, bool replace) const QString newPath = m_path + QDir::separator() + QString::fromLatin1(item->checksum()); try { // A directory is in the way but it isn't registered to the current cache, remove. - if (QDir().exists(newPath)) + QDir dir; + if (dir.exists(newPath)) QInstaller::removeDirectory(newPath); - QInstaller::copyDirectoryContents(item->path(), newPath); + switch (mode) { + case Copy: + QInstaller::copyDirectoryContents(item->path(), newPath); + break; + case Move: + // First, try moving the top level directory + if (!dir.rename(item->path(), newPath)) { + qCDebug(lcDeveloperBuild) << "Failed to rename directory" << item->path() + << "to" << newPath << ". Trying again."; + // If that does not work, fallback to moving the contents one by one + QInstaller::moveDirectoryContents(item->path(), newPath); + } + break; + default: + throw Error(QCoreApplication::translate("GenericDataCache", + "Unknown register mode selected!")); + } } catch (const Error &e) { setErrorString(QCoreApplication::translate("GenericDataCache", "Error while copying item to path \"%1\": %2").arg(newPath, e.message())); diff --git a/src/libs/installer/genericdatacache.h b/src/libs/installer/genericdatacache.h index 2bdf6697e..5c1732334 100644 --- a/src/libs/installer/genericdatacache.h +++ b/src/libs/installer/genericdatacache.h @@ -64,6 +64,11 @@ template <typename T> class INSTALLER_EXPORT GenericDataCache { public: + enum RegisterMode { + Copy = 0, + Move = 1 + }; + GenericDataCache(); explicit GenericDataCache(const QString &path, const QString &type, const QString &version); ~GenericDataCache(); @@ -85,7 +90,7 @@ public: T *itemByChecksum(const QByteArray &checksum) const; T *itemByPath(const QString &path) const; - bool registerItem(T *item, bool replace = false); + bool registerItem(T *item, bool replace = false, RegisterMode mode = Copy); bool removeItem(const QByteArray &checksum); QList<T *> obsoleteItems() const; diff --git a/src/libs/installer/metadatajob_p.h b/src/libs/installer/metadatajob_p.h index ef2729dbb..5340e5d1c 100644 --- a/src/libs/installer/metadatajob_p.h +++ b/src/libs/installer/metadatajob_p.h @@ -140,7 +140,7 @@ public: QStringList registeredKeys; bool success = true; for (auto *meta : qAsConst(*m_updates)) { - if (!m_cache->registerItem(meta, true)) { + if (!m_cache->registerItem(meta, true, GenericDataCache<Metadata>::Move)) { success = false; break; } |