Example in tst_databasetable how to handle different Json / Table data

+ camel case handling
This commit is contained in:
Filip Bucek 2019-11-18 10:41:24 +01:00
parent 4dfd4227cb
commit 793bfde1de
7 changed files with 143 additions and 19 deletions

View File

@ -19,6 +19,16 @@ QByteArray DatabaseTable::jsonData() const
return doc.toJson(QJsonDocument::Compact);
}
bool DatabaseTable::fromJson(const QByteArray &data)
{
// in: JSON ( e.g. {"id": 300} )
QJsonDocument doc = QJsonDocument::fromJson(data);
QVariantMap variant = qvariant_cast<QVariantMap>(doc.toVariant());
// Populate this object data
bool res = fromVariantMap(variant);
return res;
}
/** Creates universal variant structure to hold key / value pairs */
QVariantMap DatabaseTable::toVariantMap() const
@ -76,16 +86,6 @@ QList<std::shared_ptr<DatabaseTable> > DatabaseTable::fromListVariantMap(const Q
return list;
}
bool DatabaseTable::fromJson(const QByteArray &data)
{
// in: JSON ( e.g. {"id": 300} )
QJsonDocument doc = QJsonDocument::fromJson(data);
QVariantMap variant = qvariant_cast<QVariantMap>(doc.toVariant());
// Populate this object data
bool res = fromVariantMap(variant);
return res;
}
QString DatabaseTable::textSQLIteType(QVariant::Type type) const
{

View File

@ -84,13 +84,13 @@ public:
* @brief Creates JSON from QMetaObject data ( Q_PROPERTY ) -> TABLE_PROPERTY
* @return text json e.g. { "id": 00344 }
*/
QByteArray jsonData() const;
virtual QByteArray jsonData() const;
/**
* @brief Populates object with JSON {"id": 300} )
* @return true if success TODO: not implemented corrrectly
*/
bool fromJson(const QByteArray &data);
virtual bool fromJson(const QByteArray &data);
/**
* @brief Creates VariantMap from QMetaObject data ( Q_PROPERTY )

View File

@ -56,7 +56,7 @@ QString DatabaseUtils::createTableText(const DatabaseTable *table, const QString
if (!prop.isUser())
continue;
QString name = prop.name();
QString name = fromCamelCase(prop.name());
QVariant::Type type = prop.type();
QString textType;
@ -116,9 +116,12 @@ QSqlQuery DatabaseUtils::insertIntoTable(const DatabaseTable *table, const QStri
QVariantMap valueMap = table->toVariantMap();
// in: id / 23233
// out: columns: id
// out: values: :id
auto keys = valueMap.keys();
for (auto key : keys) {
for (auto _key : keys) {
QString key = fromCamelCase(_key);
if (!columns.isEmpty()) {
columns += ", ";
values += ", ";
@ -152,7 +155,8 @@ QSqlQuery DatabaseUtils::updateTable(const DatabaseTable *table, const QString t
auto keys = valueMap.keys();
for (auto key : keys) {
for (auto _key : keys) {
QString key = fromCamelCase(_key);
if (!columnsAndValues.isEmpty()) {
columnsAndValues += ", ";
}
@ -184,6 +188,27 @@ void DatabaseUtils::setSqlType(const QString &sqlType)
mSqlType = sqlType;
}
QString DatabaseUtils::fromCamelCase(const QString &s)
{
static QRegularExpression regExp1 {"(.)([A-Z][a-z]+)"};
static QRegularExpression regExp2 {"([a-z0-9])([A-Z])"};
QString result = s;
result.replace(regExp1, "\\1_\\2");
result.replace(regExp2, "\\1_\\2");
return result.toLower();
}
QString serversdk::DatabaseUtils::toCamelCase(const QString &s)
{
QStringList parts = s.split('_', QString::SkipEmptyParts);
for (int i=1; i<parts.size(); ++i)
parts[i].replace(0, 1, parts[i][0].toUpper());
return parts.join("");
}
} // namespace serversdk

View File

@ -3,6 +3,7 @@
#include "databasetable.h"
#include <QObject>
#include <QRegularExpression>
#include <QSqlQuery>
#include <QSqlRecord>
@ -48,6 +49,9 @@ public:
QString sqlType() const;
void setSqlType(const QString &sqlType);
static QString fromCamelCase(const QString &s);
static QString toCamelCase(const QString& s);
private:
QString createTableText(const DatabaseTable *table, const QString table_name) const;
@ -56,5 +60,6 @@ private:
QString mSqlType;
};
} // namespace serversdk

View File

@ -13,6 +13,58 @@ class BookTable : public serversdk::DatabaseTable
};
QString enumjson = R"({"authErrors":255,"flags":["Enabled","NoValidity"],"subjectId":"1438aade-3aa6-4885-8e0f-138dedae727a"})";
class EnumTest : public serversdk::DatabaseTable
{
Q_OBJECT
TABLE_PROPERTY(int, authErrors, setAuthErrors, 0);
TABLE_PROPERTY(bool, enabled, setEnabled, false);
TABLE_PROPERTY(bool, noValidity, setNoValidity, false);
TABLE_PROPERTY(QString, subjectId, setSubjectId, QString());
public:
QByteArray jsonData() const override
{
auto variantMap = this->toVariantMap();
auto enabled = variantMap["enabled"].toBool();
auto noValidity = variantMap["noValidity"].toBool();
variantMap.remove("enabled");
variantMap.remove("noValidity");
QVariantList flags;
if ( enabled ) {
flags << "Enabled";
}
if ( noValidity ) {
flags << "NoValidity";
}
variantMap.insert("flags", flags);
QJsonDocument doc = QJsonDocument::fromVariant(variantMap);
return doc.toJson(QJsonDocument::Compact);
}
bool fromJson(const QByteArray &data) override
{
QJsonDocument doc = QJsonDocument::fromJson(data);
QVariantMap variant = qvariant_cast<QVariantMap>(doc.toVariant());
QVariantList flags = variant["flags"].toList();
for (auto value : flags) {
if ( value.toString() == "Enabled") {
variant.insert("enabled", true);
}
if ( value.toString() == "NoValidity") {
variant.insert("noValidity", true);
}
}
variant.remove("flags");
// Populate this object data
bool res = fromVariantMap(variant);
return res;
}
};
class DatabaseTableTest : public QObject
{
@ -26,6 +78,7 @@ private slots:
void constructor_test();
void qvariant_test();
void json_test();
void enum_test();
};
@ -61,6 +114,35 @@ void DatabaseTableTest::json_test()
QCOMPARE(table->jsonData(), expected);
}
void DatabaseTableTest::enum_test()
{
auto table = std::make_unique<EnumTest>();
table->setAuthErrors(255);
table->setNoValidity(true);
table->setEnabled(true);
table->setSubjectId("1438aade-3aa6-4885-8e0f-138dedae727a");
QCOMPARE(table->jsonData(), enumjson.toUtf8());
EnumTest jsonTest;
jsonTest.fromJson(enumjson.toUtf8());
QCOMPARE(jsonTest.authErrors(), 255);
QCOMPARE(jsonTest.noValidity(), true);
QCOMPARE(jsonTest.enabled(), true);
QCOMPARE(jsonTest.subjectId(), QStringLiteral("1438aade-3aa6-4885-8e0f-138dedae727a"));
}
QTEST_APPLESS_MAIN(DatabaseTableTest)
#include "tst_databasetable.moc"

View File

@ -33,6 +33,8 @@ public:
private slots:
void createTable_test();
void toCamelCase_test();
void fromCamelCase_test();
};
@ -64,6 +66,18 @@ void DatabaseUtilsTest::createTable_test()
QCOMPARE(sql, expected);
}
void DatabaseUtilsTest::toCamelCase_test()
{
QString test1 = "id_name";
QCOMPARE(serversdk::DatabaseUtils::toCamelCase(test1), QStringLiteral("idName"));
}
void DatabaseUtilsTest::fromCamelCase_test()
{
QString test1 = "idName";
QCOMPARE(serversdk::DatabaseUtils::fromCamelCase(test1), QStringLiteral("id_name"));
}
QTEST_APPLESS_MAIN(DatabaseUtilsTest)

View File

@ -90,9 +90,7 @@ void SqliteTest::createTable_test()
// ENSURE SAME
QCOMPARE(list.count(), 1);
auto first = list.first();
QVERIFY(first);
auto names_tab = std::dynamic_pointer_cast<Names>(first);
auto names_tab = list.first();
QVERIFY(names_tab);
QCOMPARE(names_tab->name(), QStringLiteral("Testname"));