_hasServerEntries = true;
}
+ if (_queryLocal == NormalQuery) {
+ if (!_discoveryData->_shouldDiscoverLocaly(_currentFolder._local)
+ && (_currentFolder._local == _currentFolder._original || !_discoveryData->_shouldDiscoverLocaly(_currentFolder._original))) {
+ _queryLocal = ParentNotChanged;
+ }
+ }
+
if (_queryLocal == NormalQuery) {
/*QDirIterator dirIt(_propagator->_localDir + _currentFolder);
while (dirIt.hasNext()) {
}
_localEntries.clear();
- if (_queryServer == ParentNotChanged) {
+ if (_queryServer == ParentNotChanged || _queryLocal == ParentNotChanged) {
// fetch all the name from the DB
auto pathU8 = _currentFolder._original.toUtf8();
// FIXME cache, and do that better (a query that do not get stuff recursively)
if (!_discoveryData->_statedb->getFilesBelowPath(pathU8, [&](const SyncJournalFileRecord &rec) {
if (rec._path.indexOf("/", pathU8.size() + 1) > 0)
return;
- auto name = QString::fromUtf8(rec._path.mid(pathU8.size() + 1));
+ auto name = pathU8.isEmpty() ? rec._path : QString::fromUtf8(rec._path.mid(pathU8.size() + 1));
if (rec._type == ItemTypeVirtualFile || rec._type == ItemTypeVirtualFileDownload) {
name.chop(_discoveryData->_syncOptions._virtualFileSuffix.size());
}
}
}
+
for (const auto &f : entriesNames) {
auto localEntry = localEntriesHash.value(f);
auto serverEntry = serverEntriesHash.value(f);
+ SyncJournalFileRecord record = dbEntriesHash.value(f);
PathTuple path;
if ((localEntry.isValid() && localEntry.isVirtualFile)) {
Q_ASSERT(localEntry.name.endsWith(_discoveryData->_syncOptions._virtualFileSuffix));
path = _currentFolder.addName(localEntry.name);
path._server.chop(_discoveryData->_syncOptions._virtualFileSuffix.size());
+ } else if (_queryLocal == ParentNotChanged && record.isValid() && record._type == ItemTypeVirtualFile) {
+ QString name = f + _discoveryData->_syncOptions._virtualFileSuffix;
+ path = _currentFolder.addName(name);
+ path._server.chop(_discoveryData->_syncOptions._virtualFileSuffix.size());
} else {
path = _currentFolder.addName(f);
}
if (handleExcluded(path._target, localEntry.isDirectory || serverEntry.isDirectory, isHidden))
continue;
- SyncJournalFileRecord record = dbEntriesHash[f];
- if (_queryServer != ParentNotChanged && !_discoveryData->_statedb->getFileRecord(path._original, &record)) {
+ if (_queryServer != ParentNotChanged && _queryLocal != ParentNotChanged && !_discoveryData->_statedb->getFileRecord(path._original, &record)) {
qFatal("TODO: DB ERROR HANDLING");
}
if (_queryServer == InBlackList || _discoveryData->isInSelectiveSyncBlackList(path._original)) {
const SyncJournalFileRecord &dbEntry)
{
const char *hasServer = serverEntry.isValid() ? "true" : _queryServer == ParentNotChanged ? "db" : "false";
+ const char *hasLocal = localEntry.isValid() ? "true" : _queryLocal == ParentNotChanged ? "db" : "false";
qCInfo(lcDisco).nospace() << "Processing " << path._original
- << " | valid: " << dbEntry.isValid() << "/" << localEntry.isValid() << "/" << hasServer
+ << " | valid: " << dbEntry.isValid() << "/" << hasLocal << "/" << hasServer
<< " | mtime: " << dbEntry._modtime << "/" << localEntry.modtime << "/" << serverEntry.modtime
<< " | size: " << dbEntry._fileSize << "/" << localEntry.size << "/" << serverEntry.size
<< " | etag: " << dbEntry._etag << "//" << serverEntry.etag
item->_size = serverEntry.size;
if (serverEntry.isDirectory && dbEntry._type == ItemTypeDirectory) {
item->_instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
- } else if (!localEntry.isValid()) {
+ } else if (!localEntry.isValid() && _queryLocal != ParentNotChanged) {
// Deleted locally, changed on server
item->_instruction = CSYNC_INSTRUCTION_NEW;
} else {
}
}
}
+ } else if (_queryLocal == ParentNotChanged && dbEntry.isValid()) {
+ if (_queryServer != ParentNotChanged && !serverEntry.isValid()) {
+ // Not modified locally (ParentNotChanged), bit not on the server: Removed on the server.
+ item->_instruction = CSYNC_INSTRUCTION_REMOVE;
+ item->_direction = SyncFileItem::Down;
+ }
} else if (_queryServer != ParentNotChanged && !serverEntry.isValid()) {
// Not locally, not on the server. The entry is stale!
qCInfo(lcDisco) << "Stale DB entry";
qCInfo(lcDisco) << "Discovered" << item->_file << item->_instruction << item->_direction << item->_type;
- if (item->isDirectory() || localEntry.isDirectory || serverEntry.isDirectory) {
- if (item->_instruction == CSYNC_INSTRUCTION_SYNC) {
- item->_instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
- }
+ if (item->isDirectory() && item->_instruction == CSYNC_INSTRUCTION_SYNC)
+ item->_instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
+
+ bool recurse = item->isDirectory() || localEntry.isDirectory || serverEntry.isDirectory;
+ if (_queryLocal != NormalQuery && _queryServer != NormalQuery)
+ recurse = false;
+ if (recurse) {
auto job = new ProcessDirectoryJob(item, recurseQueryServer,
- localEntry.isDirectory || item->_instruction == CSYNC_INSTRUCTION_RENAME ? NormalQuery : ParentDontExist,
+ _queryLocal == ParentNotChanged ? ParentNotChanged : localEntry.isDirectory || item->_instruction == CSYNC_INSTRUCTION_RENAME ? NormalQuery : ParentDontExist,
_discoveryData, this);
job->_currentFolder = path;
if (item->_instruction == CSYNC_INSTRUCTION_REMOVE) {
* This should be a full relative file path, example:
* foo/bar/file.txt
*/
- void addTouchedPath(const QByteArray &relativePath);
+ void addTouchedPath(const QString &relativePath);
/** Call when a sync run starts that rediscovers all local files */
void startSyncFullDiscovery();
void startSyncPartialDiscovery();
/** Access list of files that shall be locally rediscovered. */
- const std::set<QByteArray> &localDiscoveryPaths() const;
+ const std::set<QString> &localDiscoveryPaths() const;
public slots:
/**
* Mostly a collection of files the filewatchers have reported as touched.
* Also includes files that have had errors in the last sync run.
*/
- std::set<QByteArray> _localDiscoveryPaths;
+ std::set<QString> _localDiscoveryPaths;
/**
* The paths that the current sync run used for local discovery.
* For failing syncs, this list will be merged into _localDiscoveryPaths
* again when the sync is done to make sure everything is retried.
*/
- std::set<QByteArray> _previousLocalDiscoveryPaths;
+ std::set<QString> _previousLocalDiscoveryPaths;
};
} // namespace OCC
_csync_ctx->read_remote_from_db = true;
_lastLocalDiscoveryStyle = _localDiscoveryStyle;
- _csync_ctx->should_discover_locally_fn = [this](const QByteArray &path) {
- return shouldDiscoverLocally(path);
- };
_csync_ctx->new_files_are_virtual = _syncOptions._newFilesAreVirtual;
_csync_ctx->virtual_file_suffix = _syncOptions._virtualFileSuffix.toUtf8();
_discoveryPhase->_syncOptions = _syncOptions;
_discoveryPhase->_selectiveSyncBlackList = selectiveSyncBlackList;
_discoveryPhase->_selectiveSyncWhiteList = _journal->getSelectiveSyncList(SyncJournalDb::SelectiveSyncWhiteList, &ok);
+ _discoveryPhase->_shouldDiscoverLocaly = [this](const QString &s) { return shouldDiscoverLocally(s); };
if (!ok) {
qCWarning(lcEngine) << "Unable to read selective sync list, aborting.";
csyncError(tr("Unable to read from the sync journal."));
return _account;
}
-void SyncEngine::setLocalDiscoveryOptions(LocalDiscoveryStyle style, std::set<QByteArray> paths)
+void SyncEngine::setLocalDiscoveryOptions(LocalDiscoveryStyle style, std::set<QString> paths)
{
_localDiscoveryStyle = style;
_localDiscoveryPaths = std::move(paths);
}
-bool SyncEngine::shouldDiscoverLocally(const QByteArray &path) const
+bool SyncEngine::shouldDiscoverLocally(const QString &path) const
{
if (_localDiscoveryStyle == LocalDiscoveryStyle::FilesystemOnly)
return true;
* revert afterwards. Use _lastLocalDiscoveryStyle to discover the last
* sync's style.
*/
- void setLocalDiscoveryOptions(LocalDiscoveryStyle style, std::set<QByteArray> paths = {});
+ void setLocalDiscoveryOptions(LocalDiscoveryStyle style, std::set<QString> paths = {});
/**
* Returns whether the given folder-relative path should be locally discovered
* Example: If path is 'foo/bar' and style is DatabaseAndFilesystem and dirs contains
* 'foo/bar/touched_file', then the result will be true.
*/
- bool shouldDiscoverLocally(const QByteArray &path) const;
+ bool shouldDiscoverLocally(const QString &path) const;
/** Access the last sync run's local discovery style */
LocalDiscoveryStyle lastLocalDiscoveryStyle() const { return _lastLocalDiscoveryStyle; }
/** The kind of local discovery the last sync run used */
LocalDiscoveryStyle _lastLocalDiscoveryStyle = LocalDiscoveryStyle::FilesystemOnly;
LocalDiscoveryStyle _localDiscoveryStyle = LocalDiscoveryStyle::FilesystemOnly;
- std::set<QByteArray> _localDiscoveryPaths;
+ std::set<QString> _localDiscoveryPaths;
};
}