swift
datastore.cpp
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 
4 #include "misc/db/datastore.h"
5 
6 #include <QDateTime>
7 #include <QStringBuilder>
8 #include <QtGlobal>
9 
10 #include "misc/comparefunctions.h"
12 #include "misc/icon.h"
13 
14 namespace swift::misc::db
15 {
16  QVersionNumber IDatastoreObject::getQVersion() const { return QVersionNumber::fromString(this->getVersion()); }
17 
18  void IDatastoreObject::setTimestampVersionFromDatabaseJson(const QJsonObject &json, const QString &prefix)
19  {
20  // we check 2 formats, the DB format and the backend object format
21  QString timestampString(json.value(prefix % u"lastupdated").toString());
22  if (timestampString.isEmpty()) { timestampString = json.value(prefix % u"tsLastUpdated").toString(); }
23  const QDateTime ts(CDatastoreUtility::parseTimestamp(timestampString));
24  this->setUtcTimestamp(ts);
25 
26  // version
27  this->setVersion(json.value(prefix % u"version").toString());
28  }
29 
31  {
32  if (m_dbKey < 0) { return {}; }
33  return QString::number(m_dbKey);
34  }
35 
37  {
38  if (m_dbKey < 0) { return {}; }
39  return prefix % u'(' % QString::number(m_dbKey) % u')';
40  }
41 
43  {
44  bool ok;
45  const int k = key.toInt(&ok);
46  m_dbKey = ok ? k : -1;
47  }
48 
50 
51  bool IDatastoreObjectWithIntegerKey::matchesDbKeyState(db::DbKeyStateFilter filter) const
52  {
53  if (filter == All) { return true; }
54  const bool validKey = this->hasValidDbKey();
55  return (validKey && filter.testFlag(Valid)) || (!validKey && filter.testFlag(Invalid));
56  }
57 
59  {
60  static const CIcon empty;
61  if (this->hasValidDbKey()) { return CIcon::iconByIndex(CIcons::StandardIconDatabaseKey16); }
62  return empty;
63  }
64 
65  int IDatastoreObjectWithIntegerKey::stringToDbKey(const QString &candidate)
66  {
67  if (candidate.isEmpty()) { return invalidDbKey(); }
68  bool ok;
69  int k = candidate.toInt(&ok);
70  return ok ? k : invalidDbKey();
71  }
72 
74  {
75  if (this->hasValidDbKey()) { return QJsonValue(m_dbKey); }
76  return QJsonValue();
77  }
78 
80  const QString &prefix)
81  {
82  // this function is performance sensitive, as it is called for all DB data
83  const int dbKey = json.value(prefix % u"id").toInt(-1);
84  this->setDbKey(dbKey);
86  }
87 
88  bool IDatastoreObjectWithIntegerKey::existsKey(const QJsonObject &json, const QString &prefix)
89  {
90  const QJsonValue jv(json.value(prefix % u"id"));
91  return !(jv.isNull() || jv.isUndefined());
92  }
93 
95  {
97  const ColumnIndex i = index.frontCasted<ColumnIndex>();
98  switch (i)
99  {
100  case IndexDbIntegerKey: return QVariant::fromValue(m_dbKey);
101  case IndexDbKeyAsString: return QVariant::fromValue(this->getDbKeyAsString());
102  case IndexIsLoadedFromDb: return QVariant::fromValue(this->hasValidDbKey());
103  case IndexDatabaseIcon: return QVariant::fromValue(this->toDatabaseIcon());
104  case IndexVersion: return QVariant::fromValue(this->getVersion());
105  default: break;
106  }
107  return QVariant();
108  }
109 
111  {
113  {
114  ITimestampBased::setPropertyByIndex(index, variant);
115  return;
116  }
117  const ColumnIndex i = index.frontCasted<ColumnIndex>();
118  switch (i)
119  {
120  case IndexDbIntegerKey: m_dbKey = variant.toInt(); break;
121  case IndexDbKeyAsString: m_dbKey = stringToDbKey(variant.toString()); break;
122  case IndexVersion: this->setVersion(variant.toString()); break;
123  default: break;
124  }
125  }
126 
128  const IDatastoreObjectWithIntegerKey &compareValue) const
129  {
131  {
132  return ITimestampBased::comparePropertyByIndex(index, compareValue);
133  }
134  const ColumnIndex i = index.frontCasted<ColumnIndex>();
135  switch (i)
136  {
137  case IndexDbKeyAsString: // fall thru
138  case IndexDbIntegerKey: return Compare::compare(m_dbKey, compareValue.getDbKey());
139  case IndexDatabaseIcon: return Compare::compare(this->hasValidDbKey(), compareValue.hasValidDbKey());
140  case IndexVersion: return this->getVersion().compare(compareValue.getVersion());
141  default: break;
142  }
143  Q_ASSERT_X(false, Q_FUNC_INFO, "Compare failed");
144  return 0;
145  }
146 
148  {
149  if (ITimestampBased::canHandleIndex(index)) { return true; }
150  const int i = index.frontCasted<int>();
151  return (i >= static_cast<int>(IndexDbIntegerKey)) && (i < static_cast<int>(IndexEndMarker));
152  }
153 
155  {
156  if (this->hasValidDbKey()) { return QJsonValue(m_dbKey); }
157  static const QJsonValue null;
158  return null;
159  }
160 
162  {
163  if (m_dbKey.isEmpty()) { return {}; }
164  return prefix % '(' % m_dbKey % ')';
165  }
166 
167  bool IDatastoreObjectWithStringKey::matchesDbKeyState(db::DbKeyStateFilter filter) const
168  {
169  if (filter == All) { return true; }
170  return this->hasValidDbKey() && filter.testFlag(Valid);
171  }
172 
174  {
175  static const CIcon empty;
176  if (this->hasValidDbKey()) { return CIcon::iconByIndex(CIcons::StandardIconDatabaseKey16); }
177  return empty;
178  }
179 
181  const QString &prefix)
182  {
183  QString dbKey = json.value(prefix % u"id").toString();
184  this->setDbKey(dbKey);
186  }
187 
188  bool IDatastoreObjectWithStringKey::existsKey(const QJsonObject &json, const QString &prefix)
189  {
190  const QJsonValue jv(json.value(prefix % u"id"));
191  return !(jv.isNull() || jv.isUndefined());
192  }
193 
195  {
197  const ColumnIndex i = index.frontCasted<ColumnIndex>();
198  switch (i)
199  {
200  case IndexDbKeyAsString: // fall thru
201  case IndexDbStringKey: return QVariant::fromValue(m_dbKey);
202  case IndexDatabaseIcon: return QVariant::fromValue(this->toDatabaseIcon());
203  case IndexIsLoadedFromDb: return QVariant::fromValue(m_loadedFromDb);
204  case IndexVersion: return QVariant::fromValue(this->getVersion());
205  default: break;
206  }
207  return QVariant();
208  }
209 
211  {
213  {
214  ITimestampBased::setPropertyByIndex(index, variant);
215  return;
216  }
217  const ColumnIndex i = index.frontCasted<ColumnIndex>();
218  switch (i)
219  {
220  case IndexDbStringKey:
221  case IndexDbKeyAsString: m_dbKey = variant.value<QString>(); break;
222  case IndexIsLoadedFromDb: m_loadedFromDb = variant.toBool(); break;
223  case IndexVersion: this->setVersion(variant.toString()); break;
224  default: break;
225  }
226  }
227 
229  const IDatastoreObjectWithStringKey &compareValue) const
230  {
232  {
233  return ITimestampBased::comparePropertyByIndex(index, compareValue);
234  }
235  const ColumnIndex i = index.frontCasted<ColumnIndex>();
236  switch (i)
237  {
238  case IndexDbKeyAsString: // fall thru
239  case IndexDbStringKey: return m_dbKey.compare(compareValue.getDbKey());
240  case IndexDatabaseIcon: return Compare::compare(this->hasValidDbKey(), compareValue.hasValidDbKey());
241  case IndexVersion: return this->getVersion().compare(compareValue.getVersion());
242  default: break;
243  }
244  Q_ASSERT_X(false, Q_FUNC_INFO, "Compare failed");
245  return 0;
246  }
247 
249  {
250  if (index.isEmpty()) { return false; }
251  if (ITimestampBased::canHandleIndex(index)) { return true; }
252  const int i = index.frontCasted<int>();
253  return (i >= static_cast<int>(IndexDbStringKey)) && (i < static_cast<int>(IndexEndMarker));
254  }
255 } // namespace swift::misc::db
Value object for icons. An icon is stored in the global icon repository and identified by its index....
Definition: icon.h:39
static const CIcon & iconByIndex(CIcons::IconIndex index)
Icon for given index.
Definition: icon.cpp:54
Non-owning reference to a CPropertyIndex with a subset of its features.
CastType frontCasted() const
First element casted to given type, usually the PropertIndex enum.
void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
Set property by index.
int comparePropertyByIndex(CPropertyIndexRef index, const ITimestampBased &compareValue) const
Compare for index.
static bool canHandleIndex(CPropertyIndexRef index)
Can given index be handled.
void setUtcTimestamp(const QDateTime &timestamp)
Set timestamp.
QVariant propertyByIndex(CPropertyIndexRef index) const
Property by index.
static QDateTime parseTimestamp(const QString &timestamp)
Parse a timestamp object.
QVersionNumber getQVersion() const
Version as QVersion.
Definition: datastore.cpp:16
void setTimestampVersionFromDatabaseJson(const QJsonObject &json, const QString &prefix=QString())
Set versionn and timestamp values.
Definition: datastore.cpp:18
const QString & getVersion() const
Version info.
Definition: datastore.h:48
void setVersion(const QString &version)
Version info.
Definition: datastore.h:57
Class from which a derived class can inherit datastore-related functions.
Definition: datastore.h:70
static int stringToDbKey(const QString &candidate)
Convert string to DB key.
Definition: datastore.cpp:65
const CIcon & toDatabaseIcon() const
Database icon if this has valid key, otherwise empty.
Definition: datastore.cpp:58
QVariant propertyByIndex(swift::misc::CPropertyIndexRef index) const
Property by index.
Definition: datastore.cpp:94
QJsonValue getDbKeyAsJsonValue() const
Key as JSON value, or null.
Definition: datastore.cpp:73
QString getDbKeyAsString() const
DB key as string.
Definition: datastore.cpp:30
bool isLoadedFromDb() const
Loaded from DB.
Definition: datastore.cpp:49
static bool existsKey(const QJsonObject &json, const QString &prefix=QString())
Is a key available?
Definition: datastore.cpp:88
static bool canHandleIndex(swift::misc::CPropertyIndexRef index)
Can given index be handled?
Definition: datastore.cpp:147
void setDbKey(int key)
Set the DB key.
Definition: datastore.h:96
QString getDbKeyAsStringInParentheses(const QString &prefix={}) const
Db key in parentheses, e.g. "(3)".
Definition: datastore.cpp:36
int comparePropertyByIndex(CPropertyIndexRef index, const IDatastoreObjectWithIntegerKey &compareValue) const
Compare for index.
Definition: datastore.cpp:127
void setKeyVersionTimestampFromDatabaseJson(const QJsonObject &json, const QString &prefix=QString())
Set key and timestamp values.
Definition: datastore.cpp:79
bool matchesDbKeyState(db::DbKeyStateFilter filter) const
Matches filter?
Definition: datastore.cpp:51
bool hasValidDbKey() const
Has valid DB key.
Definition: datastore.h:102
void setPropertyByIndex(swift::misc::CPropertyIndexRef index, const QVariant &variant)
Set property by index.
Definition: datastore.cpp:110
Class from which a derived class can inherit datastore-related functions.
Definition: datastore.h:166
bool m_loadedFromDb
as we have no artificial key, it can happen key is set, but not loaded from DB
Definition: datastore.h:252
QVariant propertyByIndex(swift::misc::CPropertyIndexRef index) const
Property by index.
Definition: datastore.cpp:194
void setPropertyByIndex(swift::misc::CPropertyIndexRef index, const QVariant &variant)
Set property by index.
Definition: datastore.cpp:210
static bool existsKey(const QJsonObject &json, const QString &prefix=QString())
Is a key available?
Definition: datastore.cpp:188
bool hasValidDbKey() const
Has valid DB key.
Definition: datastore.h:195
const CIcon & toDatabaseIcon() const
Database icon if this has valid key, otherwise empty.
Definition: datastore.cpp:173
static bool canHandleIndex(swift::misc::CPropertyIndexRef index)
Can given index be handled.
Definition: datastore.cpp:248
QJsonValue getDbKeyAsJsonValue() const
Key as JSON value, or null.
Definition: datastore.cpp:154
const QString & getDbKey() const
Get DB key.
Definition: datastore.h:180
QString getDbKeyAsStringInParentheses(const QString &prefix={}) const
Db key in parentheses, e.g. "(3)".
Definition: datastore.cpp:161
void setKeyVersionTimestampFromDatabaseJson(const QJsonObject &json, const QString &prefix=QString())
Set key and timestamp values.
Definition: datastore.cpp:180
int comparePropertyByIndex(swift::misc::CPropertyIndexRef index, const IDatastoreObjectWithStringKey &compareValue) const
Compare for index.
Definition: datastore.cpp:228
bool matchesDbKeyState(db::DbKeyStateFilter filter) const
Matches filter?
Definition: datastore.cpp:167
void setDbKey(const QString &key)
Set the DB key.
Definition: datastore.h:192