Revision f12670e9
Von Christian Ehringfeld vor etwa 10 Jahren hinzugefügt
| EntityManager.pro | ||
|---|---|---|
|
|
||
|
#QMAKE_CXXFLAGS += -Winit-self
|
||
|
CONFIG(release, debug|release):DEFINES += QT_NO_DEBUG_OUTPUT
|
||
|
|
||
|
DISTFILES += \
|
||
|
README.md \
|
||
|
LICENSE \
|
||
|
Doxyfile
|
||
| README.md | ||
|---|---|---|
|
Tutorial(wip):
|
||
|
https://synlos.net/redmine/projects/entitymanager/wiki/Tutorial
|
||
|
|
||
|
### Minimum requirements
|
||
|
|
||
|
- GCC 4.8 or clang 3.3
|
||
|
- >= Qt 5.4
|
||
|
- any platform supported by Qt
|
||
|
|
||
|
## German
|
||
|
Mit dem CuteEntityManager ist es möglich, Entities zu persistieren, zu
|
||
| samples/simple/main.cpp | ||
|---|---|---|
|
"Müsli"));
|
||
|
auto ep = a.objectCast<CuteEntityManager::Entity>();
|
||
|
qDebug() << e->create(ep, true, true);
|
||
|
int i = 0;
|
||
|
|
||
|
while(false); {
|
||
|
i++;
|
||
|
}
|
||
|
qDebug() << i;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
| src/database.cpp | ||
|---|---|---|
|
using namespace CuteEntityManager;
|
||
|
|
||
|
Database::Database(QSqlDatabase database, bool loggerActivated, bool logQueries,
|
||
|
bool logErrors) {
|
||
|
bool logErrors, MsgType type) {
|
||
|
this->database = database;
|
||
|
this->init();
|
||
|
this->connectionName = this->database.connectionName();
|
||
|
this->initLogger(loggerActivated, logQueries, logErrors);
|
||
|
this->initLogger(loggerActivated, logQueries, logErrors, type);
|
||
|
}
|
||
|
|
||
|
Database::Database(QString databaseType, QString connectionName,
|
||
|
QString hostname,
|
||
|
QString databasename,
|
||
|
QString username, QString password, qint64 port, bool loggerActivated,
|
||
|
bool logQueries, bool logErrors, QString databaseOptions) {
|
||
|
bool logQueries, bool logErrors, QString databaseOptions, MsgType type) {
|
||
|
this->database = QSqlDatabase::addDatabase(databaseType, connectionName);
|
||
|
this->connectionName = connectionName;
|
||
|
if (!hostname.isEmpty()) {
|
||
| ... | ... | |
|
this->database.setConnectOptions(databaseOptions);
|
||
|
}
|
||
|
this->init();
|
||
|
this->initLogger(loggerActivated, logQueries, logErrors);
|
||
|
this->initLogger(loggerActivated, logQueries, logErrors, type);
|
||
|
}
|
||
|
|
||
|
void Database::init() {
|
||
| ... | ... | |
|
QSqlDriver::Transactions);
|
||
|
}
|
||
|
|
||
|
void Database::initLogger(bool activated, bool logQueries, bool logErrors) {
|
||
|
void Database::initLogger(bool activated, bool logQueries, bool logErrors,
|
||
|
MsgType type) {
|
||
|
this->logQueries = logQueries;
|
||
|
this->logErrors = logErrors;
|
||
|
if (activated) {
|
||
|
this->logger = new Logger(QDir::currentPath() + "/db" + this->connectionName +
|
||
|
".log");
|
||
|
".log", type);
|
||
|
}
|
||
|
}
|
||
|
|
||
| src/database.h | ||
|---|---|---|
|
#include "enums/databasetype.h"
|
||
|
#include "logger.h"
|
||
|
namespace CuteEntityManager {
|
||
|
#ifdef QT_DEBUG
|
||
|
#define DEFAULTMSGTYPE MsgType::DEBUG
|
||
|
#else
|
||
|
#define DEFAULTMSGTYPE MsgType::CRITICAL
|
||
|
#endif
|
||
|
class Database {
|
||
|
private:
|
||
|
QSqlDatabase database;
|
||
| ... | ... | |
|
bool supportTransactions;
|
||
|
Logger *logger = nullptr;
|
||
|
void init();
|
||
|
void initLogger(bool activated, bool logQueries, bool logErrors);
|
||
|
void initLogger(bool activated, bool logQueries, bool logErrors, MsgType type);
|
||
|
bool logQueries;
|
||
|
bool logErrors;
|
||
|
|
||
|
public:
|
||
|
Database(QSqlDatabase database, bool loggerActivated = true,
|
||
|
bool logQueries = false, bool logErrors = true);
|
||
|
bool logQueries = false, bool logErrors = true,MsgType type= DEFAULTMSGTYPE);
|
||
|
~Database();
|
||
|
Database(QString databaseType, QString connectionName = QString(""),
|
||
|
QString hostname = QString(""),
|
||
|
QString databasename = QString("") ,
|
||
|
QString username = QString(""), QString password = QString(""),
|
||
|
qint64 port = 0, bool loggerActivated = true, bool logQueries = false,
|
||
|
bool logErrors = true, QString databaseOptions = "");
|
||
|
bool logErrors = true, QString databaseOptions = "",MsgType type= DEFAULTMSGTYPE);
|
||
|
QSqlDatabase getDatabase();
|
||
|
QString getConnectionName();
|
||
|
QSqlQuery getQuery();
|
||
| src/entityinspector.cpp | ||
|---|---|---|
|
#include <QDateTime>
|
||
|
using namespace CuteEntityManager;
|
||
|
|
||
|
EntityInspector::EntityInspector() {
|
||
|
this->initLogger();
|
||
|
EntityInspector::EntityInspector(const MsgType msgType) {
|
||
|
this->initLogger(msgType);
|
||
|
}
|
||
|
|
||
|
EntityInspector::~EntityInspector() {
|
||
| ... | ... | |
|
QStringList classes = EntityInstanceFactory::getRegisteredClasses();
|
||
|
QString msg = QDateTime::currentDateTime().toString(Qt::ISODate) +
|
||
|
" - Start checking entities\n";
|
||
|
qInfo() << msg;
|
||
|
this->logger->logMsg(msg);
|
||
|
this->logger->logMsg(msg, MsgType::INFO);
|
||
|
bool ok = true;
|
||
|
for (int i = 0; i < classes.size(); ++i) {
|
||
|
bool r = this->checkEntity(classes.at(i));
|
||
| ... | ... | |
|
msg += classes.at(i) + " is erroneous!";
|
||
|
msg += "\n";
|
||
|
msg += "###############################\n";
|
||
|
qWarning() << msg;
|
||
|
this->logger->logMsg(msg, MsgType::CRITICAL);
|
||
|
ok = false;
|
||
|
} else {
|
||
|
msg = "Entity class " + classes.at(i) + " seems ok.\n";
|
||
|
qInfo() << msg;
|
||
|
this->logger->logMsg(msg, MsgType::INFO);
|
||
|
}
|
||
|
this->logger->logMsg(msg);
|
||
|
}
|
||
|
msg = QDateTime::currentDateTime().toString(Qt::ISODate) +
|
||
|
" - End checking entities\n";
|
||
|
qInfo() << msg;
|
||
|
this->logger->logMsg(msg);
|
||
|
this->logger->logMsg(msg, MsgType::INFO);
|
||
|
return ok;
|
||
|
}
|
||
|
|
||
|
bool EntityInspector::checkEntity(QString name) {
|
||
|
QString msg = "--------------------\n";
|
||
|
msg += "Checking " + name + " now.\n";
|
||
|
qDebug() << msg;
|
||
|
auto entity = this->instantiateEntity(name, msg);
|
||
|
this->logger->logMsg(msg, MsgType::DEBUG);
|
||
|
auto entity = this->instantiateEntity(name);
|
||
|
bool ok = true;
|
||
|
if (entity) {
|
||
|
bool relations = this->verifyRelations(entity, msg);
|
||
|
bool pk = this->checkPrimaryKey(entity, msg);
|
||
|
this->verifyBlobAttributes(entity, msg);
|
||
|
this->verifyTransientAttributes(entity, msg);
|
||
|
bool relations = this->verifyRelations(entity);
|
||
|
bool pk = this->checkPrimaryKey(entity);
|
||
|
this->verifyBlobAttributes(entity);
|
||
|
this->verifyTransientAttributes(entity);
|
||
|
ok = pk && relations;
|
||
|
delete entity;
|
||
|
entity = nullptr;
|
||
|
}
|
||
|
this->logger->logMsg(msg);
|
||
|
return ok;
|
||
|
}
|
||
|
|
||
|
Entity *EntityInspector::instantiateEntity(const QString name, QString &msg) {
|
||
|
Entity *EntityInspector::instantiateEntity(const QString name) {
|
||
|
auto entity = EntityInstanceFactory::createInstance(name);
|
||
|
QString internMsg = "";
|
||
|
QString msg = "";
|
||
|
if (entity) {
|
||
|
internMsg = name + " is instantiable.";
|
||
|
qInfo() << internMsg;
|
||
|
msg = name + " is instantiable.";
|
||
|
this->logger->logMsg(msg, MsgType::INFO);
|
||
|
} else {
|
||
|
internMsg = name + " is NOT instantiable!";
|
||
|
qCritical() << internMsg;
|
||
|
msg = name + " is NOT instantiable!";
|
||
|
this->logger->logMsg(msg, MsgType::CRITICAL);
|
||
|
}
|
||
|
msg += internMsg + "\n";
|
||
|
return entity;
|
||
|
}
|
||
|
|
||
|
void EntityInspector::checkMetaProperties(QHash<QString, QMetaProperty>
|
||
|
&metaProperties, QString &msg, bool &ok, QHash<QString, Relation> &relations) {
|
||
|
&metaProperties, bool &ok, QHash<QString, Relation> &relations) {
|
||
|
QString msg = "";
|
||
|
for (auto i = metaProperties.constBegin(); i != metaProperties.constEnd();
|
||
|
++i) {
|
||
|
QString typeName = QString(i.value().typeName());
|
||
| ... | ... | |
|
msg += i.key() + " must use QSharedPointer.\n";
|
||
|
}
|
||
|
}
|
||
|
this->logger->logMsg(msg, MsgType::CRITICAL);
|
||
|
}
|
||
|
|
||
|
bool EntityInspector::verifyRelations(Entity *&entity, QString &msg) {
|
||
|
bool EntityInspector::verifyRelations(Entity *&entity) {
|
||
|
bool ok = true;
|
||
|
auto metaProperties = EntityHelper::getMetaProperties(entity);
|
||
|
auto relations = entity->getRelations();
|
||
|
QString iMsg = "";
|
||
|
this->checkMetaProperties(metaProperties, iMsg, ok, relations);
|
||
|
QString msg = "";
|
||
|
this->checkMetaProperties(metaProperties, ok, relations);
|
||
|
for (auto i = relations.constBegin(); i != relations.constEnd(); ++i) {
|
||
|
this->checkRelationTypos(i.key(), i.value(), iMsg, ok);
|
||
|
this->checkRelationTypos(i.key(), i.value(), ok);
|
||
|
if (!metaProperties.contains(i.key())) {
|
||
|
iMsg += "For relation " + i.key() + " no property exists!";
|
||
|
msg += "For relation " + i.key() + " no property exists!";
|
||
|
ok = false;
|
||
|
} else {
|
||
|
auto metaProperty = metaProperties.value(i.key());
|
||
|
if (!QString(metaProperty.typeName()).contains("QSharedPointer")) {
|
||
|
iMsg += "Property " + QString(metaProperty.name()) +
|
||
|
" must be a type like QList<QSharedPointer<T>> or simply QSharedPointer<T>.";
|
||
|
msg += "Property " + QString(metaProperty.name()) +
|
||
|
" must be a type like QList<QSharedPointer<T>> or simply QSharedPointer<T>.";
|
||
|
} else {
|
||
|
auto var = metaProperty.read(entity);
|
||
|
bool rel = this->checkRelation(var, i.value(), msg, metaProperty);
|
||
|
bool rel = this->checkRelation(var, i.value(), metaProperty);
|
||
|
if (!rel) {
|
||
|
ok = false;
|
||
|
} else {
|
||
|
this->checkRelationMappings(metaProperty, i.value(), msg, ok);
|
||
|
this->checkRelationMappings(metaProperty, i.value(), ok);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (!iMsg.isEmpty()) {
|
||
|
qCritical() << iMsg;
|
||
|
msg += iMsg;
|
||
|
if (!msg.isEmpty()) {
|
||
|
this->logger->logMsg(msg, MsgType::CRITICAL);
|
||
|
}
|
||
|
return ok;
|
||
|
}
|
||
|
|
||
|
void EntityInspector::verifyTransientAttributes(Entity *&entity, QString &msg) {
|
||
|
void EntityInspector::verifyTransientAttributes(Entity *&entity) {
|
||
|
auto metaProperties = EntityHelper::getMetaProperties(entity);
|
||
|
auto relations = entity->getRelations();
|
||
|
auto transientAttributes = entity->getTransientAttributes();
|
||
|
auto blobs = entity->getBLOBColumns();
|
||
|
QString iMsg = "";
|
||
|
QString msg = "";
|
||
|
for (int i = 0; i < transientAttributes.size(); ++i) {
|
||
|
QString attr = transientAttributes.at(i);
|
||
|
if (!metaProperties.contains(attr)) {
|
||
|
iMsg += "No transient attribute called " + attr + ".\n";
|
||
|
msg += "No transient attribute called " + attr + ".\n";
|
||
|
}
|
||
|
if (relations.contains(transientAttributes.at(i))) {
|
||
|
iMsg += "A transient attribute should not be declared as relation: " +
|
||
|
attr + ".\n";
|
||
|
msg += "A transient attribute should not be declared as relation: " +
|
||
|
attr + ".\n";
|
||
|
}
|
||
|
if (blobs.contains(attr)) {
|
||
|
iMsg += "A transient attribute should not be declared as blob column: " + attr +
|
||
|
".\n";
|
||
|
msg += "A transient attribute should not be declared as blob column: " + attr +
|
||
|
".\n";
|
||
|
}
|
||
|
}
|
||
|
if (!iMsg.isEmpty()) {
|
||
|
qWarning() << iMsg;
|
||
|
msg += iMsg;
|
||
|
if (!msg.isEmpty()) {
|
||
|
this->logger->logMsg(msg, MsgType::WARNING);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool EntityInspector::checkRelation(const QVariant &entity,
|
||
|
const Relation &r, QString &msg, const QMetaProperty &property) const {
|
||
|
QString iMsg = "";
|
||
|
const Relation &r, const QMetaProperty &property) const {
|
||
|
QString msg = "";
|
||
|
bool many = r.getType() == RelationType::MANY_TO_MANY
|
||
|
|| r.getType() == RelationType::ONE_TO_MANY;
|
||
|
QString propType = QString(property.type());
|
||
|
bool canConvertList = entity.canConvert<QVariantList>() || (many
|
||
|
&& propType.contains("QList"));
|
||
|
if ((many && !canConvertList)) {
|
||
|
iMsg = "Relation type of " + r.getPropertyName() +
|
||
|
" must be MANY_TO_MANY or ONE_TO_MANY.\n";
|
||
|
iMsg += "Or you can change the attribute type to QSharedPointer<T>.\n";
|
||
|
msg = "Relation type of " + r.getPropertyName() +
|
||
|
" must be MANY_TO_MANY or ONE_TO_MANY.\n";
|
||
|
msg += "Or you can change the attribute type to QSharedPointer<T>.\n";
|
||
|
} else if ((!many && canConvertList)) {
|
||
|
iMsg = "Relation type of " + r.getPropertyName() +
|
||
|
" must be MANY_TO_ONE or ONE_TO_ONE.\n";
|
||
|
iMsg += "Or you can change the attribute type to QList<QSharedPointer<T>>.\n";
|
||
|
msg = "Relation type of " + r.getPropertyName() +
|
||
|
" must be MANY_TO_ONE or ONE_TO_ONE.\n";
|
||
|
msg += "Or you can change the attribute type to QList<QSharedPointer<T>>.\n";
|
||
|
}
|
||
|
if (many && r.getType() == RelationType::ONE_TO_MANY
|
||
|
&& r.getMappedBy().isEmpty()) {
|
||
|
iMsg += "Relation " + r.getPropertyName() +
|
||
|
" needs a mappedBy attribute of the foreign class.\n";
|
||
|
msg += "Relation " + r.getPropertyName() +
|
||
|
" needs a mappedBy attribute of the foreign class.\n";
|
||
|
}
|
||
|
if (!iMsg.isEmpty()) {
|
||
|
msg += iMsg;
|
||
|
qCritical() << iMsg;
|
||
|
if (!msg.isEmpty()) {
|
||
|
this->logger->logMsg(msg, MsgType::CRITICAL);
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void EntityInspector::checkRelationTypos(const QString &name, const Relation &r,
|
||
|
QString &msg, bool &ok) {
|
||
|
bool &ok) {
|
||
|
if (name != r.getPropertyName()) {
|
||
|
ok = false;
|
||
|
msg += "Relation " + name + " has a typo.\n";
|
||
|
msg += "Name " + name + "and relation name " + r.getPropertyName() +
|
||
|
" are not equal.\n";
|
||
|
this->logger->logMsg("Relation " + name + " has a typo.\n" + "Name " + name +
|
||
|
"and relation name " + r.getPropertyName() +
|
||
|
" are not equal.\n", MsgType::WARNING);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void EntityInspector::checkRelationMappings(QMetaProperty &property,
|
||
|
const Relation &r, QString &msg, bool &ok) {
|
||
|
const Relation &r, bool &ok) {
|
||
|
QString foreignEntityName = EntityInstanceFactory::extractEntityType(
|
||
|
property.typeName());
|
||
|
auto foreignInstance = EntityInstanceFactory::createInstance(foreignEntityName);
|
||
| ... | ... | |
|
}
|
||
|
if (r.getMappedBy().isEmpty()) {
|
||
|
if (foundMappedBy == 0) {
|
||
|
msg += "Optional: The relation " + r.getPropertyName() +
|
||
|
" is not mapped in foreign class " + foreignEntityName +
|
||
|
". You could map it.\n";
|
||
|
this->logger->logMsg("Optional: The relation " + r.getPropertyName() +
|
||
|
" is not mapped in foreign class " + foreignEntityName +
|
||
|
". You could map it.\n", MsgType::INFO);
|
||
|
} else if (foundMappedBy > 1) {
|
||
|
msg += "The relation " + r.getPropertyName() + " is mapped several times (" +
|
||
|
QString::number(foundMappedBy) + ") by foreign class " + foreignEntityName +
|
||
|
". You should map it only once!\n";
|
||
|
this->logger->logMsg("The relation " + r.getPropertyName() +
|
||
|
" is mapped several times (" +
|
||
|
QString::number(foundMappedBy) + ") by foreign class " + foreignEntityName +
|
||
|
". You should map it only once!\n", MsgType::WARNING);
|
||
|
ok = false;
|
||
|
}
|
||
|
} else if (!foundForeignMappedRelation) {
|
||
|
msg += "Relation " + r.getPropertyName() + " with mappedBy attribute " +
|
||
|
r.getMappedBy() + " has no mapped relation in " + foreignEntityName +
|
||
|
" class!\n";
|
||
|
this->logger->logMsg("Relation " + r.getPropertyName() +
|
||
|
" with mappedBy attribute " +
|
||
|
r.getMappedBy() + " has no mapped relation in " + foreignEntityName +
|
||
|
" class!\n", MsgType::CRITICAL);
|
||
|
ok = false;
|
||
|
}
|
||
|
delete foreignInstance;
|
||
|
foreignInstance = nullptr;
|
||
|
} else {
|
||
|
msg += "Can't create object for property/relation " + r.getPropertyName() +
|
||
|
"!\n";
|
||
|
msg += "Classname: " + foreignEntityName + "\n";
|
||
|
msg += "Is the class registered?\n";
|
||
|
this->logger->logMsg("Can't create object for property/relation " +
|
||
|
r.getPropertyName() +
|
||
|
"\n" + "Classname: " + foreignEntityName + "\n" + "Is the class registered?\n",
|
||
|
MsgType::CRITICAL);
|
||
|
ok = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool EntityInspector::checkPrimaryKey(Entity *&entity, QString &msg) {
|
||
|
bool EntityInspector::checkPrimaryKey(Entity *&entity) {
|
||
|
QString pk = entity->getPrimaryKey();
|
||
|
auto metaprops = EntityHelper::getMetaProperties(entity);
|
||
|
QString iMsg = "";
|
||
|
bool ok = true;
|
||
|
if (!metaprops.contains(pk)) {
|
||
|
ok = false;
|
||
|
iMsg = "Property " + pk +
|
||
|
" for primary key not exists. Please check your getPrimaryKey() method!\n";
|
||
|
this->logger->logMsg("Property " + pk +
|
||
|
" for primary key not exists. Please check your getPrimaryKey() method!\n",
|
||
|
MsgType::CRITICAL);
|
||
|
}
|
||
|
qCritical() << iMsg;
|
||
|
msg += iMsg;
|
||
|
return ok;
|
||
|
}
|
||
|
|
||
|
void EntityInspector::verifyBlobAttributes(Entity *&entity, QString &msg) {
|
||
|
void EntityInspector::verifyBlobAttributes(Entity *&entity) {
|
||
|
auto metaprops = EntityHelper::getMetaProperties(entity);
|
||
|
auto blobs = entity->getBLOBColumns();
|
||
|
QString iMsg = "";
|
||
|
QString msg = "";
|
||
|
for (int i = 0; i < blobs.size(); ++i) {
|
||
|
QString name = blobs.at(i);
|
||
|
if (!metaprops.contains(name)) {
|
||
|
iMsg += "For blob column " + name + " no property exists.\n";
|
||
|
msg += "For blob column " + name + " no property exists.\n";
|
||
|
}
|
||
|
}
|
||
|
qWarning() << iMsg;
|
||
|
msg += iMsg;
|
||
|
this->logger->logMsg(msg, MsgType::WARNING);
|
||
|
}
|
||
|
|
||
|
void EntityInspector::initLogger() {
|
||
|
this->logger = new Logger(QDir::currentPath() + "/entity.log");
|
||
|
void EntityInspector::initLogger(const MsgType msgType) {
|
||
|
this->logger = new Logger(QDir::currentPath() + "/entity.log", msgType);
|
||
|
}
|
||
| src/entityinspector.h | ||
|---|---|---|
|
*/
|
||
|
class EntityInspector {
|
||
|
public:
|
||
|
EntityInspector();
|
||
|
EntityInspector(const MsgType msgType = MsgType::DEBUG);
|
||
|
~EntityInspector();
|
||
|
bool checkRegisteredEntities();
|
||
|
bool checkEntity(QString name);
|
||
|
|
||
|
private:
|
||
|
Entity *instantiateEntity(const QString name, QString &msg);
|
||
|
bool verifyRelations(Entity *&entity, QString &msg);
|
||
|
void verifyTransientAttributes(Entity *&entity, QString &msg);
|
||
|
bool checkRelation(const QVariant &entity, const Relation &r, QString &msg,
|
||
|
Entity *instantiateEntity(const QString name);
|
||
|
bool verifyRelations(Entity *&entity);
|
||
|
void verifyTransientAttributes(Entity *&entity);
|
||
|
bool checkRelation(const QVariant &entity, const Relation &r,
|
||
|
const QMetaProperty &property) const;
|
||
|
void checkRelationTypos(const QString &name, const Relation &r, QString &msg,
|
||
|
void checkRelationTypos(const QString &name, const Relation &r,
|
||
|
bool &ok);
|
||
|
void checkRelationMappings(QMetaProperty &property, const Relation &r,
|
||
|
QString &msg, bool &ok);
|
||
|
bool checkPrimaryKey(Entity *&entity, QString &msg);
|
||
|
void verifyBlobAttributes(Entity *&entity, QString &msg);
|
||
|
bool &ok);
|
||
|
bool checkPrimaryKey(Entity *&entity);
|
||
|
void verifyBlobAttributes(Entity *&entity);
|
||
|
void checkMetaProperties(QHash<QString, QMetaProperty> &metaProperties,
|
||
|
QString &msg, bool &ok, QHash<QString, Relation> &relations);
|
||
|
void initLogger();
|
||
|
bool &ok, QHash<QString, Relation> &relations);
|
||
|
void initLogger(const MsgType msgType);
|
||
|
Logger *logger = nullptr;
|
||
|
};
|
||
|
}
|
||
| src/entitymanager.cpp | ||
|---|---|---|
|
ignoreHasChanged, validate, relationsIgnoreHasChanged);
|
||
|
}
|
||
|
|
||
|
EntityManager::EntityManager(QSqlDatabase database,
|
||
|
bool logQueries, const bool inspectEntities) : QObject() {
|
||
|
auto db = new Database(database, true, logQueries);
|
||
|
EntityManager::EntityManager(QSqlDatabase database, bool logQueries,
|
||
|
const bool inspectEntities,
|
||
|
MsgType logActions) : QObject() {
|
||
|
auto db = new Database(database, true, logQueries, true, logActions);
|
||
|
this->db = QSharedPointer<Database>(db);
|
||
|
this->init(inspectEntities);
|
||
|
this->init(inspectEntities,logActions);
|
||
|
}
|
||
|
|
||
|
EntityManager::EntityManager(const QString &databaseType, QString databasename ,
|
||
|
QString hostname, QString username, QString password, QString port,
|
||
|
bool logQueries, QString databaseOptions,
|
||
|
const bool inspectEntities) : QObject() {
|
||
|
auto db = new Database(databaseType, this->createConnection(), hostname,
|
||
|
databasename, username,
|
||
|
password,
|
||
|
port.toInt(), true, logQueries, true, databaseOptions);
|
||
|
this->db = QSharedPointer<Database>(db);
|
||
|
this->init(inspectEntities);
|
||
|
}
|
||
|
|
||
|
void EntityManager::init(bool inspect) {
|
||
|
void EntityManager::init(bool inspect,const MsgType msgType) {
|
||
|
auto schema = Database::getSchema(Database::getDatabaseType(
|
||
|
this->db->getDatabase().driverName()), this->db);
|
||
|
this->schema = QSharedPointer<Schema>(schema);
|
||
| ... | ... | |
|
this->queryInterpreter = QSharedPointer<QueryInterpreter>(new QueryInterpreter(
|
||
|
this->schema->getQueryBuilder()));
|
||
|
this->appendToInstanceList();
|
||
|
#ifdef QT_DEBUG
|
||
|
inspect = true;
|
||
|
#endif
|
||
|
if (inspect) {
|
||
|
EntityInspector inspector = EntityInspector();
|
||
|
EntityInspector inspector = EntityInspector(msgType);
|
||
|
inspector.checkRegisteredEntities();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
EntityManager::EntityManager(const QString &databaseType, QString databasename,
|
||
|
QString hostname, QString username, QString password, QString port,
|
||
|
bool logQueries, QString databaseOptions, const bool inspectEntities,
|
||
|
CuteEntityManager::MsgType logActions) : QObject() {
|
||
|
auto db = new Database(databaseType, this->createConnection(), hostname,
|
||
|
databasename, username,
|
||
|
password,
|
||
|
port.toInt(), true, logQueries, true, databaseOptions, logActions);
|
||
|
this->db = QSharedPointer<Database>(db);
|
||
|
this->init(inspectEntities,logActions);
|
||
|
}
|
||
|
|
||
|
EntityManager::~EntityManager() {
|
||
|
EntityManager::removeConnectionName(this->db->getConnectionName());
|
||
|
EntityManager::instances.remove(this->objectName());
|
||
| src/entitymanager.h | ||
|---|---|---|
|
#include "querybuilder.h"
|
||
|
#include "validators/errormsg.h"
|
||
|
namespace CuteEntityManager {
|
||
|
#ifdef QT_DEBUG
|
||
|
#define DEFAULTMSGTYPE MsgType::DEBUG
|
||
|
#define INSPECTENTITIES true
|
||
|
#else
|
||
|
#define DEFAULTMSGTYPE MsgType::CRITICAL
|
||
|
#define INSPECTENTITIES false
|
||
|
#endif
|
||
|
|
||
|
|
||
|
class Logger;
|
||
|
class QueryInterpreter;
|
||
| ... | ... | |
|
bool hasChanged(QSharedPointer<Entity> &entity);
|
||
|
|
||
|
public:
|
||
|
EntityManager(QSqlDatabase database, bool logQueries = false, const bool inspectEntities = false);
|
||
|
EntityManager(QSqlDatabase database, bool logQueries = false,
|
||
|
const bool inspectEntities = INSPECTENTITIES,
|
||
|
MsgType logActions = DEFAULTMSGTYPE);
|
||
|
EntityManager(const QString &databaseType, QString databasename = "" ,
|
||
|
QString hostname = "",
|
||
|
QString username = "",
|
||
|
QString password = "", QString port = "", bool logQueries = false,
|
||
|
QString databaseOptions = "", const bool inspectEntities = false);
|
||
|
QString databaseOptions = "", const bool inspectEntities = INSPECTENTITIES,
|
||
|
MsgType logActions = DEFAULTMSGTYPE);
|
||
|
virtual ~EntityManager();
|
||
|
static QStringList getConnectionNames();
|
||
|
static void removeConnectionName(const QString &name);
|
||
| ... | ... | |
|
return newList;
|
||
|
}
|
||
|
|
||
|
void init(bool inspect);
|
||
|
void init(bool inspect, const MsgType msgType);
|
||
|
QList<QHash<QString, QVariant> > findAll(const QSharedPointer<Entity> &e);
|
||
|
void resolveRelations(const QSharedPointer<Entity> &entity,
|
||
|
const QHash<QString, QVariant> &map, const bool refresh = false);
|
||
| src/logger.cpp | ||
|---|---|---|
|
#include <QDateTime>
|
||
|
|
||
|
using namespace CuteEntityManager;
|
||
|
Logger::Logger(QString path) {
|
||
|
|
||
|
Logger::Logger(QString path, MsgType min) {
|
||
|
this->path = path;
|
||
|
this->minimum = min;
|
||
|
}
|
||
|
|
||
|
Logger::~Logger() {
|
||
| ... | ... | |
|
QString msg = "{" + QString("\"time\":\"") +
|
||
|
QDateTime::currentDateTime().toString(Qt::ISODate) + QString("\"") + errorMsg;
|
||
|
msg += this->generateLogMsg(q) + "}";
|
||
|
this->logMsg(msg);
|
||
|
if (errorMsg.isEmpty()) {
|
||
|
qDebug() << msg.replace("\"", "'");
|
||
|
} else {
|
||
|
qWarning() << msg.replace("\"", "'");
|
||
|
}
|
||
|
this->logMsg(msg, errorMsg.isEmpty() ? MsgType::DEBUG : MsgType::WARNING);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Logger::lastError(const QSqlError &e) {
|
||
|
if (e.isValid()) {
|
||
|
this->logMsg(this->generateLogMsg(e));
|
||
|
this->logMsg(this->generateLogMsg(e), MsgType::WARNING);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Logger::logMsg(const QString &value) {
|
||
|
QFile log(this->getPath());
|
||
|
log.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append);
|
||
|
log.seek(log.size());
|
||
|
QTextStream stream(&log);
|
||
|
stream.setCodec("UTF-8");
|
||
|
stream << value;
|
||
|
stream << "\n";
|
||
|
stream.flush();
|
||
|
log.close();
|
||
|
void Logger::logMsg(const QString &value, const MsgType type) {
|
||
|
if (!value.isEmpty() && this->shouldBeLogged(type)) {
|
||
|
this->outputToConsole(type, value);
|
||
|
QFile log(this->getPath());
|
||
|
log.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append);
|
||
|
log.seek(log.size());
|
||
|
QTextStream stream(&log);
|
||
|
stream.setCodec("UTF-8");
|
||
|
stream << value;
|
||
|
stream << "\n";
|
||
|
stream.flush();
|
||
|
log.close();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
QString Logger::generateLogMsg(const QSqlQuery &q, bool withValues) const {
|
||
| ... | ... | |
|
return r;
|
||
|
}
|
||
|
|
||
|
bool Logger::shouldBeLogged(const MsgType &type) const {
|
||
|
switch (type) {
|
||
|
case MsgType::DEBUG:
|
||
|
return this->minimum == MsgType::DEBUG;
|
||
|
case MsgType::INFO:
|
||
|
return this->minimum == MsgType::DEBUG || this->minimum == MsgType::INFO;
|
||
|
case MsgType::WARNING:
|
||
|
return this->minimum == MsgType::DEBUG || this->minimum == MsgType::INFO
|
||
|
|| this->minimum == MsgType::WARNING;
|
||
|
case MsgType::CRITICAL:
|
||
|
return this->minimum == MsgType::DEBUG || this->minimum == MsgType::INFO
|
||
|
|| this->minimum == MsgType::WARNING || this->minimum == MsgType::CRITICAL;
|
||
|
default:
|
||
|
return true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Logger::outputToConsole(const MsgType &type, const QString &msg) const {
|
||
|
switch (type) {
|
||
|
case MsgType::DEBUG:
|
||
|
qDebug() << msg;
|
||
|
break;
|
||
|
case MsgType::INFO:
|
||
|
qInfo() << msg;
|
||
|
break;
|
||
|
case MsgType::WARNING:
|
||
|
qWarning() << msg;
|
||
|
break;
|
||
|
case MsgType::CRITICAL:
|
||
|
qCritical() << msg;
|
||
|
break;
|
||
|
case MsgType::FATAL:
|
||
|
qFatal(msg.toUtf8().constData());
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
MsgType Logger::getMinimum() const {
|
||
|
return minimum;
|
||
|
}
|
||
|
|
||
|
void Logger::setMinimum(const MsgType &value) {
|
||
|
minimum = value;
|
||
|
}
|
||
|
|
||
|
QString Logger::getPath() {
|
||
|
if (this->path.isEmpty()) {
|
||
|
this->path = this->defaultPath();
|
||
| src/logger.h | ||
|---|---|---|
|
#include <QSqlError>
|
||
|
#include <QSqlQuery>
|
||
|
namespace CuteEntityManager {
|
||
|
|
||
|
enum class MsgType { DEBUG, INFO, WARNING, CRITICAL, FATAL};
|
||
|
|
||
|
class Logger {
|
||
|
#ifdef QT_DEBUG
|
||
|
#define DEFAULTMSGTYPE MsgType::DEBUG
|
||
|
#else
|
||
|
#define DEFAULTMSGTYPE MsgType::CRITICAL
|
||
|
#endif
|
||
|
|
||
|
public:
|
||
|
Logger(QString path = "");
|
||
|
Logger(QString path = "", MsgType min = DEFAULTMSGTYPE);
|
||
|
~Logger();
|
||
|
QString defaultPath() const;
|
||
|
|
||
| ... | ... | |
|
void lastError(const QSqlQuery &q, bool logQuery = false);
|
||
|
QString getPath();
|
||
|
void setPath(const QString &value);
|
||
|
void logMsg(const QString &value);
|
||
|
void logMsg(const QString &value, const MsgType type = MsgType::DEBUG);
|
||
|
|
||
|
MsgType getMinimum() const;
|
||
|
void setMinimum(const MsgType &value);
|
||
|
|
||
|
protected:
|
||
|
QString generateLogMsg(const QSqlError &e) const;
|
||
|
QString generateLogMsg(const QSqlQuery &q, bool withValues = true) const;
|
||
|
bool shouldBeLogged(const MsgType &type) const;
|
||
|
void outputToConsole(const MsgType &type, const QString &msg) const;
|
||
|
|
||
|
|
||
|
private:
|
||
|
QString path;
|
||
|
MsgType minimum;
|
||
|
};
|
||
|
}
|
||
|
#endif // LOGGER_H
|
||
Auch abrufbar als: Unified diff
some logger stuff