swift
Loading...
Searching...
No Matches
infodatareader.cpp
1// SPDX-FileCopyrightText: Copyright (C) 2016 swift Project Community / Contributors
2// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3
5
6#include <QJsonDocument>
7#include <QJsonObject>
8#include <QTimer>
9
10#include "core/application.h"
12#include "misc/logmessage.h"
14#include "misc/sequence.h"
15#include "misc/verify.h"
16
17using namespace swift::misc;
18using namespace swift::misc::network;
19using namespace swift::misc::db;
20using namespace swift::core::data;
21
22namespace swift::core::db
23{
26 : CDatabaseReader(owner, config, "CInfoDataReader"), m_mode(mode)
27 {
28 Q_ASSERT_X(mode == CDbFlags::DbReading || mode == CDbFlags::Shared, Q_FUNC_INFO, "Wrong mode");
29 }
30
32 {
33 QReadLocker l(&m_lockInfoObjects);
34 return m_infoObjects;
35 }
36
38 {
39 QReadLocker l(&m_lockInfoObjects);
40 return m_infoObjects.size();
41 }
42
44
45 void CInfoDataReader::synchronizeCaches(CEntityFlags::Entity entities)
46 {
47 // no caching used here
48 SWIFT_VERIFY_X(false, Q_FUNC_INFO, "Using this for CInfoDataReader makes no sense");
49 Q_UNUSED(entities);
50 }
51
52 void CInfoDataReader::admitCaches(CEntityFlags::Entity entities)
53 {
54 // no caching used here
55 SWIFT_VERIFY_X(false, Q_FUNC_INFO, "Using this for CInfoDataReader makes no sense");
56 Q_UNUSED(entities);
57 }
58
59 void CInfoDataReader::invalidateCaches(CEntityFlags::Entity entities)
60 {
61 // no caching used here
62 SWIFT_VERIFY_X(false, Q_FUNC_INFO, "Using this for CInfoDataReader makes no sense");
63 Q_UNUSED(entities);
64 }
65
66 QDateTime CInfoDataReader::getCacheTimestamp(CEntityFlags::Entity entity) const
67 {
68 // no own caching used here
69 Q_UNUSED(entity);
70 Q_ASSERT_X(CEntityFlags::isSingleEntity(entity), Q_FUNC_INFO, "Need single entity");
71 Q_ASSERT_X(sApp, Q_FUNC_INFO, "Need sApp");
72
74 {
75 SWIFT_VERIFY_X(false, Q_FUNC_INFO, "Using this for CInfoDataReader makes no sense");
76 return {};
77 }
78
79 // Forward to web data services so I get cache data from other readers
81 return sApp->getWebDataServices()->getCacheTimestamp(entity);
82 }
83
84 int CInfoDataReader::getCacheCount(CEntityFlags::Entity entity) const
85 {
86 // no own caching used here
87 Q_UNUSED(entity);
88 Q_ASSERT_X(CEntityFlags::isSingleEntity(entity), Q_FUNC_INFO, "Need single entity");
89 Q_ASSERT_X(sApp, Q_FUNC_INFO, "Need sApp");
90
92 {
93 SWIFT_VERIFY_X(false, Q_FUNC_INFO, "Using this for CInfoDataReader makes no sense");
94 return 0;
95 }
96
97 // Forward to web data services so I get cache data from other readers
99 return sApp->getWebDataServices()->getCacheCount(entity);
100 }
101
103 {
104 SWIFT_VERIFY_X(false, Q_FUNC_INFO, "Using this for CInfoDataReader makes no sense");
106 }
107
108 CEntityFlags::Entity CInfoDataReader::getEntitiesWithCacheTimestampNewerThan(const QDateTime &threshold) const
109 {
110 Q_UNUSED(threshold);
111 SWIFT_VERIFY_X(false, Q_FUNC_INFO, "Using this for CInfoDataReader makes no sense");
113 }
114
115 bool CInfoDataReader::hasChangedUrl(CEntityFlags::Entity entity, CUrl &oldUrlInfo, CUrl &newUrlInfo) const
116 {
117 // not implemented
118 Q_UNUSED(entity);
119
120 // init the URLs
121 oldUrlInfo = this->getBaseUrl(CDbFlags::DbReading);
122 newUrlInfo = this->getBaseUrl(CDbFlags::DbReading);
123 return false;
124 }
125
126 CUrl CInfoDataReader::getDbServiceBaseUrl() const { return sApp->getGlobalSetup().getDbInfoReaderUrl(); }
127
129 {
130 if (!this->doWorkCheck())
131 {
132 return;
133 }
134
135 const CUrl url(this->getInfoObjectsUrl());
136 const CUrlLogList urlLogList(this->getUrlLogList()); // thread safe copy
137
138 if (urlLogList.hasPending())
139 {
140 CLogMessage(this).info(u"Info data reading still pending, summary: '%1'") << urlLogList.getSummary();
141 return;
142 }
143 if (!url.isEmpty())
144 {
145 this->getFromNetworkAndLog(url, { this, &CInfoDataReader::parseInfoObjectsData });
146 emit this->dataRead(this->getEntityForMode(), CEntityFlags::ReadStarted, 0, url);
147 }
148 else
149 {
150 this->logNoWorkingUrl(this->getEntityForMode());
151 }
152 }
153
154 void CInfoDataReader::parseInfoObjectsData(QNetworkReply *nwReplyPtr)
155 {
156 // wrap pointer, make sure any exit cleans up reply
157 // required to use delete later as object is created in a different thread
159 if (!this->doWorkCheck())
160 {
161 return;
162 }
163
164 const CDatabaseReader::JsonDatastoreResponse res =
166 if (res.hasErrorMessage())
167 {
168 CLogMessage::preformatted(res.lastWarningOrAbove());
169 emit this->dataRead(this->getEntityForMode(), CEntityFlags::ReadFailed, 0, res.getUrl());
170 return;
171 }
172
173 // get all or incremental set
174 const CDbInfoList infoObjects = CDbInfoList::fromDatabaseJson(res.getJsonArray());
175 const int n = infoObjects.size();
176
177 // Service URL => DB data
178 // DB data directory => shared files
179 const QString urlStr = nwReply->url().toString();
180 Q_UNUSED(urlStr) // debug only
181
182 // this part needs to be synchronized
183 {
184 QWriteLocker wl(&m_lockInfoObjects);
185 m_infoObjects = infoObjects;
186 }
187
188 this->emitAndLogDataRead(this->getEntityForMode(), n, res);
189 }
190
191 CUrl CInfoDataReader::getDbInfoObjectsUrl() const
192 {
193 return getBaseUrl(CDbFlags::DbReading).withAppendedPath("jsondbinfo.php");
194 }
195
196 CUrl CInfoDataReader::getSharedInfoObjectsUrl() const
197 {
199 }
200
201 CEntityFlags::EntityFlag CInfoDataReader::getEntityForMode() const
202 {
203 if (m_mode == CDbFlags::DbReading)
204 {
206 }
207 if (m_mode == CDbFlags::Shared)
208 {
210 }
211 qFatal("Wrong mode");
213 }
214
215 void CInfoDataReader::read(CEntityFlags::Entity entities, CDbFlags::DataRetrievalModeFlag mode,
216 const QDateTime &newerThan)
217 {
218 Q_UNUSED(entities)
219 Q_UNUSED(mode)
220 Q_UNUSED(newerThan)
221 Q_ASSERT_X(false, Q_FUNC_INFO, "Not implemented for CInfoDataReader");
222 }
223
225 {
226 switch (m_mode)
227 {
228 case CDbFlags::DbReading: return getDbInfoObjectsUrl();
229 case CDbFlags::Shared: return getSharedInfoObjectsUrl();
230 default: qFatal("Wrong mode");
231 }
232 return {};
233 }
234
235 CStatusMessageList CInfoDataReader::readFromJsonFiles(const QString &dir, CEntityFlags::Entity whatToRead,
236 bool overrideNewer)
237 {
238 Q_UNUSED(dir)
239 Q_UNUSED(whatToRead)
240 Q_UNUSED(overrideNewer)
241 Q_ASSERT_X(false, Q_FUNC_INFO, "Not supported");
242
243 return CStatusMessage(this).error(u"Not supported");
244 }
245
246 bool CInfoDataReader::readFromJsonFilesInBackground(const QString &dir, CEntityFlags::Entity whatToRead,
247 bool overrideNewer)
248 {
249 Q_UNUSED(dir)
250 Q_UNUSED(whatToRead)
251 Q_UNUSED(overrideNewer)
252 Q_ASSERT_X(false, Q_FUNC_INFO, "Not supported");
253 return false;
254 }
255
256 CEntityFlags::Entity CInfoDataReader::getSupportedEntities() const { return this->getEntityForMode(); }
257} // namespace swift::core::db
swift::misc::network::CUrlLogList getUrlLogList() const
Get the URL log list.
QNetworkReply * getFromNetworkAndLog(const swift::misc::network::CUrl &url, const swift::misc::CSlot< void(QNetworkReply *)> &callback)
Get request from network, and log with m_urlReadLog.
bool doWorkCheck() const
Still enabled etc.?
Value object encapsulating a list of reader configs.
void emitAndLogDataRead(swift::misc::network::CEntityFlags::Entity entity, int number, const JsonDatastoreResponse &res)
Emit signal and log when data have been read.
void logNoWorkingUrl(swift::misc::network::CEntityFlags::Entity entity)
Log if no working URL exists, using m_noWorkingUrlSeverity.
CDatabaseReader(QObject *owner, const CDatabaseReaderConfigList &config, const QString &name)
Constructor.
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.
CDatabaseReader::JsonDatastoreResponse setStatusAndTransformReplyIntoDatastoreResponse(QNetworkReply *nwReply)
Check if terminated or error, otherwise split into array of objects.
int getInfoObjectCount() const
Get info list size (either shared or from DB).
swift::misc::db::CDbInfoList getInfoObjects() const
Get info list (either shared or from DB).
void synchronizeCaches(swift::misc::network::CEntityFlags::Entity entities)
Admit caches for given entities.
void readInfoData()
Allow to call directly, special for info objects reader.
int getCacheCount(swift::misc::network::CEntityFlags::Entity entity) const
Cache`s number of entities.
swift::misc::CStatusMessageList readFromJsonFiles(const QString &dir, swift::misc::network::CEntityFlags::Entity whatToRead, bool overrideNewer)
Data read from local data.
swift::misc::network::CUrl getInfoObjectsUrl() const
URL depending on mode, i.e. shared/DB.
void invalidateCaches(swift::misc::network::CEntityFlags::Entity entities)
Invalidate the caches for given entities.
bool hasChangedUrl(swift::misc::network::CEntityFlags::Entity entity, swift::misc::network::CUrl &oldUrlInfo, swift::misc::network::CUrl &newUrlInfo) const
Changed URL, means the cache values have been read from elsewhere.
void admitCaches(swift::misc::network::CEntityFlags::Entity entities)
Admit caches for given entities.
CInfoDataReader(QObject *owner, const CDatabaseReaderConfigList &config, swift::misc::db::CDbFlags::DataRetrievalModeFlag mode)
Constructor.
swift::misc::network::CEntityFlags::Entity getEntitiesWithCacheTimestampNewerThan(const QDateTime &threshold) const
Entities already having data in cache (based on timestamp assumption).
swift::misc::network::CEntityFlags::Entity getEntitiesWithCacheCount() const
Entities already having data in cache.
QDateTime getCacheTimestamp(swift::misc::network::CEntityFlags::Entity entity) const
Get cache timestamp.
swift::misc::network::CUrl getDbServiceBaseUrl() const
Get the service URL, individual for each reader.
bool areAllInfoObjectsRead() const
All data read?
bool readFromJsonFilesInBackground(const QString &dir, swift::misc::network::CEntityFlags::Entity whatToRead, bool overrideNewer)
Data read from local data.
swift::misc::network::CEntityFlags::Entity getSupportedEntities() const
Supported entities by this reader.
const QObject * owner() const
Owner of the worker.
Definition worker.h:352
Class for emitting a log message.
Definition logmessage.h:27
static void preformatted(const CStatusMessage &statusMessage)
Sends a verbatim, preformatted message to the log.
Derived & error(const char16_t(&format)[N])
Set the severity to error, providing a format string.
Derived & info(const char16_t(&format)[N])
Set the severity to info, providing a format string.
size_type size() const
Returns number of elements in the sequence.
Definition sequence.h:273
Streamable status message, e.g.
Status messages, e.g. from Core -> GUI.
DataRetrievalModeFlag
Which data to read, requires corresponding readers.
Definition dbflags.h:25
@ DbReading
directly from DB
Definition dbflags.h:27
@ Shared
shared directory
Definition dbflags.h:29
static const QString & sharedInfoFileName()
Get shared info file name.
Definition dbinfo.cpp:155
Value object encapsulating a list of info objects.
Definition dbinfolist.h:27
static CDbInfoList fromDatabaseJson(const QJsonArray &array)
From our database JSON format.
static bool isSingleEntity(CEntityFlags::Entity flag)
Representing single entity?
EntityFlag
Which data to read, requires corresponding readers.
Definition entityflags.h:26
@ DbInfoObjectEntity
info about DB data (kind of metadata)
Definition entityflags.h:28
@ SharedInfoObjectEntity
info about shared DB data (metadata)
Definition entityflags.h:29
@ ReadStarted
reading has been started
Definition entityflags.h:62
Value object encapsulating information of a location, kind of simplified CValueObject compliant versi...
Definition url.h:27
bool isEmpty() const
Empty.
Definition url.cpp:63
CUrl withAppendedPath(const QString &path) const
Append path.
Definition url.cpp:151
Value object encapsulating a list of voice rooms.
Definition urlloglist.h:26
bool hasPending() const
Any pending calls.
QString getSummary() const
Summary.
Core data traits (aka cached values) and classes.
Classes interacting with the swift database (aka "datastore").
Free functions in swift::misc.
QObject(QObject *parent)
#define SWIFT_VERIFY_X(COND, WHERE, WHAT)
A weaker kind of assert.
Definition verify.h:26