added default implementation for the DBObject::prepareSaveQuery method.

This commit is contained in:
Andrei Yankovich 2020-10-24 15:25:40 +03:00
parent 8fb7002e2e
commit 46a08a8223
7 changed files with 141 additions and 32 deletions

View File

@ -14,7 +14,7 @@ endif()
find_package(Qt5 COMPONENTS Core Test REQUIRED)
if(NOT DEFINED HEART_BUILD_LVL)
set(HEART_BUILD_LVL 2)
set(HEART_BUILD_LVL 1)
endif()
include(QuasarAppLib/CMake/ccache.cmake)

View File

@ -15,6 +15,7 @@
#include <QSqlRecord>
#include <QVariantMap>
#include <QSharedPointer>
#include <quasarapp.h>
namespace QH {
namespace PKG {
@ -55,6 +56,65 @@ bool DBObject::fromSqlRecord(const QSqlRecord &q) {
return false;
}
// To-Do need to tested
PrepareResult DBObject::prepareSaveQuery(QSqlQuery &q) const {
DBVariantMap map = variantMap();
if (!map.size()) {
QuasarAppUtils::Params::log("The variantMap method return an empty map.",
QuasarAppUtils::Error);
return PrepareResult::Fail;
}
QString queryString = "INSERT INTO %0(%1) VALUES (%3) "
"ON CONFLICT(id) DO UPDATE SET %2";
queryString = queryString.arg(tableName());
QString tableInsertHeader = "id, ";
QString tableInsertValues = "'" + getId().toBase64() + "', ";
QString tableUpdateValues = "";
for (auto it = map.begin(); it != map.end(); ++it) {
bool fInsertUpdate = it.value().type == MemberType::InsertUpdate;
tableInsertHeader += it.key();
tableInsertValues += ":" + it.key();
if (fInsertUpdate) {
tableUpdateValues += it.key() + "=:" + it.key();
}
if (it + 1 != map.end()) {
tableInsertHeader += ", ";
tableInsertValues += ", ";
if (fInsertUpdate) {
tableUpdateValues += ", ";
}
}
}
queryString = queryString.arg(tableInsertHeader);
queryString = queryString.arg(tableUpdateValues);
queryString = queryString.arg(tableInsertValues);
if (q.prepare(queryString)) {
for (auto it = map.begin(); it != map.end(); ++it) {
q.bindValue(":" + it.key(), it.value().value);
}
return PrepareResult::Success;
}
return PrepareResult::Fail;
}
bool DBObject::isCached() const {
return true;
}
@ -182,5 +242,10 @@ void DBObject::clear() {
setId({});
}
DBVariant::DBVariant(const QVariant &value, MemberType type) {
this->value = value;
this->type = type;
}
}
}

View File

@ -32,6 +32,34 @@ enum class PrepareResult {
Disabled,
};
/**
* @brief The MemberType enum. This enum contains types of members DBObjects classes.
* for more information see the DBObject::variantMap method.
*/
enum class MemberType {
//// Member of DBObjects will be inserted but not updated.
InsertOnly,
//// Member of DBObjects will be inserted and updated.
InsertUpdate
};
/**
* @brief The DBVariant struct contains QVariant value of the DBObjects member and it type.
*/
struct DBVariant {
DBVariant(const QVariant& value, MemberType type);
QVariant value;
MemberType type;
};
/**
* @brief DBVariantMap this is Map with key and valu with data type.
* \code{cpp}
* QMap<QString key, {QVariant value, MemberType type}>;
* \endcode
*/
typedef QMap<QString, DBVariant> DBVariantMap;
/**
* @brief The DBObject class- main class for work with data base.
*/
@ -89,6 +117,8 @@ public:
* If id is empty this implementation use data from altarnativeKey method. See DBObject::altarnativeKey fr more information.
* @param q This is query object.
* @return PrepareResult object with information about prepare results.
*
* @note If you want disable this mehod just override it and return the PrepareResult::Disabled value.
*/
virtual PrepareResult prepareSelectQuery(QSqlQuery& q) const;
@ -118,6 +148,15 @@ public:
* @brief prepareSaveQuery This method should be prepare a query for save object into database.
* You need to create a own save sql query for this object into database.
* Override this metod for save item into database.
* By Default This method prepare a slect query using the data that returned from the variantMap method.
*
* Default save query have a next template:
* \code{sql}
* INSERT INTO %0(%1) VALUES (%3)
* ON CONFLICT(id) DO UPDATE SET %2;
* \endcode
*
* For more information see the DBObject::variantMap method.
* @note befor creating a own object you need to create a own database structure.
* @param q This is query object.
* @return PrepareResult object with information about prepare results.
@ -151,8 +190,10 @@ public:
return PrepareResult::Fail;
}
* \endcode
*
* @note If you want disable this mehod just override it and return the PrepareResult::Disabled value.
*/
virtual PrepareResult prepareSaveQuery(QSqlQuery& q) const = 0 ;
virtual PrepareResult prepareSaveQuery(QSqlQuery& q) const;
/**
* @brief prepareRemoveQuery This method method should be prepare a query for remove this object from a database.
@ -161,6 +202,8 @@ public:
* If id is empty the default implementation use data from altarnativeKey method.
* @param q This is query object.
* @return PrepareResult object with information about prepare results.
*
* @note If you want disable this mehod just override it and return the PrepareResult::Disabled value.
*/
virtual PrepareResult prepareRemoveQuery(QSqlQuery& q) const;
@ -173,6 +216,7 @@ public:
* but contains common characteristics of several objects)
* @return True if item in cache.
* Default implementation retun true only
*
*/
virtual bool isCached() const;
@ -240,6 +284,24 @@ protected:
bool init() override;
/**
* @brief variantMap This method should be create a DBVariantMap implementation of this database object.
* Example of retuen value:
*
* \code{cpp}
* return {{"name", {"Andrei", MemberType::InsertOnly}},
* {"age", {26, MemberType::InsertUpdate}},
* {"extraData", {QByteArray{}, MemberType::InsertUpdate}}};
* \endcode
*
* @note This method using for create a default sql save request
* see the DBObject::prepareSaveQuery method for more information.
* @return the QVariantMap implementation of this database object.
*
* @note If you want disable this functionality then override this method and return an empty map. But do not forget override the DBObject::prepareSelectQuery method because its default implementation return error message.
*/
virtual DBVariantMap variantMap() const = 0;
private:
QString getWhereBlock() const;

View File

@ -162,6 +162,10 @@ BaseId MemberPermisionObject::generateId() const {
return _key.hash();
}
DBVariantMap MemberPermisionObject::variantMap() const {
return {};
}
PermisionData MemberPermisionObject::key() const {
return _key;
}

View File

@ -68,12 +68,12 @@ protected:
QDataStream &fromStream(QDataStream &stream) override;
QDataStream &toStream(QDataStream &stream) const override;
BaseId generateId() const override;
DBVariantMap variantMap() const override;
private:
Permission _permisions;
PermisionData _key;
};
}
}

View File

@ -35,34 +35,6 @@ DBObject *NetworkMember::createDBObject() const {
return create<NetworkMember>();
}
PrepareResult NetworkMember::prepareSaveQuery(QSqlQuery &q) const {
QString queryString = "INSERT INTO %0(%1) VALUES (%3) "
"ON CONFLICT(id) DO UPDATE SET %2";
queryString = queryString.arg(tableName());
queryString = queryString.arg("id, authenticationData, trust");
queryString = queryString.arg("authenticationData=:AuthenticationData, "
"trust=" + QString::number(_trust));
QString values;
values += "'" + getId().toBase64() + "', ";
values += ":AuthenticationData, ";
values += QString::number(_trust);
queryString = queryString.arg(values);
if (q.prepare(queryString)) {
q.bindValue(":AuthenticationData", authenticationData());
return PrepareResult::Success;
}
QuasarAppUtils::Params::log("Query:" + queryString,
QuasarAppUtils::Error);
return PrepareResult::Fail;
}
bool NetworkMember::fromSqlRecord(const QSqlRecord &q) {
if (!DBObject::fromSqlRecord(q)) {
return false;
@ -107,6 +79,11 @@ BaseId NetworkMember::generateId() const {
return QCryptographicHash::hash(authenticationData(), QCryptographicHash::Sha256);
}
DBVariantMap NetworkMember::variantMap() const {
return {{"authenticationData", {_authenticationData, MemberType::InsertOnly}},
{"trust", {_trust, MemberType::InsertUpdate}}};
}
int NetworkMember::trust() const {
return _trust;
}

View File

@ -28,7 +28,6 @@ public:
// DBObject interface
DBObject *createDBObject() const override;
PrepareResult prepareSaveQuery(QSqlQuery &q) const override;
bool fromSqlRecord(const QSqlRecord &q) override;
/**
@ -75,10 +74,12 @@ protected:
QDataStream &fromStream(QDataStream &stream) override;
QDataStream &toStream(QDataStream &stream) const override;
BaseId generateId() const override;
DBVariantMap variantMap() const override;
private:
QByteArray _authenticationData;
int _trust;
};
}
}