8 #include <QJsonDocument>
10 #include <QJsonValueRef>
11 #include <QMetaObject>
12 #include <QNetworkReply>
14 #include <QReadLocker>
15 #include <QStringBuilder>
17 #include <QWriteLocker>
33 using namespace swift::misc::db;
34 using namespace swift::misc::network;
48 Q_ASSERT_X(
hasStarted(), Q_FUNC_INFO,
"Thread was not started yet!");
51 Q_ASSERT_X(!entities.testFlag(CEntityFlags::DbInfoObjectEntity), Q_FUNC_INFO,
"Read info objects directly");
56 CEntityFlags::Entity allEntities = entities;
57 CEntityFlags::Entity cachedEntities = CEntityFlags::NoEntity;
58 CEntityFlags::Entity dbEntities = CEntityFlags::NoEntity;
59 CEntityFlags::Entity sharedEntities = CEntityFlags::NoEntity;
60 CEntityFlags::Entity currentEntity =
61 CEntityFlags::iterateDbEntities(allEntities);
65 const QString currentEntityName = CEntityFlags::entitiesToString(currentEntity);
69 Q_ASSERT_X(!rm.testFlag(CDbFlags::Unspecified), Q_FUNC_INFO,
"Missing retrieval mode");
70 const QString rmString = CDbFlags::flagToString(rm);
72 CDbFlags::modeToModeFlag(rm & CDbFlags::DbReadingOrShared);
73 const QString rmDbOrSharedFlagString = CDbFlags::flagToString(rmDbOrSharedFlag);
74 const bool rmDbReadingOrShared =
75 (rmDbOrSharedFlag == CDbFlags::DbReading || rmDbOrSharedFlag == CDbFlags::Shared);
76 const int currentEntityCount = this->
getCacheCount(currentEntity);
78 if (rm.testFlag(CDbFlags::Ignore) || rm.testFlag(CDbFlags::Canceled))
82 else if (rm.testFlag(CDbFlags::Cached))
90 Q_ASSERT_X(!
getBaseUrl(rmDbOrSharedFlag).isEmpty(), Q_FUNC_INFO,
"Wrong retrieval mode");
94 const bool changedUrl = this->
hasChangedUrl(currentEntity, oldUrlInfo, newUrlInfo);
97 const qint64 cacheTimestamp = cacheTs.isValid() ? cacheTs.toMSecsSinceEpoch() : -1;
98 const qint64 latestEntityTimestamp =
99 latestEntityTs.isValid() ? latestEntityTs.toMSecsSinceEpoch() : -1;
100 Q_ASSERT_X(latestEntityTimestamp >= 0, Q_FUNC_INFO,
"Missing timestamp");
101 if (!changedUrl && cacheTimestamp >= latestEntityTimestamp && cacheTimestamp >= 0 &&
102 latestEntityTimestamp >= 0)
105 cachedEntities |= currentEntity;
107 << currentEntityName << cacheTs.toString() << cacheTimestamp;
111 Q_ASSERT_X(rmDbReadingOrShared, Q_FUNC_INFO,
"Wrong retrieval mode");
112 if (rmDbOrSharedFlag == CDbFlags::DbReading) { dbEntities |= currentEntity; }
113 else if (rmDbOrSharedFlag == CDbFlags::Shared) { sharedEntities |= currentEntity; }
118 u
"Data location for '%1' changed ('%2'->'%3'), will override cache for reading '%4'")
120 << rmDbOrSharedFlagString;
124 CLogMessage(
this).
info(u
"Cache for '%1' outdated, latest entity (%2, %3), reading '%4'")
125 << currentEntityName << latestEntityTs.toString() << latestEntityTimestamp
126 << rmDbOrSharedFlagString;
132 if (!rmDbReadingOrShared)
134 CLogMessage(
this).
info(u
"No DB or shared reading for '%1', read mode is: '%2'")
135 << currentEntityName << rmString;
139 CLogMessage(
this).
info(u
"No DB info objects for '%1', read mode is: '%2'")
140 << currentEntityName << rmString;
142 if (currentEntityCount > 0)
145 << currentEntityName << currentEntityCount;
151 if (!rmDbReadingOrShared)
154 CLogMessage(
this).
info(u
"Triggered reading cache for '%1', read mode: %2")
155 << currentEntityName << rmString;
160 CLogMessage(
this).
info(u
"No info object for '%1', triggered reading cache, read mode: %2")
161 << currentEntityName << rmString;
164 cachedEntities |= currentEntity;
170 Q_ASSERT_X(rmDbReadingOrShared, Q_FUNC_INFO,
"Wrong retrieval mode");
171 if (rmDbOrSharedFlag == CDbFlags::DbReading) { dbEntities |= currentEntity; }
172 else if (rmDbOrSharedFlag == CDbFlags::Shared) { sharedEntities |= currentEntity; }
174 currentEntity = CEntityFlags::iterateDbEntities(allEntities);
178 if (cachedEntities != CEntityFlags::NoEntity)
184 if (dbEntities != CEntityFlags::NoEntity)
186 CLogMessage(
this).
info(u
"Start reading DB entities: %1") << CEntityFlags::entitiesToString(dbEntities);
191 if (sharedEntities != CEntityFlags::NoEntity)
194 << CEntityFlags::entitiesToString(sharedEntities);
200 const QDateTime &newerThan)
207 bool checkCacheTsUpfront)
209 if (entities == CEntityFlags::NoEntity) {
return CEntityFlags::NoEntity; }
210 if (checkCacheTsUpfront)
213 if (newerHeaderEntities != entities)
215 const CEntityFlags::Entity validInCacheEntities = (entities ^ newerHeaderEntities) & entities;
216 CLogMessage(
this).
info(u
"Reduced '%1' to '%2' before triggering load of shared files (still in cache)")
217 << CEntityFlags::entitiesToString(entities) << CEntityFlags::entitiesToString(newerHeaderEntities);
221 if (validInCacheEntities != CEntityFlags::NoEntity)
223 QPointer<CDatabaseReader> myself(
this);
225 if (!myself) {
return; }
227 emit this->dataRead(validInCacheEntities, CEntityFlags::ReadFinished, 0, {});
230 if (newerHeaderEntities == CEntityFlags::NoEntity) {
return CEntityFlags::NoEntity; }
231 entities = newerHeaderEntities;
240 const QDateTime &newerThan)
242 Q_ASSERT_X(mode == CDbFlags::DbReading || mode == CDbFlags::Shared, Q_FUNC_INFO,
"Wrong mode");
245 if (entities == CEntityFlags::NoEntity) {
return; }
247 QPointer<CDatabaseReader> myself(
this);
250 this->read(entities, mode, newerThan);
257 Q_ASSERT_X(nwReply, Q_FUNC_INFO,
"missing reply");
262 const QString dataFileData = nwReply->readAll();
265 if (dataFileData.isEmpty())
270 else { CDatabaseReader::stringToDatastoreResponse(dataFileData, datastoreResponse); }
272 return datastoreResponse;
280 return headerResponse;
284 QNetworkReply *nwReply)
const
286 Q_ASSERT_X(nwReply, Q_FUNC_INFO,
"Missing reply");
297 if (nwReply->error() == QNetworkReply::NoError)
305 const QString error(nwReply->errorString());
306 const QString url(nwReply->url().toString());
353 Q_ASSERT_X(CEntityFlags::isSingleEntity(entity), Q_FUNC_INFO,
"need single entity");
360 CEntityFlags::Entity currentEntity = CEntityFlags::iterateDbEntities(myEntities);
361 while (currentEntity != CEntityFlags::NoEntity)
364 currentEntity = CEntityFlags::iterateDbEntities(myEntities);
371 Q_ASSERT_X(CEntityFlags::isSingleEntity(entity), Q_FUNC_INFO,
"need single entity");
372 static const QDateTime e;
374 if (il.
isEmpty() || entity == CEntityFlags::NoEntity) {
return e; }
379 if (!info.
isValid()) {
return e; }
385 Q_ASSERT_X(CEntityFlags::isSingleEntity(entity), Q_FUNC_INFO,
"need single entity");
386 static const QDateTime e;
388 if (il.
isEmpty() || entity == CEntityFlags::NoEntity) {
return e; }
391 if (!info.
isValid()) {
return e; }
397 Q_ASSERT_X(CEntityFlags::isSingleEntity(entity), Q_FUNC_INFO,
"need single entity");
398 static const QDateTime e;
404 Q_ASSERT_X(CEntityFlags::isSingleEntity(entity), Q_FUNC_INFO,
"need single entity");
406 if (!cacheTs.isValid()) {
return true; }
409 if (!headerTimestamp.isValid()) {
return false; }
410 return headerTimestamp > cacheTs;
415 Q_ASSERT_X(CEntityFlags::isSingleEntity(entity), Q_FUNC_INFO,
"need single entity");
417 if (!cacheTs.isValid()) {
return true; }
420 if (!sharedInfoTimestamp.isValid()) {
return false; }
421 return sharedInfoTimestamp > cacheTs;
426 entities &= CEntityFlags::AllDbEntitiesNoInfoObjects;
427 CEntityFlags::Entity currentEntity = CEntityFlags::iterateDbEntities(entities);
428 CEntityFlags::Entity newerEntities = CEntityFlags::NoEntity;
429 while (currentEntity != CEntityFlags::NoEntity)
432 currentEntity = CEntityFlags::iterateDbEntities(entities);
434 return newerEntities;
439 entities &= CEntityFlags::AllDbEntitiesNoInfoObjects;
440 CEntityFlags::Entity currentEntity = CEntityFlags::iterateDbEntities(entities);
441 CEntityFlags::Entity newerEntities = CEntityFlags::NoEntity;
442 while (currentEntity != CEntityFlags::NoEntity)
445 currentEntity = CEntityFlags::iterateDbEntities(entities);
447 return newerEntities;
458 if (cachedEntities == CEntityFlags::NoEntity) {
return CEntityFlags::NoEntity; }
459 CEntityFlags::Entity emitted = CEntityFlags::NoEntity;
460 CEntityFlags::Entity cachedEntitiesToEmit = cachedEntities;
461 CEntityFlags::Entity currentCachedEntity = CEntityFlags::iterateDbEntities(cachedEntitiesToEmit);
462 while (currentCachedEntity)
465 if (!onlyIfHasData || c > 0)
467 emit this->
dataRead(currentCachedEntity, CEntityFlags::ReadFinished, c, {});
468 emitted |= currentCachedEntity;
470 currentCachedEntity = CEntityFlags::iterateDbEntities(cachedEntitiesToEmit);
478 Q_ASSERT_X(CEntityFlags::isSingleEntity(entity), Q_FUNC_INFO,
"Expect single entity");
480 << number << CEntityFlags::entitiesToString(entity) << res.
getUrlString()
483 res.
isRestricted() ? CEntityFlags::ReadFinishedRestricted : CEntityFlags::ReadFinished,
490 << CEntityFlags::entitiesToString(entity);
500 case CDbFlags::SharedInfoOnly:
502 default: qFatal(
"Wrong mode");
break;
509 if (oldUrl.
isEmpty()) {
return true; }
510 Q_ASSERT_X(!currentUrl.
isEmpty(), Q_FUNC_INFO,
"No base URL");
513 const QString current(currentUrl.
getFullUrl(
false));
514 return old != current;
521 QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr);
532 const QString fileName = nwReplyPtr->url().fileName();
533 const CEntityFlags::Entity entity = CEntityFlags::singleEntityByName(fileName);
536 CLogMessage(
this).
info(u
"Received header for shared file of '%1' from '%2'")
578 if (!ts.isValid()) {
return false; }
579 return ts > threshold;
592 const bool overrideNewerOnly =
true;
599 return s ?
CStatusMessage(
this).
info(u
"Started reading in background from '%1' of entities: '%2'")
601 CStatusMessage(this).error(u
"Starting reading in background from '%1' of entities: '%2' failed")
621 Q_ASSERT_X(nwReply, Q_FUNC_INFO,
"Missing network reply");
622 if (nwReply && nwReply->isFinished())
632 if (!fileInfo.birthTime().isValid()) {
return false; }
633 if (!overrideNewerOnly) {
return true; }
635 const qint64 fileTs = fileInfo.birthTime().toUTC().toMSecsSinceEpoch();
637 if (!cacheDateTime.isValid()) {
return true; }
638 const qint64 cacheTs = cacheDateTime.toUTC().toMSecsSinceEpoch();
639 if (fileTs > cacheTs)
642 << fileInfo.absoluteFilePath() << cacheDateTime.toUTC().toString());
648 << fileInfo.absoluteFilePath() << cacheDateTime.toUTC().toString());
663 const QString fileName = url.fileName();
664 const CEntityFlags::Entity entity = CEntityFlags::singleEntityByName(fileName);
665 if (CEntityFlags::isSingleEntity(entity))
674 Q_ASSERT_X(CEntityFlags::isSingleEntity(entity), Q_FUNC_INFO,
"needs single entity");
677 case CDbFlags::Shared:
return CDbInfo::entityToSharedName(entity);
678 case CDbFlags::SharedInfoOnly:
return CDbInfo::sharedInfoFileName();
680 case CDbFlags::DbReading:
return CDbInfo::entityToServiceName(entity);
686 if (!ts.isValid()) {
return {}; }
687 return ts.toUTC().toString(Qt::ISODate);
692 static const QStringList cats =
700 static const QString p(
"latestTimestamp");
706 if (!ts.isValid())
return {};
722 void CDatabaseReader::stringToDatastoreResponse(
const QString &jsonContent,
723 JsonDatastoreResponse &datastoreResponse)
725 const int status = datastoreResponse.getHttpStatusCode();
726 if (jsonContent.isEmpty())
728 static const QString errorMsg =
"Empty JSON string, status: %1, URL: '%2', load time: %3";
729 datastoreResponse.setMessage(
731 errorMsg.arg(status).arg(datastoreResponse.getUrlString(),
732 datastoreResponse.getLoadTimeStringWithStartedHint())));
737 if (jsonResponse.isEmpty())
739 if (CNetworkUtils::looksLikePhpErrorMessage(jsonContent))
741 static const QString errorMsg =
"Looks like PHP errror, status %1, URL: '%2', msg: %3";
742 const QString phpErrorMessage = CNetworkUtils::removeHtmlPartsFromPhpErrorMessage(jsonContent);
743 datastoreResponse.setMessage(
745 errorMsg.arg(status).arg(datastoreResponse.getUrlString(), phpErrorMessage)));
749 static const QString errorMsg =
"Empty JSON document, URL: '%1', load time: %2";
750 datastoreResponse.setMessage(
752 errorMsg.arg(datastoreResponse.getUrlString(),
753 datastoreResponse.getLoadTimeStringWithStartedHint())));
758 if (jsonResponse.isArray())
761 datastoreResponse.setJsonArray(jsonResponse.array());
762 datastoreResponse.setLastModifiedTimestamp(QDateTime::currentDateTimeUtc());
766 const QJsonObject responseObject(jsonResponse.object());
767 datastoreResponse.setJsonArray(responseObject[
"data"].toArray());
768 const QString ts(responseObject[
"latest"].toString());
769 datastoreResponse.setLastModifiedTimestamp(ts.isEmpty() ? QDateTime::currentDateTimeUtc() :
770 CDatastoreUtility::parseTimestamp(ts));
771 datastoreResponse.setRestricted(responseObject[
"restricted"].toBool());
783 m_arraySize = value.size();
788 static const QString s(
"DB: %1 | restricted: %2 | array: %3 | string size: %4 | content: %5");
789 return s.arg(boolToYesNo(this->isLoadedFromDb()), boolToYesNo(this->isRestricted()))
790 .arg(this->getArraySize())
792 .arg(this->getContentLengthHeader());
797 const QString fn(getUrl().getFileName());
798 return CDbInfo::sharedFileNames().contains(fn, Qt::CaseInsensitive);
803 return QStringLiteral(
"%1ms").arg(getLoadTimeMs());
808 if (m_requestStarted < 0) {
return this->getLoadTimeString(); }
809 const qint64 diff = QDateTime::currentMSecsSinceEpoch() - m_requestStarted;
810 static const QString s(
"%1 load time, started %2ms before now");
811 return s.arg(this->getLoadTimeString()).arg(diff);
816 Q_ASSERT_X(nwReply, Q_FUNC_INFO,
"Need valid reply");
817 this->setUrl(nwReply->url());
818 const QVariant started = nwReply->property(
"started");
819 if (started.isValid() && started.canConvert<qint64>())
821 const qint64 now = QDateTime::currentMSecsSinceEpoch();
822 const qint64
start = started.value<qint64>();
823 this->setLoadTimeMs(now -
start);
824 m_requestStarted =
start;
825 m_responseReceived = now;
828 const QVariant qvStatusCode = nwReply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
829 if (qvStatusCode.isValid() && qvStatusCode.canConvert<
int>()) { m_httpStatusCode = qvStatusCode.toInt(); }
831 const QDateTime lastModified = nwReply->header(QNetworkRequest::LastModifiedHeader).toDateTime();
832 const qulonglong size = nwReply->header(QNetworkRequest::ContentLengthHeader).toULongLong();
833 this->setLastModifiedTimestamp(lastModified);
834 this->setContentLengthHeader(size);
SWIFT_CORE_EXPORT swift::core::CApplication * sApp
Single instance of application object.
data::CGlobalSetup getGlobalSetup() const
Global setup.
bool hasWebDataServices() const
Web data services available?
bool isShuttingDown() const
Is application shutting down?
CWebDataServices * getWebDataServices() const
Get the web data services.
Support for threaded based reading and parsing tasks such as data files via http, or file system and ...
std::atomic_llong m_networkReplyCurrent
current bytes
static const QStringList & getLogCategories()
Log categories.
virtual void networkReplyProgress(int logId, qint64 current, qint64 max, const QUrl &url)
Network request progress.
std::atomic_int m_networkReplyProgress
Progress percentage 0...100.
void threadAssertCheck() const
Make sure everything runs correctly in own thread.
void logNetworkReplyReceived(QNetworkReply *reply)
Network reply received, mark in m_urlReadLog.
bool doWorkCheck() const
Still enabled etc.?
std::atomic_llong m_networkReplyMax
max bytes
swift::core::db::CInfoDataReader * getDbInfoDataReader() const
DB info data reader.
swift::core::db::CInfoDataReader * getSharedInfoDataReader() const
Shared info data reader.
const swift::misc::network::CUrl & getDbRootDirectoryUrl() const
Root directory of DB.
swift::misc::network::CUrl getSharedDbDataDirectoryUrl()
Get shared DB data directory URL.
Details how to read a certain entity.
swift::misc::db::CDbFlags::DataRetrievalMode getRetrievalMode() const
Supported modes.
Value object encapsulating a list of reader configs.
CDatabaseReaderConfig findFirstOrDefaultForEntity(const swift::misc::network::CEntityFlags::Entity entities) const
Find first one matching given.
Specialized version of threaded reader for DB data.
virtual QDateTime getCacheTimestamp(swift::misc::network::CEntityFlags::Entity entity) const =0
Get cache timestamp.
virtual bool hasChangedUrl(swift::misc::network::CEntityFlags::Entity entity, swift::misc::network::CUrl &oldUrlInfo, swift::misc::network::CUrl &newUrlInfo) const =0
Changed URL, means the cache values have been read from elsewhere.
virtual void admitCaches(swift::misc::network::CEntityFlags::Entity entities)=0
Admit caches for given entities.
QDateTime getLatestSharedFileHeaderTimestamp(swift::misc::network::CEntityFlags::Entity entity) const
Header timestamp (last-modified) for shared file.
void emitAndLogDataRead(swift::misc::network::CEntityFlags::Entity entity, int number, const JsonDatastoreResponse &res)
Emit signal and log when data have been read.
swift::misc::CStatusMessageList initFromLocalResourceFiles(bool inBackground)
Init from local resource file.
swift::misc::network::CEntityFlags::Entity emitReadSignalPerSingleCachedEntity(swift::misc::network::CEntityFlags::Entity cachedEntities, bool onlyIfHasData)
Split into single entity and send dataRead signal.
HeaderResponse transformReplyIntoHeaderResponse(QNetworkReply *nwReply) const
Check if terminated or error, otherwise set header information.
static QString queryLatestTimestamp(const QDateTime &ts)
Latest timestamp query for DB.
QNetworkReply::NetworkError m_1stReplyStatus
Successful connection?
bool isSharedHeaderNewerThanCacheTimestamp(swift::misc::network::CEntityFlags::Entity entity) const
Is the file timestamp newer than cache timestamp?
swift::misc::db::CDbInfoList getSharedInfoObjects() const
Shared info list (latest data timestamps from DB web service)
virtual void cacheHasChanged(swift::misc::network::CEntityFlags::Entity entities)
Cache for given entity has changed.
virtual void networkReplyProgress(int logId, qint64 current, qint64 max, const QUrl &url)
Network request progress.
bool hasSharedInfoObjects() const
Shared info objects available?
swift::misc::CStatusMessage::StatusSeverity m_severityNoWorkingUrl
severity of message if there is no working URL
void sharedFileHeaderRead(swift::misc::network::CEntityFlags::Entity entity, const QString &fileName, bool success)
Header of shared file read.
bool hasReceivedOkReply() const
Has received Ok response from server at least once?
static QString dateTimeToDbLatestTs(const QDateTime &ts)
A newer than value understood by swift DB.
void setReplyStatus(QNetworkReply::NetworkError status, const QString &message="")
Feedback about connection status.
static const QStringList & getLogCategories()
Log categories.
virtual int getCacheCount(swift::misc::network::CEntityFlags::Entity entity) const =0
Cache`s number of entities.
void entityDownloadProgress(swift::misc::network::CEntityFlags::Entity entity, int logId, int progress, qint64 current, qint64 max, const QUrl &url)
Download progress for an entity.
QDateTime getLatestEntityTimestampFromSharedInfoObjects(swift::misc::network::CEntityFlags::Entity entity) const
Obtain latest object timestamp from shared info objects.
QReadWriteLock m_statusLock
Lock.
JsonDatastoreResponse transformReplyIntoDatastoreResponse(QNetworkReply *nwReply) const
Check if terminated or error, otherwise split into array of objects.
bool hasSharedFileHeader(const swift::misc::network::CEntityFlags::Entity entity) const
Header of shared file read (for single entity)?
QDateTime getLatestEntityTimestampFromDbInfoObjects(swift::misc::network::CEntityFlags::Entity entity) const
Obtain latest object timestamp from DB info objects.
void logNoWorkingUrl(swift::misc::network::CEntityFlags::Entity entity)
Log if no working URL exists, using m_noWorkingUrlSeverity.
bool supportsAnyOfEntities(swift::misc::network::CEntityFlags::Entity entities) const
Is any of the given entities supported here by this reader.
QString getSupportedEntitiesAsString() const
Supported entities as string.
void swiftDbDataRead(bool success)
DB have been read.
bool hasDbInfoObjects() const
DB info objects available?
swift::misc::network::CEntityFlags::Entity getEntitesWithNewerHeaderTimestamp(swift::misc::network::CEntityFlags::Entity entities) const
Those entities where the timestamp of the header is newer than the cache timestamp.
swift::misc::network::CEntityFlags::Entity getEntitesWithNewerSharedInfoObject(swift::misc::network::CEntityFlags::Entity entities) const
Those entities where the timestamp of a shared info object is newer than the cache timestamp.
CDatabaseReaderConfig getConfigForEntity(swift::misc::network::CEntityFlags::Entity entity) const
Config for given entity.
QMap< swift::misc::network::CEntityFlags::Entity, HeaderResponse > m_sharedFileResponses
file responses of the shared files
void receivedSharedFileHeader(QNetworkReply *nwReplyPtr)
Received a reply of a header for a shared file.
swift::misc::network::CEntityFlags::Entity maskBySupportedEntities(swift::misc::network::CEntityFlags::Entity entities) const
Mask by supported entities.
swift::misc::network::CEntityFlags::Entity triggerLoadingDirectlyFromSharedFiles(swift::misc::network::CEntityFlags::Entity entities, bool checkCacheTsUpfront)
Start loading from shared files in own thread.
bool hasSharedFileHeaders(const swift::misc::network::CEntityFlags::Entity entities) const
Headers of shared file read (for single entity)?
bool hasReceivedFirstReply() const
Has received 1st reply?
bool overrideCacheFromFile(bool overrideNewerOnly, const QFileInfo &fileInfo, swift::misc::network::CEntityFlags::Entity entity, swift::misc::CStatusMessageList &msgs) const
Override cache from file.
virtual swift::misc::network::CUrl getDbServiceBaseUrl() const =0
Get the service URL, individual for each reader.
static const QString & parameterLatestTimestamp()
Name of latest timestamp.
static const swift::misc::network::CUrl & getDbUrl()
DB base URL.
swift::misc::db::CDbInfoList getDbInfoObjects() const
DB Info list (latest data timestamps from DB web service)
QString m_statusMessage
Returned status message from watchdog.
void startReadFromBackendInBackgroundThread(swift::misc::network::CEntityFlags::Entity entities, swift::misc::db::CDbFlags::DataRetrievalModeFlag mode, const QDateTime &newerThan=QDateTime())
Start reading in own thread (without config/caching)
virtual bool readFromJsonFilesInBackground(const QString &dir, swift::misc::network::CEntityFlags::Entity whatToRead, bool overrideNewer)=0
Data read from local data.
virtual swift::misc::network::CEntityFlags::Entity getSupportedEntities() const =0
Supported entities by this reader.
swift::misc::network::CUrl getBaseUrl(swift::misc::db::CDbFlags::DataRetrievalModeFlag mode) const
Base URL for mode (either a shared or DB URL)
void dataRead(swift::misc::network::CEntityFlags::Entity entities, swift::misc::network::CEntityFlags::ReadState state, int number, const QUrl &url)
Combined read signal.
virtual swift::misc::CStatusMessageList readFromJsonFiles(const QString &dir, swift::misc::network::CEntityFlags::Entity whatToRead, bool overrideNewer)=0
Data read from local data.
CDatabaseReaderConfigList m_config
DB reder configuration.
bool setHeaderInfoPart(HeaderResponse &headerResponse, QNetworkReply *nwReply) const
Set the header part.
static bool isChangedUrl(const swift::misc::network::CUrl &oldUrl, const swift::misc::network::CUrl ¤tUrl)
Has URL been changed? Means we load from a different server.
static QString fileNameForMode(swift::misc::network::CEntityFlags::Entity entity, swift::misc::db::CDbFlags::DataRetrievalModeFlag mode)
File name for given mode, either php service or shared file name.
CDatabaseReader::JsonDatastoreResponse setStatusAndTransformReplyIntoDatastoreResponse(QNetworkReply *nwReply)
Check if terminated or error, otherwise split into array of objects.
void readInBackgroundThread(swift::misc::network::CEntityFlags::Entity entities, const QDateTime &newerThan)
Start reading in own thread.
bool m_1stReplyReceived
Successful connection? Does not mean data / authorizations are correct.
swift::misc::network::CEntityFlags::Entity triggerLoadingDirectlyFromDb(swift::misc::network::CEntityFlags::Entity entities, const QDateTime &newerThan)
Start loading from DB in own thread.
const QString & getStatusMessage() const
Status message (error message)
void logParseMessage(const QString &entity, int size, int msElapsed, const JsonDatastoreResponse &response) const
Parsing info message.
bool isSharedInfoObjectNewerThanCacheTimestamp(swift::misc::network::CEntityFlags::Entity entity) const
Is the shared info timestamp newer than cache timestamp?
bool hasCacheTimestampNewerThan(swift::misc::network::CEntityFlags::Entity entity, const QDateTime &threshold) const
Has entity a valid and newer timestamp.
void receivedSharedFileHeaderNonClosing(QNetworkReply *nwReplyPtr)
Received a reply of a header for a shared file.
static QJsonDocument databaseJsonToQJsonDocument(const QString &content)
Database JSON from content string, which can be compressed.
swift::misc::db::CDbInfoList getInfoObjects() const
Get info list (either shared or from DB)
void start(QThread::Priority priority=QThread::InheritPriority)
Starts a thread and moves the worker into it.
static const QString & webservice()
Webservice.
static const QString & swiftDbWebservice()
Webservice with swift DB.
Class for emitting a log message.
static void preformatted(const CStatusMessage &statusMessage)
Sends a verbatim, preformatted message to the log.
Derived & info(const char16_t(&format)[N])
Set the severity to info, providing a format string.
void push_back(const T &value)
Appends an element at the end of the sequence.
bool isEmpty() const
Synonym for empty.
Streamable status message, e.g.
constexpr static auto SeverityError
Status severities.
Status messages, e.g. from Core -> GUI.
Locations of important directories for swift files.
static const QString & staticDbFilesDirectory()
Where static DB files are located.
static QString currentThreadInfo()
Info about current thread, for debug messages.
static bool isInThisThread(const QObject *toBeTested)
Is the current thread the object's thread?
bool isAbandoned() const
For the task to check whether it can finish early.
bool hasStarted() const
True if the worker has started.
QDateTime getUtcTimestamp() const
Get timestamp.
DataRetrievalModeFlag
Which data to read, requires corresponding readers.
Info about the latest models.
bool isValid() const
Valid?
Value object encapsulating a list of info objects.
CDbInfo findFirstByEntityOrDefault(swift::misc::network::CEntityFlags::Entity entity) const
Find by entity.
QString toQString(bool i18n=false) const
Cast as QString.
What and state of reading from web services.
Value object encapsulating information of a location, kind of simplified CValueObject compliant versi...
bool isEmpty() const
Empty.
CUrl withAppendedPath(const QString &path) const
Append path.
const QString & getHost() const
Get host.
QString getFullUrl(bool withQuery=true) const
Qualified name.
Core data traits (aka cached values) and classes.
Classes interacting with the swift database (aka "datastore").
Backend services of the swift project, like dealing with the network or the simulators.
Free functions in swift::misc.
auto singleShot(int msec, QObject *target, F &&task)
Starts a single-shot timer which will call a task in the thread of the given object when it times out...
Response from our database (depending on JSON DB backend generates)
bool isRestricted() const
Incremental data, restricted by query?
QString toQString() const
String info.
void setJsonArray(const QJsonArray &value)
Set the JSON array.
bool isLoadedFromDb() const
Is loaded from database.
void setStringSize(int size)
Set string size.