diff --git a/src/blackcore/db/databasereader.cpp b/src/blackcore/db/databasereader.cpp index ef721151f..e4a95ce03 100644 --- a/src/blackcore/db/databasereader.cpp +++ b/src/blackcore/db/databasereader.cpp @@ -269,8 +269,8 @@ namespace BlackCore { static const CDbInfoList e; if (!sApp->hasWebDataServices()) { return e; } - if (!sApp->getWebDataServices()->getInfoDataReader()) { return e; } - return sApp->getWebDataServices()->getInfoDataReader()->getDbInfoObjects(); + if (!sApp->getWebDataServices()->getDbInfoDataReader()) { return e; } + return sApp->getWebDataServices()->getDbInfoDataReader()->getDbInfoObjects(); } bool CDatabaseReader::hasInfoObjects() const diff --git a/src/blackcore/db/infodatareader.cpp b/src/blackcore/db/infodatareader.cpp index 50a5897ab..87b50c3ec 100644 --- a/src/blackcore/db/infodatareader.cpp +++ b/src/blackcore/db/infodatareader.cpp @@ -91,37 +91,17 @@ namespace BlackCore return sApp->getGlobalSetup().getDbInfoReaderUrl(); } - void CInfoDataReader::read(CEntityFlags::Entity entities, const QDateTime &newerThan) + void CInfoDataReader::read() { - this->ps_read(entities, CDbFlags::DbReading, newerThan); - } - - void CInfoDataReader::ps_read(CEntityFlags::Entity entities, CDbFlags::DataRetrievalModeFlag mode, const QDateTime &newerThan) - { - Q_UNUSED(mode); - CEntityFlags::Entity triggeredRead = CEntityFlags::NoEntity; - CUrl url(getInfoObjectsUrl()); - if (entities.testFlag(CEntityFlags::InfoObjectEntity)) + const CUrl url(getDbInfoObjectsUrl()); + if (!url.isEmpty()) { - if (!url.isEmpty()) - { - if (!newerThan.isNull()) - { - const QString tss(newerThan.toString(Qt::ISODate)); - url.appendQuery(QString(parameterLatestTimestamp() + "=" + tss)); - } - sApp->getFromNetwork(url, { this, &CInfoDataReader::ps_parseInfoObjectsData}); - triggeredRead |= CEntityFlags::InfoObjectEntity; - } - else - { - CLogMessage(this).error("No URL for %1") << CEntityFlags::flagToString(CEntityFlags::InfoObjectEntity); - } + sApp->getFromNetwork(url, { this, &CInfoDataReader::ps_parseInfoObjectsData}); + emit dataRead(CEntityFlags::InfoObjectEntity, CEntityFlags::StartRead, 0); } - - if (triggeredRead != CEntityFlags::NoEntity) + else { - emit dataRead(triggeredRead, CEntityFlags::StartRead, 0); + CLogMessage(this).error("No URL for %1") << CEntityFlags::flagToString(CEntityFlags::InfoObjectEntity); } } @@ -153,7 +133,7 @@ namespace BlackCore this->emitAndLogDataRead(CEntityFlags::InfoObjectEntity, n, res); } - CUrl CInfoDataReader::getInfoObjectsUrl() const + CUrl CInfoDataReader::getDbInfoObjectsUrl() const { return getBaseUrl(CDbFlags::DbReading).withAppendedPath("jsondbinfo.php"); } diff --git a/src/blackcore/db/infodatareader.h b/src/blackcore/db/infodatareader.h index 250241769..dbe1186e0 100644 --- a/src/blackcore/db/infodatareader.h +++ b/src/blackcore/db/infodatareader.h @@ -46,19 +46,18 @@ namespace BlackCore bool areAllDataRead() const; //! URL info objects web service - BlackMisc::Network::CUrl getInfoObjectsUrl() const; + BlackMisc::Network::CUrl getDbInfoObjectsUrl() const; - // cache handling for base class + //! Allow to call directly, special for info objects reader + void read(); + + // cache handling for base class: no cache handling here in that case virtual BlackMisc::Network::CEntityFlags::Entity getSupportedEntities() const override; virtual QDateTime getCacheTimestamp(BlackMisc::Network::CEntityFlags::Entity entity) const override; virtual int getCacheCount(BlackMisc::Network::CEntityFlags::Entity entity) const override; virtual void synchronizeCaches(BlackMisc::Network::CEntityFlags::Entity entities) override; virtual void admitCaches(BlackMisc::Network::CEntityFlags::Entity entities) override; - public slots: - //! Allow to call CInfoDataReader::ps_read directly, special for info objects - void read(BlackMisc::Network::CEntityFlags::Entity entities = BlackMisc::Network::CEntityFlags::InfoObjectEntity, const QDateTime &newerThan = QDateTime()); - protected: // cache handling for base class virtual void invalidateCaches(BlackMisc::Network::CEntityFlags::Entity entities) override; @@ -69,10 +68,6 @@ namespace BlackCore //! Info objects have been read void ps_parseInfoObjectsData(QNetworkReply *nwReply); - //! Read / re-read data file - void ps_read(BlackMisc::Network::CEntityFlags::Entity entities = BlackMisc::Network::CEntityFlags::InfoObjectEntity, - BlackMisc::Db::CDbFlags::DataRetrievalModeFlag mode = BlackMisc::Db::CDbFlags::DbReading, const QDateTime &newerThan = QDateTime()); - private: BlackMisc::Db::CDbInfoList m_infoObjects; BlackMisc::Network::CUrl m_urlInfoObjects; diff --git a/src/blackcore/webdataservices.cpp b/src/blackcore/webdataservices.cpp index 80fe80ea6..df32fbd93 100644 --- a/src/blackcore/webdataservices.cpp +++ b/src/blackcore/webdataservices.cpp @@ -42,6 +42,7 @@ using namespace BlackCore::Db; using namespace BlackCore::Data; using namespace BlackCore::Vatsim; using namespace BlackMisc; +using namespace BlackMisc::Db; using namespace BlackMisc::Simulation; using namespace BlackMisc::Network; using namespace BlackMisc::Aviation; @@ -61,10 +62,10 @@ namespace BlackCore // check if I need info objects const bool readFromSwiftDb = dbReaderConfig.possiblyReadsFromSwiftDb(); // DB read access const bool writeToSwiftDb = dbReaderConfig.possiblyWritesToSwiftDb(); // DB write access - if (!readFromSwiftDb && readers.testFlag(CWebReaderFlags::InfoDataReader)) + if (!readFromSwiftDb && readers.testFlag(CWebReaderFlags::DbInfoDataReader)) { // will remove info reader because not needed - readers &= ~CWebReaderFlags::InfoDataReader; + readers &= ~CWebReaderFlags::DbInfoDataReader; this->m_readers = readers; CLogMessage(this).info("Remove info object reader because not needed"); } @@ -73,7 +74,7 @@ namespace BlackCore CEntityFlags::Entity entities = CWebReaderFlags::allEntitiesForReaders(readers); if (entities.testFlag(CEntityFlags::InfoObjectEntity)) { - Q_ASSERT_X(readers.testFlag(CWebReaderFlags::InfoDataReader), Q_FUNC_INFO, "info object but no reader"); + Q_ASSERT_X(readers.testFlag(CWebReaderFlags::DbInfoDataReader), Q_FUNC_INFO, "info object but no reader"); CLogMessage(this).info("Using info objects for swift DB entities"); } @@ -154,17 +155,17 @@ namespace BlackCore void CWebDataServices::triggerReadOfInfoObjects() { - initInfoObjectReaderAndTriggerRead(); + initDbInfoObjectReaderAndTriggerRead(); } bool CWebDataServices::canConnectSwiftDb() const { - if (!m_icaoDataReader && !m_modelDataReader && !m_airportDataReader && !m_infoDataReader) { return false; } + if (!m_icaoDataReader && !m_modelDataReader && !m_airportDataReader && !m_dbInfoDataReader) { return false; } // use the first one to test - if (m_infoDataReader) + if (m_dbInfoDataReader) { - return m_infoDataReader->hasReceivedOkReply(); + return m_dbInfoDataReader->hasReceivedOkReply(); } else if (m_icaoDataReader) { @@ -195,7 +196,7 @@ namespace BlackCore void CWebDataServices::admitDbCaches(CEntityFlags::Entity entities) { // hint: all the readers use own threads - if (this->m_infoDataReader) { this->m_infoDataReader->admitCaches(entities); } + if (this->m_dbInfoDataReader) { this->m_dbInfoDataReader->admitCaches(entities); } if (this->m_modelDataReader) { this->m_modelDataReader->admitCaches(entities); } if (this->m_icaoDataReader) { this->m_icaoDataReader->admitCaches(entities); } if (this->m_airportDataReader) { this->m_airportDataReader->admitCaches(entities); } @@ -269,7 +270,7 @@ namespace BlackCore CEntityFlags::Entity CWebDataServices::triggerLoadingDirectlyFromDb(CEntityFlags::Entity whatToRead, const QDateTime &newerThan) { CEntityFlags::Entity triggeredRead = CEntityFlags::NoEntity; - if (m_infoDataReader) + if (m_dbInfoDataReader) { this->triggerReadOfInfoObjects(); triggeredRead |= CEntityFlags::InfoObjectEntity; @@ -364,7 +365,7 @@ namespace BlackCore Q_ASSERT_X(CEntityFlags::isSingleEntity(entity), Q_FUNC_INFO, "Need single entity"); if (CEntityFlags::anySwiftDbEntity(entity)) { - CInfoDataReader *ir = this->getInfoDataReader(); + CInfoDataReader *ir = this->getDbInfoDataReader(); if (!ir) { return QDateTime(); } return ir->getLatestEntityTimestampFromInfoObjects(entity); } @@ -730,7 +731,7 @@ namespace BlackCore if (this->m_modelDataReader) { this->m_modelDataReader->gracefulShutdown(); } if (this->m_airportDataReader) { this->m_airportDataReader->gracefulShutdown(); } if (this->m_icaoDataReader) { this->m_icaoDataReader->gracefulShutdown(); } - if (this->m_infoDataReader) { this->m_infoDataReader->gracefulShutdown(); } + if (this->m_dbInfoDataReader) { this->m_dbInfoDataReader->gracefulShutdown(); } if (this->m_databaseWriter) { this->m_databaseWriter->gracefulShutdown(); } } @@ -791,12 +792,12 @@ namespace BlackCore const bool databaseUp = CInfoDataReader::canPingSwiftServer(); if (!databaseUp) { dbReaderConfig.markAsDbDown(); } - if (anyDbEntities && flags.testFlag(CWebReaderFlags::WebReaderFlag::InfoDataReader)) + if (anyDbEntities && flags.testFlag(CWebReaderFlags::WebReaderFlag::DbInfoDataReader)) { // info data reader has a special role, it will not be triggered in triggerRead() if (databaseUp) { - this->initInfoObjectReaderAndTriggerRead(); + this->initDbInfoObjectReaderAndTriggerRead(); } else { @@ -805,8 +806,11 @@ namespace BlackCore } } - // 1b. Read shared headers if needed - // --> See below after readers have been connected + // 1b. Read info objects if needed + if (needsSharedInfoObjects) + { + this->initSharedInfoObjectReaderAndTriggerRead(); + } // 2. Status file, updating the VATSIM related caches if (flags.testFlag(CWebReaderFlags::VatsimStatusReader) || flags.testFlag(CWebReaderFlags::VatsimDataReader) || flags.testFlag(CWebReaderFlags::VatsimMetarReader)) @@ -908,24 +912,25 @@ namespace BlackCore Q_UNUSED(c); // signal connect flag } - void CWebDataServices::initInfoObjectReaderAndTriggerRead() + void CWebDataServices::initDbInfoObjectReaderAndTriggerRead() { - if (!this->m_infoDataReader) + if (!this->m_dbInfoDataReader) { - this->m_infoDataReader = new CInfoDataReader(this, m_dbReaderConfig); - bool c = connect(this->m_infoDataReader, &CInfoDataReader::dataRead, this, &CWebDataServices::ps_readFromSwiftDb); + this->m_dbInfoDataReader = new CInfoDataReader(this, m_dbReaderConfig); + bool c = connect(this->m_dbInfoDataReader, &CInfoDataReader::dataRead, this, &CWebDataServices::ps_readFromSwiftDb); Q_ASSERT_X(c, Q_FUNC_INFO, "Info reader connect failed"); // relay signal - c = connect(this->m_infoDataReader, &CInfoDataReader::dataRead, this, &CWebDataServices::dataRead); + c = connect(this->m_dbInfoDataReader, &CInfoDataReader::dataRead, this, &CWebDataServices::dataRead); Q_ASSERT_X(c, Q_FUNC_INFO, "Info reader connect failed"); + Q_UNUSED(c); // start in own thread - this->m_infoDataReader->start(QThread::LowPriority); + this->m_dbInfoDataReader->start(QThread::LowPriority); } // and trigger read - QTimer::singleShot(0, [this]() { this->m_infoDataReader->read(CEntityFlags::InfoObjectEntity, QDateTime()); }); + QTimer::singleShot(0, [this]() { this->m_dbInfoDataReader->read(); }); } CDatabaseReader *CWebDataServices::getDbReader(CEntityFlags::Entity entity) const @@ -1050,10 +1055,10 @@ namespace BlackCore { // with info objects wait until info objects are loaded Q_ASSERT_X(!entities.testFlag(CEntityFlags::InfoObjectEntity), Q_FUNC_INFO, "Info object must be read upfront, do not pass as entity here"); - const bool waitForInfoReader = this->m_infoDataReader && !this->m_infoDataReader->areAllDataRead() && !this->m_infoDataReader->isMarkedAsFailed(); + const bool waitForInfoReader = this->m_dbInfoDataReader && !this->m_dbInfoDataReader->areAllDataRead() && !this->m_dbInfoDataReader->isMarkedAsFailed(); if (waitForInfoReader) { - if (!this->waitForInfoObjects(entities)) { return; } // will call this function again after some time + if (!this->waitForDbInfoObjects(entities)) { return; } // will call this function again after some time } const bool waitForSharedHeaders = m_dbReaderConfig.needsSharedHeadersLoaded(entities); @@ -1067,38 +1072,39 @@ namespace BlackCore this->triggerRead(entities); } - bool CWebDataServices::waitForInfoObjects(CEntityFlags::Entity entities) + bool CWebDataServices::waitForDbInfoObjects(CEntityFlags::Entity entities) { const int waitForInfoObjectsMs = 1000; // ms const int maxWaitCycles = 10; // try to read - if (this->m_infoObjectTrials > maxWaitCycles) + if (this->m_dbInfoObjectTrials > maxWaitCycles) { - CLogMessage(this).warning("Cannot read info objects for %1 from %2") + CLogMessage(this).warning("Cannot read info objects for '%1' from '%2'") << CEntityFlags::flagToString(entities) - << this->m_infoDataReader->getInfoObjectsUrl().toQString(); + << this->m_dbInfoDataReader->getInfoObjectsUrl().toQString(); // continue here and read data without info objects - return true; // no need wait any longer + this->m_dbInfoDataReader->setMarkedAsFailed(true); + return true; // carry on, regardless of situation } - else if (this->m_infoDataReader->hasReceivedFirstReply()) + else if (this->m_dbInfoDataReader->hasReceivedFirstReply()) { - if (this->m_infoDataReader->areAllDataRead()) + if (this->m_dbInfoDataReader->areAllDataRead()) { // we have all data and carry on - CLogMessage(this).info("Info objects for %1 loaded (trial %2) from %3") + CLogMessage(this).info("Info objects for '%1' loaded (trial %2) from '%3'") << CEntityFlags::flagToString(entities) - << this->m_infoObjectTrials - << this->m_infoDataReader->getInfoObjectsUrl().toQString(); - return true; // no need wait any longer + << this->m_dbInfoObjectTrials + << this->m_dbInfoDataReader->getInfoObjectsUrl().toQString(); + return true; // no need to wait any longer } else { // we have received a response, but not all data yet - if (this->m_infoDataReader->hasReceivedOkReply()) + if (this->m_dbInfoDataReader->hasReceivedOkReply()) { // ok, this means we are parsing - this->m_infoObjectTrials++; + this->m_dbInfoObjectTrials++; this->readDeferredInBackground(entities, waitForInfoObjectsMs); return false; // wait } @@ -1107,19 +1113,19 @@ namespace BlackCore // we have a response, but a failure // means server is alive, but responded with error // such an error (access, ...) normally will not go away - CLogMessage(this).error("Info objects loading for %1 failed from %2, '%3'") + CLogMessage(this).error("Info objects loading for '%1' failed from '%2', '%3'") << CEntityFlags::flagToString(entities) - << this->m_infoDataReader->getInfoObjectsUrl().toQString() - << this->m_infoDataReader->getStatusMessage(); - this->m_infoDataReader->setMarkedAsFailed(true); - return true; // no need wait any longer + << this->m_dbInfoDataReader->getInfoObjectsUrl().toQString() + << this->m_dbInfoDataReader->getStatusMessage(); + this->m_dbInfoDataReader->setMarkedAsFailed(true); + return true; // carry on, regardless of situation } } } else { // wait for 1st reply - this->m_infoObjectTrials++; + this->m_dbInfoObjectTrials++; this->readDeferredInBackground(entities, waitForInfoObjectsMs); return false; // wait } diff --git a/src/blackcore/webdataservices.h b/src/blackcore/webdataservices.h index 1fa0480aa..e9ed44543 100644 --- a/src/blackcore/webdataservices.h +++ b/src/blackcore/webdataservices.h @@ -108,7 +108,7 @@ namespace BlackCore Vatsim::CVatsimMetarReader *getMetarReader() const { return m_vatsimMetarReader; } //! Info data reader - Db::CInfoDataReader *getInfoDataReader() const { return m_infoDataReader; } + BlackCore::Db::CInfoDataReader *getDbInfoDataReader() const { return m_dbInfoDataReader; } //! Currently used URL for shared DB data BlackMisc::Network::CUrl getDbReaderCurrentSharedDbDataUrl() const; @@ -389,9 +389,10 @@ namespace BlackCore void dataRead(BlackMisc::Network::CEntityFlags::Entity entity, BlackMisc::Network::CEntityFlags::ReadState state, int number); //! Header of shared file read + //! \deprecated shared file headers will be replaced by dbinfo.json void sharedFileHeaderRead(BlackMisc::Network::CEntityFlags::Entity entity, const QString &fileName, bool success); - // simplified signals + // simplified signals follow // 1) simple signature // 2) fired direct after read, no need to wait for other entities @@ -450,8 +451,8 @@ namespace BlackCore //! Init the readers void initReaders(CWebReaderFlags::WebReader flags, BlackMisc::Network::CEntityFlags::Entity entities); - //! Init the info objects readers - void initInfoObjectReaderAndTriggerRead(); + //! Init the info objects reader (DB web service) + void initDbInfoObjectReaderAndTriggerRead(); //! DB reader for given entity Db::CDatabaseReader *getDbReader(BlackMisc::Network::CEntityFlags::Entity entity) const; @@ -463,18 +464,18 @@ namespace BlackCore bool signalEntitiesRead(BlackMisc::Network::CEntityFlags::Entity entities); //! Wait for info objects to be read - bool waitForInfoObjects(BlackMisc::Network::CEntityFlags::Entity entities); + bool waitForDbInfoObjects(BlackMisc::Network::CEntityFlags::Entity entities); //! Wait for shared headers to be read bool waitForSharedHeaders(BlackMisc::Network::CEntityFlags::Entity entities); CWebReaderFlags::WebReader m_readers = CWebReaderFlags::WebReaderFlag::None; //!< which readers are available - BlackCore::Db::CDatabaseReaderConfigList m_dbReaderConfig; //!< how to read DB data - BlackMisc::Network::CEntityFlags::Entity m_entitiesPeriodicallyRead = BlackMisc::Network::CEntityFlags::NoEntity; //!< those entities which are permanently updated by timers + BlackMisc::Network::CEntityFlags::Entity m_entitiesPeriodicallyRead = BlackMisc::Network::CEntityFlags::NoEntity; //!< entities permanently updated by timers BlackMisc::Network::CEntityFlags::Entity m_swiftDbEntitiesRead = BlackMisc::Network::CEntityFlags::NoEntity; //!< entities read + BlackCore::Db::CDatabaseReaderConfigList m_dbReaderConfig; //!< how to read DB data bool m_initialRead = false; //!< Initial read started bool m_signalledHeaders = false; //!< headers loading has been signalled - int m_infoObjectTrials = 0; //!< Tried to read info objects + int m_dbInfoObjectTrials = 0; //!< Tried to read info objects int m_sharedHeadersTrials = 0; //!< Tried to read shared file headers QSet m_signalledEntities; //!< remember signalled entites @@ -485,8 +486,8 @@ namespace BlackCore Vatsim::CVatsimMetarReader *m_vatsimMetarReader = nullptr; Db::CIcaoDataReader *m_icaoDataReader = nullptr; Db::CModelDataReader *m_modelDataReader = nullptr; - Db::CInfoDataReader *m_infoDataReader = nullptr; Db::CAirportDataReader *m_airportDataReader = nullptr; + Db::CInfoDataReader *m_dbInfoDataReader = nullptr; // writing objects directly into DB Db::CDatabaseWriter *m_databaseWriter = nullptr; diff --git a/src/blackcore/webreaderflags.cpp b/src/blackcore/webreaderflags.cpp index 28a6ecdfd..0fb45c29a 100644 --- a/src/blackcore/webreaderflags.cpp +++ b/src/blackcore/webreaderflags.cpp @@ -31,7 +31,7 @@ namespace BlackCore f |= AirportReader; } - if (entity.testFlag(CEntityFlags::InfoObjectEntity)) { f |= InfoDataReader; } + if (entity.testFlag(CEntityFlags::InfoObjectEntity)) { f |= DbInfoDataReader; } if (entity.testFlag(CEntityFlags::BookingEntity)) { f |= VatsimBookingReader; } if (entity.testFlag(CEntityFlags::VatsimDataFile)) { f |= VatsimDataReader; } if (entity.testFlag(CEntityFlags::VatsimStatusFile)) { f |= VatsimStatusReader; } @@ -51,7 +51,7 @@ namespace BlackCore if (readers.testFlag(IcaoDataReader)) { entities |= CEntityFlags::AllIcaoAndCountries; } if (readers.testFlag(ModelReader)) { entities |= CEntityFlags::DistributorLiveryModel; } if (readers.testFlag(AirportReader)) { entities |= CEntityFlags::AirportEntity; } - if (readers.testFlag(InfoDataReader)) { entities |= CEntityFlags::InfoObjectEntity; } + if (readers.testFlag(DbInfoDataReader)) { entities |= CEntityFlags::InfoObjectEntity; } if (readers.testFlag(VatsimBookingReader)) { entities |= CEntityFlags::BookingEntity; } if (readers.testFlag(VatsimMetarReader)) { entities |= CEntityFlags::MetarEntity; } if (readers.testFlag(VatsimDataReader)) { entities |= CEntityFlags::VatsimDataFile; } @@ -66,7 +66,7 @@ namespace BlackCore bool CWebReaderFlags::isFromSwiftDb(WebReader reader) { - return reader.testFlag(ModelReader) || reader.testFlag(IcaoDataReader) || reader.testFlag(InfoDataReader); + return reader.testFlag(ModelReader) || reader.testFlag(IcaoDataReader) || reader.testFlag(DbInfoDataReader); } } // namespace diff --git a/src/blackcore/webreaderflags.h b/src/blackcore/webreaderflags.h index 9352cdc5a..b7519b50c 100644 --- a/src/blackcore/webreaderflags.h +++ b/src/blackcore/webreaderflags.h @@ -37,9 +37,9 @@ namespace BlackCore IcaoDataReader = 1 << 4, //!< reader for ICAO data ModelReader = 1 << 5, //!< reader for model data such as liveries, models, etc AirportReader = 1 << 6, //!< reader for airport list - InfoDataReader = 1 << 7, //!< DB info data (metdata, how many data, when updated) + DbInfoDataReader = 1 << 7, //!< DB info data (metdata, how many data, when updated) AllVatsimReaders = VatsimBookingReader | VatsimDataReader | VatsimMetarReader | VatsimStatusReader, //!< all VATSIM readers - AllSwiftDbReaders = IcaoDataReader | ModelReader | InfoDataReader | AirportReader, //!< all swift data + AllSwiftDbReaders = IcaoDataReader | ModelReader | DbInfoDataReader | AirportReader, //!< all swift data AllReaders = AllSwiftDbReaders | AllVatsimReaders //!< everything }; Q_DECLARE_FLAGS(WebReader, WebReaderFlag)