diff --git a/serversdk.pri b/serversdk.pri index 8e2fea1..a01d8c8 100644 --- a/serversdk.pri +++ b/serversdk.pri @@ -32,6 +32,7 @@ else:win32:CONFIG(debug, debug|release): LIBS += -L$$SDKDIR/debug/ -lserversdk else:unix: LIBS += -L$$SDKDIR/ -lserversdk QT += network sql +CONFIG += c++14 INCLUDEPATH += $$shell_quote($$PWD/src/) DEPENDPATH += $$shell_quote($$PWD/src/serversdk) diff --git a/src/serversdk/databasemanager.cpp b/src/serversdk/databasemanager.cpp index 9a1e959..eed5099 100644 --- a/src/serversdk/databasemanager.cpp +++ b/src/serversdk/databasemanager.cpp @@ -72,21 +72,55 @@ void DatabaseManager::close() mDatabase.close(); } -bool DatabaseManager::executeQuery(QSqlQuery &query) +QSqlQuery DatabaseManager::execPlainSql(const QString &sqlText) { - if (mDryMode){ - QString sqlStatement = getLastQuery(query); - qDebug() << sqlStatement; + QSqlQuery query(mDatabase); + return executeQuery(query, sqlText); +} +QSqlQuery DatabaseManager::executeQuery(QSqlQuery &query, const QString &sqlText) +{ + + // Get correct SQL statement and correct isSelect + // Need for output correct SQL command + // isSelect is needed for correct bahaviour of 'dryMode' only select should be executed + QString sqlStatement = sqlText; + bool isSelect = false; + if ( sqlText.isEmpty()) { + sqlStatement = getLastQuery(query); + isSelect = query.isSelect(); + } else { + if (sqlText.startsWith("SELECT", Qt::CaseInsensitive)) { + isSelect = true; + } } - if (!mDryMode || query.isSelect()){ - if (!query.exec()){ - QString msg = QString("Source: Database Manager, Error: %1").arg(query.lastError().text()); - log(QString(msg)); - emit error(); - } + + if (mDryMode) { + qCInfo(sdkdb) << "SQL statement: " << sqlStatement; } - return true; + + // Execute only SELECT statement or when not drymode + if ( isSelect || !mDryMode ) { + int res = false; + if ( ! sqlText.isEmpty()) { // prepared statement. + res = query.exec(sqlText); + return processResult(res, query); + } else { + res = query.exec(); + return processResult(res, query); + } + } + return query; +} + +QSqlQuery DatabaseManager::processResult(int res, const QSqlQuery &query) const +{ + if ( !res ) { + QString msg = QString("Source: Database Manager, Error: %1").arg(query.lastError().text()); + qCWarning(sdkdb) << msg; + log(msg); + } + return query; } QString DatabaseManager::getLastQuery(const QSqlQuery& query) const @@ -104,6 +138,24 @@ QString DatabaseManager::getLastQuery(const QSqlQuery& query) const void DatabaseManager::log(const QString &msg) const { qDebug() << "database logger implement logger"; + qDebug() << msg; +} + +bool DatabaseManager::dryMode() const +{ + return mDryMode; +} + +void DatabaseManager::setDryMode(bool dryMode) +{ + mDryMode = dryMode; +} + +QSqlDatabase DatabaseManager::database() const +{ + Q_ASSERT(mDatabase.isValid()); + Q_ASSERT(mDatabase.isOpen()); + return mDatabase; } } // core diff --git a/src/serversdk/databasemanager.h b/src/serversdk/databasemanager.h index 4da4b98..63e4f76 100644 --- a/src/serversdk/databasemanager.h +++ b/src/serversdk/databasemanager.h @@ -21,13 +21,24 @@ public: DatabaseManager(const QString& host, const QString& dbName, const QString& user, const QString& password, bool mDryMode = false); ~DatabaseManager(); + // Attributes + bool dryMode() const; + void setDryMode(bool dryMode); + + bool openSQLite(const QString &path, const QString &connectionName = QStringLiteral("qt_sql_default_connection")); bool isValid() const; bool isOpen() const; void close(); + // SQL handling + QSqlQuery execPlainSql(const QString &sqlText); + QSqlQuery executeQuery(QSqlQuery &query, const QString &sqlText = QString()); + QSqlDatabase database() const; + + private: - bool executeQuery(QSqlQuery &query); + QSqlQuery processResult(int res, const QSqlQuery &query) const; QString getLastQuery(const QSqlQuery &query) const; void log(const QString &msg) const; diff --git a/src/serversdk/databasetable.cpp b/src/serversdk/databasetable.cpp index 736a65d..9e17f83 100644 --- a/src/serversdk/databasetable.cpp +++ b/src/serversdk/databasetable.cpp @@ -12,12 +12,11 @@ DatabaseTable::DatabaseTable(QObject *parent) : QObject(parent) /** Creates universal variant structure to hold key / value pairs */ -QVariantMap DatabaseTable::toVariantMap() +QVariantMap DatabaseTable::toVariantMap() const { QVariantMap variantMap; const QMetaObject *metaObj = this->metaObject(); - qDebug() << "properties: "; for (int i = metaObj->propertyOffset(); i < metaObj->propertyCount(); ++i) { QMetaProperty prop = metaObj->property(i); // Skip non USER so -> ( Q_PROPERTY( ...... USER false ) only @@ -35,26 +34,6 @@ QVariantMap DatabaseTable::toVariantMap() return variantMap; } -QString DatabaseTable::createTableSQL() const -{ - QString sql = QString("CREATE TABLE %1").arg(this->metaObject()->className()); - - QVariantMap variantMap; - - const QMetaObject *metaObj = this->metaObject(); - qDebug() << "properties: "; - for (int i = metaObj->propertyOffset(); i < metaObj->propertyCount(); ++i) { - QMetaProperty prop = metaObj->property(i); - // Skip non USER so -> ( Q_PROPERTY( ...... USER false ) only - if (!prop.isUser()) - continue; - - QString name = prop.name(); - - - } -} - diff --git a/src/serversdk/databasetable.h b/src/serversdk/databasetable.h index 37bc652..4bd8681 100644 --- a/src/serversdk/databasetable.h +++ b/src/serversdk/databasetable.h @@ -27,13 +27,8 @@ class DatabaseTable : public QObject TABLE_PROPERTY(QString, name, setName, QString()); public: explicit DatabaseTable(QObject *parent = nullptr); - QVariantMap toVariantMap(); - QString createTableSQL() const; + QVariantMap toVariantMap() const; - -signals: - -public slots: }; } // namespace serversdk diff --git a/src/serversdk/databaseutils.cpp b/src/serversdk/databaseutils.cpp index 0499e25..979d87a 100644 --- a/src/serversdk/databaseutils.cpp +++ b/src/serversdk/databaseutils.cpp @@ -1,8 +1,10 @@ #include "databaseutils.h" +#include "databasemanager.h" #include "logger.h" #include + namespace serversdk { /** @@ -26,21 +28,23 @@ namespace serversdk { * * */ -DatabaseUtils::DatabaseUtils(const QString type) - : mSqlType(type) +DatabaseUtils::DatabaseUtils(DatabaseManager *manager, const QString type) + : mDatabaseManager(manager), mSqlType(type) { - + Q_ASSERT(mDatabaseManager); } -QString DatabaseUtils::createTableSQL(const DatabaseTable *table, const QString tableName) const + +QString DatabaseUtils::createTableText(const DatabaseTable *table, const QString table_name) const { QString userData; - if (tableName.isEmpty()) + if (table_name.isEmpty()) { return QString(); + } // out: "CREATE TABLE colnod_subject ( " - QString sql = QString("CREATE TABLE %1 ( ").arg(tableName); + QString sql = QString("CREATE TABLE %1 ( ").arg(table_name); const QMetaObject *metaObj = table->metaObject(); int total = metaObj->propertyCount(); @@ -97,6 +101,45 @@ QString DatabaseUtils::createTableSQL(const DatabaseTable *table, const QString return sql; } +QSqlQuery DatabaseUtils::createTable(const DatabaseTable *table, const QString tableName) const +{ + // CREATE TABLE ... + QString sql = createTableText(table, tableName); + return mDatabaseManager->execPlainSql(sql); +} + + +QSqlQuery DatabaseUtils::insertIntoTable(const DatabaseTable *table, const QString table_name) const +{ + QString columns; + QString values; + + QVariantMap valueMap = table->toVariantMap(); + + + auto keys = valueMap.keys(); + for (auto key : keys) { + if (!columns.isEmpty()) { + columns += ", "; + values += ", "; + } + columns += key; + values += ":" + key; + } + + QSqlQuery query(mDatabaseManager->database()); + QString queryText = QString("INSERT OR IGNORE INTO %1 ( %2 ) VALUES ( %3 );").arg(table_name).arg(columns).arg(values); + query.prepare(queryText); + + for (auto key : keys ) { + auto value = valueMap.value(key); + query.bindValue(":"+key, value); + } + + QSqlQuery res = mDatabaseManager->executeQuery(query); + return res; +} + QString DatabaseUtils::sqlType() const { return mSqlType; @@ -107,6 +150,7 @@ void DatabaseUtils::setSqlType(const QString &sqlType) mSqlType = sqlType; } + QString DatabaseUtils::textSQLIteType(QVariant::Type type) const { switch (type) { diff --git a/src/serversdk/databaseutils.h b/src/serversdk/databaseutils.h index 03c6dfa..852e488 100644 --- a/src/serversdk/databaseutils.h +++ b/src/serversdk/databaseutils.h @@ -1,24 +1,38 @@ #pragma once -#include - #include "databasetable.h" +#include +#include + +class DatabaseUtilsTest; + namespace serversdk { + +class DatabaseManager; + class DatabaseUtils : public QObject { Q_OBJECT + friend class ::DatabaseUtilsTest; public: - explicit DatabaseUtils(const QString type = "SQLITE"); - QString createTableSQL(const DatabaseTable *table, const QString table_name) const; + explicit DatabaseUtils(DatabaseManager *manager = nullptr, const QString type = "SQLITE"); + + QSqlQuery createTable(const DatabaseTable *table, const QString table_name) const; + + QSqlQuery insertIntoTable(const DatabaseTable *table, const QString table_name) const; QString sqlType() const; void setSqlType(const QString &sqlType); private: + QString createTableText(const DatabaseTable *table, const QString table_name) const; + + QString textSQLIteType(QVariant::Type type) const; private: + DatabaseManager *mDatabaseManager = nullptr; QString mSqlType; }; diff --git a/src/serversdk/request.cpp b/src/serversdk/request.cpp index 9823581..d0b41ef 100644 --- a/src/serversdk/request.cpp +++ b/src/serversdk/request.cpp @@ -6,12 +6,15 @@ namespace serversdk { +Request::Request(QString type, QString url, QByteArray requestData) + : mType(type), mUrl(url), mRequestData(requestData) +{ +} Request::~Request() { } - QNetworkRequest Request::networkRequest() const { QNetworkRequest request(QUrl(this->mUrl)); @@ -39,6 +42,16 @@ void Request::appendData(const QByteArray &array) mResponseData += array; } +QString Request::type() const +{ + return mType; +} + +void Request::setType(const QString &type) +{ + mType = type; +} + QString Request::url() const { return mUrl; diff --git a/src/serversdk/request.h b/src/serversdk/request.h index ff4d51c..8fc48ff 100644 --- a/src/serversdk/request.h +++ b/src/serversdk/request.h @@ -2,6 +2,7 @@ #include #include +#include namespace serversdk { @@ -12,7 +13,7 @@ class Request : public QObject { public: Request() = default; ~Request() override; - Request(QString type, QString url, QByteArray responseData = QByteArray()); + Request(QString type, QString url, QByteArray requestData = QByteArray()); virtual QNetworkRequest networkRequest() const; // Data handling data @@ -23,6 +24,8 @@ public: // Attributes QString url() const; void setUrl(const QString &url); + QString type() const; + void setType(const QString &type); // Authorization QString userName() const; @@ -36,6 +39,10 @@ public: QString basicAuthorization() const; QString bearerAuthorization() const; + // Additional attributes + void logStartTime() { mStartTime = QDateTime::currentDateTime(); } + void logFinishTime() { mStartTime = QDateTime::currentDateTime(); } + private: // Data handling @@ -46,7 +53,7 @@ signals: void finished(); private: - QString mType; // POST, GET + QString mType = "GET"; // POST, GET QString mUrl; // Authorization @@ -57,6 +64,10 @@ private: // Data QByteArray mRequestData; QByteArray mResponseData; + + // Additional attributes + QDateTime mStartTime; + QDateTime mFinishTime; }; diff --git a/src/serversdk/requestmanager.cpp b/src/serversdk/requestmanager.cpp index 8814857..4fb4a70 100644 --- a/src/serversdk/requestmanager.cpp +++ b/src/serversdk/requestmanager.cpp @@ -21,14 +21,30 @@ RequestManager::RequestManager(QObject *parent) }); } - /** - * @brief Soap::processRequest - * @param soapRequest + * @brief Process request using QNetworkAccessManger + * + * @param Request */ void RequestManager::processRequest(const std::shared_ptr& request) { - QNetworkReply *reply = mNetworkAccessManager.post(request->networkRequest(), request->requestData()); + QNetworkReply *reply = nullptr; + request->logStartTime(); + + if (request->type() == "POST") { + reply = mNetworkAccessManager.post(request->networkRequest(), request->requestData()); + } else if (request->type() == "GET") { + if ( ! request->responseData().isEmpty()) { + qCWarning(sdknetwork) << "Response data is not empty, and you are trying to use get ( not sending any data)"; + } + reply = mNetworkAccessManager.get(request->networkRequest()); + } else if (request->type() == "PUT") { + reply = mNetworkAccessManager.put(request->networkRequest(), request->requestData()); + } else { + qCritical(sdknetwork) << "Using request type:" << request->type() << "is not implemented"; + return; + } + mRequestMap.insert(reply, request); connect(reply, &QNetworkReply::sslErrors, this, &RequestManager::sslErrors); @@ -36,6 +52,7 @@ void RequestManager::processRequest(const std::shared_ptr& request) connect(reply, &QNetworkReply::finished, this, [=]() { std::shared_ptr request = mRequestMap.value(reply); + request->logFinishTime(); mRequestMap.remove(reply); reply->deleteLater(); emit request->finished(); diff --git a/src/serversdk/soaprequest.cpp b/src/serversdk/soaprequest.cpp index f065c44..83d909a 100644 --- a/src/serversdk/soaprequest.cpp +++ b/src/serversdk/soaprequest.cpp @@ -5,6 +5,7 @@ namespace serversdk { SoapRequest::SoapRequest(QString action, QString endpoint, QByteArray data) : mSoapAction(action) { + setType("POST"); setUrl(endpoint); setRequestData(data); } diff --git a/test/auto/database/tst_databaseutils.cpp b/test/auto/database/tst_databaseutils.cpp index a5b6903..ca5a4ba 100644 --- a/test/auto/database/tst_databaseutils.cpp +++ b/test/auto/database/tst_databaseutils.cpp @@ -1,3 +1,4 @@ +#include "serversdk/databasemanager.h" #include "serversdk/databaseutils.h" #include "serversdk/databasetable.h" @@ -48,8 +49,9 @@ void DatabaseUtilsTest::createTable_test() { auto table = std::make_unique(); - serversdk::DatabaseUtils utils; - QString sql = utils.createTableSQL(table.get(), "subjects"); + auto db = std::make_unique(); + serversdk::DatabaseUtils utils(db.get()); + QString sql = utils.createTableText(table.get(), "subjects"); QString expected = "CREATE TABLE subjects ( " "id TEXT PRIMARY KEY, " diff --git a/test/auto/database/tst_sqlite.cpp b/test/auto/database/tst_sqlite.cpp index 25d3be0..ffbbaf8 100644 --- a/test/auto/database/tst_sqlite.cpp +++ b/test/auto/database/tst_sqlite.cpp @@ -1,8 +1,17 @@ #include #include "serversdk/databasemanager.h" +#include "serversdk/databaseutils.h" // add necessary includes here + +class Names : public serversdk::DatabaseTable { + Q_OBJECT + TABLE_PROPERTY(int, id, set_id, 0); + TABLE_PROPERTY(QString, name, set_name, 0); +}; + + class SqliteTest : public QObject { Q_OBJECT @@ -13,6 +22,7 @@ public: private slots: void createDb_test(); + void createTable_test(); }; @@ -52,6 +62,47 @@ void SqliteTest::createDb_test() Q_ASSERT(!QFileInfo::exists(dbpath)); } +void SqliteTest::createTable_test() +{ + // Prepare temporary path for database + QTemporaryDir dir; + QString dbpath = dir.path() + "/testdb.sqlite"; + serversdk::DatabaseManager db; + db.openSQLite(dbpath); + Q_ASSERT(db.isOpen()); + + + + // Not correct way + auto names = std::make_unique(); + + + // Creating table + serversdk::DatabaseUtils utils(&db); + QSqlQuery query = utils.createTable(names.get(), "names"); +// Q_ASSERT(query.isValid()); + + // Inserting into table + names->set_id(2); + names->set_name("Testname"); + + utils.insertIntoTable(names.get(), "names"); + QSqlQuery insertQuery = utils.insertIntoTable(names.get(), "names"); + //Q_ASSERT(insertQuery.isValid()); + + + + // Select from table + QSqlQuery selectSQL("SELECT * FROM names"); +// Q_ASSERT(db.executeQuery(selectSQL)); + while (selectSQL.next()) { + QString value = selectSQL.value(1).toString(); + qDebug() << "value is" << value; + } + + //db.create +} + QTEST_APPLESS_MAIN(SqliteTest) #include "tst_sqlite.moc" diff --git a/test/auto/tst_soap/tst_soaptest.cpp b/test/auto/tst_soap/tst_soaptest.cpp index d87b661..5a80510 100644 --- a/test/auto/tst_soap/tst_soaptest.cpp +++ b/test/auto/tst_soap/tst_soaptest.cpp @@ -46,15 +46,15 @@ void SoapTest::public_soap_xml() { QString soapAction = "blz:getBank"; QString endpoint = "http://www.thomas-bayer.com/axis2/services/BLZService"; - QString xml = QString("" \ - "" \ - " " \ - " " \ - " %1" \ - " " \ - "" \ + QString xml = QString("" + "" + " " + " " + " %1" + " " + "" "").arg("10020200"); QByteArray xmlRequest = xml.toUtf8();