mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-25 14:36:01 +03:00
Merge pull request #7201 from nextcloud/backport/7193/stable-3.14
[stable-3.14] Bugfix/fix upload locked files
This commit is contained in:
commit
b6211ff082
12 changed files with 43 additions and 13 deletions
|
@ -49,7 +49,7 @@ Q_LOGGING_CATEGORY(lcDb, "nextcloud.sync.database", QtInfoMsg)
|
|||
#define GET_FILE_RECORD_QUERY \
|
||||
"SELECT path, inode, modtime, type, md5, fileid, remotePerm, filesize," \
|
||||
" ignoredChildrenRemote, contentchecksumtype.name || ':' || contentChecksum, e2eMangledName, isE2eEncrypted, " \
|
||||
" lock, lockOwnerDisplayName, lockOwnerId, lockType, lockOwnerEditor, lockTime, lockTimeout, isShared, lastShareStateFetchedTimestmap, sharedByMe" \
|
||||
" lock, lockOwnerDisplayName, lockOwnerId, lockType, lockOwnerEditor, lockTime, lockTimeout, lockToken, isShared, lastShareStateFetchedTimestmap, sharedByMe" \
|
||||
" FROM metadata" \
|
||||
" LEFT JOIN checksumtype as contentchecksumtype ON metadata.contentChecksumTypeId == contentchecksumtype.id"
|
||||
|
||||
|
@ -74,9 +74,10 @@ static void fillFileRecordFromGetQuery(SyncJournalFileRecord &rec, SqlQuery &que
|
|||
rec._lockstate._lockEditorApp = query.stringValue(16);
|
||||
rec._lockstate._lockTime = query.int64Value(17);
|
||||
rec._lockstate._lockTimeout = query.int64Value(18);
|
||||
rec._isShared = query.intValue(19) > 0;
|
||||
rec._lastShareStateFetchedTimestamp = query.int64Value(20);
|
||||
rec._sharedByMe = query.intValue(21) > 0;
|
||||
rec._lockstate._lockToken = query.stringValue(19);
|
||||
rec._isShared = query.intValue(20) > 0;
|
||||
rec._lastShareStateFetchedTimestamp = query.int64Value(21);
|
||||
rec._sharedByMe = query.intValue(22) > 0;
|
||||
}
|
||||
|
||||
static QByteArray defaultJournalMode(const QString &dbPath)
|
||||
|
@ -826,6 +827,7 @@ bool SyncJournalDb::updateMetadataTableStructure()
|
|||
addColumn(QStringLiteral("lockOwnerEditor"), QStringLiteral("TEXT"));
|
||||
addColumn(QStringLiteral("lockTime"), QStringLiteral("INTEGER"));
|
||||
addColumn(QStringLiteral("lockTimeout"), QStringLiteral("INTEGER"));
|
||||
addColumn(QStringLiteral("lockToken"), QStringLiteral("TEXT"));
|
||||
|
||||
SqlQuery query(_db);
|
||||
query.prepare("CREATE INDEX IF NOT EXISTS caseconflicts_basePath ON caseconflicts(basePath);");
|
||||
|
@ -987,8 +989,8 @@ Result<void, QString> SyncJournalDb::setFileRecord(const SyncJournalFileRecord &
|
|||
const auto query = _queryManager.get(PreparedSqlQueryManager::SetFileRecordQuery, QByteArrayLiteral("INSERT OR REPLACE INTO metadata "
|
||||
"(phash, pathlen, path, inode, uid, gid, mode, modtime, type, md5, fileid, remotePerm, filesize, ignoredChildrenRemote, "
|
||||
"contentChecksum, contentChecksumTypeId, e2eMangledName, isE2eEncrypted, lock, lockType, lockOwnerDisplayName, lockOwnerId, "
|
||||
"lockOwnerEditor, lockTime, lockTimeout, isShared, lastShareStateFetchedTimestmap, sharedByMe) "
|
||||
"VALUES (?1 , ?2, ?3 , ?4 , ?5 , ?6 , ?7, ?8 , ?9 , ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20, ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28);"),
|
||||
"lockOwnerEditor, lockTime, lockTimeout, lockToken, isShared, lastShareStateFetchedTimestmap, sharedByMe) "
|
||||
"VALUES (?1 , ?2, ?3 , ?4 , ?5 , ?6 , ?7, ?8 , ?9 , ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20, ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29);"),
|
||||
_db);
|
||||
if (!query) {
|
||||
qCDebug(lcDb) << "database error:" << query->error();
|
||||
|
@ -1020,9 +1022,10 @@ Result<void, QString> SyncJournalDb::setFileRecord(const SyncJournalFileRecord &
|
|||
query->bindValue(23, record._lockstate._lockEditorApp);
|
||||
query->bindValue(24, record._lockstate._lockTime);
|
||||
query->bindValue(25, record._lockstate._lockTimeout);
|
||||
query->bindValue(26, record._isShared);
|
||||
query->bindValue(27, record._lastShareStateFetchedTimestamp);
|
||||
query->bindValue(28, record._sharedByMe);
|
||||
query->bindValue(26, record._lockstate._lockToken);
|
||||
query->bindValue(27, record._isShared);
|
||||
query->bindValue(28, record._lastShareStateFetchedTimestamp);
|
||||
query->bindValue(29, record._sharedByMe);
|
||||
|
||||
if (!query->exec()) {
|
||||
qCDebug(lcDb) << "database error:" << query->error();
|
||||
|
@ -1616,7 +1619,7 @@ bool SyncJournalDb::updateLocalMetadata(const QString &filename,
|
|||
const auto query = _queryManager.get(PreparedSqlQueryManager::SetFileRecordLocalMetadataQuery, QByteArrayLiteral("UPDATE metadata"
|
||||
" SET inode=?2, modtime=?3, filesize=?4, lock=?5, lockType=?6,"
|
||||
" lockOwnerDisplayName=?7, lockOwnerId=?8, lockOwnerEditor = ?9,"
|
||||
" lockTime=?10, lockTimeout=?11"
|
||||
" lockTime=?10, lockTimeout=?11, lockToken=?12"
|
||||
" WHERE phash == ?1;"),
|
||||
_db);
|
||||
if (!query) {
|
||||
|
@ -1635,6 +1638,7 @@ bool SyncJournalDb::updateLocalMetadata(const QString &filename,
|
|||
query->bindValue(9, lockInfo._lockEditorApp);
|
||||
query->bindValue(10, lockInfo._lockTime);
|
||||
query->bindValue(11, lockInfo._lockTimeout);
|
||||
query->bindValue(12, lockInfo._lockToken);
|
||||
if (!query->exec()) {
|
||||
qCDebug(lcDb) << "database error:" << query->error();
|
||||
return false;
|
||||
|
|
|
@ -39,6 +39,7 @@ struct SyncJournalFileLockInfo {
|
|||
QString _lockEditorApp;
|
||||
qint64 _lockTime = 0;
|
||||
qint64 _lockTimeout = 0;
|
||||
QString _lockToken;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -712,6 +712,7 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(const SyncFileItemPtr &it
|
|||
item->_lockEditorApp = serverEntry.lockEditorApp;
|
||||
item->_lockTime = serverEntry.lockTime;
|
||||
item->_lockTimeout = serverEntry.lockTimeout;
|
||||
item->_lockToken = serverEntry.lockToken;
|
||||
|
||||
qCDebug(lcDisco()) << "item lock for:" << item->_file
|
||||
<< item->_locked
|
||||
|
@ -720,7 +721,8 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(const SyncFileItemPtr &it
|
|||
<< item->_lockOwnerType
|
||||
<< item->_lockEditorApp
|
||||
<< item->_lockTime
|
||||
<< item->_lockTimeout;
|
||||
<< item->_lockTimeout
|
||||
<< item->_lockToken;
|
||||
|
||||
// Check for missing server data
|
||||
{
|
||||
|
|
|
@ -415,7 +415,8 @@ void DiscoverySingleDirectoryJob::start()
|
|||
<< "http://nextcloud.org/ns:lock-owner-type"
|
||||
<< "http://nextcloud.org/ns:lock-owner-editor"
|
||||
<< "http://nextcloud.org/ns:lock-time"
|
||||
<< "http://nextcloud.org/ns:lock-timeout";
|
||||
<< "http://nextcloud.org/ns:lock-timeout"
|
||||
<< "http://nextcloud.org/ns:lock-token";
|
||||
}
|
||||
props << "http://nextcloud.org/ns:is-mount-root";
|
||||
|
||||
|
@ -547,7 +548,9 @@ static void propertyMapToRemoteInfo(const QMap<QString, QString> &map, RemotePer
|
|||
result.lockTimeout = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (property == "lock-token") {
|
||||
result.lockToken = value;
|
||||
}
|
||||
}
|
||||
|
||||
if (result.isDirectory && map.contains("size")) {
|
||||
|
|
|
@ -86,6 +86,7 @@ struct RemoteInfo
|
|||
QString lockEditorApp;
|
||||
qint64 lockTime = 0;
|
||||
qint64 lockTimeout = 0;
|
||||
QString lockToken;
|
||||
};
|
||||
|
||||
struct LocalInfo
|
||||
|
|
|
@ -115,6 +115,7 @@ void LockFileJob::setFileRecordLocked(SyncJournalFileRecord &record) const
|
|||
record._lockstate._lockEditorApp = _editorName;
|
||||
record._lockstate._lockTime = _lockTime;
|
||||
record._lockstate._lockTimeout = _lockTimeout;
|
||||
record._lockstate._lockToken = _lockToken;
|
||||
if (!_etag.isEmpty()) {
|
||||
record._etag = _etag;
|
||||
}
|
||||
|
@ -129,6 +130,7 @@ void LockFileJob::resetState()
|
|||
_userId.clear();
|
||||
_lockTime = 0;
|
||||
_lockTimeout = 0;
|
||||
_lockToken.clear();
|
||||
}
|
||||
|
||||
SyncJournalFileRecord LockFileJob::handleReply()
|
||||
|
@ -241,6 +243,8 @@ void LockFileJob::decodeStartElement(const QString &name,
|
|||
_editorName = reader.readElementText();
|
||||
} else if (name == QStringLiteral("getetag")) {
|
||||
_etag = reader.readElementText().toUtf8();
|
||||
} else if (name == QStringLiteral("lock-token")) {
|
||||
_lockToken = reader.readElementText();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ private:
|
|||
QByteArray _etag;
|
||||
qint64 _lockTime = 0;
|
||||
qint64 _lockTimeout = 0;
|
||||
QString _lockToken;
|
||||
QString _remoteSyncPathWithTrailingSlash;
|
||||
QString _localSyncPath;
|
||||
};
|
||||
|
|
|
@ -328,6 +328,9 @@ void PropagateUploadFileNG::finishUpload()
|
|||
|
||||
const auto fileSize = _fileToUpload._size;
|
||||
headers[QByteArrayLiteral("OC-Total-Length")] = QByteArray::number(fileSize);
|
||||
if (_item->_locked == SyncFileItem::LockStatus::LockedItem) {
|
||||
headers[QByteArrayLiteral("If")] = (QLatin1String("<") + propagator()->account()->davUrl().toString() + _fileToUpload._file + "> (<opaquelocktoken:" + _item->_lockToken.toUtf8() + ">)").toUtf8();
|
||||
}
|
||||
|
||||
const auto job = new MoveJob(propagator()->account(), Utility::concatUrlPath(chunkUploadFolderUrl(), "/.file"), destination, headers, this);
|
||||
_jobs.append(job);
|
||||
|
|
|
@ -102,6 +102,10 @@ void PropagateUploadFileV1::startNextChunk()
|
|||
|
||||
QString path = _fileToUpload._file;
|
||||
|
||||
if (_item->_locked == SyncFileItem::LockStatus::LockedItem) {
|
||||
headers[QByteArrayLiteral("If")] = (QLatin1String("<") + propagator()->account()->davUrl().toString() + _fileToUpload._file + "> (<opaquelocktoken:" + _item->_lockToken.toUtf8() + ">)").toUtf8();
|
||||
}
|
||||
|
||||
qint64 chunkStart = 0;
|
||||
qint64 currentChunkSize = fileSize;
|
||||
bool isFinalChunk = false;
|
||||
|
|
|
@ -440,6 +440,7 @@ void OCC::SyncEngine::slotItemDiscovered(const OCC::SyncFileItemPtr &item)
|
|||
lockInfo._lockOwnerType = static_cast<qint64>(item->_lockOwnerType);
|
||||
lockInfo._lockOwnerDisplayName = item->_lockOwnerDisplayName;
|
||||
lockInfo._lockEditorApp = item->_lockOwnerDisplayName;
|
||||
lockInfo._lockToken = item->_lockToken;
|
||||
|
||||
if (!_journal->updateLocalMetadata(item->_file, item->_modtime, item->_size, item->_inode, lockInfo)) {
|
||||
qCWarning(lcEngine) << "Could not update local metadata for file" << item->_file;
|
||||
|
|
|
@ -125,6 +125,7 @@ SyncJournalFileRecord SyncFileItem::toSyncJournalFileRecordWithInode(const QStri
|
|||
rec._lockstate._lockEditorApp = _lockEditorApp;
|
||||
rec._lockstate._lockTime = _lockTime;
|
||||
rec._lockstate._lockTimeout = _lockTimeout;
|
||||
rec._lockstate._lockToken = _lockToken;
|
||||
|
||||
// Update the inode if possible
|
||||
rec._inode = _inode;
|
||||
|
@ -163,6 +164,7 @@ SyncFileItemPtr SyncFileItem::fromSyncJournalFileRecord(const SyncJournalFileRec
|
|||
item->_lockEditorApp = rec._lockstate._lockEditorApp;
|
||||
item->_lockTime = rec._lockstate._lockTime;
|
||||
item->_lockTimeout = rec._lockstate._lockTimeout;
|
||||
item->_lockToken = rec._lockstate._lockToken;
|
||||
item->_sharedByMe = rec._sharedByMe;
|
||||
item->_isShared = rec._isShared;
|
||||
item->_lastShareStateFetchedTimestamp = rec._lastShareStateFetchedTimestamp;
|
||||
|
@ -220,6 +222,8 @@ SyncFileItemPtr SyncFileItem::fromProperties(const QString &filePath, const QMap
|
|||
item->_lockTimeout = ok ? intConvertedValue : 0;
|
||||
}
|
||||
|
||||
item->_lockToken = properties.value(QStringLiteral("lock-token"));
|
||||
|
||||
const auto date = QDateTime::fromString(properties.value(QStringLiteral("getlastmodified")), Qt::RFC2822Date);
|
||||
Q_ASSERT(date.isValid());
|
||||
if (date.toSecsSinceEpoch() > 0) {
|
||||
|
@ -250,6 +254,7 @@ void SyncFileItem::updateLockStateFromDbRecord(const SyncJournalFileRecord &dbRe
|
|||
_lockEditorApp = dbRecord._lockstate._lockEditorApp;
|
||||
_lockTime = dbRecord._lockstate._lockTime;
|
||||
_lockTimeout = dbRecord._lockstate._lockTimeout;
|
||||
_lockToken = dbRecord._lockstate._lockToken;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -326,6 +326,7 @@ public:
|
|||
QString _lockEditorApp;
|
||||
qint64 _lockTime = 0;
|
||||
qint64 _lockTimeout = 0;
|
||||
QString _lockToken;
|
||||
|
||||
bool _isShared = false;
|
||||
time_t _lastShareStateFetchedTimestamp = 0;
|
||||
|
|
Loading…
Reference in a new issue