mirror of
https://github.com/nextcloud/desktop.git
synced 2025-10-26 11:17:43 +00:00
Virtual Files: Allow to download a folder recursively from the socket API
Issue: #6466
This commit is contained in:
parent
104f8c9ba2
commit
1753ce651b
@ -1962,6 +1962,25 @@ void SyncJournalDb::clearFileTable()
|
||||
query.exec();
|
||||
}
|
||||
|
||||
void SyncJournalDb::markVirtualFileForDownloadRecursively(const QByteArray &path)
|
||||
{
|
||||
QMutexLocker lock(&_mutex);
|
||||
if (!checkConnect())
|
||||
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);
|
||||
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.bindValue(1, path);
|
||||
query.exec();
|
||||
}
|
||||
|
||||
void SyncJournalDb::commit(const QString &context, bool startTrans)
|
||||
{
|
||||
QMutexLocker lock(&_mutex);
|
||||
|
||||
@ -245,6 +245,12 @@ public:
|
||||
*/
|
||||
void clearFileTable();
|
||||
|
||||
/**
|
||||
* Set the 'ItemTypeVirtualFileDownload' to all the files that have the ItemTypeVirtualFile flag
|
||||
* within the directory specified path path
|
||||
*/
|
||||
void markVirtualFileForDownloadRecursively(const QByteArray &path);
|
||||
|
||||
private:
|
||||
int getFileRecordCount();
|
||||
bool updateDatabaseStructure();
|
||||
|
||||
@ -519,11 +519,16 @@ void Folder::downloadVirtualFile(const QString &_relativepath)
|
||||
_journal.getFileRecord(relativepath, &record);
|
||||
if (!record.isValid())
|
||||
return;
|
||||
record._type = ItemTypeVirtualFileDownload;
|
||||
_journal.setFileRecord(record);
|
||||
|
||||
// Make sure we go over that file during the discovery
|
||||
_journal.avoidReadFromDbOnNextSync(relativepath);
|
||||
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) {
|
||||
_journal.markVirtualFileForDownloadRecursively(relativepath);
|
||||
} else {
|
||||
qCWarning(lcFolder) << "Invalid existing record " << record._type << " for file " << _relativepath;
|
||||
}
|
||||
|
||||
// Schedule a sync (Folder man will start the sync in a few ms)
|
||||
slotScheduleThisFolder();
|
||||
|
||||
@ -242,6 +242,9 @@ public:
|
||||
*/
|
||||
void registerFolderWatcher();
|
||||
|
||||
/** new files are downloaded as virtual files */
|
||||
bool useVirtualFiles() { return _definition.useVirtualFiles; }
|
||||
|
||||
signals:
|
||||
void syncStateChange();
|
||||
void syncStarted();
|
||||
|
||||
@ -611,7 +611,7 @@ void SocketApi::command_DOWNLOAD_VIRTUAL_FILE(const QString &filesArg, SocketLis
|
||||
auto suffix = QStringLiteral(APPLICATION_DOTVIRTUALFILE_SUFFIX);
|
||||
|
||||
for (const auto &file : files) {
|
||||
if (!file.endsWith(suffix))
|
||||
if (!file.endsWith(suffix) && !QFileInfo(file).isDir())
|
||||
continue;
|
||||
QString relativePath;
|
||||
auto folder = FolderMan::instance()->folderForPath(file, &relativePath);
|
||||
@ -764,7 +764,7 @@ void SocketApi::command_GET_MENU_ITEMS(const QString &argument, OCC::SocketListe
|
||||
auto virtualFileSuffix = QStringLiteral(APPLICATION_DOTVIRTUALFILE_SUFFIX);
|
||||
bool hasVirtualFile = false;
|
||||
for (const auto &file : files) {
|
||||
if (file.endsWith(virtualFileSuffix))
|
||||
if (file.endsWith(virtualFileSuffix) || (folder->useVirtualFiles() && QFileInfo(file).isDir()))
|
||||
hasVirtualFile = true;
|
||||
}
|
||||
if (hasVirtualFile)
|
||||
|
||||
@ -485,6 +485,105 @@ private slots:
|
||||
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
|
||||
QVERIFY(!dbRecord(fakeFolder, "A/a1.owncloud").isValid());
|
||||
}
|
||||
|
||||
void testDownloadRecursive()
|
||||
{
|
||||
FakeFolder fakeFolder{ FileInfo() };
|
||||
SyncOptions syncOptions;
|
||||
syncOptions._newFilesAreVirtual = true;
|
||||
fakeFolder.syncEngine().setSyncOptions(syncOptions);
|
||||
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
|
||||
|
||||
// Create a virtual file for remote files
|
||||
fakeFolder.remoteModifier().mkdir("A");
|
||||
fakeFolder.remoteModifier().mkdir("A/Sub");
|
||||
fakeFolder.remoteModifier().mkdir("A/Sub/SubSub");
|
||||
fakeFolder.remoteModifier().mkdir("A/Sub2");
|
||||
fakeFolder.remoteModifier().mkdir("B");
|
||||
fakeFolder.remoteModifier().mkdir("B/Sub");
|
||||
fakeFolder.remoteModifier().insert("A/a1");
|
||||
fakeFolder.remoteModifier().insert("A/a2");
|
||||
fakeFolder.remoteModifier().insert("A/Sub/a3");
|
||||
fakeFolder.remoteModifier().insert("A/Sub/a4");
|
||||
fakeFolder.remoteModifier().insert("A/Sub/SubSub/a5");
|
||||
fakeFolder.remoteModifier().insert("A/Sub2/a6");
|
||||
fakeFolder.remoteModifier().insert("B/b1");
|
||||
fakeFolder.remoteModifier().insert("B/Sub/b2");
|
||||
QVERIFY(fakeFolder.syncOnce());
|
||||
QVERIFY(fakeFolder.currentLocalState().find("A/a1.owncloud"));
|
||||
QVERIFY(fakeFolder.currentLocalState().find("A/a2.owncloud"));
|
||||
QVERIFY(fakeFolder.currentLocalState().find("A/Sub/a3.owncloud"));
|
||||
QVERIFY(fakeFolder.currentLocalState().find("A/Sub/a4.owncloud"));
|
||||
QVERIFY(fakeFolder.currentLocalState().find("A/Sub/SubSub/a5.owncloud"));
|
||||
QVERIFY(fakeFolder.currentLocalState().find("A/Sub2/a6.owncloud"));
|
||||
QVERIFY(fakeFolder.currentLocalState().find("B/b1.owncloud"));
|
||||
QVERIFY(fakeFolder.currentLocalState().find("B/Sub/b2.owncloud"));
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("A/a1"));
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("A/a2"));
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("A/Sub/a3"));
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("A/Sub/a4"));
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("A/Sub/SubSub/a5"));
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("A/Sub2/a6"));
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("B/b1"));
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("B/Sub/b2"));
|
||||
|
||||
|
||||
// Download All file in the directory A/Sub
|
||||
// (as in Folder::downloadVirtualFile)
|
||||
fakeFolder.syncJournal().markVirtualFileForDownloadRecursively("A/Sub");
|
||||
|
||||
QVERIFY(fakeFolder.syncOnce());
|
||||
QVERIFY(fakeFolder.currentLocalState().find("A/a1.owncloud"));
|
||||
QVERIFY(fakeFolder.currentLocalState().find("A/a2.owncloud"));
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("A/Sub/a3.owncloud"));
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("A/Sub/a4.owncloud"));
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("A/Sub/SubSub/a5.owncloud"));
|
||||
QVERIFY(fakeFolder.currentLocalState().find("A/Sub2/a6.owncloud"));
|
||||
QVERIFY(fakeFolder.currentLocalState().find("B/b1.owncloud"));
|
||||
QVERIFY(fakeFolder.currentLocalState().find("B/Sub/b2.owncloud"));
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("A/a1"));
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("A/a2"));
|
||||
QVERIFY(fakeFolder.currentLocalState().find("A/Sub/a3"));
|
||||
QVERIFY(fakeFolder.currentLocalState().find("A/Sub/a4"));
|
||||
QVERIFY(fakeFolder.currentLocalState().find("A/Sub/SubSub/a5"));
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("A/Sub2/a6"));
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("B/b1"));
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("B/Sub/b2"));
|
||||
|
||||
// Add a file in a subfolder that was downloaded
|
||||
// Currently, this continue to add it as a virtual file.
|
||||
fakeFolder.remoteModifier().insert("A/Sub/SubSub/a7");
|
||||
QVERIFY(fakeFolder.syncOnce());
|
||||
QVERIFY(fakeFolder.currentLocalState().find("A/Sub/SubSub/a7.owncloud"));
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("A/Sub/SubSub/a7"));
|
||||
|
||||
// Now download all files in "A"
|
||||
fakeFolder.syncJournal().markVirtualFileForDownloadRecursively("A");
|
||||
QVERIFY(fakeFolder.syncOnce());
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("A/a1.owncloud"));
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("A/a2.owncloud"));
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("A/Sub/a3.owncloud"));
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("A/Sub/a4.owncloud"));
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("A/Sub/SubSub/a5.owncloud"));
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("A/Sub2/a6.owncloud"));
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("A/Sub/SubSub/a7.owncloud"));
|
||||
QVERIFY(fakeFolder.currentLocalState().find("B/b1.owncloud"));
|
||||
QVERIFY(fakeFolder.currentLocalState().find("B/Sub/b2.owncloud"));
|
||||
QVERIFY(fakeFolder.currentLocalState().find("A/a1"));
|
||||
QVERIFY(fakeFolder.currentLocalState().find("A/a2"));
|
||||
QVERIFY(fakeFolder.currentLocalState().find("A/Sub/a3"));
|
||||
QVERIFY(fakeFolder.currentLocalState().find("A/Sub/a4"));
|
||||
QVERIFY(fakeFolder.currentLocalState().find("A/Sub/SubSub/a5"));
|
||||
QVERIFY(fakeFolder.currentLocalState().find("A/Sub2/a6"));
|
||||
QVERIFY(fakeFolder.currentLocalState().find("A/Sub/SubSub/a7"));
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("B/b1"));
|
||||
QVERIFY(!fakeFolder.currentLocalState().find("B/Sub/b2"));
|
||||
|
||||
// Now download remaining files in "B"
|
||||
fakeFolder.syncJournal().markVirtualFileForDownloadRecursively("B");
|
||||
QVERIFY(fakeFolder.syncOnce());
|
||||
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_GUILESS_MAIN(TestSyncVirtualFiles)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user