diff --git a/src/blackmisc/db/datastoreobjectlist.cpp b/src/blackmisc/db/datastoreobjectlist.cpp index f965c9c85..d00d8b025 100644 --- a/src/blackmisc/db/datastoreobjectlist.cpp +++ b/src/blackmisc/db/datastoreobjectlist.cpp @@ -7,19 +7,21 @@ * contained in the LICENSE file. */ -#include "blackmisc/db/datastoreobjectlist.h" -#include "blackmisc/predicates.h" -#include "blackmisc/countrylist.h" +#include "blackmisc/simulation/aircraftmodellist.h" +#include "blackmisc/simulation/distributorlist.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/datastoreobjectlist.h" #include "blackmisc/db/dbinfolist.h" #include "blackmisc/db/artifactlist.h" #include "blackmisc/db/distributionlist.h" -#include "blackmisc/simulation/aircraftmodellist.h" -#include "blackmisc/simulation/distributorlist.h" +#include "blackmisc/predicates.h" +#include "blackmisc/countrylist.h" +#include "blackmisc/json.h" +#include "blackmisc/variantprivate.h" #include #include @@ -205,15 +207,16 @@ namespace BlackMisc return c; } - if (Json::looksLikeSwiftDataObject(jsonObject)) + // cache or settings format? + if (Json::looksLikeSwiftDataObjectJson(jsonObject)) { const QJsonObject cacheObj = Json::swiftDataObjectValue(jsonObject); - // swift own format CONTAINER container; - container.convertFromJson(cacheObj); + Private::CValueObjectMetaInfoHelper::convertFromMemoizedJson(cacheObj, container, true, 0); // handles both, memoized or "normal" convertFromJson return container; } + // plain vanilla container, does not match memoized objects if (Json::looksLikeSwiftContainerJson(jsonObject)) { CONTAINER container; @@ -221,9 +224,18 @@ namespace BlackMisc return container; } + // still as type/value pair + if (Json::looksLikeSwiftTypeValuePairJson(jsonObject)) + { + const QJsonObject valueObject = jsonObject.value("value").toObject(); + CONTAINER container; + Private::CValueObjectMetaInfoHelper::convertFromMemoizedJson(valueObject, container, true, 0); // handles both, memoized or "normal" convertFromJson + return container; + } + + // DB format, as array if (jsonObject.contains("data")) { - // DB format return IDatastoreObjectList::fromDatabaseJson(jsonObject.value("data").toArray()); } @@ -231,6 +243,20 @@ namespace BlackMisc throw CJsonException("Unsupported JSON format"); } + template + CONTAINER IDatastoreObjectList::fromMultipleJsonFormats(const QString &jsonString) + { + // also accept cache format + if (jsonString.isEmpty()) + { + const CONTAINER c; + return c; + } + + const QJsonObject jo = Json::jsonObjectFromString(jsonString, false); + return IDatastoreObjectList::fromMultipleJsonFormats(jo); + } + template QDateTime IDatastoreObjectList::latestDbTimestamp() const { diff --git a/src/blackmisc/db/datastoreobjectlist.h b/src/blackmisc/db/datastoreobjectlist.h index 59356837e..3684e48d4 100644 --- a/src/blackmisc/db/datastoreobjectlist.h +++ b/src/blackmisc/db/datastoreobjectlist.h @@ -70,6 +70,10 @@ namespace BlackMisc //! \remark supports native swift C++ format, DB format, and cache format static CONTAINER fromMultipleJsonFormats(const QJsonObject &jsonObject); + //! From multiple JSON formats + //! \remark supports native swift C++ format, DB format, and cache format + static CONTAINER fromMultipleJsonFormats(const QString &jsonString); + //! From DB JSON with default prefixes //! \remark Specialized classes might have their own fromDatabaseJson implementation static CONTAINER fromDatabaseJson(const QJsonArray &array); diff --git a/src/blackmisc/json.cpp b/src/blackmisc/json.cpp index fd9e5c04b..236139e87 100644 --- a/src/blackmisc/json.cpp +++ b/src/blackmisc/json.cpp @@ -58,7 +58,7 @@ const QJsonValue &operator >>(const QJsonValue &json, QString &value) const QJsonValue &operator >>(const QJsonValue &json, QStringList &value) { - for (auto && element : json.toArray()) { value << element.toString(); } + for (auto &&element : json.toArray()) { value << element.toString(); } return json; } @@ -132,7 +132,7 @@ QJsonValueRef operator >>(QJsonValueRef json, QString &value) QJsonValueRef operator >>(QJsonValueRef json, QStringList &value) { - for (auto && element : json.toArray()) { value << element.toString(); } + for (auto &&element : json.toArray()) { value << element.toString(); } return json; } @@ -473,16 +473,31 @@ namespace BlackMisc return looksLikeJson(json); } - bool looksLikeSwiftDataObject(const QJsonObject &object) + bool looksLikeSwiftDataObjectJson(const QJsonObject &object) { + // key + // - type + // - value if (object.size() != 1) { return false; } - const QString key = object.keys().front(); + const QStringList keys = object.keys(); + if (keys.size() != 1) { return false; } + const QString key = keys.front(); const QJsonObject cacheObject = object.value(key).toObject(); return (cacheObject.contains("type") && cacheObject.contains("value")); } + QJsonObject swiftDataObjectValue(const QString &jsonString) + { + const QJsonObject obj = jsonObjectFromString(jsonString); + if (obj.isEmpty()) { return obj; } + return swiftDataObjectValue(obj); + } + QJsonObject swiftDataObjectValue(const QJsonObject &object) { + // key + // - type + // - value if (object.size() != 1) { return object; } // no cache format const QString key = object.keys().front(); const QJsonObject cacheObject = object.value(key).toObject(); @@ -510,13 +525,6 @@ namespace BlackMisc return object; } - QJsonObject swiftDataObjectValue(const QString &jsonString) - { - const QJsonObject obj = jsonObjectFromString(jsonString); - if (obj.isEmpty()) { return obj; } - return swiftDataObjectValue(obj); - } - QJsonObject unwrapCache(const QString &jsonString) { @@ -530,5 +538,15 @@ namespace BlackMisc // CContainerbase::convertFromJson return object.contains("containerbase"); } + + bool looksLikeSwiftTypeValuePairJson(const QJsonObject &object) + { + return (object.contains("type") && object.contains("value")); + } + + bool looksLikeSwiftDbJson(const QJsonObject &object) + { + return (object.contains("data")); + } } // ns } // ns diff --git a/src/blackmisc/json.h b/src/blackmisc/json.h index a868f0cd5..7dda8f859 100644 --- a/src/blackmisc/json.h +++ b/src/blackmisc/json.h @@ -261,26 +261,34 @@ namespace BlackMisc //! \remark Quick check if the string could be a valid swift JSON string BLACKMISC_EXPORT bool looksLikeSwiftJson(const QString &json); - //! Looks like a valid swift container JSON object + //! Looks like a valid swift container JSON object? BLACKMISC_EXPORT bool looksLikeSwiftContainerJson(const QJsonObject &object); - //! Looks like a cache/setting object - BLACKMISC_EXPORT bool looksLikeSwiftDataObject(const QJsonObject &object); + //! Looks like a cache/setting object? + BLACKMISC_EXPORT bool looksLikeSwiftDataObjectJson(const QJsonObject &object); - //! The value of a cache/setting object + //! Looks like a swift type/value pair? + BLACKMISC_EXPORT bool looksLikeSwiftTypeValuePairJson(const QJsonObject &object); + + //! Looks like a swift DB format? + BLACKMISC_EXPORT bool looksLikeSwiftDbJson(const QJsonObject &object); + + //! The value part of a cache/setting object //! \remark if data object unstrip from that, otherwise leave unchanged + //! \remark this is the value ONLY! BLACKMISC_EXPORT QJsonObject swiftDataObjectValue(const QJsonObject &object); //! The value of a cache/setting object //! \remark if data object unstrip from that, otherwise leave unchanged + //! \remark this is the value ONLY! BLACKMISC_EXPORT QJsonObject swiftDataObjectValue(const QString &jsonString); - //! The value of a cache/setting object + //! The type/value of a cache/setting object //! \remark if cache object unstrip from that, otherwise leave unchanged //! \remark format is type/value BLACKMISC_EXPORT QJsonObject unwrapCache(const QJsonObject &object); - //! The value of a cache/setting object + //! The type/value object of a cache/setting object //! \remark if cache object unstrip from that, otherwise leave unchanged //! \remark format is type/value BLACKMISC_EXPORT QJsonObject unwrapCache(const QString &jsonString);