6 #ifndef SWIFT_MISC_DB_DATABASEOBJECTLIST_H
7 #define SWIFT_MISC_DB_DATABASEOBJECTLIST_H
20 namespace swift::misc::db
25 template <
class OBJ,
class CONTAINER,
typename KEYTYPE>
28 static constexpr
bool hasIntegerKey =
29 std::is_base_of_v<IDatastoreObjectWithIntegerKey, OBJ> && std::is_same_v<int, KEYTYPE>;
30 static constexpr
bool hasStringKey =
31 std::is_base_of_v<IDatastoreObjectWithStringKey, OBJ> && std::is_base_of_v<QString, KEYTYPE>;
32 static_assert(hasIntegerKey || hasStringKey,
33 "ObjectType needs to implement IDatastoreObjectWithXXXXKey and have appropriate KeyType");
37 OBJ
findByKey(KEYTYPE key,
const OBJ ¬Found = OBJ())
const
39 return this->
container().findFirstByOrDefault(&OBJ::getDbKey, key, notFound);
46 if (keys.
isEmpty()) {
return objects; }
49 if (!keys.
contains(obj.getDbKey())) {
continue; }
50 objects.push_back(obj);
61 if (!obj.hasValidDbKey()) {
continue; }
62 objects.push_back(obj);
73 if (obj.hasValidDbKey()) {
continue; }
74 objects.push_back(obj);
82 if (this->
container().isEmpty()) {
return OBJ(); }
84 [](
const OBJ &obj1,
const OBJ &obj2) {
85 bool v1 = obj1.hasValidDbKey();
86 bool v2 = obj2.hasValidDbKey();
87 if (v1 && v2) {
return obj1.getDbKey() < obj2.getDbKey(); }
102 if (!obj.hasValidDbKey()) {
continue; }
103 keys.
insert(obj.getDbKey());
114 if (!obj.hasValidDbKey()) {
continue; }
115 map.insert(obj.getDbKey(), obj);
126 if (!obj.hasValidDbKey()) {
continue; }
127 keys.
insert(obj.getDbKeyAsString());
141 else { s += separator + k; }
152 if (ok) { *ok =
false; }
155 KEYTYPE max = *std::max_element(keys.
begin(), keys.
end());
156 if (ok) { *ok =
true; }
163 if (keys.
isEmpty()) {
return 0; }
164 if (this->
container().isEmpty()) {
return 0; }
168 if (keys.
contains(obj.getDbKey())) {
continue; }
169 newValues.push_back(obj);
171 const int delta = this->
container().size() - newValues.size();
172 if (delta > 0) { this->
container() = newValues; }
179 if (this->
container().isEmpty()) {
return 0; }
183 if (!obj.hasValidDbKey()) {
continue; }
184 newValues.push_back(obj);
186 int delta = this->
container().size() - newValues.size();
202 newValues.removeObjectsWithKeys(keys);
203 int removeSize = newValues.size();
206 return newValues.size() - removeSize;
213 objs.removeObjectsWithoutDbKey();
214 if (objs.isEmpty()) {
return QDateTime(); }
215 return objs.latestTimestamp();
222 objs.removeObjectsWithoutDbKey();
223 if (objs.isEmpty()) {
return QDateTime(); }
224 return objs.oldestDbTimestamp();
233 if (obj.hasValidDbKey() && withKey) { count++; }
246 if (!obj.hasValidDbKey()) {
return true; }
256 if (!obj.hasValidDbKey()) {
continue; }
257 if (obj.getDbKey() == key) {
return true; }
274 if (json::looksLikeSwiftDataObjectJson(jsonObject))
276 const QJsonObject cacheObj = json::swiftDataObjectValue(jsonObject);
278 private_ns::CValueObjectMetaInfoHelper::convertFromMemoizedJson(
284 if (json::looksLikeSwiftContainerJson(jsonObject))
292 if (json::looksLikeSwiftTypeValuePairJson(jsonObject))
296 private_ns::CValueObjectMetaInfoHelper::convertFromMemoizedJson(
331 for (
const QJsonValue &value : array) {
container.push_back(OBJ::fromDatabaseJson(value.toObject())); }
342 container.push_back(OBJ::fromDatabaseJson(value.toObject(), prefix));
Thrown when a convertFromJson method encounters an unrecoverable error in JSON data.
Build a QMap more efficiently when calling insert() in a for loop.
Build a QSet more efficiently when calling insert() in a for loop.
void insert(const T &value)
Add an element to the set. Runs in amortized constant time.
List of objects with timestamp. Such objects should implement.
const CONTAINER & container() const
Container.
List of objects read from database. Such objects should implement.
int replaceOrAddObjectsByKey(const CONTAINER &container)
Update or insert data (based on DB key)
void sortByKey()
Sort by timestamp.
QDateTime oldestDbTimestamp() const
Latest DB timestamp (means objects with DB key)
QSet< QString > toDbKeyStringSet() const
All keys as string set (also integer keys will be converted to string)
int removeObjectsWithKeys(const QSet< KEYTYPE > &keys)
Remove objects with keys.
int removeObjectsWithoutDbKey()
Remove objects without key.
OBJ findByKey(KEYTYPE key, const OBJ ¬Found=OBJ()) const
Object with key, notFound otherwise.
static CONTAINER fromDatabaseJson(const QJsonArray &array, const QString &prefix)
From DB JSON.
OBJ maxKeyObject() const
Object with max.key.
KEYTYPE getMaxKey(bool *ok=nullptr) const
Max.key value (making sense with integer key)
QDateTime latestDbTimestamp() const
Latest DB timestamp (means objects with DB key)
QMap< KEYTYPE, OBJ > toDbKeyValueMap() const
As map with DB key/object.
static CONTAINER fromDatabaseJson(const QJsonArray &array)
From DB JSON with default prefixes.
QSet< KEYTYPE > toDbKeySet() const
All keys as set.
QString dbKeysAsString(const QString &separator) const
The DB keys as string.
IDatastoreObjectList()=default
Constructor.
static CONTAINER fromMultipleJsonFormats(const QJsonObject &jsonObject)
From multiple JSON formats.
int countWithValidDbKey() const
Number of entries with valid DB key.
CONTAINER findObjectsWithoutDbKey() const
Objects without DB key.
CONTAINER findByKeys(const QSet< KEYTYPE > &keys) const
Object with key, notFound otherwise.
static CONTAINER fromMultipleJsonFormats(const QString &jsonString)
From multiple JSON formats.
bool containsAnyObjectWithoutKey() const
Any object without key?
int countWithValidDbKey(bool withKey) const
Number of objects with/without key.
bool containsDbKey(KEYTYPE key) const
Contains object with key?
CONTAINER findObjectsWithDbKey() const
Objects with DB key.
QJsonObject jsonObjectFromString(const QString &json, bool acceptCacheFormat)
JSON Object from string.
auto MemberLess(Ts... vs)
Predicate which compares the return values of some member functions of two objects.
T::const_iterator begin(const LockFreeReader< T > &reader)
Non-member begin() and end() for so LockFree containers can be used in ranged for loops.
T::const_iterator end(const LockFreeReader< T > &reader)
Non-member begin() and end() for so LockFree containers can be used in ranged for loops.
bool contains(QLatin1StringView key) const const
bool isEmpty() const const
QJsonValue value(QLatin1StringView key) const const
QJsonArray toArray() const const
QJsonObject toObject() const const
QSet< T >::iterator begin()
bool contains(const QSet< T > &other) const const
QSet< T >::iterator end()
bool isEmpty() const const
bool isEmpty() const const