/* Copyright (C) 2015 * swift Project Community / Contributors * * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, * including this file, may be copied, modified, propagated, or distributed except according to the terms * contained in the LICENSE file. */ #include "blackmisc/db/datastoreobjectlist.h" #include "blackmisc/predicates.h" #include "blackmisc/countrylist.h" #include "blackmisc/aviation/airport.h" #include "blackmisc/aviation/airportlist.h" #include "blackmisc/aviation/liverylist.h" #include "blackmisc/aviation/aircrafticaocodelist.h" #include "blackmisc/aviation/airlineicaocodelist.h" #include "blackmisc/db/dbinfolist.h" #include "blackmisc/db/distributionlist.h" #include "blackmisc/simulation/aircraftmodellist.h" #include "blackmisc/simulation/distributorlist.h" #include #include #include #include #include namespace BlackMisc { namespace Db { template IDatastoreObjectList::IDatastoreObjectList() { constexpr bool hasIntegerKey = std::is_base_of::value && std::is_same::value; constexpr bool hasStringKey = std::is_base_of::value && std::is_base_of::value; static_assert(hasIntegerKey || hasStringKey, "ObjectType needs to implement IDatastoreObjectWithXXXXKey and have appropriate KeyType"); } template OBJ IDatastoreObjectList::findByKey(KEYTYPE key, const OBJ ¬Found) const { return this->container().findFirstByOrDefault(&OBJ::getDbKey, key, notFound); } template OBJ IDatastoreObjectList::maxKeyObject() const { if (this->container().isEmpty()) { return OBJ(); } const OBJ max = *std::max_element(this->container().begin(), this->container().end(), [](const OBJ & obj1, const OBJ & obj2) { bool v1 = obj1.hasValidDbKey(); bool v2 = obj2.hasValidDbKey(); if (v1 && v2) { return obj1.getDbKey() < obj2.getDbKey(); } return v2; }); return max; } template void IDatastoreObjectList::sortByKey() { this->container().sort(BlackMisc::Predicates::MemberLess(&OBJ::getDbKey)); } template QSet IDatastoreObjectList::toDbKeySet() const { QSet keys; for (const OBJ &obj : ITimestampObjectList::container()) { if (!obj.hasValidDbKey()) { continue; } keys.insert(obj.getDbKey()); } return keys; } template QSet IDatastoreObjectList::toDbKeyStringSet() const { QSet keys; for (const OBJ &obj : ITimestampObjectList::container()) { if (!obj.hasValidDbKey()) { continue; } keys.insert(obj.getDbKeyAsString()); } return keys; } template QString IDatastoreObjectList::dbKeysAsString(const QString &separator) const { if (ITimestampObjectList::container().isEmpty()) { return ""; } const QSet keys = IDatastoreObjectList::toDbKeyStringSet(); QString s; for (const QString &k : keys) { if (s.isEmpty()) { s += k; } else { s += separator + k; } } return s; } template KEYTYPE IDatastoreObjectList::getMaxKey(bool *ok) const { QSet keys(this->toDbKeySet()); if (keys.isEmpty()) { if (ok) { *ok = false; } return KEYTYPE(); } KEYTYPE max = *std::max_element(keys.begin(), keys.end()); if (ok) { *ok = true; } return max; } template int IDatastoreObjectList::removeObjectsWithKeys(const QSet &keys) { if (keys.isEmpty()) { return 0; } if (this->container().isEmpty()) { return 0; } CONTAINER newValues; for (const OBJ &obj : ITimestampObjectList::container()) { if (keys.contains(obj.getDbKey())) { continue; } newValues.push_back(obj); } int delta = this->container().size() - newValues.size(); this->container() = newValues; return delta; } template int IDatastoreObjectList::removeObjectsWithoutDbKey() { if (this->container().isEmpty()) { return 0; } CONTAINER newValues; for (const OBJ &obj : ITimestampObjectList::container()) { if (!obj.hasValidDbKey()) { continue; } newValues.push_back(obj); } int delta = this->container().size() - newValues.size(); this->container() = newValues; return delta; } template int IDatastoreObjectList::replaceOrAddObjectsByKey(const CONTAINER &container) { if (container.isEmpty()) { return 0; } if (this->container().isEmpty()) { this->container() = container; return this->container().size(); } CONTAINER newValues(this->container()); const QSet keys(container.toDbKeySet()); newValues.removeObjectsWithKeys(keys); int removeSize = newValues.size(); // size after removing data newValues.push_back(container); this->container() = newValues; return newValues.size() - removeSize; } template QDateTime IDatastoreObjectList::oldestDbTimestamp() const { CONTAINER objs(this->container()); objs.removeObjectsWithoutDbKey(); if (objs.isEmpty()) { return QDateTime(); } return objs.oldestDbTimestamp(); } template int IDatastoreObjectList::countWithValidDbKey() const { int count = 0; for (const OBJ &obj : ITimestampObjectList::container()) { if (obj.hasValidDbKey()) { count++; } } return count; } template QDateTime IDatastoreObjectList::latestDbTimestamp() const { CONTAINER objs(this->container()); objs.removeObjectsWithoutDbKey(); if (objs.isEmpty()) { return QDateTime(); } return objs.latestTimestamp(); } template CONTAINER IDatastoreObjectList::fromDatabaseJson(const QJsonArray &array) { CONTAINER container; for (const QJsonValue &value : array) { container.push_back(OBJ::fromDatabaseJson(value.toObject())); } return container; } template CONTAINER IDatastoreObjectList::fromDatabaseJson(const QJsonArray &array, const QString &prefix) { CONTAINER container; for (const QJsonValue &value : array) { container.push_back(OBJ::fromDatabaseJson(value.toObject(), prefix)); } return container; } // see here for the reason of thess forward instantiations // https://isocpp.org/wiki/faq/templates#separate-template-fn-defn-from-decl //! \cond PRIVATE template class BLACKMISC_EXPORT_DEFINE_TEMPLATE IDatastoreObjectList; template class BLACKMISC_EXPORT_DEFINE_TEMPLATE IDatastoreObjectList; template class BLACKMISC_EXPORT_DEFINE_TEMPLATE IDatastoreObjectList; template class BLACKMISC_EXPORT_DEFINE_TEMPLATE IDatastoreObjectList; template class BLACKMISC_EXPORT_DEFINE_TEMPLATE IDatastoreObjectList; template class BLACKMISC_EXPORT_DEFINE_TEMPLATE IDatastoreObjectList; template class BLACKMISC_EXPORT_DEFINE_TEMPLATE IDatastoreObjectList; template class BLACKMISC_EXPORT_DEFINE_TEMPLATE IDatastoreObjectList; template class BLACKMISC_EXPORT_DEFINE_TEMPLATE IDatastoreObjectList; //! \endcond } // ns } // ns