Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/owncloud/client.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Goffart <ogoffart@woboq.com>2018-05-28 15:49:02 +0300
committerOlivier Goffart <olivier@woboq.com>2018-05-30 12:57:57 +0300
commit1753ce651bf7f8fabcbb0d920fcc4ad3fe0bfde2 (patch)
treeddd78743a8c9c1b727d47911858bb494edb96c09
parent104f8c9ba2399fc3d2ff7212e273948b337c7d1f (diff)
Virtual Files: Allow to download a folder recursively from the socket API
Issue: #6466
-rw-r--r--src/common/syncjournaldb.cpp19
-rw-r--r--src/common/syncjournaldb.h6
-rw-r--r--src/gui/folder.cpp15
-rw-r--r--src/gui/folder.h3
-rw-r--r--src/gui/socketapi.cpp4
-rw-r--r--test/testsyncvirtualfiles.cpp99
6 files changed, 139 insertions, 7 deletions
diff --git a/src/common/syncjournaldb.cpp b/src/common/syncjournaldb.cpp
index e052b8502..9054951f7 100644
--- a/src/common/syncjournaldb.cpp
+++ b/src/common/syncjournaldb.cpp
@@ -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);
diff --git a/src/common/syncjournaldb.h b/src/common/syncjournaldb.h
index 4db859bbe..5931e8d03 100644
--- a/src/common/syncjournaldb.h
+++ b/src/common/syncjournaldb.h
@@ -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();
diff --git a/src/gui/folder.cpp b/src/gui/folder.cpp
index 314e67f12..2e06986f8 100644
--- a/src/gui/folder.cpp
+++ b/src/gui/folder.cpp
@@ -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();
diff --git a/src/gui/folder.h b/src/gui/folder.h
index ca6468778..a38bbb928 100644
--- a/src/gui/folder.h
+++ b/src/gui/folder.h
@@ -242,6 +242,9 @@ public:
*/
void registerFolderWatcher();
+ /** new files are downloaded as virtual files */
+ bool useVirtualFiles() { return _definition.useVirtualFiles; }
+
signals:
void syncStateChange();
void syncStarted();
diff --git a/src/gui/socketapi.cpp b/src/gui/socketapi.cpp
index fabb65469..43466eb6d 100644
--- a/src/gui/socketapi.cpp
+++ b/src/gui/socketapi.cpp
@@ -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)
diff --git a/test/testsyncvirtualfiles.cpp b/test/testsyncvirtualfiles.cpp
index 0bcd33c51..db677a306 100644
--- a/test/testsyncvirtualfiles.cpp
+++ b/test/testsyncvirtualfiles.cpp
@@ -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)