Skip to content

Commit be3fa68

Browse files
committed
Include saved uploads in partial sync
Fixes: owncloud/enterprise#5382
1 parent 064874c commit be3fa68

File tree

7 files changed

+80
-36
lines changed

7 files changed

+80
-36
lines changed

changelog/unreleased/5382_2

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Bugfix: Properly resume upload with a partial local discovery
2+
3+
https://github.com/owncloud/enterprise/issues/5382
4+
https://github.com/owncloud/client/pull/10200

src/common/preparedsqlquerymanager.h

+1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class OCSYNC_EXPORT PreparedSqlQueryManager
7171
SetDownloadInfoQuery,
7272
DeleteDownloadInfoQuery,
7373
GetUploadInfoQuery,
74+
GetAllUploadInfoQuery,
7475
SetUploadInfoQuery,
7576
DeleteUploadInfoQuery,
7677
DeleteFileRecordPhash,

src/common/syncjournaldb.cpp

+53-21
Original file line numberDiff line numberDiff line change
@@ -1407,31 +1407,63 @@ SyncJournalDb::UploadInfo SyncJournalDb::getUploadInfo(const QString &file)
14071407
{
14081408
QMutexLocker locker(&_mutex);
14091409

1410+
1411+
if (!checkConnect()) {
1412+
return {};
1413+
}
1414+
1415+
const auto query = _queryManager.get(PreparedSqlQueryManager::GetUploadInfoQuery,
1416+
QByteArrayLiteral("SELECT chunk, transferid, errorcount, size, modtime, contentChecksum FROM uploadinfo WHERE path=?1"),
1417+
_db);
1418+
if (!query) {
1419+
return {};
1420+
}
1421+
query->bindValue(1, file);
1422+
1423+
if (!query->exec()) {
1424+
return {};
1425+
}
1426+
14101427
UploadInfo res;
1428+
if (query->next().hasData) {
1429+
res._chunk = query->intValue(0);
1430+
res._transferid = query->intValue(1);
1431+
res._errorCount = query->intValue(2);
1432+
res._size = query->int64Value(3);
1433+
res._modtime = query->int64Value(4);
1434+
res._contentChecksum = query->baValue(5);
1435+
res._valid = true;
1436+
}
1437+
return res;
1438+
}
14111439

1412-
if (checkConnect()) {
1413-
const auto query = _queryManager.get(PreparedSqlQueryManager::GetUploadInfoQuery, QByteArrayLiteral("SELECT chunk, transferid, errorcount, size, modtime, contentChecksum FROM "
1414-
"uploadinfo WHERE path=?1"),
1415-
_db);
1416-
if (!query) {
1417-
return res;
1418-
}
1419-
query->bindValue(1, file);
1440+
std::vector<SyncJournalDb::UploadInfo> SyncJournalDb::getUploadInfos()
1441+
{
1442+
QMutexLocker locker(&_mutex);
14201443

1421-
if (!query->exec()) {
1422-
return res;
1423-
}
1444+
const auto query = _queryManager.get(PreparedSqlQueryManager::GetAllUploadInfoQuery,
1445+
QByteArrayLiteral("SELECT chunk, transferid, errorcount, size, modtime, contentChecksum, path FROM uploadinfo"),
1446+
_db);
1447+
if (!query) {
1448+
return {};
1449+
}
14241450

1425-
if (query->next().hasData) {
1426-
bool ok = true;
1427-
res._chunk = query->intValue(0);
1428-
res._transferid = query->intValue(1);
1429-
res._errorCount = query->intValue(2);
1430-
res._size = query->int64Value(3);
1431-
res._modtime = query->int64Value(4);
1432-
res._contentChecksum = query->baValue(5);
1433-
res._valid = ok;
1434-
}
1451+
if (!query->exec()) {
1452+
return {};
1453+
}
1454+
1455+
std::vector<UploadInfo> res;
1456+
while (query->next().hasData) {
1457+
UploadInfo info;
1458+
info._chunk = query->intValue(0);
1459+
info._transferid = query->intValue(1);
1460+
info._errorCount = query->intValue(2);
1461+
info._size = query->int64Value(3);
1462+
info._modtime = query->int64Value(4);
1463+
info._contentChecksum = query->baValue(5);
1464+
info._path = query->baValue(6);
1465+
info._valid = true;
1466+
res.push_back(std::move(info));
14351467
}
14361468
return res;
14371469
}

src/common/syncjournaldb.h

+9-14
Original file line numberDiff line numberDiff line change
@@ -108,21 +108,14 @@ class OCSYNC_EXPORT SyncJournalDb : public QObject
108108
};
109109
struct UploadInfo
110110
{
111-
UploadInfo()
112-
: _chunk(0)
113-
, _transferid(0)
114-
, _size(0)
115-
, _errorCount(0)
116-
, _valid(false)
117-
{
118-
}
119-
int _chunk;
120-
uint _transferid;
121-
qint64 _size;
122-
qint64 _modtime;
123-
int _errorCount;
124-
bool _valid;
111+
int _chunk = 0;
112+
uint _transferid = 0;
113+
qint64 _size = 0;
114+
qint64 _modtime = 0;
115+
int _errorCount = 0;
116+
bool _valid = false;
125117
QByteArray _contentChecksum;
118+
QByteArray _path;
126119
/**
127120
* Returns true if this entry refers to a chunked upload that can be continued.
128121
* (As opposed to a small file transfer which is stored in the db so we can detect the case
@@ -137,6 +130,8 @@ class OCSYNC_EXPORT SyncJournalDb : public QObject
137130
int downloadInfoCount();
138131

139132
UploadInfo getUploadInfo(const QString &file);
133+
std::vector<UploadInfo> getUploadInfos();
134+
140135
void setUploadInfo(const QString &file, const UploadInfo &i);
141136
// Return the list of transfer ids that were removed.
142137
QVector<uint> deleteStaleUploadInfos(const QSet<QString> &keep);

src/libsync/syncengine.cpp

+9-1
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,13 @@ void SyncEngine::setLocalDiscoveryOptions(LocalDiscoveryStyle style, std::set<QS
889889
_localDiscoveryStyle = style;
890890
_localDiscoveryPaths = std::move(paths);
891891

892+
893+
// add running upload to the local discovery
894+
const auto info = _journal->getUploadInfos();
895+
for (const auto &i : info) {
896+
_localDiscoveryPaths.insert(QString::fromUtf8(i._path));
897+
}
898+
892899
// Normalize to make sure that no path is a contained in another.
893900
// Note: for simplicity, this code consider anything less than '/' as a path separator, so for
894901
// example, this will remove "foo.bar" if "foo" is in the list. This will mean we might have
@@ -908,8 +915,9 @@ void SyncEngine::setLocalDiscoveryOptions(LocalDiscoveryStyle style, std::set<QS
908915

909916
bool SyncEngine::shouldDiscoverLocally(const QString &path) const
910917
{
911-
if (_localDiscoveryStyle == LocalDiscoveryStyle::FilesystemOnly)
918+
if (_localDiscoveryStyle == LocalDiscoveryStyle::FilesystemOnly) {
912919
return true;
920+
}
913921

914922
// The intention is that if "A/X" is in _localDiscoveryPaths:
915923
// - parent folders like "/", "A" will be discovered (to make sure the discovery reaches the

src/libsync/syncengine.h

+2
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,8 @@ private slots:
300300
/** The kind of local discovery the last sync run used */
301301
LocalDiscoveryStyle _lastLocalDiscoveryStyle = LocalDiscoveryStyle::FilesystemOnly;
302302
LocalDiscoveryStyle _localDiscoveryStyle = LocalDiscoveryStyle::FilesystemOnly;
303+
304+
// must be ordered
303305
std::set<QString> _localDiscoveryPaths;
304306

305307
// destructor called

test/testchunkingng.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,7 @@ private slots:
654654
fakeFolder.localModifier().insert(QStringLiteral("A/a0"), size);
655655
QVERIFY(fakeFolder.applyLocalModificationsAndSync());
656656
QVERIFY(fakeFolder.currentLocalState() != fakeFolder.currentRemoteState());
657+
QVERIFY(fakeFolder.syncEngine().isAnotherSyncNeeded());
657658
QCOMPARE(counter.nMOVE, 1);
658659

659660
counter.reset();
@@ -666,6 +667,7 @@ private slots:
666667
QCOMPARE(counter.nPUT, 0);
667668
QCOMPARE(counter.nMOVE, 1);
668669
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
670+
QVERIFY(!fakeFolder.syncEngine().isAnotherSyncNeeded());
669671
}
670672
};
671673

0 commit comments

Comments
 (0)