Skip to content

Commit

Permalink
Propagator: Recover from 'precondition failed' error
Browse files Browse the repository at this point in the history
When we detect a precondition failed, it is possible that it is
because the etag in the database is wrong.  We must therefore not
read from the database on the next sync.  In order to avoid that, we
reset the etag of parent directories to invalid values

Fixes #1767
  • Loading branch information
ogoffart committed Jun 3, 2014
1 parent 24616be commit 6e10b8c
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/mirall/propagator_qnam.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,12 @@ void PropagateUploadFileQNAM::slotPutFinished()
errorString += QLatin1String(" (") + rx.cap(1) + QLatin1Char(')');
}

if (_item._httpErrorCode == 412) {
// Precondition Failed: Maybe the bad etag is in the database, we need to clear the
// parent folder etag so we won't read from DB next sync.
_propagator->_journal->avoidReadFromDbOnNextSync(_item._file);
}

done(classifyError(err, _item._httpErrorCode), errorString);
return;
}
Expand Down
22 changes: 22 additions & 0 deletions src/mirall/syncjournaldb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,28 @@ void SyncJournalDb::avoidRenamesOnNextSync(const QString& path)
}
}

void SyncJournalDb::avoidReadFromDbOnNextSync(const QString& fileName)
{
//Make sure that on the next sync, filName is not read from the DB but use the PROPFIND to
//get the info from the server
// We achieve that by clearing the etag of the parents directory recursively

QMutexLocker locker(&_mutex);

if( !checkConnect() ) {
return;
}

QSqlQuery query(_db);
// This query will match entries for whitch the path is a prefix of fileName
query.prepare("UPDATE metadata SET md5='_invalid_' WHERE ? LIKE(path||'/%') AND type == 2"); // CSYNC_FTW_TYPE_DIR == 2
query.bindValue(0, fileName);
if( !query.exec() ) {
qDebug() << "SQL error in avoidRenamesOnNextSync: "<< query.lastError().text();
} else {
qDebug() << query.executedQuery() << fileName;
}
}

void SyncJournalDb::commit(const QString& context, bool startTrans)
{
Expand Down
6 changes: 6 additions & 0 deletions src/mirall/syncjournaldb.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ class OWNCLOUDSYNC_EXPORT SyncJournalDb : public QObject
SyncJournalBlacklistRecord blacklistEntry( const QString& );
void avoidRenamesOnNextSync(const QString &path);

/**
* Make sure that on the next sync, filName is not read from the DB but use the PROPFIND to
* get the info from the server
*/
void avoidReadFromDbOnNextSync(const QString& fileName);

bool postSyncCleanup( const QHash<QString, QString>& items );

/* Because sqlite transactions is really slow, we encapsulate everything in big transactions
Expand Down

0 comments on commit 6e10b8c

Please sign in to comment.