swift
databasereader.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) 2015 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #ifndef SWIFT_CORE_DB_DATABASEREADER_H
7 #define SWIFT_CORE_DB_DATABASEREADER_H
8 
9 #include <QDateTime>
10 #include <QJsonArray>
11 #include <QMap>
12 #include <QNetworkReply>
13 #include <QObject>
14 #include <QReadWriteLock>
15 #include <QString>
16 #include <QtGlobal>
17 
19 #include "core/swiftcoreexport.h"
20 #include "core/threadedreader.h"
21 #include "misc/db/dbinfolist.h"
22 #include "misc/network/url.h"
23 #include "misc/pq/time.h"
24 #include "misc/statusmessage.h"
25 #include "misc/valueobject.h"
26 
27 class QNetworkReply;
28 class QFileInfo;
29 
30 namespace swift::misc
31 {
32  class CLogCategoryList;
33 }
34 namespace swift::core::db
35 {
38  {
39  Q_OBJECT
40 
41  public:
44  {
45  private:
46  QDateTime m_lastModified;
47  int m_httpStatusCode = -1;
48  qulonglong m_contentLengthHeader = 0;
49  qint64 m_requestStarted = -1;
50  qint64 m_responseReceived = -1;
51  qint64 m_loadTimeMs = -1;
52  swift::misc::CStatusMessage m_message;
54 
55  public:
57  bool hasTimestamp() const { return m_lastModified.isValid(); }
58 
60  bool isNewer(const QDateTime &ts) const
61  {
62  return m_lastModified.toMSecsSinceEpoch() > ts.toMSecsSinceEpoch();
63  }
64 
66  bool isNewer(qint64 mSecsSinceEpoch) const { return m_lastModified.toMSecsSinceEpoch() > mSecsSinceEpoch; }
67 
69  const QDateTime &getLastModifiedTimestamp() const { return m_lastModified; }
70 
72  void setLastModifiedTimestamp(const QDateTime &updated) { m_lastModified = updated; }
73 
75  qulonglong getContentLengthHeader() const { return m_contentLengthHeader; }
76 
78  void setContentLengthHeader(qulonglong size) { m_contentLengthHeader = size; }
79 
81  bool hasErrorMessage() const
82  {
84  }
85 
87  bool hasWarningOrAboveMessage() const { return m_message.isWarningOrAbove(); }
88 
90  const swift::misc::CStatusMessage &lastWarningOrAbove() const { return m_message; }
91 
93  void setMessage(const swift::misc::CStatusMessage &lastErrorOrWarning) { m_message = lastErrorOrWarning; }
94 
96  const swift::misc::network::CUrl &getUrl() const { return m_url; }
97 
99  QString getUrlString() const { return m_url.toQString(); }
100 
102  void setUrl(const swift::misc::network::CUrl &url) { m_url = url; }
103 
105  bool isSharedFile() const;
106 
108  bool hasHttpStatusCode() const { return m_httpStatusCode >= 0; }
109 
111  int getHttpStatusCode() const { return m_httpStatusCode; }
112 
114  qint64 getLoadTimeMs() const { return m_loadTimeMs; }
115 
117  QString getLoadTimeString() const;
118 
120  QString getLoadTimeStringWithStartedHint() const;
121 
123  void setLoadTimeMs(qint64 deltaTime) { m_loadTimeMs = deltaTime; }
124 
126  void setValues(const QNetworkReply *nwReply);
127  };
128 
131  {
132  private:
133  QJsonArray m_jsonArray;
134  int m_arraySize = -1;
135  int m_stringSize = 0;
136  bool m_restricted = false;
137 
138  public:
140  bool isEmpty() const { return m_jsonArray.isEmpty(); }
141 
143  bool isLoadedFromDb() const;
144 
146  bool isRestricted() const { return m_restricted; }
147 
149  void setRestricted(bool restricted) { m_restricted = restricted; }
150 
152  QJsonArray getJsonArray() const { return m_jsonArray; }
153 
155  int getArraySize() const { return m_jsonArray.size(); }
156 
158  void setJsonArray(const QJsonArray &value);
159 
161  void setStringSize(int size) { m_stringSize = size; }
162 
164  QString toQString() const;
165 
167  operator QJsonArray() const { return m_jsonArray; }
168  };
169 
172  void readInBackgroundThread(swift::misc::network::CEntityFlags::Entity entities, const QDateTime &newerThan);
173 
176  swift::misc::network::CEntityFlags::Entity
177  triggerLoadingDirectlyFromDb(swift::misc::network::CEntityFlags::Entity entities, const QDateTime &newerThan);
178 
181  swift::misc::network::CEntityFlags::Entity
182  triggerLoadingDirectlyFromSharedFiles(swift::misc::network::CEntityFlags::Entity entities,
183  bool checkCacheTsUpfront);
184 
187  bool hasReceivedOkReply() const;
188 
192  bool hasReceivedOkReply(QString &message) const;
193 
196  bool hasReceivedFirstReply() const;
197 
199  virtual swift::misc::network::CEntityFlags::Entity getSupportedEntities() const = 0;
200 
202  QString getSupportedEntitiesAsString() const;
203 
205  swift::misc::network::CEntityFlags::Entity
206  maskBySupportedEntities(swift::misc::network::CEntityFlags::Entity entities) const;
207 
209  bool supportsAnyOfEntities(swift::misc::network::CEntityFlags::Entity entities) const;
210 
212  virtual QDateTime getCacheTimestamp(swift::misc::network::CEntityFlags::Entity entity) const = 0;
213 
215  bool hasCacheTimestampNewerThan(swift::misc::network::CEntityFlags::Entity entity,
216  const QDateTime &threshold) const;
217 
220  virtual int getCacheCount(swift::misc::network::CEntityFlags::Entity entity) const = 0;
221 
224  virtual swift::misc::network::CEntityFlags::Entity getEntitiesWithCacheCount() const = 0;
225 
228  virtual swift::misc::network::CEntityFlags::Entity
229  getEntitiesWithCacheTimestampNewerThan(const QDateTime &threshold) const = 0;
230 
232  bool hasDbInfoObjects() const;
233 
235  bool hasSharedInfoObjects() const;
236 
238  bool hasSharedFileHeader(const swift::misc::network::CEntityFlags::Entity entity) const;
239 
241  bool hasSharedFileHeaders(const swift::misc::network::CEntityFlags::Entity entities) const;
242 
245  QDateTime getLatestEntityTimestampFromDbInfoObjects(swift::misc::network::CEntityFlags::Entity entity) const;
246 
249  QDateTime
250  getLatestEntityTimestampFromSharedInfoObjects(swift::misc::network::CEntityFlags::Entity entity) const;
251 
254  QDateTime getLatestSharedFileHeaderTimestamp(swift::misc::network::CEntityFlags::Entity entity) const;
255 
258  bool isSharedHeaderNewerThanCacheTimestamp(swift::misc::network::CEntityFlags::Entity entity) const;
259 
261  bool isSharedInfoObjectNewerThanCacheTimestamp(swift::misc::network::CEntityFlags::Entity entity) const;
262 
264  swift::misc::network::CEntityFlags::Entity
265  getEntitesWithNewerHeaderTimestamp(swift::misc::network::CEntityFlags::Entity entities) const;
266 
268  swift::misc::network::CEntityFlags::Entity
269  getEntitesWithNewerSharedInfoObject(swift::misc::network::CEntityFlags::Entity entities) const;
270 
272  const QString &getStatusMessage() const;
273 
276 
279  swift::misc::CStatusMessageList initFromLocalResourceFiles(bool inBackground);
280 
283  swift::misc::CStatusMessageList initFromLocalResourceFiles(swift::misc::network::CEntityFlags::Entity entities,
284  bool inBackground);
285 
288  swift::misc::network::CEntityFlags::Entity whatToRead,
289  bool overrideNewer) = 0;
290 
292  virtual bool readFromJsonFilesInBackground(const QString &dir,
293  swift::misc::network::CEntityFlags::Entity whatToRead,
294  bool overrideNewer) = 0;
295 
297  static const QStringList &getLogCategories();
298 
301  static void stringToDatastoreResponse(const QString &jsonContent,
302  CDatabaseReader::JsonDatastoreResponse &datastoreResponse);
303 
304  signals:
306  void swiftDbDataRead(bool success);
307 
310  void dataRead(swift::misc::network::CEntityFlags::Entity entities,
311  swift::misc::network::CEntityFlags::ReadState state, int number, const QUrl &url);
312 
314  void sharedFileHeaderRead(swift::misc::network::CEntityFlags::Entity entity, const QString &fileName,
315  bool success);
316 
320 
322  void entityDownloadProgress(swift::misc::network::CEntityFlags::Entity entity, int logId, int progress,
323  qint64 current, qint64 max, const QUrl &url);
324 
325  protected:
327  QString m_statusMessage;
328  bool m_1stReplyReceived = false;
329  mutable QReadWriteLock m_statusLock;
330  QNetworkReply::NetworkError m_1stReplyStatus = QNetworkReply::UnknownServerError;
335 
337  CDatabaseReader(QObject *owner, const CDatabaseReaderConfigList &config, const QString &name);
338 
340  CDatabaseReader::JsonDatastoreResponse setStatusAndTransformReplyIntoDatastoreResponse(QNetworkReply *nwReply);
341 
344  swift::misc::db::CDbInfoList getDbInfoObjects() const;
345 
348  swift::misc::db::CDbInfoList getSharedInfoObjects() const;
349 
351  CDatabaseReaderConfig getConfigForEntity(swift::misc::network::CEntityFlags::Entity entity) const;
352 
354  swift::misc::network::CEntityFlags::Entity
355  emitReadSignalPerSingleCachedEntity(swift::misc::network::CEntityFlags::Entity cachedEntities,
356  bool onlyIfHasData);
357 
359  void emitAndLogDataRead(swift::misc::network::CEntityFlags::Entity entity, int number,
360  const JsonDatastoreResponse &res);
361 
364 
366  void logNoWorkingUrl(swift::misc::network::CEntityFlags::Entity entity);
367 
370 
372  static const swift::misc::network::CUrl &getDbUrl();
373 
375  static QString fileNameForMode(swift::misc::network::CEntityFlags::Entity entity,
377 
379  static const QString &parameterLatestTimestamp();
380 
383  static QString dateTimeToDbLatestTs(const QDateTime &ts);
384 
386  static QString queryLatestTimestamp(const QDateTime &ts);
387 
391  virtual void synchronizeCaches(swift::misc::network::CEntityFlags::Entity entities) = 0;
392 
394  virtual void admitCaches(swift::misc::network::CEntityFlags::Entity entities) = 0;
395 
397  virtual void invalidateCaches(swift::misc::network::CEntityFlags::Entity entities) = 0;
398 
401  virtual bool hasChangedUrl(swift::misc::network::CEntityFlags::Entity entity,
402  swift::misc::network::CUrl &oldUrlInfo,
403  swift::misc::network::CUrl &newUrlInfo) const = 0;
404 
406  virtual void cacheHasChanged(swift::misc::network::CEntityFlags::Entity entities);
407 
409  static bool isChangedUrl(const swift::misc::network::CUrl &oldUrl,
410  const swift::misc::network::CUrl &currentUrl);
412 
415  void startReadFromBackendInBackgroundThread(swift::misc::network::CEntityFlags::Entity entities,
417  const QDateTime &newerThan = QDateTime());
418 
420  void receivedSharedFileHeader(QNetworkReply *nwReplyPtr);
421 
423  void receivedSharedFileHeaderNonClosing(QNetworkReply *nwReplyPtr);
424 
426  JsonDatastoreResponse transformReplyIntoDatastoreResponse(QNetworkReply *nwReply) const;
427 
429  HeaderResponse transformReplyIntoHeaderResponse(QNetworkReply *nwReply) const;
430 
432  bool setHeaderInfoPart(HeaderResponse &headerResponse, QNetworkReply *nwReply) const;
433 
436  void setReplyStatus(QNetworkReply::NetworkError status, const QString &message = "");
437 
440  void setReplyStatus(QNetworkReply *nwReply);
441 
444  bool overrideCacheFromFile(bool overrideNewerOnly, const QFileInfo &fileInfo,
445  swift::misc::network::CEntityFlags::Entity entity,
446  swift::misc::CStatusMessageList &msgs) const;
447 
449  void logParseMessage(const QString &entity, int size, int msElapsed,
450  const JsonDatastoreResponse &response) const;
451 
453  virtual void networkReplyProgress(int logId, qint64 current, qint64 max, const QUrl &url) override;
454 
455  private:
457  virtual void read(swift::misc::network::CEntityFlags::Entity entities,
458  swift::misc::db::CDbFlags::DataRetrievalModeFlag mode, const QDateTime &newerThan) = 0;
459  };
460 } // namespace swift::core::db
461 
462 #endif // SWIFT_CORE_DB_DATABASEREADER_H
Support for threaded based reading and parsing tasks such as data files via http, or file system and ...
Details how to read a certain entity.
Value object encapsulating a list of reader configs.
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.
void sharedFileHeaderRead(swift::misc::network::CEntityFlags::Entity entity, const QString &fileName, bool success)
Header of shared file read.
virtual swift::misc::network::CEntityFlags::Entity getEntitiesWithCacheCount() const =0
Entities already having data in cache.
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.
QReadWriteLock m_statusLock
Lock.
void swiftDbDataRead(bool success)
DB have been read.
QMap< swift::misc::network::CEntityFlags::Entity, HeaderResponse > m_sharedFileResponses
file responses of the shared files
virtual swift::misc::network::CUrl getDbServiceBaseUrl() const =0
Get the service URL, individual for each reader.
virtual void read(swift::misc::network::CEntityFlags::Entity entities, swift::misc::db::CDbFlags::DataRetrievalModeFlag mode, const QDateTime &newerThan)=0
Read / re-read data file.
QString m_statusMessage
Returned status message from watchdog.
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.
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.
virtual swift::misc::network::CEntityFlags::Entity getEntitiesWithCacheTimestampNewerThan(const QDateTime &threshold) const =0
Entities already having data in cache (based on timestamp assumption)
CDatabaseReaderConfigList m_config
DB reder configuration.
swift::misc::CStatusMessageList initFromLocalResourceFiles(swift::misc::network::CEntityFlags::Entity entities, bool inBackground)
Init from local resource file.
virtual void invalidateCaches(swift::misc::network::CEntityFlags::Entity entities)=0
Invalidate the caches for given entities.
virtual void synchronizeCaches(swift::misc::network::CEntityFlags::Entity entities)=0
Admit caches for given entities.
void databaseReaderMessages(const swift::misc::CStatusMessageList &messages)
Database reader messages.
void setSeverityNoWorkingUrl(swift::misc::CStatusMessage::StatusSeverity s)
Severity used for log messages in case of no URLs.
Streamable status message, e.g.
bool isWarningOrAbove() const
Warning or above.
constexpr static auto SeverityError
Status severities.
StatusSeverity getSeverity() const
Message severity.
constexpr static auto SeverityWarning
Status severities.
Status messages, e.g. from Core -> GUI.
DataRetrievalModeFlag
Which data to read, requires corresponding readers.
Definition: dbflags.h:25
Value object encapsulating a list of info objects.
Definition: dbinfolist.h:27
QString toQString(bool i18n=false) const
Cast as QString.
Definition: mixinstring.h:76
Value object encapsulating information of a location, kind of simplified CValueObject compliant versi...
Definition: url.h:27
Classes interacting with the swift database (aka "datastore").
Free functions in swift::misc.
StatusSeverity
Status severities.
Definition: statusmessage.h:35
const swift::misc::network::CUrl & getUrl() const
URL loaded.
QString getUrlString() const
URL loaded as string.
bool hasHttpStatusCode() const
Has HTTP status code?
void setLoadTimeMs(qint64 deltaTime)
Set the load time (delta start -> response received)
bool isNewer(qint64 mSecsSinceEpoch) const
Is response newer?
void setUrl(const swift::misc::network::CUrl &url)
Set the loaded URL.
const QDateTime & getLastModifiedTimestamp() const
Get the "last-modified" timestamp.
bool hasWarningOrAboveMessage() const
Warning or error message?
int getHttpStatusCode() const
HTTP status code.
void setLastModifiedTimestamp(const QDateTime &updated)
Set update timestamp, default normally "last-modified".
void setContentLengthHeader(qulonglong size)
Set the content length.
qulonglong getContentLengthHeader() const
Header content length.
bool isNewer(const QDateTime &ts) const
Is response newer?
void setMessage(const swift::misc::CStatusMessage &lastErrorOrWarning)
Set the error/warning message.
qint64 getLoadTimeMs() const
Load time in ms (from request to response)
const swift::misc::CStatusMessage & lastWarningOrAbove() const
Last error or warning.
Response from our database (depending on JSON DB backend generates)
QJsonArray getJsonArray() const
Get the JSON array.
bool isRestricted() const
Incremental data, restricted by query?
void setRestricted(bool restricted)
Mark as restricted.
#define SWIFT_CORE_EXPORT
Export a class or function from the library.