From: Christian Kamm Date: Tue, 27 Nov 2018 09:22:23 +0000 (+0100) Subject: vfs: Use PinState in sync algorithm #6815 X-Git-Tag: archive/raspbian/3.16.7-1_deb13u1+rpi1~1^2~12^2~21^2~468^2~358 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=486c25cb47faae8083b2f597b5ddf832036c3c6d;p=nextcloud-desktop.git vfs: Use PinState in sync algorithm #6815 New files are virtual if the file's pin state is OnlineOnly. --- diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp index 1a1f5fad7..64984f7ea 100644 --- a/src/libsync/discovery.cpp +++ b/src/libsync/discovery.cpp @@ -400,7 +400,10 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo( } // Turn new remote files into virtual files if the option is enabled. auto &opts = _discoveryData->_syncOptions; - if (!localEntry.isValid() && opts._vfs->mode() != Vfs::Off && opts._newFilesAreVirtual && item->_type == ItemTypeFile) { + if (!localEntry.isValid() + && item->_type == ItemTypeFile + && opts._vfs->mode() != Vfs::Off + && directoryPinState() == PinState::OnlineOnly) { item->_type = ItemTypeVirtualFile; if (isVfsWithSuffix()) addVirtualFileSuffix(path._original); @@ -1318,6 +1321,19 @@ bool ProcessDirectoryJob::runLocalQuery() return true; } +PinState ProcessDirectoryJob::directoryPinState() +{ + if (_pinStateCache) + return *_pinStateCache; + + // Get the path's pinstate and anchor to the root option + _pinStateCache = _discoveryData->_statedb->pinStateForPath(_currentFolder._original.toUtf8()); + if (*_pinStateCache == PinState::Unspecified) + _pinStateCache = _discoveryData->_syncOptions._newFilesAreVirtual ? PinState::OnlineOnly : PinState::AlwaysLocal; + + return *_pinStateCache; +} + bool ProcessDirectoryJob::isVfsWithSuffix() const { return _discoveryData->_syncOptions._vfs->mode() == Vfs::WithSuffix; diff --git a/src/libsync/discovery.h b/src/libsync/discovery.h index 7927077a8..99d0013b1 100644 --- a/src/libsync/discovery.h +++ b/src/libsync/discovery.h @@ -18,6 +18,7 @@ #include "discoveryphase.h" #include "syncfileitem.h" #include "common/asserts.h" +#include "common/syncjournaldb.h" class ExcludedFiles; @@ -177,6 +178,9 @@ private: */ bool runLocalQuery(); + /** Retrieve and cache directory pin state */ + PinState directoryPinState(); + QueryMode _queryServer; QueryMode _queryLocal; @@ -216,6 +220,7 @@ private: PathTuple _currentFolder; bool _childModified = false; // the directory contains modified item what would prevent deletion bool _childIgnored = false; // The directory contains ignored item that would prevent deletion + Optional _pinStateCache; // The directories pin-state, once retrieved, see directoryPinState() signals: void finished(); diff --git a/test/testsyncvirtualfiles.cpp b/test/testsyncvirtualfiles.cpp index b1f5d53f1..cc38527a9 100644 --- a/test/testsyncvirtualfiles.cpp +++ b/test/testsyncvirtualfiles.cpp @@ -739,6 +739,61 @@ private slots: QVERIFY(fakeFolder.currentRemoteState().find("A/a3.nextcloud")); // regular upload QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); } + + void testNewVirtuals() + { + FakeFolder fakeFolder{ FileInfo() }; + SyncOptions syncOptions = vfsSyncOptions(); + syncOptions._newFilesAreVirtual = true; + fakeFolder.syncEngine().setSyncOptions(syncOptions); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + + auto setPin = [&] (const QByteArray &path, PinState state) { + fakeFolder.syncJournal().setPinStateForPath(path, state); + }; + + fakeFolder.remoteModifier().mkdir("local"); + fakeFolder.remoteModifier().mkdir("online"); + fakeFolder.remoteModifier().mkdir("unspec"); + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + + setPin("local", PinState::AlwaysLocal); + setPin("online", PinState::OnlineOnly); + + // Test 1: root is OnlineOnly + fakeFolder.remoteModifier().insert("file1"); + fakeFolder.remoteModifier().insert("online/file1"); + fakeFolder.remoteModifier().insert("local/file1"); + fakeFolder.remoteModifier().insert("unspec/file1"); + QVERIFY(fakeFolder.syncOnce()); + + QVERIFY(fakeFolder.currentLocalState().find("file1.nextcloud")); + QVERIFY(fakeFolder.currentLocalState().find("online/file1.nextcloud")); + QVERIFY(fakeFolder.currentLocalState().find("local/file1")); + QVERIFY(fakeFolder.currentLocalState().find("unspec/file1.nextcloud")); + + // Test 2: root is AlwaysLocal + syncOptions._newFilesAreVirtual = false; + fakeFolder.syncEngine().setSyncOptions(syncOptions); + + fakeFolder.remoteModifier().insert("file2"); + fakeFolder.remoteModifier().insert("online/file2"); + fakeFolder.remoteModifier().insert("local/file2"); + fakeFolder.remoteModifier().insert("unspec/file2"); + QVERIFY(fakeFolder.syncOnce()); + + QVERIFY(fakeFolder.currentLocalState().find("file2")); + QVERIFY(fakeFolder.currentLocalState().find("online/file2.nextcloud")); + QVERIFY(fakeFolder.currentLocalState().find("local/file2")); + QVERIFY(fakeFolder.currentLocalState().find("unspec/file2")); + + // file1 is unchanged + QVERIFY(fakeFolder.currentLocalState().find("file1.nextcloud")); + QVERIFY(fakeFolder.currentLocalState().find("online/file1.nextcloud")); + QVERIFY(fakeFolder.currentLocalState().find("local/file1")); + QVERIFY(fakeFolder.currentLocalState().find("unspec/file1.nextcloud")); + } }; QTEST_GUILESS_MAIN(TestSyncVirtualFiles)