diff --git a/SiaDrive.Api/UploadManager.cpp b/SiaDrive.Api/UploadManager.cpp index 632a2d3..e438db0 100644 --- a/SiaDrive.Api/UploadManager.cpp +++ b/SiaDrive.Api/UploadManager.cpp @@ -136,56 +136,98 @@ void CUploadManager::FileAction(const String& siaPath, const String& filePath, c } else { - CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(CreatingTemporarySiaDriveFile(siaPath, filePath, tempSourcePath))); - if (RetryableAction(::CopyFile(filePath.c_str(), tempSourcePath.c_str(), FALSE), DEFAULT_RETRY_COUNT, DEFAULT_RETRY_DELAY_MS)) + // Check for retry queue condition + if (!::PathFileExists(tempSourcePath.c_str()) && ::PathFileExists(siaDriveFilePath.c_str())) { - // Delete existing '.siadrive' file, if found - // !!Should never come here. If so, there was a problem with startup clean-up - if (!RetryDeleteFileIfExists(siaDriveFilePath)) - { - CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteSiaDriveFileFailed(siaPath, filePath, siaDriveFilePath))); - } - - // Rename '.siadrive.temp' to '.siadrive' - CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(RenamingTemporarySiaDriveFile(siaPath, filePath, tempSourcePath, siaDriveFilePath))); - if (RetryableAction(::MoveFile(tempSourcePath.c_str(), siaDriveFilePath.c_str()), DEFAULT_RETRY_COUNT, DEFAULT_RETRY_DELAY_MS)) + try { std::lock_guard l(_uploadMutex); - SET_STATUS(UploadStatus::Queued, UploadAddedToQueue, ModifyUploadStatusFailed) - if (statusUpdated && !RetryDeleteFileIfExists(tempSourcePath)) + SQLite::Statement query(_uploadDatabase, QUERY_STATUS); + query.bind("@sia_path", CW2A(siaPath.c_str()).m_psz); + if (query.executeStep()) { - CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath))); + UploadStatus uploadStatus = static_cast(static_cast(query.getColumn(5))); + if (uploadStatus == UploadStatus::Copying) + { + SET_STATUS(UploadStatus::Queued, UploadAddedToQueue, ModifyUploadStatusFailed) + } } } - else + catch (SQLite::Exception e) { - CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(RenamingTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath, siaDriveFilePath))); - if (!RetryDeleteFileIfExists(tempSourcePath)) - { - CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath))); - } - + CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DatabaseExceptionOccurred(e))); + } + } + else + { + CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(CreatingTemporarySiaDriveFile(siaPath, filePath, tempSourcePath))); + if (RetryableAction(::CopyFile(filePath.c_str(), tempSourcePath.c_str(), FALSE), DEFAULT_RETRY_COUNT, DEFAULT_RETRY_DELAY_MS)) + { + // Delete existing '.siadrive' file, if found + // !!Should never come here. If so, there was a problem with startup clean-up if (!RetryDeleteFileIfExists(siaDriveFilePath)) { CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteSiaDriveFileFailed(siaPath, filePath, siaDriveFilePath))); } + // Rename '.siadrive.temp' to '.siadrive' + CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(RenamingTemporarySiaDriveFile(siaPath, filePath, tempSourcePath, siaDriveFilePath))); + if (RetryableAction(::MoveFile(tempSourcePath.c_str(), siaDriveFilePath.c_str()), DEFAULT_RETRY_COUNT, DEFAULT_RETRY_DELAY_MS)) + { + if (!RetryDeleteFileIfExists(tempSourcePath)) + { + CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath))); + } + + try + { + std::lock_guard l(_uploadMutex); + SQLite::Statement query(_uploadDatabase, QUERY_STATUS); + query.bind("@sia_path", CW2A(siaPath.c_str()).m_psz); + if (query.executeStep()) + { + UploadStatus uploadStatus = static_cast(static_cast(query.getColumn(5))); + if (uploadStatus == UploadStatus::Copying) + { + SET_STATUS(UploadStatus::Queued, UploadAddedToQueue, ModifyUploadStatusFailed) + } + } + } + catch (SQLite::Exception e) + { + CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DatabaseExceptionOccurred(e))); + } + } + else + { + CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(RenamingTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath, siaDriveFilePath))); + if (!RetryDeleteFileIfExists(tempSourcePath)) + { + CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath))); + } + + if (!RetryDeleteFileIfExists(siaDriveFilePath)) + { + CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteSiaDriveFileFailed(siaPath, filePath, siaDriveFilePath))); + } + + // Requeued + } + } + else + { + CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(CreatingTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath))); + + // If temp copy fails, try to delete + // If partial copy and file is unable to be deleted, log warning + if (!RetryDeleteFileIfExists(tempSourcePath)) + { + CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath))); + } + // Requeued } } - else - { - CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(CreatingTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath))); - - // If temp copy fails, try to delete - // If partial copy and file is unable to be deleted, log warning - if (!RetryDeleteFileIfExists(tempSourcePath)) - { - CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DeleteTemporarySiaDriveFileFailed(siaPath, filePath, tempSourcePath))); - } - - // Requeued - } } { @@ -366,11 +408,11 @@ UploadError CUploadManager::AddOrUpdate(const String& siaPath, String filePath) // Check copying if (query.executeStep()) { - UploadStatus uploadStatus = static_cast(static_cast(query.getColumn(4))); + UploadStatus uploadStatus = static_cast(static_cast(query.getColumn(5))); CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(ExistingUploadFound(siaPath, filePath, uploadStatus))); if (uploadStatus == UploadStatus::Uploading) { - SET_STATUS(UploadStatus::Modified, UploadStatusModified, ModifyUploadStatusFailed) + SET_STATUS(UploadStatus::Modified, UploadStatusSetToModified, ModifyUploadStatusFailed) } } else @@ -447,12 +489,33 @@ UploadError CUploadManager::Remove(const String& siaPath) try { bool remove = false; + SQLite::Statement query(_uploadDatabase, QUERY_STATUS); query.bind("@sia_path", CW2A(siaPath.c_str()).m_psz); if (query.executeStep()) { - + String filePath = CA2W(query.getColumn(3)).m_psz; + UploadStatus uploadStatus = static_cast(static_cast(query.getColumn(5))); + switch (uploadStatus) + { + case UploadStatus::Queued: + case UploadStatus::Modified: + case UploadStatus::Copying: + case UploadStatus::Uploading: + { + SET_STATUS(UploadStatus::Remove, UploadStatusSetToRemoved, ModifyUploadStatusFailed) + remove = statusUpdated; + } + break; + + default: + { + remove = false; + } + break; + } } + if (remove) { std::lock_guard l2(_fileQueueMutex); @@ -465,5 +528,6 @@ UploadError CUploadManager::Remove(const String& siaPath) ret = UploadError::DatabaseError; } + return ret; } \ No newline at end of file diff --git a/SiaDrive.Api/UploadManager.h b/SiaDrive.Api/UploadManager.h index 110298d..98f36ac 100644 --- a/SiaDrive.Api/UploadManager.h +++ b/SiaDrive.Api/UploadManager.h @@ -207,11 +207,11 @@ public: } }; -class UploadStatusModified : +class UploadStatusSetToModified : public CEvent { public: - UploadStatusModified(const String& siaPath, const String& filePath) : + UploadStatusSetToModified(const String& siaPath, const String& filePath) : _siaPath(siaPath), _filePath(filePath) { @@ -219,7 +219,7 @@ public: } public: - virtual ~UploadStatusModified() + virtual ~UploadStatusSetToModified() { } @@ -230,12 +230,44 @@ private: public: virtual String GetSingleLineMessage() const override { - return L"UploadStatusModified|SP|" + _siaPath + L"|FP|" + _filePath; + return L"UploadStatusSetToModified|SP|" + _siaPath + L"|FP|" + _filePath; } virtual std::shared_ptr Clone() const override { - return std::shared_ptr(new UploadStatusModified(_siaPath, _filePath)); + return std::shared_ptr(new UploadStatusSetToModified(_siaPath, _filePath)); + } +}; + +class UploadStatusSetToRemoved : + public CEvent +{ +public: + UploadStatusSetToRemoved(const String& siaPath, const String& filePath) : + _siaPath(siaPath), + _filePath(filePath) + { + + } + +public: + virtual ~UploadStatusSetToRemoved() + { + } + +private: + const String _siaPath; + const String _filePath; + +public: + virtual String GetSingleLineMessage() const override + { + return L"UploadStatusSetToRemoved|SP|" + _siaPath + L"|FP|" + _filePath; + } + + virtual std::shared_ptr Clone() const override + { + return std::shared_ptr(new UploadStatusSetToRemoved(_siaPath, _filePath)); } };