Vfs: Improve sync protocol entries for actions
authorChristian Kamm <mail@ckamm.de>
Fri, 8 Feb 2019 11:21:25 +0000 (12:21 +0100)
committerKevin Ottens <kevin.ottens@nextcloud.com>
Tue, 15 Dec 2020 09:58:41 +0000 (10:58 +0100)
Creating a new virtual file and replacing a file with a virtual one now
have their own text in the protocol, not just "Downloaded".

To do this, the SyncFileItem type is kept as
ItemTypeVirtualFileDehydration for these actions. Added new code to
ensure the type isn't written to the database.

While looking at this, I've also added documentation on SyncFileItem's
_file, _renameTarget, _originalFile and destination() because some of
the semantics weren't clear.

src/libsync/progressdispatcher.cpp
src/libsync/propagatedownload.cpp
src/libsync/syncfileitem.cpp
src/libsync/syncfileitem.h
test/testsyncvirtualfiles.cpp

index 1352801732e8aada5ba94688a071ff7a673f1e64..3fbc6d3616a9f76b4a472ada60388ca29d56f8fd 100644 (file)
@@ -29,7 +29,13 @@ QString Progress::asResultString(const SyncFileItem &item)
     case CSYNC_INSTRUCTION_NEW:
     case CSYNC_INSTRUCTION_TYPE_CHANGE:
         if (item._direction != SyncFileItem::Up) {
-            return QCoreApplication::translate("progress", "Downloaded");
+            if (item._type == ItemTypeVirtualFile) {
+                return QCoreApplication::translate("progress", "Virtual file created");
+            } else if (item._type == ItemTypeVirtualFileDehydration) {
+                return QCoreApplication::translate("progress", "Replaced by virtual file");
+            } else {
+                return QCoreApplication::translate("progress", "Downloaded");
+            }
         } else {
             return QCoreApplication::translate("progress", "Uploaded");
         }
index 39bec7eaea7938c9c4569e52ed729a944903fe80..e925c209d46cbdbbb4905be5923ee5c0dd45f913 100644 (file)
@@ -427,11 +427,13 @@ void PropagateDownloadFile::startAfterIsEncryptedIsChecked()
         }
 
         qCDebug(lcPropagateDownload) << "dehydrating file" << _item->_file;
-        _item->_type = ItemTypeVirtualFile; // Needed?
         vfs->dehydratePlaceholder(*_item);
         propagator()->_journal->deleteFileRecord(_item->_originalFile);
-        if (!_item->_renameTarget.isEmpty())
-            _item->_file = _item->_renameTarget;
+        // NOTE: This is only done because other rename-like ops also adjust _file, even though
+        // updateMetadata() will store at destination() anyway. Doing this may not be necessary
+        // but maybe it has an effect on reporting (destination() and moves aren't handled
+        // consistently everywhere)
+        _item->_file = _item->destination();
         updateMetadata(false);
         return;
     }
index 2d993ec116e2063c6312c5c3555e8c53f99b6600..c72cb1b468b6c8a00c7957e053f130822580b308 100644 (file)
@@ -29,7 +29,14 @@ SyncJournalFileRecord SyncFileItem::toSyncJournalFileRecordWithInode(const QStri
     SyncJournalFileRecord rec;
     rec._path = destination().toUtf8();
     rec._modtime = _modtime;
+
+    // Some types should never be written to the database when propagation completes
     rec._type = _type;
+    if (rec._type == ItemTypeVirtualFileDownload)
+        rec._type = ItemTypeFile;
+    if (rec._type == ItemTypeVirtualFileDehydration)
+        rec._type = ItemTypeVirtualFile;
+
     rec._etag = _etag;
     rec._fileId = _fileId;
     rec._fileSize = _size;
index 6e0fe86c4909f27cbb5a235726bd45e39532a245..b410244334d112cb9b6b42bf577aa476b394467e 100644 (file)
@@ -196,15 +196,30 @@ public:
     }
 
     // Variables useful for everybody
+
+    /** The syncfolder-relative filesystem path that the operation is about
+     *
+     * For rename operation this is the rename source and the target is in _renameTarget.
+     */
     QString _file;
-    // for renames: the name _file should be renamed to
-    // for dehydrations: the name _file should become after dehydration (like adding a suffix)
+
+    /** for renames: the name _file should be renamed to
+     * for dehydrations: the name _file should become after dehydration (like adding a suffix)
+     * otherwise empty. Use destination() to find the sync target.
+     */
     QString _renameTarget;
 
+    /** The db-path of this item.
+     *
+     * This can easily differ from _file and _renameTarget if parts of the path were renamed.
+     */
+    QString _originalFile;
+
     /// Whether there's end to end encryption on this file.
     /// If the file is encrypted, the _encryptedFilename is
     /// the encrypted name on the server.
     QString _encryptedFileName;
+
     ItemType _type BITFIELD(3);
     Direction _direction BITFIELD(3);
     bool _serverHasIgnoredFiles BITFIELD(1);
@@ -234,7 +249,6 @@ public:
 
     // Variables used by the propagator
     csync_instructions_e _instruction = CSYNC_INSTRUCTION_NONE;
-    QString _originalFile; // as it is in the csync tree
     time_t _modtime = 0;
     QByteArray _etag;
     quint64 _size = 0;
index 3c461cad011c2adb7627623811e6536acc8ad2c4..ce140c0b8cb1763cdbedf30bb87fab4ff8aa264d 100644 (file)
@@ -678,9 +678,11 @@ private slots:
         QVERIFY(isDehydrated("A/a1"));
         QVERIFY(hasDehydratedDbEntries("A/a1"));
         QVERIFY(itemInstruction(completeSpy, "A/a1.nextcloud", CSYNC_INSTRUCTION_SYNC));
+        QCOMPARE(findItem(completeSpy, "A/a1.nextcloud")->_type, ItemTypeVirtualFileDehydration);
         QVERIFY(isDehydrated("A/a2"));
         QVERIFY(hasDehydratedDbEntries("A/a2"));
         QVERIFY(itemInstruction(completeSpy, "A/a2.nextcloud", CSYNC_INSTRUCTION_SYNC));
+        QCOMPARE(findItem(completeSpy, "A/a2.nextcloud")->_type, ItemTypeVirtualFileDehydration);
 
         QVERIFY(!fakeFolder.currentLocalState().find("B/b1"));
         QVERIFY(!fakeFolder.currentRemoteState().find("B/b1"));