diff --git a/src/serversdk/databasemanager.cpp b/src/serversdk/databasemanager.cpp index a5299e7..628fa8d 100644 --- a/src/serversdk/databasemanager.cpp +++ b/src/serversdk/databasemanager.cpp @@ -116,6 +116,12 @@ QSqlQuery DatabaseManager::executeQuery(QSqlQuery &query, const QString &sqlText return query; } +QSqlQuery DatabaseManager::createQuery() +{ + QSqlQuery query(mDatabase); + return query; +} + QSqlQuery DatabaseManager::processResult(int res, const QSqlQuery &query) const { if ( !res ) { diff --git a/src/serversdk/databasemanager.h b/src/serversdk/databasemanager.h index e082e7c..1e4139c 100644 --- a/src/serversdk/databasemanager.h +++ b/src/serversdk/databasemanager.h @@ -25,7 +25,6 @@ public: bool dryMode() const; void setDryMode(bool dryMode); - bool openSQLite(const QString &path, const QString &connectionName = QStringLiteral("qt_sql_default_connection")); bool openPostgres(const QString& host, const QString& dbName, const QString& user, const QString& password, const QString &connectionName = QStringLiteral("qt_sql_default_connection")); bool isValid() const; @@ -35,6 +34,7 @@ public: // SQL handling QSqlQuery execPlainSql(const QString &sqlText); QSqlQuery executeQuery(QSqlQuery &query, const QString &sqlText = QString()); + QSqlQuery createQuery(); QSqlDatabase database() const; diff --git a/src/serversdk/databasetable.cpp b/src/serversdk/databasetable.cpp index 3e3b2f1..b03e8d9 100644 --- a/src/serversdk/databasetable.cpp +++ b/src/serversdk/databasetable.cpp @@ -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(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 > 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(doc.toVariant()); - - // Populate this object data - bool res = fromVariantMap(variant); - return res; -} QString DatabaseTable::textSQLIteType(QVariant::Type type) const { diff --git a/src/serversdk/databasetable.h b/src/serversdk/databasetable.h index bd6dea4..018ea98 100644 --- a/src/serversdk/databasetable.h +++ b/src/serversdk/databasetable.h @@ -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 ) diff --git a/src/serversdk/databaseutils.cpp b/src/serversdk/databaseutils.cpp index d1dcc8e..298fe11 100644 --- a/src/serversdk/databaseutils.cpp +++ b/src/serversdk/databaseutils.cpp @@ -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 += ", "; @@ -131,8 +134,42 @@ QSqlQuery DatabaseUtils::insertIntoTable(const DatabaseTable *table, const QStri QString queryText = QString("INSERT INTO %1 ( %2 ) VALUES ( %3 );").arg(table_name).arg(columns).arg(values); query.prepare(queryText); - for (auto key : keys ) { - auto value = valueMap.value(key); + for (auto _key : keys ) { + QString key = fromCamelCase(_key); + auto value = valueMap.value(_key); + query.bindValue(":"+key, value); + } + + QSqlQuery res = mDatabaseManager->executeQuery(query); + return res; +} + +QSqlQuery DatabaseUtils::updateTable(const DatabaseTable *table, const QString table_name) const +{ + QString columnsAndValues; + + // tepmporary, for edit ( add one more parameter to func sth like QList with conditions + QString conditions; + conditions = "id = :id"; + + QVariantMap valueMap = table->toVariantMap(); + + auto keys = valueMap.keys(); + for (auto _key : keys) { + QString key = fromCamelCase(_key); + if (!columnsAndValues.isEmpty()) { + columnsAndValues += ", "; + } + columnsAndValues += key + " = :" + key; + } + + QSqlQuery query(mDatabaseManager->database()); + QString queryText = QString("UPDATE %1 SET %2 WHERE %3;").arg(table_name).arg(columnsAndValues).arg(conditions); + query.prepare(queryText); + + for (auto _key : keys ) { + QString key = fromCamelCase(_key); + auto value = valueMap.value(_key); query.bindValue(":"+key, value); } @@ -152,6 +189,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 +#include #include #include @@ -24,6 +25,8 @@ public: QSqlQuery insertIntoTable(const DatabaseTable *table, const QString table_name) const; + QSqlQuery updateTable(const DatabaseTable *table, const QString table_name) const; + template QList> tableFromQuery(QSqlQuery query) const { QList> list; @@ -46,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; @@ -54,5 +60,6 @@ private: QString mSqlType; }; + } // namespace serversdk diff --git a/test/auto/database/tst_databasetable.cpp b/test/auto/database/tst_databasetable.cpp index d58dabc..0aa5aa8 100644 --- a/test/auto/database/tst_databasetable.cpp +++ b/test/auto/database/tst_databasetable.cpp @@ -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(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(); + 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" diff --git a/test/auto/database/tst_databaseutils.cpp b/test/auto/database/tst_databaseutils.cpp index 8d2618a..442f8c3 100644 --- a/test/auto/database/tst_databaseutils.cpp +++ b/test/auto/database/tst_databaseutils.cpp @@ -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) diff --git a/test/auto/database/tst_sqlite.cpp b/test/auto/database/tst_sqlite.cpp index bfc9c4e..6480e04 100644 --- a/test/auto/database/tst_sqlite.cpp +++ b/test/auto/database/tst_sqlite.cpp @@ -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(first); + auto names_tab = list.first(); QVERIFY(names_tab); QCOMPARE(names_tab->name(), QStringLiteral("Testname"));