vfs: Allow (de-)hydrating the full sync folder
authorChristian Kamm <mail@ckamm.de>
Tue, 8 Jan 2019 11:24:15 +0000 (12:24 +0100)
committerKevin Ottens <kevin.ottens@nextcloud.com>
Tue, 15 Dec 2020 09:58:33 +0000 (10:58 +0100)
src/common/syncjournaldb.cpp
src/common/syncjournaldb.h
src/gui/folder.cpp
src/gui/folder.h
test/testsyncjournaldb.cpp

index 9f321e362ff521be5e4069d2e858ef1a70d2a487..eb2e3f32ae54ed376a25ccad68e273814561a13e 100644 (file)
@@ -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();
index 525800a088c6b056deaa44e55940861859527028..dd6b4ff3dcd682f259a528aa503ecebc9cc799f0 100644 (file)
@@ -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);
 
index 7f7bc4110c65c94de24b018820a6e62940c6d577..5615bec7f3281010454ca01a06f9f32b48292605 100644 (file)
@@ -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;
index a1c891a9503b628a91e7411165acc3dfb84336e9..5b5a7ecb50390b4e9a25044989712ad836412813 100644 (file)
@@ -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);
 
index 55eca73adec925fd64b75a0e5e12708d9252f6e6..4a0d377482d247e2cf47cb23d950a4cb31c1f9a8 100644 (file)
@@ -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: