Revision e332a521
Von Christian Ehringfeld vor etwa 10 Jahren hinzugefügt
| src/entity.h | ||
|---|---|---|
|
namespace CuteEntityManager {
|
||
|
|
||
|
/**
|
||
|
* You mustn't name any persisted property objectName, because its pre used by Qt and will be ignored by Entity Manager
|
||
|
* You must not name any persisted property objectName, because its pre used by Qt and will be ignored by Entity Manager
|
||
|
* @brief The Entity class
|
||
|
*/
|
||
|
class Entity : public QObject {
|
||
| ... | ... | |
|
QString getErrorsAsString() const;
|
||
|
void setErrors(const QList<ErrorMsg> &value);
|
||
|
|
||
|
protected:
|
||
|
protected:
|
||
|
explicit Entity (QObject *parent = 0);
|
||
|
virtual QString slimToString() const;
|
||
|
QList<ErrorMsg> errors;
|
||
| src/entityinspector.cpp | ||
|---|---|---|
|
#include "entityinspector.h"
|
||
|
#include <QDir>
|
||
|
#include <QDebug>
|
||
|
#include <QDateTime>
|
||
|
using namespace CuteEntityManager;
|
||
|
|
||
|
EntityInspector::EntityInspector()
|
||
|
{
|
||
|
EntityInspector::EntityInspector() {
|
||
|
this->initLogger();
|
||
|
}
|
||
|
|
||
|
EntityInspector::~EntityInspector() {
|
||
|
if (this->logger) {
|
||
|
delete this->logger;
|
||
|
this->logger = nullptr;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool EntityInspector::checkRegisteredEntities() {
|
||
|
QStringList classes = EntityInstanceFactory::getRegisteredClasses();
|
||
|
QString msg = QDateTime::currentDateTime().toString(Qt::ISODate) +
|
||
|
" - Start checking entities\n";
|
||
|
qInfo() << msg;
|
||
|
this->logger->logMsg(msg);
|
||
|
bool ok = true;
|
||
|
for (int i = 0; i < classes.size(); ++i) {
|
||
|
bool r = this->checkEntity(classes.at(i));
|
||
|
if (!r) {
|
||
|
msg = "###############################";
|
||
|
msg += "\n";
|
||
|
msg += classes.at(i) + " is erroneous!";
|
||
|
msg += "\n";
|
||
|
msg += "###############################\n";
|
||
|
qWarning() << msg;
|
||
|
ok = false;
|
||
|
} else {
|
||
|
msg = "Entity class " + classes.at(i) + " seems ok!\n";
|
||
|
qInfo() << msg;
|
||
|
}
|
||
|
this->logger->logMsg(msg);
|
||
|
}
|
||
|
msg = QDateTime::currentDateTime().toString(Qt::ISODate) +
|
||
|
" - End checking entities\n";
|
||
|
qInfo() << msg;
|
||
|
this->logger->logMsg(msg);
|
||
|
return ok;
|
||
|
}
|
||
|
|
||
|
bool EntityInspector::checkEntity(QString name) {
|
||
|
QString msg = "--------------------\n";
|
||
|
msg += "Checking " + name + " now!\n";
|
||
|
qDebug() << msg;
|
||
|
auto entity = this->instantiateEntity(name, msg);
|
||
|
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);
|
||
|
ok = pk && relations;
|
||
|
}
|
||
|
this->logger->logMsg(msg);
|
||
|
return ok;
|
||
|
}
|
||
|
|
||
|
Entity *EntityInspector::instantiateEntity(const QString name, QString &msg) {
|
||
|
auto entity = EntityInstanceFactory::createInstance(name);
|
||
|
QString internMsg = "";
|
||
|
if (entity) {
|
||
|
internMsg = name + " is instanceable!";
|
||
|
qInfo() << internMsg;
|
||
|
} else {
|
||
|
internMsg = name + " is NOT instanceable!";
|
||
|
qCritical() << internMsg;
|
||
|
}
|
||
|
msg += internMsg + "\n";
|
||
|
return entity;
|
||
|
}
|
||
|
|
||
|
void EntityInspector::checkMetaProperties(QHash<QString, QMetaProperty>
|
||
|
&metaProperties, QString &msg, bool &ok, QHash<QString, Relation> &relations) {
|
||
|
for (auto i = metaProperties.constBegin(); i != metaProperties.constEnd();
|
||
|
++i) {
|
||
|
QString typeName = QString(i.value().typeName());
|
||
|
if (!i.value().isWritable()) {
|
||
|
ok = false;
|
||
|
msg += "Property " + i.key() + " is not writable!\n”";
|
||
|
}
|
||
|
if (!i.value().isReadable()) {
|
||
|
ok = false;
|
||
|
msg += "Property " + i.key() + " is not readable!\n”";
|
||
|
}
|
||
|
if (typeName.contains("QSharedPointer") && !relations.contains(i.key())) {
|
||
|
ok = false;
|
||
|
msg += "For attribute " + i.key() + " is no relation defined!\n";
|
||
|
} else if (typeName.contains("QPointer")) {
|
||
|
ok = false;
|
||
|
msg += i.key() + " must use QSharedPointer.\n";
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
bool EntityInspector::verifyRelations(Entity *&entity, QString &msg) {
|
||
|
bool ok = true;
|
||
|
auto metaProperties = EntityHelper::getMetaProperties(entity);
|
||
|
auto relations = entity->getRelations();
|
||
|
QString iMsg = "";
|
||
|
this->checkMetaProperties(metaProperties, iMsg, ok, relations);
|
||
|
for (auto i = relations.constBegin(); i != relations.constEnd(); ++i) {
|
||
|
if (!metaProperties.contains(i.key())) {
|
||
|
iMsg += "For relation " + i.key() + " is no property.";
|
||
|
} 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>";
|
||
|
} else {
|
||
|
auto var = metaProperty.read(entity);
|
||
|
bool rel = this->checkRelation(var, i.value(), msg, metaProperty);
|
||
|
if (!rel) {
|
||
|
ok = false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (!iMsg.isEmpty()) {
|
||
|
qCritical() << iMsg;
|
||
|
msg += iMsg;
|
||
|
}
|
||
|
return ok;
|
||
|
}
|
||
|
|
||
|
void EntityInspector::verifyTransientAttributes(Entity *&entity, QString &msg) {
|
||
|
auto metaProperties = EntityHelper::getMetaProperties(entity);
|
||
|
auto relations = entity->getRelations();
|
||
|
auto transientAttributes = entity->getTransientAttributes();
|
||
|
auto blobs = entity->getBLOBColumns();
|
||
|
QString iMsg = "";
|
||
|
for (int i = 0; i < transientAttributes.size(); ++i) {
|
||
|
QString attr = transientAttributes.at(i);
|
||
|
if (!metaProperties.contains(attr)) {
|
||
|
iMsg += "No transient attribute called " + attr + ".\n";
|
||
|
}
|
||
|
if (relations.contains(transientAttributes.at(i))) {
|
||
|
iMsg += "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";
|
||
|
}
|
||
|
}
|
||
|
if (!iMsg.isEmpty()) {
|
||
|
qWarning() << iMsg;
|
||
|
msg += iMsg;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
bool EntityInspector::checkRelation(const QVariant &entity,
|
||
|
const Relation &r, QString &msg, const QMetaProperty &property) const {
|
||
|
QString iMsg = "";
|
||
|
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";
|
||
|
} 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";
|
||
|
}
|
||
|
if (many && r.getType() == RelationType::ONE_TO_MANY
|
||
|
&& r.getMappedBy().isEmpty()) {
|
||
|
iMsg += "Relation " + r.getPropertyName() +
|
||
|
" needs a mappedBy attribute of the foreign class.\n";
|
||
|
}
|
||
|
if (!iMsg.isEmpty()) {
|
||
|
msg += iMsg;
|
||
|
qCritical() << iMsg;
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool EntityInspector::checkPrimaryKey(Entity *&entity, QString &msg) {
|
||
|
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";
|
||
|
}
|
||
|
qCritical() << iMsg;
|
||
|
msg += iMsg;
|
||
|
return ok;
|
||
|
}
|
||
|
|
||
|
void EntityInspector::verifyBlobAttributes(Entity *&entity, QString &msg) {
|
||
|
auto metaprops = EntityHelper::getMetaProperties(entity);
|
||
|
auto blobs = entity->getBLOBColumns();
|
||
|
QString iMsg = "";
|
||
|
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";
|
||
|
}
|
||
|
}
|
||
|
qWarning() << iMsg;
|
||
|
msg += iMsg;
|
||
|
}
|
||
|
|
||
|
void EntityInspector::initLogger() {
|
||
|
this->logger = new Logger(QDir::currentPath() + "/entity.log");
|
||
|
}
|
||
| src/entityinspector.h | ||
|---|---|---|
|
#ifndef ENTITYINSPECTOR_H
|
||
|
#define ENTITYINSPECTOR_H
|
||
|
#include <QString>
|
||
|
#include <QHash>
|
||
|
#include "entity.h"
|
||
|
#include "entityhelper.h"
|
||
|
#include "entityinstancefactory.h"
|
||
|
#include "logger.h"
|
||
|
|
||
|
namespace CuteEntityManager {
|
||
|
|
||
|
class EntityInspector
|
||
|
{
|
||
|
public:
|
||
|
/**
|
||
|
* @brief The EntityInspector class
|
||
|
* @todo verify Mappings
|
||
|
*/
|
||
|
class EntityInspector {
|
||
|
public:
|
||
|
EntityInspector();
|
||
|
~EntityInspector();
|
||
|
bool checkRegisteredEntities();
|
||
|
bool checkEntity(QString name);
|
||
|
|
||
|
//signals:
|
||
|
|
||
|
//public slots:
|
||
|
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,
|
||
|
const QMetaProperty &property) const;
|
||
|
bool checkPrimaryKey(Entity *&entity, QString &msg);
|
||
|
void verifyBlobAttributes(Entity *&entity, QString &msg);
|
||
|
void checkMetaProperties(QHash<QString, QMetaProperty> &metaProperties,
|
||
|
QString &msg, bool &ok, QHash<QString, Relation> &relations);
|
||
|
void initLogger();
|
||
|
Logger *logger = nullptr;
|
||
|
};
|
||
|
|
||
|
}
|
||
|
#endif // ENTITYINSPECTOR_H
|
||
| src/entityinstancefactory.cpp | ||
|---|---|---|
|
QVariant &entity) {
|
||
|
return *reinterpret_cast<QSharedPointer<Entity>*>(entity.data());
|
||
|
}
|
||
|
|
||
|
QStringList EntityInstanceFactory::getRegisteredClasses() {
|
||
|
QStringList registered = QStringList();
|
||
|
for (auto i = EntityInstanceFactory::instance.constBegin();
|
||
|
i != EntityInstanceFactory::instance.constEnd(); ++i) {
|
||
|
registered.append(i.key());
|
||
|
}
|
||
|
return registered;
|
||
|
}
|
||
| src/entityinstancefactory.h | ||
|---|---|---|
|
static Entity *createInstance(const QMetaObject *object);
|
||
|
static QList<QSharedPointer<Entity>> castQVariantList(QVariant &list);
|
||
|
static QSharedPointer<Entity> castQVariant(QVariant &entity);
|
||
|
static QStringList getRegisteredClasses();
|
||
|
|
||
|
template<typename T>
|
||
|
static Entity *createInstance() {
|
||
| src/entitymanager.cpp | ||
|---|---|---|
|
#include "validators/validatorfactory.h"
|
||
|
#include "validators/validator.h"
|
||
|
#include "validators/validatorrule.h"
|
||
|
#include "entityinspector.h"
|
||
|
#include <QHash>
|
||
|
|
||
|
using namespace CuteEntityManager;
|
||
| ... | ... | |
|
}
|
||
|
|
||
|
EntityManager::EntityManager(QSqlDatabase database,
|
||
|
bool logQueries) : QObject() {
|
||
|
bool logQueries, const bool inspectEntities) : QObject() {
|
||
|
auto db = new Database(database, true, logQueries);
|
||
|
this->db = QSharedPointer<Database>(db);
|
||
|
this->init();
|
||
|
this->init(inspectEntities);
|
||
|
}
|
||
|
|
||
|
EntityManager::EntityManager(const QString &databaseType, QString databasename ,
|
||
|
QString hostname, QString username, QString password, QString port,
|
||
|
bool logQueries, QString databaseOptions) : QObject() {
|
||
|
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();
|
||
|
this->init(inspectEntities);
|
||
|
}
|
||
|
|
||
|
void EntityManager::init() {
|
||
|
void EntityManager::init(bool inspect) {
|
||
|
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();
|
||
|
inspector.checkRegisteredEntities();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
EntityManager::~EntityManager() {
|
||
| ... | ... | |
|
const Relation r = iterator.key();
|
||
|
auto var = iterator.value().read(entity.data());
|
||
|
if (!var.isNull()) {
|
||
|
#ifdef QT_DEBUG //we only want this in debug mode, cause in production/release mode this check shouldn't needed
|
||
|
this->checkRelation(var, r);
|
||
|
#endif
|
||
|
if (r.getType() == RelationType::MANY_TO_ONE) {
|
||
|
auto e = EntityInstanceFactory::castQVariant(var);
|
||
|
if (this->shouldBeSaved(e, r)) {
|
||
| ... | ... | |
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void EntityManager::checkRelation(const QVariant &entity,
|
||
|
const Relation &r) const {
|
||
|
bool canConvert = entity.canConvert<QVariantList>();
|
||
|
bool many = r.getType() == RelationType::MANY_TO_MANY
|
||
|
|| r.getType() == RelationType::ONE_TO_MANY;
|
||
|
if ((many && !canConvert) || (!many && canConvert)) {
|
||
|
throw new QString("Relation " + r.getPropertyName() +
|
||
|
" has a wrong relation type.");
|
||
|
} else if (many && r.getType() == RelationType::ONE_TO_MANY
|
||
|
&& r.getMappedBy().isEmpty()) {
|
||
|
throw new QString("Relation " + r.getPropertyName() +
|
||
|
" needs a mappedBy attribute of the foreign class.");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void EntityManager::savePostPersistedRelations(const QSharedPointer<Entity>
|
||
|
&entity, QList<Entity *> &mergedObjects, bool ignoreHasChanged) {
|
||
|
auto relations = EntityHelper::getRelationProperties(entity.data());
|
||
| ... | ... | |
|
const Relation r = iterator.key();
|
||
|
auto var = iterator.value().read(entity.data());
|
||
|
if (!var.isNull()) {
|
||
|
#ifdef QT_DEBUG //we only want this in debug mode, cause in production/release mode this check shouldn't needed
|
||
|
this->checkRelation(var, r);
|
||
|
#endif
|
||
|
if (r.getType() == RelationType::MANY_TO_MANY) {
|
||
|
this->persistManyToMany(entity, r, var, mergedObjects, ignoreHasChanged);
|
||
|
} else if (r.getType() == RelationType::ONE_TO_MANY) {
|
||
| ... | ... | |
|
builder->generateManyToManyColumnName(ptr));
|
||
|
q.bindValue(0, entity->getProperty(entity->getPrimaryKey()));
|
||
|
auto prop = EntityHelper::mappedProperty(r, ptr);
|
||
|
bool propertyIsValid = this->isRelationPropertyValid(prop, r, entity, ptr);
|
||
|
QSharedPointer<Entity> item;
|
||
|
for (int var = 0; var < saved.size(); ++var) {
|
||
|
item = list.at(var);
|
||
|
if (item->getProperty(item->getPrimaryKey()).toLongLong() > -1) {
|
||
|
q.bindValue(1, item->getProperty(ptr->getPrimaryKey()));
|
||
|
bool ok = this->db->exec(q);
|
||
|
if (ok && propertyIsValid) {
|
||
|
if (ok) {
|
||
|
EntityHelper::addEntityToListProperty(item, entity, prop);
|
||
|
}
|
||
|
}
|
||
| ... | ... | |
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
bool EntityManager::isRelationPropertyValid(const QMetaProperty &prop,
|
||
|
const Relation &r, const QSharedPointer<Entity> &e,
|
||
|
const QSharedPointer<Entity> &relatedEntity) {
|
||
|
bool propertyIsValid = prop.isValid() && prop.isReadable() && prop.isWritable();
|
||
|
if (!propertyIsValid) {
|
||
|
qWarning() << "Relation is incomplete:" << r.getPropertyName();
|
||
|
qWarning() << "Involved entities: " << EntityHelper::getClassName(
|
||
|
e.data()) <<
|
||
|
"(MainEntitiy) and " << EntityHelper::getClassName(relatedEntity.data());
|
||
|
}
|
||
|
return propertyIsValid;
|
||
|
}
|
||
|
|
||
|
QString EntityManager::generateObjectName() {
|
||
|
int i = 0;
|
||
|
QString name = "em[";
|
||
| src/entitymanager.h | ||
|---|---|---|
|
* @return
|
||
|
*/
|
||
|
bool create(QList<QSharedPointer<Entity>> entities,
|
||
|
const bool persistRelations = true, const bool validate = true, const bool relationsIgnoreHasChanged = false);
|
||
|
const bool persistRelations = true, const bool validate = true,
|
||
|
const bool relationsIgnoreHasChanged = false);
|
||
|
bool create(QSharedPointer<Entity> &entity, const bool persistRelations = true,
|
||
|
const bool checkDuplicate = false, const bool validate = true, const bool relationsIgnoreHasChanged = false) ;
|
||
|
const bool checkDuplicate = false, const bool validate = true,
|
||
|
const bool relationsIgnoreHasChanged = false) ;
|
||
|
bool save(QSharedPointer<Entity> &entity, const bool persistRelations = true,
|
||
|
const bool ignoreHasChanged = false, const bool validate = true, const bool relationsIgnoreHasChanged = false);
|
||
|
const bool ignoreHasChanged = false, const bool validate = true,
|
||
|
const bool relationsIgnoreHasChanged = false);
|
||
|
bool merge(QSharedPointer<Entity> &entity, bool withRelations = true,
|
||
|
const bool validate = true, const bool relationsIgnoreHasChanged = false);
|
||
|
bool remove(QSharedPointer<Entity> &entity);
|
||
| ... | ... | |
|
bool hasChanged(QSharedPointer<Entity> &entity);
|
||
|
|
||
|
public:
|
||
|
EntityManager(QSqlDatabase database, bool logQueries = false);
|
||
|
EntityManager(QSqlDatabase database, bool logQueries = false, const bool inspectEntities = false);
|
||
|
EntityManager(const QString &databaseType, QString databasename = "" ,
|
||
|
QString hostname = "",
|
||
|
QString username = "",
|
||
|
QString password = "", QString port = "", bool logQueries = false,
|
||
|
QString databaseOptions = "");
|
||
|
QString databaseOptions = "", const bool inspectEntities = false);
|
||
|
virtual ~EntityManager();
|
||
|
static QStringList getConnectionNames();
|
||
|
static void removeConnectionName(const QString &name);
|
||
| ... | ... | |
|
return newList;
|
||
|
}
|
||
|
|
||
|
void init();
|
||
|
void init(bool inspect);
|
||
|
QList<QHash<QString, QVariant> > findAll(const QSharedPointer<Entity> &e);
|
||
|
void resolveRelations(const QSharedPointer<Entity> &entity,
|
||
|
const QHash<QString, QVariant> &map, const bool refresh = false);
|
||
| ... | ... | |
|
*/
|
||
|
void missingManyToManyTable(const QString &tblName,
|
||
|
const QSharedPointer<Entity> &e, const Relation &r);
|
||
|
bool isRelationPropertyValid(const QMetaProperty &prop, const Relation &r,
|
||
|
const QSharedPointer<Entity> &e, const QSharedPointer<Entity> &relatedEntity);
|
||
|
/**
|
||
|
* @brief EntityManager::generateObjectName
|
||
|
* Generates a object name with this scheme: em[anyNumber]
|
||
| ... | ... | |
|
Cache cache;
|
||
|
QString createConnection();
|
||
|
QList<QHash<QString, QVariant> > convertQueryResult(QSqlQuery &q);
|
||
|
void checkRelation(const QVariant &entity, const Relation &r) const;
|
||
|
bool checkTable(const QSharedPointer<Entity> &entity);
|
||
|
QSharedPointer<QueryInterpreter> queryInterpreter;
|
||
|
|
||
| src/logger.cpp | ||
|---|---|---|
|
|
||
|
void Logger::lastError(const QSqlQuery &q, bool logQuery) {
|
||
|
if (logQuery || q.lastError().isValid()) {
|
||
|
QFile log(this->getPath());
|
||
|
log.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append);
|
||
|
log.seek(log.size());
|
||
|
QTextStream stream(&log);
|
||
|
const QString errorMsg = this->generateLogMsg(q.lastError());
|
||
|
if (logQuery || !errorMsg.isEmpty()) {
|
||
|
QString msg = "{" + QString("\"time\":\"") +
|
||
|
QDateTime::currentDateTime().toString(Qt::ISODate) + QString("\"") + errorMsg;
|
||
|
msg += this->generateLogMsg(q) + "}";
|
||
|
stream << msg;
|
||
|
this->logMsg(msg);
|
||
|
if (errorMsg.isEmpty()) {
|
||
|
qDebug() << msg.replace("\"", "'");
|
||
|
} else {
|
||
|
qWarning() << msg.replace("\"", "'");
|
||
|
}
|
||
|
}
|
||
|
stream << "\n";
|
||
|
stream.flush();
|
||
|
log.close();
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Logger::lastError(const QSqlError &e) {
|
||
|
if (e.isValid()) {
|
||
|
QFile log(this->getPath());
|
||
|
log.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append);
|
||
|
log.seek(log.size());
|
||
|
QTextStream stream(&log);
|
||
|
qDebug() << this->generateLogMsg(e);
|
||
|
stream << this->generateLogMsg(e);
|
||
|
stream << "\n";
|
||
|
stream.flush();
|
||
|
log.close();
|
||
|
this->logMsg(this->generateLogMsg(e));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
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();
|
||
|
}
|
||
|
|
||
|
QString Logger::generateLogMsg(const QSqlQuery &q, bool withValues) const {
|
||
|
QString r = ", \"query\":\"" + q.executedQuery() + "\"";
|
||
|
if (withValues) {
|
||
| src/logger.h | ||
|---|---|---|
|
void lastError(const QSqlQuery &q, bool logQuery = false);
|
||
|
QString getPath();
|
||
|
void setPath(const QString &value);
|
||
|
void logMsg(const QString &value);
|
||
|
|
||
|
protected:
|
||
|
QString generateLogMsg(const QSqlError &e) const;
|
||
| src/querybuilder.cpp | ||
|---|---|---|
|
auto m = o->property(var);
|
||
|
if ((!superMetaObjectPropertyMap.contains(QString(m.name()))
|
||
|
|| entity->getInheritanceStrategy() == InheritanceStrategy::PER_CLASS_TABLE)
|
||
|
&& m.name() != QString("objectName") && m.isReadable()
|
||
|
&& m.name() != QString("objectName")
|
||
|
&& !entity->getTransientAttributes().contains(m.name())) {
|
||
|
if (m.isEnumType()) {
|
||
|
map.insert(m.name(), this->schema->getTypeMap()->value(
|
||
| ... | ... | |
|
QString conjunction,
|
||
|
bool ignoreID) const {
|
||
|
return this->where(EntityHelper::getEntityAttributes(
|
||
|
EntityHelper::getMetaProperties(
|
||
|
entity.data()),
|
||
|
entity),
|
||
|
conjunction, ignoreID, entity->getPrimaryKey());
|
||
|
EntityHelper::getMetaProperties(entity.data()), entity), conjunction, ignoreID,
|
||
|
entity->getPrimaryKey());
|
||
|
}
|
||
Auch abrufbar als: Unified diff
Integrated EntityInspector