return _setupParams.journal->internalPinStates().effectiveForPath(folderPath.toUtf8());
}
-Optional<VfsItemAvailability> Vfs::availabilityInDb(const QString &folderPath, const QString &pinPath)
+Vfs::AvailabilityResult Vfs::availabilityInDb(const QString &folderPath, const QString &pinPath)
{
auto pin = _setupParams.journal->internalPinStates().effectiveForPathRecursive(pinPath.toUtf8());
// not being able to retrieve the pin state isn't too bad
auto hydrationStatus = _setupParams.journal->hasHydratedOrDehydratedFiles(folderPath.toUtf8());
if (!hydrationStatus)
- return {};
+ return AvailabilityError::DbError;
if (hydrationStatus->hasDehydrated) {
if (hydrationStatus->hasHydrated)
return VfsItemAvailability::OnlineOnly;
else
return VfsItemAvailability::AllDehydrated;
- } else {
+ } else if (hydrationStatus->hasHydrated) {
if (pin && *pin == PinState::AlwaysLocal)
return VfsItemAvailability::AlwaysLocal;
else
return VfsItemAvailability::AllHydrated;
}
+ return AvailabilityError::NoSuchItem;
}
VfsOff::VfsOff(QObject *parent)
static QString modeToString(Mode mode);
static Optional<Mode> modeFromString(const QString &str);
+ enum class AvailabilityError
+ {
+ // Availability can't be retrieved due to db error
+ DbError,
+ // Availability not available since the item doesn't exist
+ NoSuchItem,
+ };
+ using AvailabilityResult = Result<VfsItemAvailability, AvailabilityError>;
+
public:
explicit Vfs(QObject* parent = nullptr);
virtual ~Vfs();
* plugins will override it to retrieve the state from elsewhere.
*
* folderPath is relative to the sync folder. Can be "" for root folder.
+ *
+ * Returns none on retrieval error.
*/
virtual Optional<PinState> pinState(const QString &folderPath) = 0;
*
* folderPath is relative to the sync folder. Can be "" for root folder.
*/
- virtual Optional<VfsItemAvailability> availability(const QString &folderPath) = 0;
+ virtual AvailabilityResult availability(const QString &folderPath) = 0;
public slots:
/** Update in-sync state based on SyncFileStatusTracker signal.
bool setPinStateInDb(const QString &folderPath, PinState state);
Optional<PinState> pinStateInDb(const QString &folderPath);
// sadly for virtual files the path in the metadata table can differ from path in 'flags'
- Optional<VfsItemAvailability> availabilityInDb(const QString &folderPath, const QString &pinPath);
+ AvailabilityResult availabilityInDb(const QString &folderPath, const QString &pinPath);
// the parameters passed to start()
VfsSetupParams _setupParams;
bool setPinState(const QString &, PinState) override { return true; }
Optional<PinState> pinState(const QString &) override { return PinState::AlwaysLocal; }
- Optional<VfsItemAvailability> availability(const QString &) override { return VfsItemAvailability::AlwaysLocal; }
+ AvailabilityResult availability(const QString &) override { return VfsItemAvailability::AlwaysLocal; }
public slots:
void fileStatusChanged(const QString &, SyncFileStatus) override {}
auto merge = [](VfsItemAvailability lhs, VfsItemAvailability rhs) {
if (lhs == rhs)
return lhs;
- auto l = int(lhs) < int(rhs) ? lhs : rhs; // reduce cases by sorting
- auto r = int(lhs) < int(rhs) ? rhs : lhs;
- if (l == VfsItemAvailability::AlwaysLocal && r == VfsItemAvailability::AllHydrated)
+ if (int(lhs) > int(rhs))
+ std::swap(lhs, rhs); // reduce cases ensuring lhs < rhs
+ if (lhs == VfsItemAvailability::AlwaysLocal && rhs == VfsItemAvailability::AllHydrated)
return VfsItemAvailability::AllHydrated;
- if (l == VfsItemAvailability::AllDehydrated && r == VfsItemAvailability::OnlineOnly)
+ if (lhs == VfsItemAvailability::AllDehydrated && rhs == VfsItemAvailability::OnlineOnly)
return VfsItemAvailability::AllDehydrated;
return VfsItemAvailability::Mixed;
};
for (const auto &file : files) {
auto fileData = FileData::get(file);
auto availability = syncFolder->vfs().availability(fileData.folderRelativePath);
- if (!availability)
- availability = VfsItemAvailability::Mixed; // db error
+ if (!availability) {
+ if (availability.error() == Vfs::AvailabilityError::DbError)
+ availability = VfsItemAvailability::Mixed;
+ if (availability.error() == Vfs::AvailabilityError::NoSuchItem)
+ continue;
+ }
if (!combined) {
- combined = availability;
+ combined = *availability;
} else {
combined = merge(*combined, *availability);
}
}
- ENFORCE(combined);
// TODO: Should be a submenu, should use icons
auto makePinContextMenu = [&](bool makeAvailableLocally, bool freeSpace) {
+ Utility::vfsFreeSpaceActionText());
};
- switch (*combined) {
- case VfsItemAvailability::AlwaysLocal:
- makePinContextMenu(false, true);
- break;
- case VfsItemAvailability::AllHydrated:
- case VfsItemAvailability::Mixed:
- makePinContextMenu(true, true);
- break;
- case VfsItemAvailability::AllDehydrated:
- case VfsItemAvailability::OnlineOnly:
- makePinContextMenu(true, false);
- break;
+ if (combined) {
+ switch (*combined) {
+ case VfsItemAvailability::AlwaysLocal:
+ makePinContextMenu(false, true);
+ break;
+ case VfsItemAvailability::AllHydrated:
+ case VfsItemAvailability::Mixed:
+ makePinContextMenu(true, true);
+ break;
+ case VfsItemAvailability::AllDehydrated:
+ case VfsItemAvailability::OnlineOnly:
+ makePinContextMenu(true, false);
+ break;
+ }
}
}
return false;
}
-Optional<VfsItemAvailability> VfsSuffix::availability(const QString &folderPath)
+Vfs::AvailabilityResult VfsSuffix::availability(const QString &folderPath)
{
const auto suffix = fileSuffix();
QString pinPath = folderPath;
{ return setPinStateInDb(folderPath, state); }
Optional<PinState> pinState(const QString &folderPath) override
{ return pinStateInDb(folderPath); }
- Optional<VfsItemAvailability> availability(const QString &folderPath) override;
+ AvailabilityResult availability(const QString &folderPath) override;
public slots:
void fileStatusChanged(const QString &, SyncFileStatus) override {}