Revision d27d606d
Von Christian Ehringfeld vor etwa 9 Jahren hinzugefügt
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
created attribute resolver