commit 95a2ba7ef0590dcda3fe4ea5a74ff5696f5c3b5a
Author: Christian Ehringfeld <c.ehringfeld@t-online.de>
Date:   Sun Dec 27 16:59:21 2015 +0100

    continued work on attribute resolver

diff --git a/src/attribute.cpp b/src/attribute.cpp
index 1686f64..450bd53 100644
--- a/src/attribute.cpp
+++ b/src/attribute.cpp
@@ -18,6 +18,12 @@ Attribute::Attribute(QString name, QString columnName, QString tableName,
     this->baseTableName = baseTableName;
 }
 
+QString Attribute::toString() const {
+    return this->name + " " + this->columnName + " " + this->tableName + " " +
+           this->relatedTable + " " + this->relatedColumnName + " " + this->conjunctedTable;
+}
+
+
 QString Attribute::getName() const {
     return name;
 }
@@ -73,11 +79,13 @@ void Attribute::setInheritance(const QString &baseTableName,
 }
 
 void Attribute::setRelation(const QString &tableName, const QMetaObject *relatedMetaObj,
+                            const Relation &relation,
                             const QString &conjunctedTable, const QString &relatedColumnName) {
     this->relatedTable = tableName;
     this->relatedClass = relatedMetaObj;
     this->conjunctedTable = conjunctedTable;
     this->relatedColumnName = relatedColumnName;
+    this->relation = relation;
 }
 
 const QMetaProperty Attribute::getMetaProperty() {
@@ -116,3 +124,6 @@ void Attribute::setRelatedColumnName(const QString &value) {
     relatedColumnName = value;
 }
 
+Relation Attribute::getRelation() const {
+    return relation;
+}
diff --git a/src/attribute.h b/src/attribute.h
index 5cba1ed..fc37aec 100644
--- a/src/attribute.h
+++ b/src/attribute.h
@@ -2,6 +2,7 @@
 #define ATTRIBUTE_H
 #include <QString>
 #include <QMetaObject>
+#include "relation.h"
 namespace CuteEntityManager {
 class Attribute {
   public:
@@ -27,7 +28,7 @@ class Attribute {
     QString getBaseTableName() const;
     void setBaseTableName(const QString &value);
     void setInheritance(const QString &baseTableName, const QMetaObject *baseMetaObj);
-    void setRelation(const QString &tableName, const QMetaObject *relatedMetaObj,
+    void setRelation(const QString &tableName, const QMetaObject *relatedMetaObj, const Relation &relation = Relation(),
                      const QString &conjunctedTable = "", const QString &relatedColumnName = "");
     const QMetaProperty getMetaProperty();
     const QMetaObject *getMetaObj() const;
@@ -42,7 +43,11 @@ class Attribute {
     QString getRelatedColumnName() const;
     void setRelatedColumnName(const QString &value);
 
-  private:
+    Relation getRelation() const;
+
+    QString toString() const;
+
+private:
     QString name;
     QString columnName;
     QString tableName;
@@ -51,6 +56,7 @@ class Attribute {
     const QMetaObject *baseMetaObj;
     QString relatedTable;
     const QMetaObject *relatedClass;
+    Relation relation;
     QString relatedColumnName;
     QString conjunctedTable;
 };
diff --git a/src/attributeresolver.cpp b/src/attributeresolver.cpp
index 8d147ef..2360288 100644
--- a/src/attributeresolver.cpp
+++ b/src/attributeresolver.cpp
@@ -43,13 +43,16 @@ Attribute *AttributeResolver::resolveManyToManyAttribute(const QSharedPointer<En
         ptr = target;
         attributeName = r.getMappedBy();
     }
-    auto obj = EntityHelper::getBaseClassObject(ptr, attributeName);
+    auto obj = EntityHelper::getBaseClassObject(e, attributeName);
+    /**
+     * @todo check inheritance and mappedBy
+     */
     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),
+    attrObj->setRelation(target->getTablename(), target->metaObject(), r,
+                         this->qb->generateManyToManyTableName(target->getTablename(), attributeName),
                          this->qb->generateColumnNameID(target->getTablename()));
     delete obj;
     return attrObj;
@@ -63,7 +66,7 @@ Attribute *AttributeResolver::resolveManyToOneAttribute(const QSharedPointer<Ent
                                        this->qb->generateColumnNameID(attr),
                                        e->getTablename(), e->metaObject());
     this->resolveInheritance(e, attrObj);
-    attrObj->setRelation(target->getTablename(), target->metaObject(), "", "id");
+    attrObj->setRelation(target->getTablename(), target->metaObject(), r, "", "id");
     delete obj;
     return attrObj;
 }
@@ -74,7 +77,7 @@ Attribute *AttributeResolver::resolveOneToManyAttribute(const QSharedPointer<Ent
     Attribute *attrObj = new Attribute(attr, "id",
                                        e->getTablename(), e->metaObject());
     this->resolveInheritance(e, attrObj);
-    attrObj->setRelation(target->getTablename(), target->metaObject(), "",
+    attrObj->setRelation(target->getTablename(), target->metaObject(), r, "",
                          this->qb->generateColumnNameID(r.getMappedBy()));
     delete obj;
     return attrObj;
@@ -144,3 +147,21 @@ Attribute *AttributeResolver::resolveAttribute(const QSharedPointer<Entity> &cla
     }
     return attr;
 }
+
+Attribute *AttributeResolver::resolveAttribute(const QString &className,
+        const QString &attribute, const QString related) {
+    Attribute *attr = nullptr;
+    if(!className.isEmpty()) {
+        if(this->containsAttribute(className, attribute)) {
+            attr = this->attributes.value(className).value(attribute);
+        } else {
+            QSharedPointer<Entity> e = QSharedPointer<Entity>(EntityInstanceFactory::createInstance(
+                                           className));
+            QSharedPointer<Entity> rel = QSharedPointer<Entity>(EntityInstanceFactory::createInstance(
+                                             related));
+            attr = this->resolveExplicitAttribute(e, attribute, rel);
+            this->addAttribute(className, attr);
+        }
+    }
+    return attr;
+}
diff --git a/src/attributeresolver.h b/src/attributeresolver.h
index ac521b5..fdd50be 100644
--- a/src/attributeresolver.h
+++ b/src/attributeresolver.h
@@ -13,6 +13,7 @@ class AttributeResolver {
     bool containsAttribute(const QString &className, const QString &attribute) const;
     Attribute* resolveAttribute(const QSharedPointer<Entity> &classObj,
                                 const QString &attribute, QSharedPointer<Entity> related = QSharedPointer<Entity>());
+    Attribute* resolveAttribute(const QString &className, const QString &attribute, const QString related="");
     QHash<QString, QHash<QString, Attribute *>> getAttributes() const;
     void setAttributes(const QHash<QString, QHash<QString, Attribute *>> &value);
   protected:
diff --git a/src/entitymanager.cpp b/src/entitymanager.cpp
index bec220a..3e4f660 100644
--- a/src/entitymanager.cpp
+++ b/src/entitymanager.cpp
@@ -818,36 +818,32 @@ void EntityManager::missingManyToManyTable(const QString &tblName,
 }
 
 void EntityManager::manyToMany(const QSharedPointer<Entity> &entity,
-                               const QMetaProperty &property, const Relation &relation, const bool refresh) {
+                               Attribute *&attr, const bool refresh) {
     QSharedPointer<Entity> secEntityPtr = QSharedPointer<Entity>
-                                          (EntityInstanceFactory::createInstance(EntityInstanceFactory::extractEntityType(
-                                                  QString(property.typeName()))));
+                                          (EntityInstanceFactory::createInstance(attr->getRelatedClass()->className()));
     auto builder = this->schema->getQueryBuilder();
-    EntityHelper::clearEntityListProperty(entity, property);
+    EntityHelper::clearEntityListProperty(entity, attr->getMetaProperty());
     if (secEntityPtr) {
-        QString tblName = builder->generateManyToManyTableName(entity, secEntityPtr,
-                          relation);
-        if (this->schema->getTables().contains(tblName)) {
-            QSqlQuery q = builder->manyToMany(tblName,
-                                              builder->generateManyToManyColumnName(entity, relation.getPropertyName()),
+        if (this->schema->getTables().contains(attr->getTableName())) {
+            QSqlQuery q = builder->manyToMany(attr->getConjunctedTable(),
+                                              attr->getColumnName(),
                                               entity->getProperty(entity->getPrimaryKey()).toLongLong());
             auto listMap = this->convertQueryResult(q);
-            auto secClassName = EntityHelper::getClassName(secEntityPtr.data());
+            auto secClassName = attr->getRelatedClass()->className();
             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(attr->getRelatedColumnName());
                 if (refresh || !(this->cache.contains(id.toLongLong(), secClassName) &&
                                  (e = this->cache.get(id.toLongLong(), secClassName)))) {
                     e = this->findById(id.toLongLong(), secClassName);
                 }
                 if (e) {
-                    EntityHelper::addEntityToListProperty(entity, e, property);
+                    EntityHelper::addEntityToListProperty(entity, e, attr->getMetaProperty());
                     e = QSharedPointer<Entity>();
                 }
             }
         } else {
-            this->missingManyToManyTable(tblName, entity, relation);
+            this->missingManyToManyTable(attr->getTableName(), entity, attr->getRelation());
         }
     }
 }
@@ -921,8 +917,9 @@ void EntityManager::resolveRelations(const QSharedPointer<Entity> &entity,
     for (auto iterator = props.constBegin(); iterator != props.constEnd(); ++iterator) {
         const Relation r = iterator.key();
         const QMetaProperty property = iterator.value();
-        QString colName = this->schema->getQueryBuilder()->generateColumnNameID(
-                              r.getPropertyName());
+        auto attr = this->ar->resolveAttribute(entity->getClassname(), r.getPropertyName(),
+                                               EntityInstanceFactory::extractEntityType(property.typeName()));
+        QString colName = attr->getColumnName();
         switch (r.getType()) {
         case RelationType::MANY_TO_ONE:
             if (map.contains(colName)) {
@@ -930,7 +927,7 @@ void EntityManager::resolveRelations(const QSharedPointer<Entity> &entity,
             }
             break;
         case RelationType::MANY_TO_MANY:
-            this->manyToMany(entity, property, r, refresh);
+            this->manyToMany(entity, attr, refresh);
             break;
         case RelationType::ONE_TO_MANY:
             this->oneToMany(entity, r, property, refresh);
diff --git a/src/entitymanager.h b/src/entitymanager.h
index 6d329d0..cb3d9d6 100644
--- a/src/entitymanager.h
+++ b/src/entitymanager.h
@@ -301,8 +301,7 @@ protected:
                    const QMetaProperty &property, const bool refresh = false);
     void oneToMany(const QSharedPointer<Entity> &entity, const Relation &r,
                    const QMetaProperty &property, const bool refresh = false);
-    void manyToMany(const QSharedPointer<Entity> &entity,
-                    const QMetaProperty &property, const Relation &relation,
+    void manyToMany(const QSharedPointer<Entity> &entity, Attribute *&attr,
                     const bool refresh = false);
     void oneToOne(const QSharedPointer<Entity> &entity, const Relation &r,
                   const QMetaProperty &property, const bool refresh = false,
diff --git a/tests/em/tst_em.cpp b/tests/em/tst_em.cpp
index 5318522..88f3b64 100644
--- a/tests/em/tst_em.cpp
+++ b/tests/em/tst_em.cpp
@@ -6,6 +6,9 @@ void EmTest::initTestCase() {
     CuteEntityManager::EntityInstanceFactory::registerClass<Article>();
     CuteEntityManager::EntityInstanceFactory::registerClass<Employee>();
     CuteEntityManager::EntityInstanceFactory::registerClass<WorkerGroup>();
+//    this->e = new
+//    CuteEntityManager::EntityManager("QSQLITE",
+//                                     QDir::currentPath() + "/db.sqlite", "", "", "", 0, true);
     this->e = new CuteEntityManager::EntityManager("QSQLITE",
             ":memory:", "", "", "", "", true, "foreign_keys = ON", false);
 }
@@ -144,6 +147,9 @@ void EmTest::cleanup() {
     QVERIFY(this->e->executeQuery(qb->dropTable("group")));
     QVERIFY(this->e->executeQuery(qb->dropTable("person")));
     QVERIFY(this->e->executeQuery(qb->dropTable("article")));
+//    QVERIFY(this->e->executeQuery(qb->dropTable("workergroup_workers")));
+//    QVERIFY(this->e->executeQuery(qb->dropTable("workergroup")));
+//    QVERIFY(this->e->executeQuery(qb->dropTable("employee")));
     auto tableNames = this->e->getSchema()->getTableNames();
     QVERIFY(!tableNames.contains("person"));
     QVERIFY(!tableNames.contains("group"));
@@ -295,6 +301,7 @@ void EmTest::testRelations() {
     p3->setGroups(groups);
     QVERIFY(this->e->save(pEnt, true, true));
     this->e->refresh(gEnt);
+    qDebug() << g->getPersons().size();
     QVERIFY(g->getPersons().size() == 2);
     auto firstPerson = g->getPersons().first();
     g->removePerson(firstPerson);
