commit 4e75d5a1eccaf269829248be40dbe3f2e0160e01
Author: Christian Ehringfeld <c.ehringfeld@t-online.de>
Date:   Sun Dec 6 12:40:18 2015 +0100

    many-to-many table name resolve

diff --git a/src/attribute.cpp b/src/attribute.cpp
new file mode 100644
index 0000000..f5c0ad5
--- /dev/null
+++ b/src/attribute.cpp
@@ -0,0 +1,7 @@
+#include "attribute.h"
+using namespace CuteEntityManager;
+Attribute::Attribute()
+{
+
+}
+
diff --git a/src/attribute.h b/src/attribute.h
new file mode 100644
index 0000000..556ce7f
--- /dev/null
+++ b/src/attribute.h
@@ -0,0 +1,17 @@
+#ifndef ATTRIBUTE_H
+#define ATTRIBUTE_H
+#include <QString>
+namespace CuteEntityManager {
+
+
+class Attribute {
+  public:
+    Attribute();
+private:
+    QString name;
+    QString className;
+    QString relatedClass;
+    QString relatedTable;
+};
+}
+#endif // ATTRIBUTE_H
diff --git a/src/entityhelper.cpp b/src/entityhelper.cpp
index dea965b..796fe2f 100644
--- a/src/entityhelper.cpp
+++ b/src/entityhelper.cpp
@@ -164,6 +164,28 @@ Entity* EntityHelper::copyObject(const Entity *entity) {
     return newInstance;
 }
 
+Entity *EntityHelper::getBaseClassObject(const QSharedPointer<Entity> &entity,
+        QString attributeName) {
+    auto superObject = EntityInstanceFactory::createInstance(entity->metaObject());
+    auto objectBefore = superObject;
+    bool first = true;
+    while(superObject) {
+        auto props = EntityHelper::getMetaProperties(superObject);
+        if(!props.contains(attributeName) ||
+                superObject->getInheritanceStrategy() == InheritanceStrategy::PER_CLASS_TABLE) {
+            break;
+        } else if(!first){
+            delete objectBefore;
+            objectBefore = nullptr;
+        } else {
+            first = false;
+        }
+        objectBefore = superObject;
+        superObject = EntityInstanceFactory::newSuperClassInstance(superObject);
+    }
+    return objectBefore;
+}
+
 const char *EntityHelper::getClassname(const Entity *entity) {
     return entity->metaObject()->className();
 }
diff --git a/src/entityhelper.h b/src/entityhelper.h
index 9bdb7d1..000f3fa 100644
--- a/src/entityhelper.h
+++ b/src/entityhelper.h
@@ -40,13 +40,14 @@ class EntityHelper {
         const Entity *entity);
     static const QHash<QString, QMetaProperty> getMetaProperties(
         const QMetaObject *object);
-    static const QHash<QString, QMetaProperty> getNonInheritedMetaProperties(const Entity *entity);
+    static const QHash<QString, QMetaProperty> getNonInheritedMetaProperties(
+        const Entity *entity);
     static const QHash<QString, QMetaProperty> getInheritedMetaProperties(
         const Entity *entity);
     static const QHash<Relation, QMetaProperty> getRelationProperties(
         const Entity *entity);
     static Entity* copyObject(const Entity *entity);
-
+    static Entity* getBaseClassObject(const QSharedPointer<Entity> &entity, QString attributeName);
 
     static const char *getClassname(const Entity *entity);
     static const QString getClassName(const Entity *entity);
@@ -54,7 +55,8 @@ class EntityHelper {
                                         QSharedPointer<Entity> add, const QMetaProperty &property);
     static void removeEntityFromListProperty(const QSharedPointer<Entity> &entity,
             QSharedPointer<Entity> remove, const QMetaProperty &property);
-    static void clearEntityListProperty(const QSharedPointer<Entity> &entity, const QMetaProperty &property);
+    static void clearEntityListProperty(const QSharedPointer<Entity> &entity,
+                                        const QMetaProperty &property);
     static void setListProperty(const QSharedPointer<Entity> &entity,
                                 QList<QSharedPointer<Entity>> &list,
                                 const QMetaProperty &property);
@@ -67,8 +69,7 @@ class EntityHelper {
     static QMetaProperty mappedProperty(const Relation &r,
                                         const QSharedPointer<Entity> &foreignEntity);
     static QHash<QString, QVariant> getEntityAttributes(const
-            QHash<QString, QMetaProperty>
-            &props,
+            QHash<QString, QMetaProperty> &props,
             const QSharedPointer<Entity> &entity);
 };
 }
diff --git a/src/entitymanager.cpp b/src/entitymanager.cpp
index 371cd43..4017784 100644
--- a/src/entitymanager.cpp
+++ b/src/entitymanager.cpp
@@ -580,8 +580,8 @@ void EntityManager::persistMappedByRelation(const QList<QSharedPointer<Entity>>
     this->db->startTransaction();
     auto builder = this->schema->getQueryBuilder();
     q = builder->manyToManyInsert(tblName,
-                                  builder->generateManyToManyColumnName(entity),
-                                  builder->generateManyToManyColumnName(ptr));
+                                  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;
@@ -733,7 +733,7 @@ void EntityManager::removeManyToManyEntityList(const QSharedPointer<Entity> &e,
             QString tblName = builder->generateManyToManyTableName(e, ptr, r);
             if (this->schema->getTables().contains(tblName)) {
                 QSqlQuery q = builder->manyToManyDelete(
-                                  tblName, builder->generateManyToManyColumnName(e),
+                                  tblName, builder->generateManyToManyColumnName(e,r.getPropertyName()),
                                   e->getProperty(e->getPrimaryKey()).toLongLong());
                 if (this->db->exec(q)) {
                     bool refresh = r.getCascadeType().contains(CascadeType::REFRESH)
@@ -786,7 +786,7 @@ void EntityManager::persistManyToMany(const QSharedPointer<Entity> &entity,
               * @todo diff and remove entity from relational object when association is deleted
               */
             q = builder->manyToManyDelete(
-                    tblName, builder->generateManyToManyColumnName(entity),
+                    tblName, builder->generateManyToManyColumnName(entity,r.getPropertyName()),
                     entity->getProperty(entity->getPrimaryKey()).toLongLong());
             ok = this->db->exec(q);
         } else {
@@ -825,13 +825,13 @@ void EntityManager::manyToMany(const QSharedPointer<Entity> &entity,
                           relation);
         if (this->schema->getTables().contains(tblName)) {
             QSqlQuery q = builder->manyToMany(tblName,
-                                              builder->generateManyToManyColumnName(entity),
+                                              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));
+                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);
diff --git a/src/querybuilder.cpp b/src/querybuilder.cpp
index 96458bb..5fb8634 100644
--- a/src/querybuilder.cpp
+++ b/src/querybuilder.cpp
@@ -150,7 +150,7 @@ void QueryBuilder::createRelationFK(QStringList &queries,
 QString QueryBuilder::createForeignKeyManyToMany(const QString &tableName,
         const QSharedPointer<Entity> &entity, const QString &update,
         const QString &remove) const {
-    QString fkColumn = this->generateManyToManyColumnName(entity);
+    QString fkColumn = this->generateManyToManyColumnName(entity, "id");
     QString indexName = this->generateIndexName(fkColumn,
                         tableName, fkColumn,
                         entity->getTablename(), true);
@@ -427,11 +427,16 @@ const {
 QString QueryBuilder::generateManyToManyTableName(const QSharedPointer<Entity>
         &firstEntity,
         const QSharedPointer<Entity> &secondEntity, const Relation &r) const {
-    if (r.getMappedBy().isEmpty()) {
-        return firstEntity->getTablename() + "_" + r.getPropertyName();
-    } else {
-        return secondEntity->getTablename() + "_" + r.getMappedBy();
+    auto ptr = firstEntity;
+    QString attributeName = r.getPropertyName();
+    if (!r.getMappedBy().isEmpty()) {
+        ptr = secondEntity;
+        attributeName = r.getMappedBy();
     }
+    auto obj = EntityHelper::getBaseClassObject(ptr, attributeName);
+    QString tblName = obj->getTablename() + "_" + attributeName;
+    delete obj;
+    return tblName;
 }
 
 QHash<QString, QHash<QString, QString>> QueryBuilder::generateRelationTables(
@@ -446,13 +451,13 @@ const QSharedPointer<Entity> &entity) const {
         if (r.getType() == RelationType::MANY_TO_MANY && r.getMappedBy().isEmpty()) {
             QHash<QString, QString> h = QHash<QString, QString>();
             h.insert(entity->getPrimaryKey(), this->schema->TYPE_BIGPK);
-            h.insert(this->generateManyToManyColumnName(entity),
+            h.insert(this->generateManyToManyColumnName(entity, r.getPropertyName()),
                      this->schema->TYPE_BIGINT);
             auto meta = props.value(r.getPropertyName());
             QSharedPointer<Entity> ptr = QSharedPointer<Entity>
                                          (EntityInstanceFactory::createInstance(EntityInstanceFactory::extractEntityType(
                                                  QMetaType::typeName(meta.userType()))));
-            h.insert(this->generateManyToManyColumnName(ptr),
+            h.insert(this->generateManyToManyColumnName(ptr, r.getMappedBy()),
                      this->schema->TYPE_BIGINT);
             relations.insert(this->generateManyToManyTableName(entity, ptr, r), h);
         }
@@ -917,9 +922,12 @@ QString QueryBuilder::limit(const quint64 &limit, const quint64 &offset,
 }
 
 QString QueryBuilder::generateManyToManyColumnName(const QSharedPointer<Entity>
-        &entity) const {
+        &entity, QString attribute) const {
     if (entity) {
-        return this->generateColumnNameID(entity->getTablename());
+        auto obj = EntityHelper::getBaseClassObject(entity, attribute);
+        QString tblName = obj->getTablename();
+        delete obj;
+        return this->generateColumnNameID(tblName);
     }
     this->database->getLogger()->logMsg("Entity is empty!", MsgType::WARNING);
     return "";
diff --git a/src/querybuilder.h b/src/querybuilder.h
index dcca6e4..9741e90 100644
--- a/src/querybuilder.h
+++ b/src/querybuilder.h
@@ -258,8 +258,7 @@ class 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)
-    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;
diff --git a/src/sqlitebackupprocessor.cpp b/src/sqlitebackupprocessor.cpp
index d6047fb..93cf48f 100644
--- a/src/sqlitebackupprocessor.cpp
+++ b/src/sqlitebackupprocessor.cpp
@@ -91,7 +91,6 @@ bool SqliteBackupProcessor::sqliteDBMemFile(bool save, QString fileName) {
             sqlite3_backup *pBackup;  /* Backup object used to copy data */
             sqlite3 *pTo;             /* Database to copy to (pFile or pInMemory) */
             sqlite3 *pFrom;           /* Database to copy from (pFile or pInMemory) */
-
             /* Open the database file identified by zFilename. Exit early if this fails
             ** for any reason. */
             rc = sqlite3_open( zFilename, &pFile );
diff --git a/src/src.pro b/src/src.pro
index f488ca0..9e0d919 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -53,7 +53,8 @@ entity.h \
     validators/lengthvalidator.h \
     schema/mysqlquerybuilder.h \
     entityinspector.h \
-    sqlitebackupprocessor.h
+    sqlitebackupprocessor.h \
+    attribute.h
 
 SOURCES += \
 entity.cpp \
@@ -97,7 +98,8 @@ entity.cpp \
     validators/lengthvalidator.cpp \
     schema/mysqlquerybuilder.cpp \
     entityinspector.cpp \
-    sqlitebackupprocessor.cpp
+    sqlitebackupprocessor.cpp \
+    attribute.cpp
 
 win32:!system-sqlite:!contains(LIBS, .*sqlite3.*) {
     include($$[QT_INSTALL_PREFIX]/../Src/qtbase/src/3rdparty/sqlite.pri)
