refs #568, allow to read incremental data based on timestamp

* signatures with QDateTime
* flags
This commit is contained in:
Klaus Basan
2016-01-08 00:35:52 +01:00
parent 46e7d42e8c
commit 46336e9cce
14 changed files with 190 additions and 46 deletions

View File

@@ -24,11 +24,14 @@ namespace BlackCore
connect(&m_watchdogTimer, &QTimer::timeout, this, &CDatabaseReader::ps_watchdog); connect(&m_watchdogTimer, &QTimer::timeout, this, &CDatabaseReader::ps_watchdog);
} }
void CDatabaseReader::readInBackgroundThread(CEntityFlags::Entity entities) void CDatabaseReader::readInBackgroundThread(CEntityFlags::Entity entities, const QDateTime &newerThan)
{ {
if (isAbandoned()) { return; } if (isAbandoned()) { return; }
this->m_watchdogTimer.stop(); this->m_watchdogTimer.stop();
bool s = QMetaObject::invokeMethod(this, "ps_read", Q_ARG(BlackMisc::Network::CEntityFlags::Entity, entities)); // ps_read is implemented in the derived classes
bool s = QMetaObject::invokeMethod(this, "ps_read",
Q_ARG(BlackMisc::Network::CEntityFlags::Entity, entities),
Q_ARG(QDateTime, newerThan));
Q_ASSERT_X(s, Q_FUNC_INFO, "Invoke failed"); Q_ASSERT_X(s, Q_FUNC_INFO, "Invoke failed");
Q_UNUSED(s); Q_UNUSED(s);
} }
@@ -63,6 +66,7 @@ namespace BlackCore
datastoreResponse.jsonArray = responseObject["data"].toArray(); datastoreResponse.jsonArray = responseObject["data"].toArray();
QString ts(responseObject["latest"].toString()); QString ts(responseObject["latest"].toString());
datastoreResponse.updated = ts.isEmpty() ? QDateTime::currentDateTimeUtc() : CDatastoreUtility::parseTimestamp(ts); datastoreResponse.updated = ts.isEmpty() ? QDateTime::currentDateTimeUtc() : CDatastoreUtility::parseTimestamp(ts);
datastoreResponse.restricted = responseObject["restricted"].toBool();
} }
return datastoreResponse; return datastoreResponse;
} }

View File

@@ -20,7 +20,6 @@
#include <QDateTime> #include <QDateTime>
#include <QTimer> #include <QTimer>
namespace BlackCore namespace BlackCore
{ {
//! Specialized version of threaded reader for DB data //! Specialized version of threaded reader for DB data
@@ -32,8 +31,9 @@ namespace BlackCore
//! Response from our database //! Response from our database
struct JsonDatastoreResponse struct JsonDatastoreResponse
{ {
QJsonArray jsonArray; //!< JSON array data QJsonArray jsonArray; //!< JSON array data
QDateTime updated; //!< when updated QDateTime updated; //!< when was the latest updated?
bool restricted = false; //!< restricted reponse, only data changed
//! Any data? //! Any data?
bool isEmpty() const { return jsonArray.isEmpty(); } bool isEmpty() const { return jsonArray.isEmpty(); }
@@ -50,12 +50,15 @@ namespace BlackCore
//! Is response newer? //! Is response newer?
bool isNewer(qint64 mSecsSinceEpoch) const { return updated.toMSecsSinceEpoch() > mSecsSinceEpoch; } bool isNewer(qint64 mSecsSinceEpoch) const { return updated.toMSecsSinceEpoch() > mSecsSinceEpoch; }
//! Incremental data
bool isRestricted() const { return restricted; }
//! Implicit conversion //! Implicit conversion
operator QJsonArray() const { return jsonArray; } operator QJsonArray() const { return jsonArray; }
}; };
//! Start reading in own thread //! Start reading in own thread
void readInBackgroundThread(BlackMisc::Network::CEntityFlags::Entity entities); void readInBackgroundThread(BlackMisc::Network::CEntityFlags::Entity entities, const QDateTime &newerThan);
//! Can connect to DB //! Can connect to DB
//! \threadsafe //! \threadsafe
@@ -69,7 +72,7 @@ namespace BlackCore
protected: protected:
BlackMisc::Network::CUrl m_watchdogUrl; //!< URL for checking if alive BlackMisc::Network::CUrl m_watchdogUrl; //!< URL for checking if alive
QTimer m_watchdogTimer { this }; //!< Timer for watchdog (DB available?) QTimer m_watchdogTimer { this }; //!< Timer for watchdog (DB available?)
QString m_watchdogMessage; //!< Returned status message QString m_watchdogMessage; //!< Returned status message from watchdog
bool m_canConnect = false; //!< Successful connection? bool m_canConnect = false; //!< Successful connection?
mutable QReadWriteLock m_watchdogLock; //!< Lock mutable QReadWriteLock m_watchdogLock; //!< Lock

View File

@@ -129,7 +129,7 @@ namespace BlackCore
return m_countries.size(); return m_countries.size();
} }
void CIcaoDataReader::ps_read(BlackMisc::Network::CEntityFlags::Entity entities) void CIcaoDataReader::ps_read(BlackMisc::Network::CEntityFlags::Entity entities, const QDateTime &newerThan)
{ {
this->threadAssertCheck(); // runs in background thread this->threadAssertCheck(); // runs in background thread
Q_ASSERT(this->m_networkManagerAircraft); Q_ASSERT(this->m_networkManagerAircraft);
@@ -139,9 +139,10 @@ namespace BlackCore
CEntityFlags::Entity entitiesTriggered = CEntityFlags::NoEntity; CEntityFlags::Entity entitiesTriggered = CEntityFlags::NoEntity;
if (entities.testFlag(CEntityFlags::AircraftIcaoEntity)) if (entities.testFlag(CEntityFlags::AircraftIcaoEntity))
{ {
QUrl url(getAircraftIcaoUrl()); CUrl url(getAircraftIcaoUrl());
if (!url.isEmpty()) if (!url.isEmpty())
{ {
if (!newerThan.isNull()) { url.appendQuery("newer=" + newerThan.toString(Qt::ISODate)); }
QNetworkRequest requestAircraft(CNetworkUtils::getNetworkRequest(url)); QNetworkRequest requestAircraft(CNetworkUtils::getNetworkRequest(url));
this->m_networkManagerAircraft->get(requestAircraft); this->m_networkManagerAircraft->get(requestAircraft);
entitiesTriggered |= CEntityFlags::AircraftIcaoEntity; entitiesTriggered |= CEntityFlags::AircraftIcaoEntity;
@@ -154,9 +155,10 @@ namespace BlackCore
if (entities.testFlag(CEntityFlags::AirlineIcaoEntity)) if (entities.testFlag(CEntityFlags::AirlineIcaoEntity))
{ {
QUrl url(getAirlineIcaoUrl()); CUrl url(getAirlineIcaoUrl());
if (!url.isEmpty()) if (!url.isEmpty())
{ {
if (!newerThan.isNull()) { url.appendQuery("newer=" + newerThan.toString(Qt::ISODate)); }
QNetworkRequest requestAirline(CNetworkUtils::getNetworkRequest(url)); QNetworkRequest requestAirline(CNetworkUtils::getNetworkRequest(url));
this->m_networkManagerAirlines->get(requestAirline); this->m_networkManagerAirlines->get(requestAirline);
entitiesTriggered |= CEntityFlags::AirlineIcaoEntity; entitiesTriggered |= CEntityFlags::AirlineIcaoEntity;
@@ -169,9 +171,10 @@ namespace BlackCore
if (entities.testFlag(CEntityFlags::CountryEntity)) if (entities.testFlag(CEntityFlags::CountryEntity))
{ {
QUrl url(getCountryUrl()); CUrl url(getCountryUrl());
if (!url.isEmpty()) if (!url.isEmpty())
{ {
if (!newerThan.isNull()) { url.appendQuery("newer=" + newerThan.toString(Qt::ISODate)); }
QNetworkRequest requestCountry(CNetworkUtils::getNetworkRequest(url)); QNetworkRequest requestCountry(CNetworkUtils::getNetworkRequest(url));
this->m_networkManagerCountries->get(requestCountry); this->m_networkManagerCountries->get(requestCountry);
entitiesTriggered |= CEntityFlags::CountryEntity; entitiesTriggered |= CEntityFlags::CountryEntity;

View File

@@ -120,7 +120,7 @@ namespace BlackCore
void ps_parseCountryData(QNetworkReply *nwReply); void ps_parseCountryData(QNetworkReply *nwReply);
//! Read / re-read data file //! Read / re-read data file
void ps_read(BlackMisc::Network::CEntityFlags::Entity entities); void ps_read(BlackMisc::Network::CEntityFlags::Entity entities, const QDateTime &newerThan);
private: private:
QNetworkAccessManager *m_networkManagerAircraft = nullptr; QNetworkAccessManager *m_networkManagerAircraft = nullptr;

View File

@@ -126,6 +126,18 @@ namespace BlackCore
return m_models.size(); return m_models.size();
} }
QList<int> CModelDataReader::getModelDbKeys() const
{
QReadLocker l(&m_lockModels);
return m_models.toDbKeyList();
}
QStringList CModelDataReader::getModelStrings() const
{
QReadLocker l(&m_lockModels);
return m_models.getModelStrings(false);
}
bool CModelDataReader::areAllDataRead() const bool CModelDataReader::areAllDataRead() const
{ {
return return
@@ -134,7 +146,7 @@ namespace BlackCore
getDistributorsCount() > 0; getDistributorsCount() > 0;
} }
void CModelDataReader::ps_read(CEntityFlags::Entity entity) void CModelDataReader::ps_read(CEntityFlags::Entity entity, const QDateTime &newerThan)
{ {
this->threadAssertCheck(); this->threadAssertCheck();
Q_ASSERT(this->m_networkManagerLivery); Q_ASSERT(this->m_networkManagerLivery);
@@ -147,6 +159,11 @@ namespace BlackCore
CUrl url(getLiveryUrl()); CUrl url(getLiveryUrl());
if (!url.isEmpty()) if (!url.isEmpty())
{ {
if (!newerThan.isNull())
{
const QString tss(newerThan.toString(Qt::ISODate));
url.appendQuery("newer=" + tss);
}
QNetworkRequest requestLivery(url); QNetworkRequest requestLivery(url);
CNetworkUtils::ignoreSslVerification(requestLivery); CNetworkUtils::ignoreSslVerification(requestLivery);
this->m_networkManagerLivery->get(requestLivery); this->m_networkManagerLivery->get(requestLivery);
@@ -163,6 +180,11 @@ namespace BlackCore
CUrl url(getDistributorUrl()); CUrl url(getDistributorUrl());
if (!url.isEmpty()) if (!url.isEmpty())
{ {
if (!newerThan.isNull())
{
const QString tss(newerThan.toString(Qt::ISODate));
url.appendQuery("newer=" + tss);
}
QNetworkRequest requestDistributor(url); QNetworkRequest requestDistributor(url);
CNetworkUtils::ignoreSslVerification(requestDistributor); CNetworkUtils::ignoreSslVerification(requestDistributor);
this->m_networkManagerDistributor->get(requestDistributor); this->m_networkManagerDistributor->get(requestDistributor);
@@ -179,6 +201,11 @@ namespace BlackCore
CUrl url(getModelUrl()); CUrl url(getModelUrl());
if (!url.isEmpty()) if (!url.isEmpty())
{ {
if (!newerThan.isNull())
{
const QString tss(newerThan.toString(Qt::ISODate));
url.appendQuery("newer=" + tss);
}
QNetworkRequest requestModel(url); QNetworkRequest requestModel(url);
CNetworkUtils::ignoreSslVerification(requestModel); CNetworkUtils::ignoreSslVerification(requestModel);
this->m_networkManagerModel->get(requestModel); this->m_networkManagerModel->get(requestModel);
@@ -202,13 +229,25 @@ namespace BlackCore
// required to use delete later as object is created in a different thread // required to use delete later as object is created in a different thread
QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr); QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr);
QString urlString(nwReply->url().toString()); QString urlString(nwReply->url().toString());
QJsonArray array = this->setStatusAndTransformReplyIntoDatastoreResponse(nwReply.data()); CDatabaseReader::JsonDatastoreResponse res = this->setStatusAndTransformReplyIntoDatastoreResponse(nwReply.data());
if (array.isEmpty()) if (res.isEmpty())
{ {
emit dataRead(CEntityFlags::LiveryEntity, CEntityFlags::ReadFailed, 0); emit dataRead(CEntityFlags::LiveryEntity, CEntityFlags::ReadFailed, 0);
return; return;
} }
CLiveryList liveries = CLiveryList::fromDatabaseJson(array);
// get all or incremental set of distributor
CLiveryList liveries;
if (res.isRestricted())
{
// create full list if it was just incremental
liveries = this->getLiveries();
liveries.replaceOrAddObjectsByKey(CLiveryList::fromDatabaseJson(res));
}
else
{
liveries = CLiveryList::fromDatabaseJson(res);
}
// this part needs to be synchronized // this part needs to be synchronized
int n = liveries.size(); int n = liveries.size();
@@ -216,8 +255,10 @@ namespace BlackCore
QWriteLocker wl(&this->m_lockLivery); QWriteLocker wl(&this->m_lockLivery);
this->m_liveries = liveries; this->m_liveries = liveries;
} }
// never emit when lock is held -> deadlock // never emit when lock is held -> deadlock
emit dataRead(CEntityFlags::LiveryEntity, CEntityFlags::ReadFinished, n); emit dataRead(CEntityFlags::LiveryEntity,
res.isRestricted() ? CEntityFlags::ReadFinishedRestricted : CEntityFlags::ReadFinished, n);
CLogMessage(this).info("Read %1 %2 from %3") << n << CEntityFlags::flagToString(CEntityFlags::LiveryEntity) << urlString; CLogMessage(this).info("Read %1 %2 from %3") << n << CEntityFlags::flagToString(CEntityFlags::LiveryEntity) << urlString;
} }
@@ -225,13 +266,25 @@ namespace BlackCore
{ {
QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr); QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr);
QString urlString(nwReply->url().toString()); QString urlString(nwReply->url().toString());
QJsonArray array = this->setStatusAndTransformReplyIntoDatastoreResponse(nwReply.data()); CDatabaseReader::JsonDatastoreResponse res = this->setStatusAndTransformReplyIntoDatastoreResponse(nwReply.data());
if (array.isEmpty()) if (res.isEmpty())
{ {
emit dataRead(CEntityFlags::DistributorEntity, CEntityFlags::ReadFailed, 0); emit dataRead(CEntityFlags::DistributorEntity, CEntityFlags::ReadFailed, 0);
return; return;
} }
CDistributorList distributors = CDistributorList::fromDatabaseJson(array);
// get all or incremental set of distributor
CDistributorList distributors;
if (res.isRestricted())
{
// create full list if it was just incremental
distributors = this->getDistributors();
distributors.replaceOrAddObjectsByKey(CDistributorList::fromDatabaseJson(res));
}
else
{
distributors = CDistributorList::fromDatabaseJson(res);
}
// this part needs to be synchronized // this part needs to be synchronized
int n = distributors.size(); int n = distributors.size();
@@ -239,7 +292,8 @@ namespace BlackCore
QWriteLocker wl(&this->m_lockDistributor); QWriteLocker wl(&this->m_lockDistributor);
this->m_distributors = distributors; this->m_distributors = distributors;
} }
emit dataRead(CEntityFlags::DistributorEntity, CEntityFlags::ReadFinished, n); emit dataRead(CEntityFlags::DistributorEntity,
res.isRestricted() ? CEntityFlags::ReadFinishedRestricted : CEntityFlags::ReadFinished, n);
CLogMessage(this).info("Read %1 %2 from %3") << n << CEntityFlags::flagToString(CEntityFlags::DistributorEntity) << urlString; CLogMessage(this).info("Read %1 %2 from %3") << n << CEntityFlags::flagToString(CEntityFlags::DistributorEntity) << urlString;
} }
@@ -247,21 +301,35 @@ namespace BlackCore
{ {
QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr); QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr);
QString urlString(nwReply->url().toString()); QString urlString(nwReply->url().toString());
QJsonArray array = this->setStatusAndTransformReplyIntoDatastoreResponse(nwReply.data()); CDatabaseReader::JsonDatastoreResponse res = this->setStatusAndTransformReplyIntoDatastoreResponse(nwReply.data());
if (array.isEmpty()) if (res.isEmpty())
{ {
emit dataRead(CEntityFlags::ModelEntity, CEntityFlags::ReadFailed, 0); emit dataRead(CEntityFlags::ModelEntity, CEntityFlags::ReadFailed, 0);
return; return;
} }
CAircraftModelList models = CAircraftModelList::fromDatabaseJson(array);
// this part needs to be synchronized // get all or incremental set of models
CAircraftModelList models;
if (res.isRestricted())
{
// create full list if it was just incremental
models = this->getModels();
models.replaceOrAddObjectsByKey(CAircraftModelList::fromDatabaseJson(res));
}
else
{
models = CAircraftModelList::fromDatabaseJson(res);
}
// syncronized update
int n = models.size(); int n = models.size();
{ {
QWriteLocker wl(&this->m_lockModels); QWriteLocker wl(&this->m_lockModels);
this->m_models = models; this->m_models = models;
} }
emit dataRead(CEntityFlags::ModelEntity, CEntityFlags::ReadFinished, n);
emit dataRead(CEntityFlags::ModelEntity,
res.isRestricted() ? CEntityFlags::ReadFinishedRestricted : CEntityFlags::ReadFinished, n);
CLogMessage(this).info("Read %1 %2 from %3") << n << CEntityFlags::flagToString(CEntityFlags::ModelEntity) << urlString; CLogMessage(this).info("Read %1 %2 from %3") << n << CEntityFlags::flagToString(CEntityFlags::ModelEntity) << urlString;
} }

View File

@@ -88,6 +88,14 @@ namespace BlackCore
//! \threadsafe //! \threadsafe
int getModelsCount() const; int getModelsCount() const;
//! Get model keys
//! \threadsafe
QList<int> getModelDbKeys() const;
//! Get model keys
//! \threadsafe
QStringList getModelStrings() const;
//! All data read? //! All data read?
//! \threadsafe //! \threadsafe
bool areAllDataRead() const; bool areAllDataRead() const;
@@ -116,7 +124,7 @@ namespace BlackCore
void ps_parseModelData(QNetworkReply *nwReply); void ps_parseModelData(QNetworkReply *nwReply);
//! Read / re-read data file //! Read / re-read data file
void ps_read(BlackMisc::Network::CEntityFlags::Entity entity = BlackMisc::Network::CEntityFlags::DistributorLiveryModel); void ps_read(BlackMisc::Network::CEntityFlags::Entity entity = BlackMisc::Network::CEntityFlags::DistributorLiveryModel, const QDateTime &newerThan = QDateTime());
private: private:
QNetworkAccessManager *m_networkManagerLivery = nullptr; QNetworkAccessManager *m_networkManagerLivery = nullptr;

View File

@@ -177,7 +177,7 @@ namespace BlackCore
return false; return false;
} }
CEntityFlags::Entity CWebDataServices::triggerRead(CEntityFlags::Entity whatToRead) CEntityFlags::Entity CWebDataServices::triggerRead(CEntityFlags::Entity whatToRead, const QDateTime &newerThan)
{ {
m_initialRead = true; m_initialRead = true;
CEntityFlags::Entity triggeredRead = CEntityFlags::NoEntity; CEntityFlags::Entity triggeredRead = CEntityFlags::NoEntity;
@@ -213,7 +213,7 @@ namespace BlackCore
if (whatToRead.testFlag(CEntityFlags::AircraftIcaoEntity) || whatToRead.testFlag(CEntityFlags::AirlineIcaoEntity) || whatToRead.testFlag(CEntityFlags::CountryEntity)) if (whatToRead.testFlag(CEntityFlags::AircraftIcaoEntity) || whatToRead.testFlag(CEntityFlags::AirlineIcaoEntity) || whatToRead.testFlag(CEntityFlags::CountryEntity))
{ {
CEntityFlags::Entity icaoEntities = whatToRead & CEntityFlags::AllIcaoAndCountries; CEntityFlags::Entity icaoEntities = whatToRead & CEntityFlags::AllIcaoAndCountries;
m_icaoDataReader->readInBackgroundThread(icaoEntities); m_icaoDataReader->readInBackgroundThread(icaoEntities, newerThan);
triggeredRead |= icaoEntities; triggeredRead |= icaoEntities;
} }
} }
@@ -223,7 +223,7 @@ namespace BlackCore
if (whatToRead.testFlag(CEntityFlags::LiveryEntity) || whatToRead.testFlag(CEntityFlags::DistributorEntity) || whatToRead.testFlag(CEntityFlags::ModelEntity)) if (whatToRead.testFlag(CEntityFlags::LiveryEntity) || whatToRead.testFlag(CEntityFlags::DistributorEntity) || whatToRead.testFlag(CEntityFlags::ModelEntity))
{ {
CEntityFlags::Entity modelEntities = whatToRead & CEntityFlags::DistributorLiveryModel; CEntityFlags::Entity modelEntities = whatToRead & CEntityFlags::DistributorLiveryModel;
m_modelDataReader->readInBackgroundThread(modelEntities); m_modelDataReader->readInBackgroundThread(modelEntities, newerThan);
triggeredRead |= modelEntities; triggeredRead |= modelEntities;
} }
} }
@@ -296,6 +296,18 @@ namespace BlackCore
return 0; return 0;
} }
QList<int> CWebDataServices::getModelDbKeys() const
{
if (m_modelDataReader) { return m_modelDataReader->getModelDbKeys(); }
return QList<int>();
}
QStringList CWebDataServices::getModelStrings() const
{
if (m_modelDataReader) { return m_modelDataReader->getModelStrings(); }
return QStringList();
}
CAircraftModelList CWebDataServices::getModelsForAircraftDesignatorAndLiveryCombinedCode(const QString &aircraftDesignator, const QString &combinedCode) const CAircraftModelList CWebDataServices::getModelsForAircraftDesignatorAndLiveryCombinedCode(const QString &aircraftDesignator, const QString &combinedCode) const
{ {
if (m_modelDataReader) { return m_modelDataReader->getModelsForAircraftDesignatorAndLiveryCombinedCode(aircraftDesignator, combinedCode); } if (m_modelDataReader) { return m_modelDataReader->getModelsForAircraftDesignatorAndLiveryCombinedCode(aircraftDesignator, combinedCode); }

View File

@@ -91,7 +91,7 @@ namespace BlackCore
//! \copydoc BlackMisc::Network::IWebDataServicesProvider::triggerRead //! \copydoc BlackMisc::Network::IWebDataServicesProvider::triggerRead
//! \ingroup webdatareaderprovider //! \ingroup webdatareaderprovider
virtual BlackMisc::Network::CEntityFlags::Entity triggerRead(BlackMisc::Network::CEntityFlags::Entity whatToRead) override; virtual BlackMisc::Network::CEntityFlags::Entity triggerRead(BlackMisc::Network::CEntityFlags::Entity whatToRead, const QDateTime &newerThan = QDateTime()) override;
//! \copydoc BlackMisc::Network::IWebDataServicesProvider::getVatsimFsdServers //! \copydoc BlackMisc::Network::IWebDataServicesProvider::getVatsimFsdServers
//! \ingroup webdatareaderprovider //! \ingroup webdatareaderprovider
@@ -145,6 +145,14 @@ namespace BlackCore
//! \ingroup webdatareaderprovider //! \ingroup webdatareaderprovider
virtual int getModelsCount() const override; virtual int getModelsCount() const override;
//! \copydoc BlackMisc::Network::IWebDataServicesProvider::getModelDbKeys
//! \ingroup webdatareaderprovider
virtual QList<int> getModelDbKeys() const override;
//! \copydoc BlackMisc::Network::IWebDataServicesProvider::getModelStrings
//! \ingroup webdatareaderprovider
virtual QStringList getModelStrings() const override;
//! \copydoc BlackMisc::Network::IWebDataServicesProvider::getModelsForAircraftDesignatorAndLiveryCombinedCode //! \copydoc BlackMisc::Network::IWebDataServicesProvider::getModelsForAircraftDesignatorAndLiveryCombinedCode
//! \ingroup webdatareaderprovider //! \ingroup webdatareaderprovider
virtual BlackMisc::Simulation::CAircraftModelList getModelsForAircraftDesignatorAndLiveryCombinedCode(const QString &aircraftDesignator, const QString &combinedCode) const override; virtual BlackMisc::Simulation::CAircraftModelList getModelsForAircraftDesignatorAndLiveryCombinedCode(const QString &aircraftDesignator, const QString &combinedCode) const override;

View File

@@ -60,9 +60,12 @@ namespace BlackGui
void CDbModelComponent::ps_modelsRead(CEntityFlags::Entity entity, CEntityFlags::ReadState readState, int count) void CDbModelComponent::ps_modelsRead(CEntityFlags::Entity entity, CEntityFlags::ReadState readState, int count)
{ {
Q_UNUSED(count); Q_UNUSED(count);
if (entity.testFlag(CEntityFlags::ModelEntity) && readState == CEntityFlags::ReadFinished) if (entity.testFlag(CEntityFlags::ModelEntity))
{ {
this->ui->tvp_AircraftModel->updateContainer(this->getModels()); if (readState == CEntityFlags::ReadFinished || readState == CEntityFlags::ReadFinishedRestricted)
{
this->ui->tvp_AircraftModel->updateContainer(this->getModels());
}
} }
} }

View File

@@ -11,6 +11,7 @@
#include "blackmisc/dbus.h" #include "blackmisc/dbus.h"
#include <QtDBus/QDBusMetaType> #include <QtDBus/QDBusMetaType>
#include <QStringList> #include <QStringList>
#include "blackmisc/verify.h"
namespace BlackMisc namespace BlackMisc
{ {
@@ -33,7 +34,7 @@ namespace BlackMisc
case AllIcaoAndCountries: return "All ICAO + country"; case AllIcaoAndCountries: return "All ICAO + country";
case AllEntities: return "All"; case AllEntities: return "All";
default: default:
Q_ASSERT_X(false, Q_FUNC_INFO, "wrong flags"); BLACK_VERIFY_X(false, Q_FUNC_INFO, "wrong flags");
return "wrong flags"; return "wrong flags";
} }
} }
@@ -58,10 +59,11 @@ namespace BlackMisc
switch (flag) switch (flag)
{ {
case ReadFinished: return "finished"; case ReadFinished: return "finished";
case ReadFinishedRestricted: return "finished (restricted)";
case ReadFailed: return "failed"; case ReadFailed: return "failed";
case StartRead: return "read started"; case StartRead: return "read started";
default: default:
Q_ASSERT_X(false, Q_FUNC_INFO, "wrong flags"); BLACK_VERIFY_X(false, Q_FUNC_INFO, "wrong flags");
return "wrong flags"; return "wrong flags";
} }
} }
@@ -71,18 +73,22 @@ namespace BlackMisc
switch (state) switch (state)
{ {
case ReadFinished: case ReadFinished:
case ReadFinishedRestricted:
case StartRead: case StartRead:
default:
return CStatusMessage::SeverityInfo; return CStatusMessage::SeverityInfo;
case ReadFailed: case ReadFailed:
return CStatusMessage::SeverityWarning; return CStatusMessage::SeverityWarning;
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "Missing state");
return CStatusMessage::SeverityInfo;
} }
} }
bool CEntityFlags::isWarningOrAbove(CEntityFlags::ReadState state) bool CEntityFlags::isWarningOrAbove(CEntityFlags::ReadState state)
{ {
CStatusMessage::StatusSeverity s = flagToSeverity(state); CStatusMessage::StatusSeverity s = flagToSeverity(state);
switch (s) { switch (s)
{
case CStatusMessage::SeverityError: case CStatusMessage::SeverityError:
case CStatusMessage::SeverityWarning: case CStatusMessage::SeverityWarning:
return true; return true;

View File

@@ -49,9 +49,10 @@ namespace BlackMisc
//! State of operation //! State of operation
enum ReadState enum ReadState
{ {
StartRead, ///< reading has been started StartRead, ///< reading has been started
ReadFinished, ///< reading done ReadFinished, ///< reading done
ReadFailed ///< reading failed ReadFinishedRestricted, ///< finished a timestamp restricted read
ReadFailed ///< reading failed
}; };
//! Convert to string //! Convert to string

View File

@@ -129,6 +129,20 @@ namespace BlackMisc
return this->m_webDataReaderProvider->getModelsCount(); return this->m_webDataReaderProvider->getModelsCount();
} }
QList<int> CWebDataServicesAware::getModelDbKeys() const
{
Q_ASSERT_X(this->m_webDataReaderProvider, Q_FUNC_INFO, "Missing provider");
if (!hasProvider()) { return QList<int>(); }
return this->m_webDataReaderProvider->getModelDbKeys();
}
QStringList CWebDataServicesAware::getModelStrings() const
{
Q_ASSERT_X(this->m_webDataReaderProvider, Q_FUNC_INFO, "Missing provider");
if (!hasProvider()) { return QStringList(); }
return this->m_webDataReaderProvider->getModelStrings();
}
CAircraftModel CWebDataServicesAware::getModelForModelString(const QString &modelString) const CAircraftModel CWebDataServicesAware::getModelForModelString(const QString &modelString) const
{ {
Q_ASSERT_X(this->m_webDataReaderProvider, Q_FUNC_INFO, "Missing provider"); Q_ASSERT_X(this->m_webDataReaderProvider, Q_FUNC_INFO, "Missing provider");
@@ -306,11 +320,11 @@ namespace BlackMisc
} }
} }
CEntityFlags::Entity CWebDataServicesAware::triggerRead(CEntityFlags::Entity whatToRead) CEntityFlags::Entity CWebDataServicesAware::triggerRead(CEntityFlags::Entity whatToRead, const QDateTime &newerThan)
{ {
Q_ASSERT_X(this->m_webDataReaderProvider, Q_FUNC_INFO, "Missing provider"); Q_ASSERT_X(this->m_webDataReaderProvider, Q_FUNC_INFO, "Missing provider");
if (!hasProvider()) { return CEntityFlags::NoEntity; } if (!hasProvider()) { return CEntityFlags::NoEntity; }
return this->m_webDataReaderProvider->triggerRead(whatToRead); return this->m_webDataReaderProvider->triggerRead(whatToRead, newerThan);
} }
bool CWebDataServicesAware::canConnectSwiftDb() const bool CWebDataServicesAware::canConnectSwiftDb() const

View File

@@ -112,6 +112,14 @@ namespace BlackMisc
//! \threadsafe //! \threadsafe
virtual int getModelsCount() const = 0; virtual int getModelsCount() const = 0;
//! Model keys
//! \threadsafe
virtual QList<int> getModelDbKeys() const = 0;
//! Model strings
//! \threadsafe
virtual QStringList getModelStrings() const = 0;
//! Models for combined code and aircraft designator //! Models for combined code and aircraft designator
//! \threadsafe //! \threadsafe
virtual BlackMisc::Simulation::CAircraftModelList getModelsForAircraftDesignatorAndLiveryCombinedCode(const QString &aircraftDesignator, const QString &combinedCode) const = 0; virtual BlackMisc::Simulation::CAircraftModelList getModelsForAircraftDesignatorAndLiveryCombinedCode(const QString &aircraftDesignator, const QString &combinedCode) const = 0;
@@ -204,7 +212,7 @@ namespace BlackMisc
std::function<void(const BlackMisc::Simulation::CAircraftModelList &, const BlackMisc::Simulation::CAircraftModelList &, const BlackMisc::CStatusMessageList &)> dataPublished) = 0; std::function<void(const BlackMisc::Simulation::CAircraftModelList &, const BlackMisc::Simulation::CAircraftModelList &, const BlackMisc::CStatusMessageList &)> dataPublished) = 0;
//! Trigger read of new data //! Trigger read of new data
virtual BlackMisc::Network::CEntityFlags::Entity triggerRead(BlackMisc::Network::CEntityFlags::Entity whatToRead) = 0; virtual BlackMisc::Network::CEntityFlags::Entity triggerRead(BlackMisc::Network::CEntityFlags::Entity whatToRead, const QDateTime &dateTime = QDateTime()) = 0;
//! Can connect to swift DB? //! Can connect to swift DB?
virtual bool canConnectSwiftDb() const = 0; virtual bool canConnectSwiftDb() const = 0;
@@ -276,6 +284,12 @@ namespace BlackMisc
//! \copydoc IWebDataServicesProvider::getModelsCount //! \copydoc IWebDataServicesProvider::getModelsCount
int getModelsCount() const; int getModelsCount() const;
//! \copydoc IWebDataServicesProvider::getModelDbKeys
QList<int> getModelDbKeys() const;
//! \copydoc IWebDataServicesProvider::getModelStrings
QStringList getModelStrings() const;
//! \copydoc IWebDataServicesProvider::getModelsForAircraftDesignatorAndLiveryCombinedCode //! \copydoc IWebDataServicesProvider::getModelsForAircraftDesignatorAndLiveryCombinedCode
BlackMisc::Simulation::CAircraftModelList getModelsForAircraftDesignatorAndLiveryCombinedCode(const QString &aircraftDesignator, const QString &combinedCode) const; BlackMisc::Simulation::CAircraftModelList getModelsForAircraftDesignatorAndLiveryCombinedCode(const QString &aircraftDesignator, const QString &combinedCode) const;
@@ -353,7 +367,7 @@ namespace BlackMisc
std::function<void(const BlackMisc::Simulation::CAircraftModelList &, const BlackMisc::Simulation::CAircraftModelList &, const BlackMisc::CStatusMessageList &)> dataPublished); std::function<void(const BlackMisc::Simulation::CAircraftModelList &, const BlackMisc::Simulation::CAircraftModelList &, const BlackMisc::CStatusMessageList &)> dataPublished);
//! \copydoc IWebDataServicesProvider::triggerRead //! \copydoc IWebDataServicesProvider::triggerRead
BlackMisc::Network::CEntityFlags::Entity triggerRead(BlackMisc::Network::CEntityFlags::Entity whatToRead); BlackMisc::Network::CEntityFlags::Entity triggerRead(BlackMisc::Network::CEntityFlags::Entity whatToRead, const QDateTime &newerThan);
//! \copydoc IWebDataServicesProvider::canConnectSwiftDb //! \copydoc IWebDataServicesProvider::canConnectSwiftDb
bool canConnectSwiftDb() const; bool canConnectSwiftDb() const;

View File

@@ -36,7 +36,7 @@ namespace BlackCoreTest
m_icaoReader.start(); m_icaoReader.start();
Expect e(&this->m_icaoReader); Expect e(&this->m_icaoReader);
EXPECT_UNIT(e) EXPECT_UNIT(e)
.send(&CIcaoDataReader::readInBackgroundThread, CEntityFlags::AllIcaoEntities) .send(&CIcaoDataReader::readInBackgroundThread, CEntityFlags::AllIcaoEntities, QDateTime())
.expect(&CIcaoDataReader::dataRead, [url]() .expect(&CIcaoDataReader::dataRead, [url]()
{ {
qDebug() << "Read ICAO data from" << url.getFullUrl(); qDebug() << "Read ICAO data from" << url.getFullUrl();
@@ -59,7 +59,7 @@ namespace BlackCoreTest
m_modelReader.start(); m_modelReader.start();
Expect e(&this->m_modelReader); Expect e(&this->m_modelReader);
EXPECT_UNIT(e) EXPECT_UNIT(e)
.send(&CModelDataReader::readInBackgroundThread, CEntityFlags::AllIcaoEntities) .send(&CModelDataReader::readInBackgroundThread, CEntityFlags::DistributorLiveryModel, QDateTime())
.expect(&CModelDataReader::dataRead, [url]() .expect(&CModelDataReader::dataRead, [url]()
{ {
qDebug() << "Read model data " << url; qDebug() << "Read model data " << url;