diff --git a/src/blackcore/webdataservices.cpp b/src/blackcore/webdataservices.cpp index 8b158768a..3704aace9 100644 --- a/src/blackcore/webdataservices.cpp +++ b/src/blackcore/webdataservices.cpp @@ -456,6 +456,25 @@ namespace BlackCore return emptyEntities; } + CEntityFlags::Entity CWebDataServices::getSychronizedEntitiesWithNewerSharedFileOrEmpty(bool syncData, CEntityFlags::Entity entities) + { + CEntityFlags::Entity loadEntities = this->getEntitiesWithNewerSharedFile(entities); + const CEntityFlags::Entity checkForEmptyEntities = CEntityFlags::entityFlagToEntity(CEntityFlags::AllDbEntitiesNoInfoObjects) & ~loadEntities; + + // it can happen the timestamps are not newer, but the data are empty + // - can happen if caches are copied and the TS does not represent the DB timestamp + // - cache files have been deleted + // - sync all DB entities + // - fast if there are no data + // - no impact if already synced + // - slow if newer synced before and all has to be done now + if (syncData) { this->synchronizeDbCaches(checkForEmptyEntities); } + + // we have no newer timestamps, but incomplete data + loadEntities |= this->getEmptyEntities(); + return loadEntities; + } + int CWebDataServices::getCacheCount(CEntityFlags::Entity entity) const { Q_ASSERT_X(CEntityFlags::isSingleEntity(entity), Q_FUNC_INFO, "Need single entity"); @@ -474,10 +493,24 @@ namespace BlackCore int CWebDataServices::getDbInfoObjectCount(CEntityFlags::Entity entity) const { - if (!m_dbInfoDataReader) return -1; + if (!m_dbInfoDataReader) { return -1; } return this->getInfoObjectCount(entity, m_dbInfoDataReader); } + int CWebDataServices::getDbInfoObjectsCount(CEntityFlags::Entity entities, bool stopIfNotFound) const + { + if (!m_dbInfoDataReader) { return -1; } + int total = 0; + CEntityFlags::EntitySet set = CEntityFlags::asSingleEntities(entities); + for (CEntityFlags::Entity single : set) + { + const int c = this->getDbInfoObjectCount(single); + if (c < 0 && stopIfNotFound) { return -1; } + if (c > 0) { total += c; } + } + return total; + } + int CWebDataServices::getSharedInfoObjectCount(CEntityFlags::Entity entity) const { if (!m_sharedInfoDataReader) return -1; diff --git a/src/blackcore/webdataservices.h b/src/blackcore/webdataservices.h index 58f2dc5e3..8b9647e2b 100644 --- a/src/blackcore/webdataservices.h +++ b/src/blackcore/webdataservices.h @@ -416,6 +416,11 @@ namespace BlackCore //! \threadsafe BlackMisc::Network::CEntityFlags::Entity getEmptyEntities(BlackMisc::Network::CEntityFlags::Entity entities = BlackMisc::Network::CEntityFlags::AllDbEntities) const; + //! Synchronized entities either empty or with newer shared file + //! \remark will synchronize entities + //! \threadsafe + BlackMisc::Network::CEntityFlags::Entity getSychronizedEntitiesWithNewerSharedFileOrEmpty(bool syncData = true, BlackMisc::Network::CEntityFlags::Entity entities = BlackMisc::Network::CEntityFlags::AllDbEntities); + //! Cache count for entity //! \threadsafe int getCacheCount(BlackMisc::Network::CEntityFlags::Entity entity) const; @@ -424,6 +429,10 @@ namespace BlackCore //! \threadsafe int getDbInfoObjectCount(BlackMisc::Network::CEntityFlags::Entity entity) const; + //! Count for 1-n entities from DB entity objects + //! \threadsafe + int getDbInfoObjectsCount(BlackMisc::Network::CEntityFlags::Entity entities, bool stopIfNotFound = true) const; + //! Count for entity from shared entity objects //! \threadsafe int getSharedInfoObjectCount(BlackMisc::Network::CEntityFlags::Entity entity) const; diff --git a/src/blackmisc/network/entityflags.cpp b/src/blackmisc/network/entityflags.cpp index 45ecbf7bc..fb0f78d41 100644 --- a/src/blackmisc/network/entityflags.cpp +++ b/src/blackmisc/network/entityflags.cpp @@ -44,23 +44,33 @@ namespace BlackMisc } } - QString CEntityFlags::flagToString(CEntityFlags::Entity flag) + QString CEntityFlags::flagToString(CEntityFlags::Entity entities) + { + return entitiesToString(entities, ", "); + } + + QStringList CEntityFlags::entitiesToStringList(CEntityFlags::Entity entities) { QStringList list; - if (flag.testFlag(AircraftIcaoEntity)) list << "Aircraft ICAO"; - if (flag.testFlag(AirlineIcaoEntity)) list << "Airline ICAO"; - if (flag.testFlag(AirportEntity)) list << "Airport"; - if (flag.testFlag(BookingEntity)) list << "VATSIM bookings"; - if (flag.testFlag(CountryEntity)) list << "Country"; - if (flag.testFlag(DistributorEntity)) list << "Distributor"; - if (flag.testFlag(DbInfoObjectEntity)) list << "Info objects (DB)"; - if (flag.testFlag(SharedInfoObjectEntity)) list << "Info objects (shared)"; - if (flag.testFlag(LiveryEntity)) list << "Livery"; - if (flag.testFlag(ModelEntity)) list << "Model"; - if (flag.testFlag(NoEntity)) list << "no data"; - if (flag.testFlag(VatsimDataFile)) list << "VATSIM data file"; - if (flag.testFlag(VatsimStatusFile)) list << "VATSIM status file"; - return list.join(", "); + if (entities.testFlag(AircraftIcaoEntity)) list << "Aircraft ICAO"; + if (entities.testFlag(AirlineIcaoEntity)) list << "Airline ICAO"; + if (entities.testFlag(AirportEntity)) list << "Airport"; + if (entities.testFlag(BookingEntity)) list << "VATSIM bookings"; + if (entities.testFlag(CountryEntity)) list << "Country"; + if (entities.testFlag(DistributorEntity)) list << "Distributor"; + if (entities.testFlag(DbInfoObjectEntity)) list << "Info objects (DB)"; + if (entities.testFlag(SharedInfoObjectEntity)) list << "Info objects (shared)"; + if (entities.testFlag(LiveryEntity)) list << "Livery"; + if (entities.testFlag(ModelEntity)) list << "Model"; + if (entities.testFlag(NoEntity)) list << "no data"; + if (entities.testFlag(VatsimDataFile)) list << "VATSIM data file"; + if (entities.testFlag(VatsimStatusFile)) list << "VATSIM status file"; + return list; + } + + QString CEntityFlags::entitiesToString(CEntityFlags::Entity entities, const QString &separator) + { + return entitiesToStringList(entities).join(separator); } bool CEntityFlags::isSingleEntity(BlackMisc::Network::CEntityFlags::Entity flag) @@ -73,9 +83,9 @@ namespace BlackMisc return state == ReadFinished || state == ReadFinishedRestricted; } - int CEntityFlags::numberOfEntities(BlackMisc::Network::CEntityFlags::Entity flag) + int CEntityFlags::numberOfEntities(BlackMisc::Network::CEntityFlags::Entity entities) { - const int c = static_cast(std::bitset<(sizeof(flag) * 8)>(flag).count()); + const int c = static_cast(std::bitset<(sizeof(entities) * 8)>(entities).count()); return c; } @@ -100,12 +110,9 @@ namespace BlackMisc { case ReadFinished: case ReadFinishedRestricted: - case StartRead: - return CStatusMessage::SeverityInfo; - case ReadSkipped: - return CStatusMessage::SeverityWarning; - case ReadFailed: - return CStatusMessage::SeverityError; + case StartRead: return CStatusMessage::SeverityInfo; + case ReadSkipped: return CStatusMessage::SeverityWarning; + case ReadFailed: return CStatusMessage::SeverityError; default: Q_ASSERT_X(false, Q_FUNC_INFO, "Missing state"); return CStatusMessage::SeverityInfo; @@ -167,6 +174,18 @@ namespace BlackMisc return NoEntity; } + CEntityFlags::Entity CEntityFlags::multipleEntitiesByNames(const QStringList &names) + { + CEntityFlags::Entity entities = NoEntity; + for (const QString &name : names) + { + const CEntityFlags::Entity singleEntity = CEntityFlags::singleEntityByName(name); + if (singleEntity == NoEntity) { continue; } + entities |= singleEntity; + } + return entities; + } + CEntityFlags::EntitySet CEntityFlags::asSingleEntities(Entity entities) { QSet s; diff --git a/src/blackmisc/network/entityflags.h b/src/blackmisc/network/entityflags.h index dd6bdb4b5..6682d88a4 100644 --- a/src/blackmisc/network/entityflags.h +++ b/src/blackmisc/network/entityflags.h @@ -17,7 +17,7 @@ #include #include -#include +#include namespace BlackMisc { @@ -43,7 +43,7 @@ namespace BlackMisc ModelEntity = 1 << 7, //!< models BookingEntity = 1 << 8, //!< bookings MetarEntity = 1 << 9, //!< METAR - VatsimDataFile = 1 << 10, //!< the VATSIM data file (multiple data entities) + VatsimDataFile = 1 << 10, //!< the VATSIM data file (multiple data entities) VatsimStatusFile = 1 << 11, //!< the VATSIM status file (URLs for data files etc.) AirportEntity = 1 << 12, //!< airports AllEntities = ((1 << 13) - 1), //!< everything @@ -63,18 +63,25 @@ namespace BlackMisc //! State of operation enum ReadState { - StartRead, //!< reading has been started - ReadFinished, //!< reading done - ReadFinishedRestricted, //!< finished a timestamp restricted read - ReadFailed, //!< reading failed - ReadSkipped //!< read skipped, e.g. because network is down + StartRead, //!< reading has been started + ReadFinished, //!< reading done + ReadFinishedRestricted, //!< finished a timestamp restricted read + ReadFailed, //!< reading failed + ReadSkipped //!< read skipped, e.g. because network is down }; //! Convert to string static QString flagToString(CEntityFlags::EntityFlag flag); //! Convert to string - static QString flagToString(CEntityFlags::Entity flag); + //! \deprecated use entities to string + static QString flagToString(CEntityFlags::Entity entities); + + //! Entities to string list + static QStringList entitiesToStringList(CEntityFlags::Entity entities); + + //! Entities to string list + static QString entitiesToString(CEntityFlags::Entity entities, const QString &separator = ", "); //! Representing single entity? static bool isSingleEntity(CEntityFlags::Entity flag); @@ -83,7 +90,7 @@ namespace BlackMisc static bool isFinishedReadState(ReadState state); //! Represented number of entities - static int numberOfEntities(CEntityFlags::Entity flag); + static int numberOfEntities(CEntityFlags::Entity entities); //! Convert to string static QString flagToString(ReadState flag); @@ -109,6 +116,9 @@ namespace BlackMisc //! Get by name static Entity singleEntityByName(const QString &name); + //! Get by multiple names + static Entity multipleEntitiesByNames(const QStringList &names); + //! As set of single entities static EntitySet asSingleEntities(Entity entities);