mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-28 19:58:56 +03:00
vfs suffix: Ignore server files or synced files with the suffix #6953
This commit is contained in:
parent
e774c6c739
commit
836d298141
2 changed files with 76 additions and 18 deletions
|
@ -82,21 +82,6 @@ void ProcessDirectoryJob::process()
|
||||||
}
|
}
|
||||||
_serverNormalQueryEntries.clear();
|
_serverNormalQueryEntries.clear();
|
||||||
|
|
||||||
for (auto &e : _localNormalQueryEntries) {
|
|
||||||
// Remove the virtual file suffix
|
|
||||||
auto name = e.name;
|
|
||||||
if (e.isVirtualFile && isVfsWithSuffix()) {
|
|
||||||
chopVirtualFileSuffix(name);
|
|
||||||
auto &entry = entries[name];
|
|
||||||
// If there is both a virtual file and a real file, we must keep the real file
|
|
||||||
if (!entry.localEntry.isValid())
|
|
||||||
entry.localEntry = std::move(e);
|
|
||||||
} else {
|
|
||||||
entries[name].localEntry = std::move(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_localNormalQueryEntries.clear();
|
|
||||||
|
|
||||||
// fetch all the name from the DB
|
// fetch all the name from the DB
|
||||||
auto pathU8 = _currentFolder._original.toUtf8();
|
auto pathU8 = _currentFolder._original.toUtf8();
|
||||||
if (!_discoveryData->_statedb->listFilesInPath(pathU8, [&](const SyncJournalFileRecord &rec) {
|
if (!_discoveryData->_statedb->listFilesInPath(pathU8, [&](const SyncJournalFileRecord &rec) {
|
||||||
|
@ -109,6 +94,21 @@ void ProcessDirectoryJob::process()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto &e : _localNormalQueryEntries) {
|
||||||
|
// Normally for vfs-suffix files the local entries need the suffix removed.
|
||||||
|
// However, don't do it if "foo.owncloud" exists on the server or in the db
|
||||||
|
// (as a non-virtual file): we don't want to create two entries.
|
||||||
|
auto name = e.name;
|
||||||
|
if (e.isVirtualFile && isVfsWithSuffix() && entries.find(name) == entries.end()) {
|
||||||
|
chopVirtualFileSuffix(name);
|
||||||
|
// If there is both a virtual file and a real file, we must keep the real file
|
||||||
|
if (entries[name].localEntry.isValid())
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
entries[name].localEntry = std::move(e);
|
||||||
|
}
|
||||||
|
_localNormalQueryEntries.clear();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Iterate over entries and process them
|
// Iterate over entries and process them
|
||||||
//
|
//
|
||||||
|
@ -123,7 +123,7 @@ void ProcessDirectoryJob::process()
|
||||||
if (e.dbEntry.isVirtualFile()) {
|
if (e.dbEntry.isVirtualFile()) {
|
||||||
ASSERT(hasVirtualFileSuffix(e.dbEntry._path));
|
ASSERT(hasVirtualFileSuffix(e.dbEntry._path));
|
||||||
addVirtualFileSuffix(path._original);
|
addVirtualFileSuffix(path._original);
|
||||||
} else if (e.localEntry.isVirtualFile) {
|
} else if (e.localEntry.isVirtualFile && !e.dbEntry.isValid()) {
|
||||||
// We don't have a db entry - but it should be at this path
|
// We don't have a db entry - but it should be at this path
|
||||||
addVirtualFileSuffix(path._original);
|
addVirtualFileSuffix(path._original);
|
||||||
}
|
}
|
||||||
|
@ -303,6 +303,18 @@ void ProcessDirectoryJob::processFile(PathTuple path,
|
||||||
if (item->_type == ItemTypeVirtualFileDehydration)
|
if (item->_type == ItemTypeVirtualFileDehydration)
|
||||||
item->_type = ItemTypeFile;
|
item->_type = ItemTypeFile;
|
||||||
|
|
||||||
|
// VFS suffixed files on the server are ignored
|
||||||
|
if (isVfsWithSuffix()) {
|
||||||
|
if (hasVirtualFileSuffix(serverEntry.name)
|
||||||
|
|| (localEntry.isVirtualFile && !dbEntry.isVirtualFile() && hasVirtualFileSuffix(dbEntry._path))) {
|
||||||
|
item->_instruction = CSYNC_INSTRUCTION_IGNORE;
|
||||||
|
item->_errorString = tr("File has extension reserved for virtual files.");
|
||||||
|
_childIgnored = true;
|
||||||
|
emit _discoveryData->itemDiscovered(item);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (serverEntry.isValid()) {
|
if (serverEntry.isValid()) {
|
||||||
processFileAnalyzeRemoteInfo(item, path, localEntry, serverEntry, dbEntry);
|
processFileAnalyzeRemoteInfo(item, path, localEntry, serverEntry, dbEntry);
|
||||||
return;
|
return;
|
||||||
|
@ -681,6 +693,9 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo(
|
||||||
item->_direction = SyncFileItem::Down;
|
item->_direction = SyncFileItem::Down;
|
||||||
item->_instruction = CSYNC_INSTRUCTION_NEW;
|
item->_instruction = CSYNC_INSTRUCTION_NEW;
|
||||||
item->_type = ItemTypeVirtualFile;
|
item->_type = ItemTypeVirtualFile;
|
||||||
|
} else {
|
||||||
|
qCInfo(lcDisco) << "Virtual file with non-virtual db entry, ignoring:" << item->_file;
|
||||||
|
item->_instruction = CSYNC_INSTRUCTION_IGNORE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!typeChange && ((dbEntry._modtime == localEntry.modtime && dbEntry._fileSize == localEntry.size) || localEntry.isDirectory)) {
|
} else if (!typeChange && ((dbEntry._modtime == localEntry.modtime && dbEntry._fileSize == localEntry.size) || localEntry.isDirectory)) {
|
||||||
|
|
|
@ -742,8 +742,7 @@ private slots:
|
||||||
void testNewVirtuals()
|
void testNewVirtuals()
|
||||||
{
|
{
|
||||||
FakeFolder fakeFolder{ FileInfo() };
|
FakeFolder fakeFolder{ FileInfo() };
|
||||||
SyncOptions syncOptions = vfsSyncOptions(fakeFolder);
|
fakeFolder.syncEngine().setSyncOptions(vfsSyncOptions(fakeFolder));
|
||||||
fakeFolder.syncEngine().setSyncOptions(syncOptions);
|
|
||||||
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
|
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
|
||||||
|
|
||||||
auto setPin = [&] (const QByteArray &path, PinState state) {
|
auto setPin = [&] (const QByteArray &path, PinState state) {
|
||||||
|
@ -791,6 +790,50 @@ private slots:
|
||||||
QVERIFY(fakeFolder.currentLocalState().find("local/file1"));
|
QVERIFY(fakeFolder.currentLocalState().find("local/file1"));
|
||||||
QVERIFY(fakeFolder.currentLocalState().find("unspec/file1.nextcloud"));
|
QVERIFY(fakeFolder.currentLocalState().find("unspec/file1.nextcloud"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check what happens if vfs-suffixed files exist on the server or in the db
|
||||||
|
void testSuffixOnServerOrDb()
|
||||||
|
{
|
||||||
|
FakeFolder fakeFolder{ FileInfo() };
|
||||||
|
|
||||||
|
QSignalSpy completeSpy(&fakeFolder.syncEngine(), SIGNAL(itemCompleted(const SyncFileItemPtr &)));
|
||||||
|
auto cleanup = [&]() {
|
||||||
|
completeSpy.clear();
|
||||||
|
};
|
||||||
|
cleanup();
|
||||||
|
|
||||||
|
// file1.nextcloud is happily synced with Vfs::Off
|
||||||
|
fakeFolder.remoteModifier().mkdir("A");
|
||||||
|
fakeFolder.remoteModifier().insert("A/file1.nextcloud");
|
||||||
|
QVERIFY(fakeFolder.syncOnce());
|
||||||
|
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
|
||||||
|
cleanup();
|
||||||
|
|
||||||
|
// Enable suffix vfs
|
||||||
|
fakeFolder.syncEngine().setSyncOptions(vfsSyncOptions(fakeFolder));
|
||||||
|
|
||||||
|
// Local changes of suffixed file do nothing
|
||||||
|
fakeFolder.localModifier().appendByte("A/file1.nextcloud");
|
||||||
|
QVERIFY(fakeFolder.syncOnce());
|
||||||
|
QVERIFY(itemInstruction(completeSpy, "A/file1.nextcloud", CSYNC_INSTRUCTION_IGNORE));
|
||||||
|
cleanup();
|
||||||
|
|
||||||
|
// Remote don't do anything either
|
||||||
|
fakeFolder.remoteModifier().appendByte("A/file1.nextcloud");
|
||||||
|
QVERIFY(fakeFolder.syncOnce());
|
||||||
|
QVERIFY(itemInstruction(completeSpy, "A/file1.nextcloud", CSYNC_INSTRUCTION_IGNORE));
|
||||||
|
cleanup();
|
||||||
|
|
||||||
|
// New files with a suffix aren't propagated downwards in the first place
|
||||||
|
fakeFolder.remoteModifier().insert("A/file2.nextcloud");
|
||||||
|
QVERIFY(fakeFolder.syncOnce());
|
||||||
|
QVERIFY(itemInstruction(completeSpy, "A/file2.nextcloud", CSYNC_INSTRUCTION_IGNORE));
|
||||||
|
QVERIFY(fakeFolder.currentRemoteState().find("A/file2.nextcloud"));
|
||||||
|
QVERIFY(!fakeFolder.currentLocalState().find("A/file2"));
|
||||||
|
QVERIFY(!fakeFolder.currentLocalState().find("A/file2.nextcloud"));
|
||||||
|
QVERIFY(!fakeFolder.currentLocalState().find("A/file2.nextcloud.nextcloud"));
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(TestSyncVirtualFiles)
|
QTEST_GUILESS_MAIN(TestSyncVirtualFiles)
|
||||||
|
|
Loading…
Reference in a new issue