Revision 2075db87
Von Christian Ehringfeld vor mehr als 10 Jahren hinzugefügt
| src/cache.cpp | ||
|---|---|---|
|
|
||
|
void Cache::insert(const QSharedPointer<Entity> &entity) {
|
||
|
if (entity.data() && entity.data()->getId() > -1) {
|
||
|
this->cache.insert(this->generateKey(entity.data()->getId(),
|
||
|
QString(entity.data()->getClassname())),
|
||
|
entity.toWeakRef());
|
||
|
QString key = this->generateKey(entity.data()->getId(),
|
||
|
QString(entity.data()->getClassname()));
|
||
|
// if(this->cache.contains(key)) {
|
||
|
// Entity* ptr = this->cache.value(key).toStrongRef().data();
|
||
|
// Entity* refreshed = entity.data();
|
||
|
// *ptr = *refreshed;
|
||
|
// } else {
|
||
|
this->cache.insert(key,entity.toWeakRef());
|
||
|
//}
|
||
|
}
|
||
|
}
|
||
|
|
||
| src/entity.cpp | ||
|---|---|---|
|
}
|
||
|
|
||
|
QString Entity::getTablename() {
|
||
|
return QString(this->metaObject()->className());
|
||
|
return QString(this->metaObject()->className()).toLower();
|
||
|
}
|
||
|
|
||
|
const QHash<QString, Relation> Entity::getRelations() const {
|
||
| src/entitymanager.cpp | ||
|---|---|---|
|
auto iterator = props.constBegin();
|
||
|
while (iterator != props.constEnd()) {
|
||
|
const Relation r = iterator.key();
|
||
|
const QMetaProperty property = iterator.value();
|
||
|
/**
|
||
|
@todo
|
||
|
**/
|
||
|
switch (r.getType()) {
|
||
|
case MANY_TO_ONE:
|
||
|
break;
|
||
|
case MANY_TO_MANY:
|
||
|
break;
|
||
|
case ONE_TO_MANY:
|
||
|
break;
|
||
|
case ONE_TO_ONE:
|
||
|
break;
|
||
|
auto property = iterator.value();
|
||
|
auto var = property.read(entity.data());
|
||
|
if (r.getType() == MANY_TO_MANY) {
|
||
|
this->removeManyToManyEntityList(entity, r, var);
|
||
|
} else if (r.getType() == ONE_TO_MANY) {
|
||
|
if (r.getCascadeType().contains(REMOVE) || r.getCascadeType().contains(ALL)) {
|
||
|
this->removeEntityList(var);
|
||
|
} else {
|
||
|
this->setNullOneToManyRelation(var, r);
|
||
|
}
|
||
|
} else if (r.getType() == MANY_TO_ONE || r.getType() == MANY_TO_ONE) {
|
||
|
this->setNullEntityPropertyRelation(var, r);
|
||
|
}
|
||
|
++iterator;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void EntityManager::setNullOneToManyRelation(QVariant &var, const Relation &r) {
|
||
|
if (!r.getMappedBy().isEmpty()) {
|
||
|
if (!var.isNull() && var.canConvert<QList<QSharedPointer<Entity>>>()) {
|
||
|
auto list = qvariant_cast<QList<QSharedPointer<Entity>>>(var);
|
||
|
if (!list.isEmpty()) {
|
||
|
auto metas = list.at(0).data()->getMetaProperties();
|
||
|
if (metas.contains(r.getMappedBy())) {
|
||
|
for (int var = 0; var < list.size(); ++var) {
|
||
|
auto entity = list.at(var);
|
||
|
this->setProperty(entity, QSharedPointer<Entity>(),
|
||
|
metas.value(r.getMappedBy()));
|
||
|
this->save(entity);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void EntityManager::setNullEntityPropertyRelation(QVariant &var,
|
||
|
const Relation &r) {
|
||
|
if (r.getCascadeType().contains(REMOVE) || r.getCascadeType().contains(ALL)) {
|
||
|
this->removeEntity(var);
|
||
|
} else if (!r.getMappedBy().isEmpty()) {
|
||
|
if (!var.isNull() && var.canConvert<QSharedPointer<Entity>>()) {
|
||
|
auto e = qvariant_cast<QSharedPointer<Entity>>(var);
|
||
|
auto metas = e.data()->getMetaProperties();
|
||
|
if (metas.contains(r.getMappedBy())) {
|
||
|
this->setProperty(e, QSharedPointer<Entity>(), metas.value(r.getMappedBy()));
|
||
|
this->save(e);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void EntityManager::removeEntity(QVariant &var) {
|
||
|
if (!var.isNull() && var.canConvert<QSharedPointer<Entity>>()) {
|
||
|
auto e = qvariant_cast<QSharedPointer<Entity>>(var);
|
||
|
this->remove(e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void EntityManager::removeEntityList(QVariant &var) {
|
||
|
if (var.canConvert<QList<QSharedPointer<Entity>>>()) {
|
||
|
QList<QSharedPointer<Entity>> list =
|
||
|
qvariant_cast<QList<QSharedPointer<Entity>>>(var);
|
||
|
for (int var = 0; var < list.size(); ++var) {
|
||
|
auto entity = list.at(var);
|
||
|
this->remove(entity);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void EntityManager::removeManyToManyEntityList(const QSharedPointer<Entity> &e,
|
||
|
const Relation &r,
|
||
|
QVariant &var) {
|
||
|
if (var.canConvert<QList<QSharedPointer<Entity>>>()) {
|
||
|
QList<QSharedPointer<Entity>> list =
|
||
|
qvariant_cast<QList<QSharedPointer<Entity>>>(var);
|
||
|
if (!list.isEmpty()) {
|
||
|
auto builder = this->schema.data()->getQueryBuilder();
|
||
|
auto ptr = list.at(0);
|
||
|
QString tblName = builder.data()->generateManyToManyTableName(e, ptr);
|
||
|
if (this->schema.data()->getTables().contains(tblName)) {
|
||
|
QSqlQuery q = builder.data()->manyToManyDelete(
|
||
|
tblName, builder.data()->generateManyToManyColumnName(e),
|
||
|
e.data()->getId());
|
||
|
bool refresh = r.getCascadeType().contains(REFRESH)
|
||
|
|| r.getCascadeType().contains(ALL);
|
||
|
bool remove = r.getCascadeType().contains(REMOVE)
|
||
|
|| r.getCascadeType().contains(ALL);
|
||
|
if (q.exec()) {
|
||
|
for (int var = 0; var < list.size(); ++var) {
|
||
|
auto entity = list.at(var);
|
||
|
if (remove) {
|
||
|
this->remove(entity);
|
||
|
} else if (refresh) {
|
||
|
/**
|
||
|
not really with good performance, alternatively iterate over relation attribute and delete pointer from list
|
||
|
**/
|
||
|
this->refresh(entity);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
QList<QSharedPointer<Entity>> EntityManager::saveRelationEntities(
|
||
|
const QList<QSharedPointer<Entity> > &list, const Relation &r) {
|
||
|
QList<QSharedPointer<Entity>> saved = QList<QSharedPointer<Entity>>();
|
||
| ... | ... | |
|
auto builder = this->schema.data()->getQueryBuilder();
|
||
|
if (secEntity) {
|
||
|
QSharedPointer<Entity> secEntityPtr = QSharedPointer<Entity>(secEntity);
|
||
|
/**
|
||
|
* @todo not good, can be buggy if the tablename starts with secEntityPtr
|
||
|
*/
|
||
|
QString tblName = builder.data()->generateManyToManyTableName(entity,
|
||
|
secEntityPtr);
|
||
|
/**
|
||
|
* maybe it would be better, to fetch first the ids, look up cache and then request missing entities
|
||
|
* with this it would be also possible to respect cascade type
|
||
|
*/
|
||
|
if (this->schema.data()->getTables().contains(tblName)) {
|
||
|
QSqlQuery q = builder.data()->manyToMany(tblName,
|
||
| src/entitymanager.h | ||
|---|---|---|
|
const QString &tblName);
|
||
|
bool shouldBeSaved(QSharedPointer<Entity> &entity , const Relation &r);
|
||
|
void removeRelations(const QSharedPointer<Entity> &entity);
|
||
|
|
||
|
void removeEntityList(QVariant &var);
|
||
|
void removeManyToManyEntityList(const QSharedPointer<Entity> &e, const Relation &r, QVariant &var);
|
||
|
void removeEntity(QVariant &var);
|
||
|
void setNullOneToManyRelation(QVariant &var, const Relation &r);
|
||
|
void setNullEntityPropertyRelation(QVariant &var, const Relation &r);
|
||
|
|
||
|
public:
|
||
|
EntityManager(QSqlDatabase database);
|
||
| src/querybuilder.cpp | ||
|---|---|---|
|
QString QueryBuilder::generateManyToManyTableName(const QSharedPointer<Entity>
|
||
|
&firstEntity,
|
||
|
const QSharedPointer<Entity> &secondEntity) const {
|
||
|
return QString(firstEntity.data()->metaObject()->className()).toLower() + "_" +
|
||
|
QString(
|
||
|
secondEntity.data()->metaObject()->className()).toLower();
|
||
|
}
|
||
|
|
||
|
QString QueryBuilder::manyToManyTableName(const QSharedPointer<Entity>
|
||
|
&firstEntity, const QSharedPointer<Entity> &secondEntity,
|
||
|
const Relation &r) const {
|
||
|
QString table = "";
|
||
|
if (r.getMappedBy().isEmpty()) {
|
||
|
table = this->generateManyToManyTableName(firstEntity, secondEntity);
|
||
|
QString first = QString(firstEntity.data()->getClassname());
|
||
|
QString second = QString(secondEntity.data()->getClassname());
|
||
|
if (QString::compare(first, second, Qt::CaseSensitive) <= 0) {
|
||
|
return firstEntity.data()->getTablename() + "_" +
|
||
|
secondEntity.data()->getTablename();
|
||
|
} else {
|
||
|
table = this->generateManyToManyTableName(secondEntity, firstEntity);
|
||
|
return secondEntity.data()->getTablename() + "_" +
|
||
|
firstEntity.data()->getTablename();
|
||
|
}
|
||
|
return table;
|
||
|
}
|
||
|
|
||
|
QHash<QString, QHash<QString, QString>> QueryBuilder::generateRelationTables(
|
||
| ... | ... | |
|
QSharedPointer<Entity> ptr = QSharedPointer<Entity>(e);
|
||
|
h.insert(this->generateManyToManyColumnName(ptr),
|
||
|
this->schema.data()->TYPE_BIGINT);
|
||
|
/**
|
||
|
@todo not good
|
||
|
@see EntityManager manyToMany()
|
||
|
**/
|
||
|
relations.insert(this->generateManyToManyTableName(entity, ptr), h);
|
||
|
relations.insert(this->generateManyToManyTableName(entity, ptr), h);
|
||
|
}
|
||
|
}
|
||
|
return relations;
|
||
| src/querybuilder.h | ||
|---|---|---|
|
const;
|
||
|
QString generateManyToManyTableName(const QSharedPointer<Entity> &firstEntity,
|
||
|
const QSharedPointer<Entity> &secondEntity) const;
|
||
|
QString manyToManyTableName(const QSharedPointer<Entity> &firstEntity,
|
||
|
const QSharedPointer<Entity> &secondEntity, const Relation &r) const;
|
||
|
|
||
|
QString transformTypeToAbstractDbType(QString typeName) const;
|
||
|
QString transformAbstractTypeToRealDbType(QString typeName) const;
|
||
Auch abrufbar als: Unified diff
considering cascade type stuff