commit 47f9301adeb693c33fdba9dd819d2b4d04295767
Author: Christian Ehringfeld <c.ehringfeld@t-online.de>
Date:   Sun Jun 21 00:06:42 2015 +0200

    small untested update

diff --git a/src/database.h b/src/database.h
index 44d78b9..f90193f 100644
--- a/src/database.h
+++ b/src/database.h
@@ -41,7 +41,8 @@ class Database {
     ~Database();
     Database(QString databaseType, QString databasename);
     Database(QString databaseType, QString connectionName, QString databasename);
-    Database(QString databaseType, QString connectionName = "", QString hostname = "",
+    Database(QString databaseType, QString connectionName = "",
+             QString hostname = "",
              QString databasename = "" ,
              QString username = "", QString password = "", qint64 port = 0);
     QSqlDatabase getDatabase();
@@ -62,7 +63,8 @@ class Database {
     void startTransaction();
     bool commitTransaction();
     static DatabaseType getDatabaseType(QString s);
-    static QSharedPointer<Schema> getSchema(int db, QSharedPointer<Database> database);
+    static QSharedPointer<Schema> getSchema(int db,
+                                            QSharedPointer<Database> database);
 
 };
 }
diff --git a/src/entity.cpp b/src/entity.cpp
index 000200d..cf6e6d6 100644
--- a/src/entity.cpp
+++ b/src/entity.cpp
@@ -38,6 +38,25 @@ const QHash<QString, Relation> Entity::getRelations() const {
     return QHash<QString, Relation>();
 }
 
+const QHash<QString, Relation> Entity::getNonInheritedRelations() const
+{
+    auto relations = this->getRelations();
+        auto superObject = EntityInstanceFactory::newSuperClassInstance(this);
+        if (superObject) {
+            auto superRelations = superObject->getRelations();
+            auto iterator = superRelations.constBegin();
+            while (iterator != relations.constEnd()) {
+                if (relations.contains(iterator.key())) {
+                    relations.remove(iterator.key());
+                }
+                ++iterator;
+            }
+            delete superObject;
+            superObject = 0;
+        }
+        return relations;
+}
+
 const QStringList Entity::getTransientAttributes() const {
     return QStringList();
 }
@@ -70,6 +89,22 @@ const QHash<QString, QMetaProperty> Entity::getMetaProperties() const {
     return Entity::getMetaProperties(this->metaObject());
 }
 
+const QHash<QString, QMetaProperty> Entity::getSuperMetaProperties() const
+{
+    auto superMetaObjectPropertyMap = QHash<QString, QMetaProperty>();
+    auto superMeta = this->metaObject()->superClass();
+    if (QString(superMeta->className()) != QString("Entity")
+            && this->getInheritanceStrategy() == JOINED_TABLE) {
+        for (int var = 0; var < superMeta->propertyCount(); ++var) {
+            QMetaProperty prop = superMeta->property(var);
+            if (prop.isReadable() && prop.isWritable()) {
+                superMetaObjectPropertyMap.insert(QString(prop.name()), prop);
+            }
+        }
+    }
+    return superMetaObjectPropertyMap;
+}
+
 const QHash<QString, QMetaProperty> Entity::getMetaProperties(const QMetaObject *object) {
     auto h = QHash<QString, QMetaProperty>();
     for (int var = 0; var < object->propertyCount(); ++var) {
diff --git a/src/entity.h b/src/entity.h
index 2ef6171..9c75b49 100644
--- a/src/entity.h
+++ b/src/entity.h
@@ -26,6 +26,7 @@
 #include <QSharedPointer>
 #include <QStack>
 #include <QQueue>
+#include "entityinstancefactory.h"
 namespace CuteEntityManager {
 
 /**
@@ -49,6 +50,7 @@ class Entity : public QObject {
      * @return
      */
     virtual const QHash<QString, Relation> getRelations() const;
+    virtual const QHash<QString, Relation> getNonInheritedRelations() const;
     virtual const QStringList getTransientAttributes() const;
     virtual const QStringList getBLOBColumns() const;
     virtual InheritanceStrategy getInheritanceStrategy() const;
@@ -57,6 +59,7 @@ class Entity : public QObject {
     virtual QString getPrimaryKey() const;
     const QStack<const QMetaObject *> superClasses() const;
     const QHash<QString, QMetaProperty> getMetaProperties() const;
+    const QHash<QString, QMetaProperty> getSuperMetaProperties() const;
     static const QHash<QString, QMetaProperty> getMetaProperties(const QMetaObject* object);
     const QHash<QString, QMetaProperty> getInheritedMetaProperties() const;
     const QHash<Relation, QMetaProperty> getRelationProperties() const;
diff --git a/src/entityinstancefactory.h b/src/entityinstancefactory.h
index 6dca983..d329cb2 100644
--- a/src/entityinstancefactory.h
+++ b/src/entityinstancefactory.h
@@ -28,9 +28,11 @@ class EntityInstanceFactory {
     static Entity *createInstance(int metaTypeId);
     static Entity *createInstance(const char *className,
                                   const QHash<QString, QVariant> &attributes);
-    static Entity *setAttributes(Entity *e, const QHash<QString, QVariant> &attributes,
+    static Entity *setAttributes(Entity *e,
+                                 const QHash<QString, QVariant> &attributes,
                                  QHash<QString, QMetaProperty> metaprops);
-    static Entity *setAttributes(Entity *e, const QHash<QString, QVariant> &attributes);
+    static Entity *setAttributes(Entity *e,
+                                 const QHash<QString, QVariant> &attributes);
     static const QString extractEntityType(const QString &s);
     static Entity *newSuperClassInstance(const Entity *e);
 
diff --git a/src/entitymanager.h b/src/entitymanager.h
index 40c0725..b6ba4e8 100644
--- a/src/entitymanager.h
+++ b/src/entitymanager.h
@@ -97,7 +97,8 @@ class EntityManager {
     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 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);
@@ -140,9 +141,11 @@ class EntityManager {
     void refresh(QSharedPointer<Entity> &entity);
     void setSchema(const QSharedPointer<Schema> &value);
     /**
-      *@TODO create indexes
      *@TODO use conditions
      */
+    /**
+     * @TODO Inheritance at create,save,merge,remove
+     */
     template<class T> qint8 count(QHash<QString, QString> condition =
                                       QHash<QString, QString>()) {
         Entity *e = EntityInstanceFactory::createInstance<T>();
diff --git a/src/querybuilder.cpp b/src/querybuilder.cpp
index 09e73f0..aea5622 100644
--- a/src/querybuilder.cpp
+++ b/src/querybuilder.cpp
@@ -30,7 +30,6 @@ QueryBuilder::QueryBuilder(QSharedPointer<Schema> schema,
 }
 
 QueryBuilder::~QueryBuilder() {
-
 }
 
 bool QueryBuilder::createTable(const QSharedPointer<Entity> &entity) const {
@@ -52,7 +51,6 @@ bool QueryBuilder::createTable(const QSharedPointer<Entity> &entity) const {
         }
     }
     return rc;
-
 }
 
 bool QueryBuilder::createIndices(const QSharedPointer<Entity> &entity) const {
@@ -63,28 +61,17 @@ bool QueryBuilder::createIndices(const QSharedPointer<Entity> &entity) const {
     if (!superIndex.isEmpty()) {
         queries.append(superIndex);
     }
-    queries.append(this->relationIndices(e));
+    queries.append(this->relationFks(entity));
     ok = this->database.data()->transaction(queries);
     return ok;
 }
 
 
-QStringList QueryBuilder::relationIndices(const Entity *e) const {
+QStringList QueryBuilder::relationFks(const QSharedPointer<Entity> &entity)
+const {
     QStringList queries = QStringList();
-    auto relations = e->getRelations();
-    auto superObject = EntityInstanceFactory::newSuperClassInstance(e);
-    if (superObject) {
-        auto superRelations = superObject->getRelations();
-        auto iterator = superRelations.constBegin();
-        while (iterator != relations.constEnd()) {
-            if (relations.contains(iterator.key())) {
-                relations.remove(iterator.key());
-            }
-            ++iterator;
-        }
-        delete superObject;
-        superObject = 0;
-    }
+    auto relations = entity.data()->getNonInheritedRelations();
+    auto props = entity.data()->getMetaProperties();
     auto iterator = relations.constBegin();
     while (iterator != relations.constEnd()) {
         auto relation = iterator.value();
@@ -95,29 +82,53 @@ QStringList QueryBuilder::relationIndices(const Entity *e) const {
             QString remove = relation.getCascadeType().contains(REMOVE)
                              || relation.getCascadeType().contains(ALL) ?  this->getForeignKeyCascade(
                                  CASCADE) : this->getForeignKeyCascade(SET_NULL);
-
-            switch (relation.getType()) {
-            case ONE_TO_ONE:
-                break;
-            case MANY_TO_MANY:
-                //    this->generateManyToManyTableName(entity, ptr);
-                break;
-            case MANY_TO_ONE:
-                /**
-                  fill in table name
-                  **/
-                //    auto m = props.value(r.getPropertyName());
-                //    Entity *e = EntityInstanceFactory::createInstance(m.type());
-                //    QSharedPointer<Entity> ptr = QSharedPointer<Entity>(e);
-                //this->addForeignKey(this->generateIndexName(relation.getPropertyName(),e->getTablename(),this->generateColumnNameID(relation.getPropertyName()),"",true));
-                break;
-            }
+            this->createRelationFK(queries, entity, relation,
+                                   props.value(relation.getPropertyName()), update, remove);
         }
         ++iterator;
     }
     return queries;
 }
 
+void QueryBuilder::createRelationFK(QStringList &queries,
+                                    const QSharedPointer<Entity> &entity, const Relation &relation,
+                                    const QMetaProperty &metaProperty, const QString &update,
+                                    const QString &remove) const {
+    QSharedPointer<Entity> ptr = QSharedPointer<Entity>
+                                 (EntityInstanceFactory::createInstance(metaProperty.type()));
+    if (ptr.data()) {
+        if (relation.getType() == ONE_TO_ONE || relation.getType() == MANY_TO_ONE) {
+            QString indexName = this->generateIndexName(relation.getPropertyName(),
+                                entity.data()->getTablename(),
+                                this->generateColumnNameID(relation.getPropertyName()),
+                                ptr.data()->getTablename(), true);
+            queries.append(this->addForeignKey(indexName, entity.data()->getTablename(),
+                                               QStringList(this->generateColumnNameID(relation.getPropertyName())),
+                                               ptr.data()->getTablename(),
+                                               QStringList(ptr.data()->getPrimaryKey()), remove, update));
+
+        } else if (relation.getType() == MANY_TO_MANY) {
+            QString tableName = this->generateManyToManyTableName(entity, ptr);
+            queries.append(this->createForeignKeyManyToMany(tableName, entity, update,
+                           remove));
+            queries.append(this->createForeignKeyManyToMany(tableName, ptr, update,
+                           remove));
+        }
+    }
+}
+
+QString QueryBuilder::createForeignKeyManyToMany(const QString &tableName,
+        const QSharedPointer<Entity> &entity, const QString &update,
+        const QString &remove) const {
+    QString fkColumn = this->generateManyToManyColumnName(entity);
+    QString indexName = this->generateIndexName(fkColumn,
+                        tableName, fkColumn,
+                        entity.data()->getTablename(), true);
+    return this->addForeignKey(indexName, tableName, QStringList(fkColumn),
+                               entity.data()->getTablename(), QStringList(entity.data()->getPrimaryKey()),
+                               remove, update);
+}
+
 QString QueryBuilder::createTable(const QString &tableName,
                                   const QHash<QString, QString> &tableDefinition) const {
     return this->createTableQuery(tableName,
@@ -127,7 +138,6 @@ QString QueryBuilder::createTable(const QString &tableName,
 QString QueryBuilder::createFkSuperClass(const Entity *e) const {
     QString r = "";
     auto superMetaObject = e->metaObject()->superClass();
-
     if (e->getInheritanceStrategy() == JOINED_TABLE
             && QString(superMetaObject->className()) != QString("Entity")) {
         Entity *superClass  = EntityInstanceFactory::createInstance(
@@ -252,32 +262,33 @@ QString QueryBuilder::generateIndexName(const QString &name,
                                         const QString &table, const QString &refColumn, const QString &refTable,
                                         const bool fk) const {
     return QString(fk ? "fk" : "idx").append("_").append(name).append(table).append(
-                refColumn).append(refTable);
+               refColumn).append(refTable);
 }
 
-QString QueryBuilder::generateColumnNameID(QString name) const
-{
+QString QueryBuilder::generateColumnNameID(QString name) const {
     return name.append("_id");
 }
 
 QString QueryBuilder::getForeignKeyCascade(DbForeignKeyCascade cascade) const {
+    QString r = "";
     switch (cascade) {
     case RESTRICT:
-        return "RESTRICT";
+        r = "RESTRICT";
         break;
     case CASCADE:
-        return "CASCADE";
+        r = "CASCADE";
         break;
     case NO_ACTION:
-        return "NO ACTION";
+        r = "NO ACTION";
         break;
     case SET_DEFAULT:
-        return "SET DEFAULT";
+        r = "SET DEFAULT";
         break;
     case SET_NULL:
-        return "SET NULL";
+        r = "SET NULL";
         break;
     }
+    return r;
 }
 
 QString QueryBuilder::dropForeignKey(QString name, QString tableName) const {
@@ -338,8 +349,7 @@ const {
     auto map = QHash<QString, QString>();
     auto o = entity.data()->metaObject();
     auto superMetaObject = entity.data()->metaObject()->superClass();
-    auto superMetaObjectPropertyMap = this->superMetaObjectPropMap(superMetaObject,
-                                      entity);
+    auto superMetaObjectPropertyMap = entity.data()->getSuperMetaProperties();
     QHash<QString, Relation> relations = entity.data()->getRelations();
     for (int var = 0; var < o->propertyCount(); ++var) {
         auto m = o->property(var);
@@ -354,7 +364,8 @@ const {
                 if (r.getType() == RelationType::MANY_TO_ONE
                         || (r.getType() == RelationType::ONE_TO_ONE
                             && r.getMappedBy().isEmpty())) {
-                    map.insert(this->generateColumnNameID(QString(m.name())), this->schema.data()->TYPE_BIGINT);
+                    map.insert(this->generateColumnNameID(QString(m.name())),
+                               this->schema.data()->TYPE_BIGINT);
                 }
             } else if (entity.data()->getBLOBColumns().contains(m.name())) {
                 map.insert(m.name(), this->schema.data()->getTypeMap().data()->value(
@@ -639,21 +650,6 @@ QString QueryBuilder::leftJoin(const QString &foreignTable,
                tableName + "." + foreignKey);
 }
 
-QHash<QString, QMetaProperty> QueryBuilder::superMetaObjectPropMap(
-    const QMetaObject *&superMeta, const QSharedPointer<Entity> &entity) const {
-    auto superMetaObjectPropertyMap = QHash<QString, QMetaProperty>();
-    if (QString(superMeta->className()) != QString("Entity")
-            && entity.data()->getInheritanceStrategy() == JOINED_TABLE) {
-        for (int var = 0; var < superMeta->propertyCount(); ++var) {
-            QMetaProperty prop = superMeta->property(var);
-            if (prop.isReadable() && prop.isWritable()) {
-                superMetaObjectPropertyMap.insert(QString(prop.name()), prop);
-            }
-        }
-    }
-    return superMetaObjectPropertyMap;
-}
-
 QString QueryBuilder::superClassColumnName(const QMetaObject *&superMeta)
 const {
     return QString(superMeta->className()).toLower();
@@ -672,7 +668,8 @@ QString QueryBuilder::limit(const qint64 &limit, const qint64 &offset) const {
 
 QString QueryBuilder::generateManyToManyColumnName(const QSharedPointer<Entity>
         &entity) const {
-    return this->generateColumnNameID(QString(entity.data()->metaObject()->className()));
+    return this->generateColumnNameID(QString(
+                                          entity.data()->metaObject()->className()));
 }
 
 QSqlQuery QueryBuilder::getQuery() const {
diff --git a/src/querybuilder.h b/src/querybuilder.h
index 5ac8a4a..ce5f262 100644
--- a/src/querybuilder.h
+++ b/src/querybuilder.h
@@ -43,7 +43,7 @@ class QueryBuilder {
     virtual bool createTable(const QSharedPointer<Entity> &entity) const;
     virtual bool createIndices(const QSharedPointer<Entity> &entity) const;
     virtual QString createTable(const QString &tableName,
-                             const QHash<QString, QString> &tableDefinition) const;
+                                const QHash<QString, QString> &tableDefinition) const;
     virtual QString createTableQuery(const QString &tableName,
                                      const QHash<QString, QString> &tableDefinition) const;
     virtual QString renameTable(QString tableName, QString newName) const;
@@ -64,7 +64,8 @@ class QueryBuilder {
                                   QString refTableName,
                                   QStringList refColumns, QString deleteConstraint,
                                   QString updateConstraint) const;
-    QString generateIndexName(const QString &name,const QString &table,const QString &refColumn,const QString &refTable,const bool fk) const;
+    QString generateIndexName(const QString &name, const QString &table,
+                              const QString &refColumn, const QString &refTable, const bool fk) const;
     QString generateColumnNameID(QString name) const;
     virtual QString getForeignKeyCascade(DbForeignKeyCascade cascade) const;
     virtual QString dropForeignKey(QString name, QString tableName) const;
@@ -76,7 +77,11 @@ class QueryBuilder {
     QHash<QString, QVariant> getEntityAttributes(const QHash<QString, QMetaProperty>
             &props,
             const QSharedPointer<Entity> &entity) const;
-    virtual QStringList relationIndices(const Entity *e) const;
+    virtual QStringList relationFks(const QSharedPointer<Entity> &entity) const;
+
+    virtual QString createForeignKeyManyToMany(const QString &tableName,
+            const QSharedPointer<Entity> &entity, const QString &update,
+            const QString &remove) const;
 
     QSharedPointer<Schema> getSchema() const;
     void setSchema(const QSharedPointer<Schema> &value);
@@ -128,6 +133,7 @@ class QueryBuilder {
     QSqlQuery getQuery() const;
 
   protected:
+    virtual void createRelationFK(QStringList &queries, const QSharedPointer<Entity> &entity, const Relation &relation, const QMetaProperty &metaProperty, const QString &update, const QString &remove) const;
     void insertRelationId(const Entity *e, QHash<QString, QVariant> &map,
                           QString relName) const;
     QString buildColumns(const QStringList &columns) const;
@@ -158,8 +164,6 @@ class QueryBuilder {
     const;
     QString leftJoin(const QString &foreignTable, const QString &tableName,
                      const QString &foreignKey);
-    QHash<QString, QMetaProperty> superMetaObjectPropMap(const QMetaObject
-            * &superMeta, const QSharedPointer<Entity> &entity) const;
     QString superClassColumnName(const QMetaObject *&superMeta) const;
 
     QSharedPointer<Schema> schema;
diff --git a/src/relation.cpp b/src/relation.cpp
index b6befc4..5843326 100644
--- a/src/relation.cpp
+++ b/src/relation.cpp
@@ -24,8 +24,9 @@ Relation::Relation(QString propertyName, RelationType type, bool optional) {
     this->type = type;
     this->optional = optional;
     this->cascadeType = {MERGE,
-                             PERSIST,
-                             REFRESH};
+                         PERSIST,
+                         REFRESH
+                        };
 }
 
 Relation::Relation(QString propertyName, RelationType type, QString mappedBy,
