From 4df101ed84293e2eadb53878c7ab5d8d64a5dc80 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Tue, 8 Jan 2019 12:24:15 +0100 Subject: [PATCH] vfs: Allow (de-)hydrating the full sync folder --- src/common/syncjournaldb.cpp | 11 ++++++++--- src/common/syncjournaldb.h | 3 +++ src/gui/folder.cpp | 8 ++++---- src/gui/folder.h | 3 +++ test/testsyncjournaldb.cpp | 6 ++++++ 5 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/common/syncjournaldb.cpp b/src/common/syncjournaldb.cpp index 9f321e362..eb2e3f32a 100644 --- a/src/common/syncjournaldb.cpp +++ b/src/common/syncjournaldb.cpp @@ -2071,14 +2071,17 @@ void SyncJournalDb::markVirtualFileForDownloadRecursively(const QByteArray &path return; static_assert(ItemTypeVirtualFile == 4 && ItemTypeVirtualFileDownload == 5, ""); - SqlQuery query("UPDATE metadata SET type=5 WHERE " IS_PREFIX_PATH_OF("?1", "path") " AND type=4;", _db); + SqlQuery query("UPDATE metadata SET type=5 WHERE " + "(" IS_PREFIX_PATH_OF("?1", "path") " OR ?1 == '') " + "AND type=4;", _db); query.bindValue(1, path); query.exec(); // We also must make sure we do not read the files from the database (same logic as in avoidReadFromDbOnNextSync) // This includes all the parents up to the root, but also all the directory within the selected dir. static_assert(ItemTypeDirectory == 2, ""); - query.prepare("UPDATE metadata SET md5='_invalid_' WHERE (" IS_PREFIX_PATH_OF("?1", "path") " OR " IS_PREFIX_PATH_OR_EQUAL("path", "?1") ") AND type == 2;"); + query.prepare("UPDATE metadata SET md5='_invalid_' WHERE " + "(" IS_PREFIX_PATH_OF("?1", "path") " OR ?1 == '' OR " IS_PREFIX_PATH_OR_EQUAL("path", "?1") ") AND type == 2;"); query.bindValue(1, path); query.exec(); } @@ -2156,7 +2159,9 @@ void SyncJournalDb::wipePinStateForPathAndBelow(const QByteArray &path) auto &query = _wipePinStateQuery; ASSERT(query.initOrReset(QByteArrayLiteral( - "DELETE FROM flags WHERE " IS_PREFIX_PATH_OR_EQUAL("?1", "path") ";"), + "DELETE FROM flags WHERE " + // Allow "" to delete everything + " (" IS_PREFIX_PATH_OR_EQUAL("?1", "path") " OR ?1 == '');"), _db)); query.bindValue(1, path); query.exec(); diff --git a/src/common/syncjournaldb.h b/src/common/syncjournaldb.h index 525800a08..dd6b4ff3d 100644 --- a/src/common/syncjournaldb.h +++ b/src/common/syncjournaldb.h @@ -258,6 +258,8 @@ public: /** * Set the 'ItemTypeVirtualFileDownload' to all the files that have the ItemTypeVirtualFile flag * within the directory specified path path + * + * The path "" marks everything. */ void markVirtualFileForDownloadRecursively(const QByteArray &path); @@ -298,6 +300,7 @@ public: * Wipes pin states for a path and below. * * Used when the user asks a subtree to have a particular pin state. + * The path "" wipes every entry. */ void wipePinStateForPathAndBelow(const QByteArray &path); diff --git a/src/gui/folder.cpp b/src/gui/folder.cpp index 7f7bc4110..5615bec7f 100644 --- a/src/gui/folder.cpp +++ b/src/gui/folder.cpp @@ -575,14 +575,14 @@ void Folder::downloadVirtualFile(const QString &_relativepath) // Set in the database that we should download the file SyncJournalFileRecord record; _journal.getFileRecord(relativepath, &record); - if (!record.isValid()) + if (!record.isValid() && !relativepath.isEmpty()) return; if (record._type == ItemTypeVirtualFile) { record._type = ItemTypeVirtualFileDownload; _journal.setFileRecord(record); // Make sure we go over that file during the discovery _journal.avoidReadFromDbOnNextSync(relativepath); - } else if (record._type == ItemTypeDirectory) { + } else if (record._type == ItemTypeDirectory || relativepath.isEmpty()) { _journal.markVirtualFileForDownloadRecursively(relativepath); } else { qCWarning(lcFolder) << "Invalid existing record " << record._type << " for file " << _relativepath; @@ -607,11 +607,11 @@ void Folder::dehydrateFile(const QString &_relativepath) SyncJournalFileRecord record; _journal.getFileRecord(relativepath, &record); - if (!record.isValid()) + if (!record.isValid() && !relativepath.isEmpty()) return; if (record._type == ItemTypeFile) { markForDehydration(record); - } else if (record._type == ItemTypeDirectory) { + } else if (record._type == ItemTypeDirectory || relativepath.isEmpty()) { _journal.getFilesBelowPath(relativepath, markForDehydration); } else { qCWarning(lcFolder) << "Invalid existing record " << record._type << " for file " << _relativepath; diff --git a/src/gui/folder.h b/src/gui/folder.h index a1c891a95..5b5a7ecb5 100644 --- a/src/gui/folder.h +++ b/src/gui/folder.h @@ -317,6 +317,8 @@ public slots: /** * Mark a virtual file as being ready for download, and start a sync. * relativepath is the path to the file (including the extension) + * Passing a folder means that all contained virtual items shall be downloaded. + * A relative path of "" downloads everything. */ void downloadVirtualFile(const QString &relativepath); @@ -325,6 +327,7 @@ public slots: * * relativepath is the path to the file * It's allowed to pass a path to a folder: all contained files will be dehydrated. + * A relative path of "" dehydrates everything. */ void dehydrateFile(const QString &relativepath); diff --git a/test/testsyncjournaldb.cpp b/test/testsyncjournaldb.cpp index 55eca73ad..4a0d37748 100644 --- a/test/testsyncjournaldb.cpp +++ b/test/testsyncjournaldb.cpp @@ -410,6 +410,12 @@ private slots: QCOMPARE(getRaw("local/local"), PinState::Inherited); QCOMPARE(getRaw("local/local/local"), PinState::Inherited); QCOMPARE(getRaw("local/local/online"), PinState::Inherited); + + // Wiping everything + _db.wipePinStateForPathAndBelow(""); + QCOMPARE(getRaw(""), PinState::Inherited); + QCOMPARE(getRaw("local"), PinState::Inherited); + QCOMPARE(getRaw("online"), PinState::Inherited); } private: -- 2.30.2