commit 2075db875392af91438d396402be2f0fe5496508
Author: Christian Ehringfeld <c.ehringfeld@t-online.de>
Date:   Tue May 26 20:41:37 2015 +0200

    considering cascade type stuff

diff --git a/src/cache.cpp b/src/cache.cpp
index c12170a..bcb9325 100644
--- a/src/cache.cpp
+++ b/src/cache.cpp
@@ -36,9 +36,15 @@ bool Cache::contains(const QString &key) {
 
 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());
+        //}
     }
 }
 
diff --git a/src/entity.cpp b/src/entity.cpp
index a792a1f..cefaed1 100644
--- a/src/entity.cpp
+++ b/src/entity.cpp
@@ -31,7 +31,7 @@ Entity::~Entity() {
 }
 
 QString Entity::getTablename() {
-    return QString(this->metaObject()->className());
+    return QString(this->metaObject()->className()).toLower();
 }
 
 const QHash<QString, Relation> Entity::getRelations() const {
diff --git a/src/entitymanager.cpp b/src/entitymanager.cpp
index 7ebff0a..df70365 100644
--- a/src/entitymanager.cpp
+++ b/src/entitymanager.cpp
@@ -343,24 +343,113 @@ void EntityManager::removeRelations(const QSharedPointer<Entity> &entity) {
     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>>();
@@ -407,13 +496,11 @@ void EntityManager::manyToMany(const QSharedPointer<Entity> &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,
diff --git a/src/entitymanager.h b/src/entitymanager.h
index 79fa719..40c0725 100644
--- a/src/entitymanager.h
+++ b/src/entitymanager.h
@@ -96,7 +96,11 @@ class EntityManager {
                                  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);
diff --git a/src/querybuilder.cpp b/src/querybuilder.cpp
index e8ec311..3520d76 100644
--- a/src/querybuilder.cpp
+++ b/src/querybuilder.cpp
@@ -249,21 +249,15 @@ const {
 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(
@@ -284,11 +278,7 @@ const {
             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;
diff --git a/src/querybuilder.h b/src/querybuilder.h
index 767d15c..99f9aee 100644
--- a/src/querybuilder.h
+++ b/src/querybuilder.h
@@ -74,8 +74,6 @@ class QueryBuilder {
     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;
