Revision d27d606d
Von Christian Ehringfeld vor etwa 10 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