Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision d27d606d

Von Christian Ehringfeld vor etwa 9 Jahren hinzugefügt

  • ID d27d606ded8e08d3f6f6d123516252baf5d1eb6d
  • Vorgänger 46d2de48
  • Nachfolger 19082efe

created attribute resolver

Unterschiede anzeigen:

src/attribute.cpp
#include "attribute.h"
#include "entityhelper.h"
using namespace CuteEntityManager;
Attribute::Attribute(QString name, QString columnName, QString tableName,
QMetaObject *metaObj, QString relatedTable, QMetaObject *relatedClass,
QString conjunctedTable) {
const QMetaObject *metaObj, QString relatedTable, const QMetaObject *relatedClass,
QString conjunctedTable, QString relatedColumnName, QString baseTableName,
const QMetaObject *baseMetaObj) {
this->name = name;
this->columnName = columnName;
this->tableName = tableName;
this->metaObj = metaObj;
this->relatedTable = relatedTable;
this->relatedClass = relatedClass;
this->conjunctedTable = conjunctedTable;
this->relatedColumnName = relatedColumnName;
this->baseMetaObj = baseMetaObj;
this->baseTableName = baseTableName;
}
QString Attribute::getName() const {
......
relatedTable = value;
}
QMetaObject *Attribute::getRelatedClass() const {
return relatedClass;
}
void Attribute::setRelatedClass(QMetaObject *value) {
relatedClass = value;
}
QString Attribute::getConjunctedTable() const {
return conjunctedTable;
}
......
conjunctedTable = value;
}
QMetaObject *Attribute::getMetaObj() const {
QString Attribute::getBaseTableName() const {
return baseTableName;
}
void Attribute::setBaseTableName(const QString &value) {
baseTableName = value;
}
void Attribute::setInheritance(const QString &baseTableName,
const QMetaObject *baseMetaObj) {
this->baseTableName = baseTableName;
this->baseMetaObj = baseMetaObj;
}
void Attribute::setRelation(const QString &tableName, const QMetaObject *relatedMetaObj,
const QString &conjunctedTable, const QString &relatedColumnName) {
this->relatedTable = tableName;
this->relatedClass = relatedMetaObj;
this->conjunctedTable = conjunctedTable;
this->relatedColumnName = relatedColumnName;
}
const QMetaProperty Attribute::getMetaProperty() {
return EntityHelper::getMetaProperties(this->getMetaObj()).value(this->getName());
}
const QMetaObject *Attribute::getMetaObj() const {
return metaObj;
}
void Attribute::setMetaObj(QMetaObject *value) {
void Attribute::setMetaObj(const QMetaObject *value) {
metaObj = value;
}
const QMetaObject *Attribute::getBaseMetaObj() const {
return baseMetaObj;
}
void Attribute::setBaseMetaObj(const QMetaObject *value) {
baseMetaObj = value;
}
const QMetaObject *Attribute::getRelatedClass() const {
return relatedClass;
}
void Attribute::setRelatedClass(const QMetaObject *value) {
relatedClass = value;
}
QString Attribute::getRelatedColumnName() const {
return relatedColumnName;
}
void Attribute::setRelatedColumnName(const QString &value) {
relatedColumnName = value;
}
src/attribute.h
#ifndef ATTRIBUTE_H
#define ATTRIBUTE_H
#include <QString>
#include <QMetaObject>
namespace CuteEntityManager {
class Attribute {
public:
Attribute(QString name, QString columnName, QString tableName, QMetaObject *metaObj,
QString relatedTable = "", QMetaObject *relatedClass = nullptr,
QString conjunctedTable = "");
Attribute(QString name, QString columnName, QString tableName, const QMetaObject *metaObj,
QString relatedTable = "", const QMetaObject *relatedClass = nullptr,
QString conjunctedTable = "", QString relatedColumnName = "", QString baseTableName = "",
const QMetaObject *baseMetaObj = nullptr);
QString getName() const;
void setName(const QString &value);
......
QString getRelatedTable() const;
void setRelatedTable(const QString &value);
QMetaObject *getRelatedClass() const;
void setRelatedClass(QMetaObject *value);
QString getConjunctedTable() const;
void setConjunctedTable(const QString &value);
QMetaObject *getMetaObj() const;
void setMetaObj(QMetaObject *value);
QString getBaseTableName() const;
void setBaseTableName(const QString &value);
void setInheritance(const QString &baseTableName, const QMetaObject *baseMetaObj);
void setRelation(const QString &tableName, const QMetaObject *relatedMetaObj,
const QString &conjunctedTable = "", const QString &relatedColumnName = "");
const QMetaProperty getMetaProperty();
const QMetaObject *getMetaObj() const;
void setMetaObj(const QMetaObject *value);
const QMetaObject *getBaseMetaObj() const;
void setBaseMetaObj(const QMetaObject *value);
const QMetaObject *getRelatedClass() const;
void setRelatedClass(const QMetaObject *value);
QString getRelatedColumnName() const;
void setRelatedColumnName(const QString &value);
private:
QString name;
QString columnName;
QString tableName;
QMetaObject *metaObj;
const QMetaObject *metaObj;
QString baseTableName;
const QMetaObject *baseMetaObj;
QString relatedTable;
QMetaObject *relatedClass;
const QMetaObject *relatedClass;
QString relatedColumnName;
QString conjunctedTable;
};
}
src/attributeresolver.cpp
#include "attributeresolver.h"
#include "entityhelper.h"
#include "querybuilder.h"
using namespace CuteEntityManager;
AttributeResolver::AttributeResolver(QSharedPointer<QueryBuilder> queryBuilder) {
this->qb = queryBuilder;
}
AttributeResolver::~AttributeResolver() {
this->qb = QSharedPointer<QueryBuilder>(nullptr);
if(!this->attributes.isEmpty()) {
QMutableHashIterator<QString, QHash<QString, Attribute*>> i(this->attributes);
while(i.hasNext()) {
i.next();
auto embeddedHash = i.value();
QMutableHashIterator<QString, Attribute*> i2(embeddedHash);
while(i2.hasNext()) {
i2.next();
auto attr = i2.value();
delete attr;
i2.remove();
}
i.remove();
}
}
}
QHash<QString, QHash<QString, Attribute *>> AttributeResolver::getAttributes() const {
return attributes;
}
void AttributeResolver::setAttributes(const QHash<QString, QHash<QString, Attribute*>>
&value) {
attributes = value;
}
Attribute *AttributeResolver::resolveManyToManyAttribute(const QSharedPointer<Entity> &e,
const QString &attr, const Relation &r, const QSharedPointer<Entity> &target) {
auto ptr = e;
QString attributeName = r.getPropertyName();
if (!r.getMappedBy().isEmpty()) {
ptr = target;
attributeName = r.getMappedBy();
}
auto obj = EntityHelper::getBaseClassObject(ptr, attributeName);
Attribute *attrObj = new Attribute(attr,
this->qb->generateColumnNameID(obj->getTablename()),
e->getTablename(), e->metaObject());
this->resolveInheritance(e, attrObj);
attrObj->setRelation(target->getTablename(), target->metaObject(),
this->qb->generateManyToManyTableName(obj->getTablename(), attributeName),
this->qb->generateColumnNameID(target->getTablename()));
delete obj;
return attrObj;
}
Attribute *AttributeResolver::resolveManyToOneAttribute(const QSharedPointer<Entity> &e,
const QString &attr, const Relation &r, const QSharedPointer<Entity> &target) {
Q_UNUSED(r);
auto obj = EntityHelper::getBaseClassObject(e, attr);
Attribute *attrObj = new Attribute(attr,
this->qb->generateColumnNameID(attr),
e->getTablename(), e->metaObject());
this->resolveInheritance(e, attrObj);
attrObj->setRelation(target->getTablename(), target->metaObject(), "", "id");
delete obj;
return attrObj;
}
Attribute *AttributeResolver::resolveOneToManyAttribute(const QSharedPointer<Entity> &e,
const QString &attr, const Relation &r, const QSharedPointer<Entity> &target) {
auto obj = EntityHelper::getBaseClassObject(e, attr);
Attribute *attrObj = new Attribute(attr, "id",
e->getTablename(), e->metaObject());
this->resolveInheritance(e, attrObj);
attrObj->setRelation(target->getTablename(), target->metaObject(), "",
this->qb->generateColumnNameID(r.getMappedBy()));
delete obj;
return attrObj;
}
Attribute *AttributeResolver::resolveNonRelatedAttribute(const QSharedPointer<Entity> &e,
const QString &attr) {
Attribute *obj = new Attribute(attr, attr, e->getTablename(), e->metaObject());
this->resolveInheritance(e, obj);
return obj;
}
const QMetaObject *AttributeResolver::resolveInheritance(const QSharedPointer<Entity> &e,
Attribute *&attribute) {
auto obj = EntityHelper::getBaseClassObject(e, attribute->getName());
if(obj && obj->getTablename() != e->getTablename()) {
attribute->setInheritance(obj->getTablename(), obj->metaObject());
}
return obj->metaObject();
}
void AttributeResolver::addAttribute(const QString &className, Attribute *&attr) {
auto attrs = this->attributes.value(className);
attrs.insert(attr->getName(), attr);
this->attributes.insert(className, attrs);
}
Attribute *AttributeResolver::resolveExplicitAttribute(const QSharedPointer<Entity>
&classObj, const QString &attribute, QSharedPointer<Entity> related) {
Attribute* a = nullptr;
if(classObj->getRelations().contains(attribute)) {
auto relation = classObj->getRelations().value(attribute);
if(relation.getType() == RelationType::MANY_TO_MANY) {
a = this->resolveManyToManyAttribute(classObj, attribute, relation, related);
} else if(relation.getType() == RelationType::MANY_TO_ONE ||
(relation.getType() == RelationType::ONE_TO_ONE && relation.getMappedBy().isEmpty())) {
a = this->resolveManyToOneAttribute(classObj, attribute, relation, related);
} else {
a = this->resolveOneToManyAttribute(classObj, attribute, relation, related);
}
} else {
a = this->resolveNonRelatedAttribute(classObj, attribute);
}
return a;
}
bool AttributeResolver::containsAttribute(const QString &className,
const QString &attribute) const {
bool r = false;
auto attributes = this->getAttributes();
if(!this->attributes.isEmpty() && attributes.contains(className) &&
!attributes.value(className).isEmpty() &&
attributes.value(className).contains(attribute)) {
r = true;
}
return r;
}
Attribute *AttributeResolver::resolveAttribute(const QSharedPointer<Entity> &classObj,
const QString &attribute, QSharedPointer<Entity> related) {
Attribute *attr = nullptr;
if(this->containsAttribute(classObj->getClassname(), attribute)) {
attr = this->attributes.value(classObj->getClassname()).value(attribute);
} else {
attr = this->resolveExplicitAttribute(classObj, attribute, related);
this->addAttribute(classObj->getClassname(), attr);
}
return attr;
}
src/attributeresolver.h
#ifndef ATTRIBUTERESOLVER_H
#define ATTRIBUTERESOLVER_H
#include <QHash>
#include <QString>
#include "attribute.h"
#include "entity.h"
namespace CuteEntityManager {
class QueryBuilder;
class AttributeResolver {
public:
AttributeResolver(QSharedPointer<QueryBuilder> queryBuilder);
virtual ~AttributeResolver();
bool containsAttribute(const QString &className, const QString &attribute) const;
Attribute* resolveAttribute(const QSharedPointer<Entity> &classObj,
const QString &attribute, QSharedPointer<Entity> related = QSharedPointer<Entity>());
QHash<QString, QHash<QString, Attribute *>> getAttributes() const;
void setAttributes(const QHash<QString, QHash<QString, Attribute *>> &value);
protected:
Attribute* resolveManyToManyAttribute(const QSharedPointer<Entity> &e,
const QString &attr, const Relation &r, const QSharedPointer<Entity> &target);
Attribute* resolveManyToOneAttribute(const QSharedPointer<Entity> &e, const QString &attr,
const Relation &r, const QSharedPointer<Entity> &target);
Attribute* resolveOneToManyAttribute(const QSharedPointer<Entity> &e, const QString &attr,
const Relation &r, const QSharedPointer<Entity> &target);
Attribute* resolveNonRelatedAttribute(const QSharedPointer<Entity> &e,
const QString &attr);
const QMetaObject *resolveInheritance(const QSharedPointer<Entity> &e,Attribute *&attribute);
void addAttribute(const QString &className, Attribute *&attr);
Attribute* resolveExplicitAttribute(const QSharedPointer<Entity> &classObj,
const QString &attribute, QSharedPointer<Entity> related = QSharedPointer<Entity>());
private:
QSharedPointer<QueryBuilder> qb;
QHash<QString, QHash<QString, Attribute*>> attributes;
};
}
#endif // ATTRIBUTERESOLVER_H
src/entitymanager.cpp
this->db->startTransaction();
auto builder = this->schema->getQueryBuilder();
q = builder->manyToManyInsert(tblName,
builder->generateManyToManyColumnName(entity,r.getPropertyName()),
builder->generateManyToManyColumnName(ptr,r.getMappedBy()));
builder->generateManyToManyColumnName(entity, r.getPropertyName()),
builder->generateManyToManyColumnName(ptr, r.getMappedBy()));
q.bindValue(0, entity->getProperty(entity->getPrimaryKey()));
auto prop = EntityHelper::mappedProperty(r, ptr);
QSharedPointer<Entity> item;
......
QString tblName = builder->generateManyToManyTableName(e, ptr, r);
if (this->schema->getTables().contains(tblName)) {
QSqlQuery q = builder->manyToManyDelete(
tblName, builder->generateManyToManyColumnName(e,r.getPropertyName()),
tblName, builder->generateManyToManyColumnName(e, r.getPropertyName()),
e->getProperty(e->getPrimaryKey()).toLongLong());
if (this->db->exec(q)) {
bool refresh = r.getCascadeType().contains(CascadeType::REFRESH)
......
* @todo diff and remove entity from relational object when association is deleted
*/
q = builder->manyToManyDelete(
tblName, builder->generateManyToManyColumnName(entity,r.getPropertyName()),
tblName, builder->generateManyToManyColumnName(entity, r.getPropertyName()),
entity->getProperty(entity->getPrimaryKey()).toLongLong());
ok = this->db->exec(q);
} else {
......
relation);
if (this->schema->getTables().contains(tblName)) {
QSqlQuery q = builder->manyToMany(tblName,
builder->generateManyToManyColumnName(entity,relation.getPropertyName()),
builder->generateManyToManyColumnName(entity, relation.getPropertyName()),
entity->getProperty(entity->getPrimaryKey()).toLongLong());
auto listMap = this->convertQueryResult(q);
auto secClassName = EntityHelper::getClassName(secEntityPtr.data());
QSharedPointer<Entity> e;
for (int var = 0; var < listMap.size(); ++var) {
auto id = listMap.at(var).value(builder->generateManyToManyColumnName(secEntityPtr,relation.getMappedBy()));
auto id = listMap.at(var).value(builder->generateManyToManyColumnName(secEntityPtr,
relation.getMappedBy()));
if (refresh || !(this->cache.contains(id.toLongLong(), secClassName) &&
(e = this->cache.get(id.toLongLong(), secClassName)))) {
e = this->findById(id.toLongLong(), secClassName);
src/entitymanager.h
#include "cache.h"
#include "querybuilder.h"
#include "validators/errormsg.h"
#include "attribute.h"
namespace CuteEntityManager {
#ifdef QT_DEBUG
#define DEFAULTMSGTYPE MsgType::DEBUG
......
return newList;
}
protected:
protected:
bool saveObject(QSharedPointer<Entity> &entity, QList<Entity *> &mergedObjects,
const bool persistRelations = true,
const bool ignoreHasChanged = false, const bool validate = true,
src/querybuilder.cpp
attributeName = r.getMappedBy();
}
auto obj = EntityHelper::getBaseClassObject(ptr, attributeName);
QString tblName = obj->getTablename() + "_" + attributeName;
QString tblName = this->generateManyToManyTableName(obj->getTablename(), attributeName);
delete obj;
return tblName;
}
QString QueryBuilder::generateManyToManyTableName(const QString &tableName,
const QString &attribute) const {
return tableName + "_" + attribute;
}
QHash<QString, QHash<QString, QString>> QueryBuilder::generateRelationTables(
const QSharedPointer<Entity> &entity) const {
auto relations = QHash<QString, QHash<QString, QString>>();
src/querybuilder.h
*/
friend class EntityManager;
friend class QueryInterpreter;
friend class AttributeResolver;
public:
QueryBuilder(Schema *schema, QSharedPointer<Database> &database);
virtual ~QueryBuilder();
......
const QSharedPointer<Entity> &entity) const;
QString generateManyToManyTableName(const QSharedPointer<Entity> &firstEntity,
const QSharedPointer<Entity> &secondEntity, const Relation &r) const;
QString generateManyToManyColumnName(const QSharedPointer<Entity> &entity, QString attribute) const;
QString generateManyToManyTableName(const QString &tableName,
const QString &attribute) const;
QString generateManyToManyColumnName(const QSharedPointer<Entity> &entity,
QString attribute) const;
QString buildCreateQuery(QHash<QString, QVariant>::const_iterator i,
QHash<QString, QVariant>::const_iterator end,
QString &p1, QString &p2) const;
src/src.pro
schema/mysqlquerybuilder.h \
entityinspector.h \
sqlitebackupprocessor.h \
attribute.h
attribute.h \
attributeresolver.h
SOURCES += \
entity.cpp \
......
schema/mysqlquerybuilder.cpp \
entityinspector.cpp \
sqlitebackupprocessor.cpp \
attribute.cpp
attribute.cpp \
attributeresolver.cpp
win32:!system-sqlite:!contains(LIBS, .*sqlite3.*) {
include($$[QT_INSTALL_PREFIX]/../Src/qtbase/src/3rdparty/sqlite.pri)

Auch abrufbar als: Unified diff