commit 99140fe92975397dfe28833c094a8648cb47b6da
Author: Christian Ehringfeld <c.ehringfeld@t-online.de>
Date:   Sat Jun 27 15:04:34 2015 +0200

    inheritance insert

diff --git a/src/database.cpp b/src/database.cpp
index 2dfd7ea..f84a479 100644
--- a/src/database.cpp
+++ b/src/database.cpp
@@ -122,7 +122,7 @@ bool Database::transaction(QList<QSqlQuery> &queries) {
 
 
 bool Database::commitTransaction() {
-    this->supportTransactions &&this->database.commit();
+    return this->supportTransactions &&this->database.commit();
 }
 
 bool Database::rollbackTransaction() {
diff --git a/src/entity.cpp b/src/entity.cpp
index e927fcb..5ecfa7d 100644
--- a/src/entity.cpp
+++ b/src/entity.cpp
@@ -169,6 +169,10 @@ QVariant Entity::property(const QString &name) const {
     return this->property(name.toLatin1().constData());
 }
 
+bool Entity::setProperty(const QString &name, const QVariant &value) {
+    return this->setProperty(name.toLatin1().constData(), value);
+}
+
 qint64 Entity::getId() const {
     return id;
 }
diff --git a/src/entity.h b/src/entity.h
index 02dd263..f936416 100644
--- a/src/entity.h
+++ b/src/entity.h
@@ -64,6 +64,7 @@ class Entity : public QObject {
     const QHash<Relation, QMetaProperty> getRelationProperties() const;
     const char *getClassname() const;
     QVariant property(const QString &name) const;
+    bool setProperty(const QString &name, const QVariant &value);
 
     qint64 getId() const;
     void setId(const qint64 &value);
diff --git a/src/entitymanager.cpp b/src/entitymanager.cpp
index 9827c19..961c538 100644
--- a/src/entitymanager.cpp
+++ b/src/entitymanager.cpp
@@ -261,7 +261,8 @@ void EntityManager::addEntityToListProperty(const QSharedPointer<Entity>
 void EntityManager::setProperty(const QSharedPointer<Entity> &entiy,
                                 QSharedPointer<Entity> value,
                                 const QMetaProperty &property) const {
-    if (value.data() && value.data()->getId() > -1) {
+    if (value && value.data()->property(value.data()->getPrimaryKey()).toLongLong()
+            > -1) {
         property.write(entiy.data(), QVariant(value));
     }
 }
@@ -548,14 +549,29 @@ bool EntityManager::create(QSharedPointer<Entity> &entity,
                            const bool persistRelations, const bool checkDuplicate) {
     bool rc = false;
     if (this->checkTable(entity) && !(checkDuplicate && this->count(entity) == 0)) {
-        QSqlQuery q = this->schema.data()->getQueryBuilder().data()->create(entity);
-        rc = this->db->transaction(q);
-        if (rc) {
-            entity.data()->setId(q.lastInsertId().toLongLong(&rc));
+        QList<QSqlQuery> q = this->schema.data()->getQueryBuilder().data()->create(
+                                 entity);
+        this->db->startTransaction();
+        bool first = true;
+        for (int var = 0; var < q.size(); ++var) {
+            auto query = q.at(var);
+            query.exec();
+            if (first) {
+                entity.data()->setProperty(entity.data()->getPrimaryKey(),
+                                           query.lastInsertId().toLongLong(&rc));
+                first = false;
+            }
+        }
+        if (!this->db->commitTransaction() || !rc) {
+            this->db->rollbackTransaction();
+            entity.data()->setId(-1);
+            rc = false;
+        } else {
             if (persistRelations) {
                 this->saveRelations(entity);
             }
             this->cache.insert(entity);
+            rc = true;
         }
     }
     return rc;
diff --git a/src/entitymanager.h b/src/entitymanager.h
index 04b6f39..f3a415e 100644
--- a/src/entitymanager.h
+++ b/src/entitymanager.h
@@ -147,7 +147,7 @@ class EntityManager : public QObject {
      *@TODO use conditions
      */
     /**
-     * @TODO Inheritance at create,save,merge
+     * @TODO Inheritance at merge
      */
     template<class T> qint8 count(QHash<QString, QString> condition =
                                       QHash<QString, QString>()) {
diff --git a/src/querybuilder.cpp b/src/querybuilder.cpp
index a9f9be3..ef4be2a 100644
--- a/src/querybuilder.cpp
+++ b/src/querybuilder.cpp
@@ -16,7 +16,6 @@
 #include "querybuilder.h"
 #include "database.h"
 #include <QMetaObject>
-#include <QMetaProperty>
 #include "entity.h"
 #include <QRegularExpression>
 #include "entityinstancefactory.h"
@@ -641,10 +640,16 @@ QSqlQuery QueryBuilder::merge(const QSharedPointer<Entity> &entity) const {
     return q;
 }
 
-QSqlQuery QueryBuilder::create(const QSharedPointer<Entity> &entity) const {
-    QHash<QString, QVariant> values = this->saveAttributes(entity);
-    return this->insert(entity.data()->getTablename(), values,
-                        entity.data()->getPrimaryKey());
+QList<QSqlQuery> QueryBuilder::create(const QSharedPointer<Entity> &entity)
+const {
+    auto attrs = this->inheritedAttributes(entity);
+    auto queries = QList<QSqlQuery>();
+    for (int var = 0; var < attrs.size(); ++var) {
+        auto attr = attrs.at(var);
+        auto attrHash = attr.getAttributes();
+        queries.append(this->insert(attr.getName(), attrHash, attr.getPk()));
+    }
+    return queries;
 }
 
 QSqlQuery QueryBuilder::insert(const QString &tableName,
@@ -761,11 +766,15 @@ QSqlQuery QueryBuilder::getQuery() const {
     return this->database.data()->getQuery();
 }
 
+
 QHash<QString, QVariant> QueryBuilder::saveAttributes(const
-        QSharedPointer<Entity> &entity) const {
-    auto props = entity.data()->getMetaProperties();
+        QSharedPointer<Entity> &entity, QHash<QString, QMetaProperty> props,
+        QHash<QString, Relation> relations) const {
+    if (props.isEmpty()) {
+        props = entity.data()->getMetaProperties();
+    }
     auto values = this->getEntityAttributes(props, entity);
-    auto relValues = this->getManyToOneAttributes(props, entity);
+    auto relValues = this->getManyToOneAttributes(props, entity, relations);
     auto iterator = relValues.constBegin();
     while (iterator != relValues.constEnd()) {
         values.insert(iterator.key(), iterator.value());
@@ -774,11 +783,66 @@ QHash<QString, QVariant> QueryBuilder::saveAttributes(const
     return values;
 }
 
+QHash<QString, QMetaProperty> QueryBuilder::processProperties(
+    const QSharedPointer<Entity> &e,
+    QHash<QString, QMetaProperty> &usedProperties) const {
+    auto properties = e.data()->getMetaProperties();
+    auto i = QMutableHashIterator<QString, QMetaProperty>(properties);
+    while (i.hasNext()) {
+        if (usedProperties.contains(i.key()) && i.key() != e.data()->getPrimaryKey()) {
+            properties.remove(i.key());
+        } else {
+            usedProperties.insert(i.key(), i.value());
+        }
+        i.next();
+    }
+    return properties;
+}
+
+QHash<QString, Relation> QueryBuilder::processRelations(
+    const QSharedPointer<Entity> &e,
+    QHash<QString, Relation> &usedRelations) const {
+    auto relations = e.data()->getRelations();
+    auto i = QMutableHashIterator<QString, Relation>(relations);
+    while (i.hasNext()) {
+        if (usedRelations.contains(i.key())) {
+            relations.remove(i.key());
+        } else {
+            usedRelations.insert(i.key(), i.value());
+        }
+        i.next();
+    }
+    return relations;
+}
+
 QList<QueryBuilder::ClassAttributes> QueryBuilder::inheritedAttributes(
     const QSharedPointer<Entity> &entity) const {
     auto list = QList<QueryBuilder::ClassAttributes>();
-
-
+    if (entity.data()->getInheritanceStrategy() == JOINED_TABLE) {
+        auto classes = QList<const QMetaObject *>();
+        classes.append(entity.data()->metaObject());
+        classes.append(entity.data()->superClasses(true));
+        auto usedProperties = QHash<QString, QMetaProperty>();
+        auto usedRelations = QHash<QString, Relation>();
+        QSharedPointer<Entity> e;
+        for (int var = classes.size(); var >= 0; --var) {
+            auto metaObj = classes.at(var);
+            e = QSharedPointer<Entity>(EntityInstanceFactory::createInstance(
+                                           metaObj->className()));
+            if (e) {
+                list.append(QueryBuilder::ClassAttributes(e.data()->getTablename(),
+                            this->saveAttributes(entity, this->processProperties(e, usedProperties),
+                                                 this->processRelations(e, usedRelations)), e.data()->getPrimaryKey()));
+            } else {
+                qDebug() << "Instance of " << metaObj->className() << " could not created";
+                break;
+            }
+        }
+    } else {
+        list.append(QueryBuilder::ClassAttributes(entity.data()->getTablename(),
+                    this->saveAttributes(entity), entity.data()->getPrimaryKey()));
+    }
+    return list;
 }
 
 QString QueryBuilder::leftJoin(const QString &foreignTable,
@@ -810,12 +874,15 @@ QHash<QString, QVariant> QueryBuilder::getEntityAttributes(
 }
 
 QHash<QString, QVariant> QueryBuilder::getManyToOneAttributes(
-    const QHash<QString, QMetaProperty>
-    &props,
-    const QSharedPointer<Entity> &entity) const {
+    QHash<QString, QMetaProperty>
+    props,
+    const QSharedPointer<Entity> &entity,
+    QHash<QString, Relation> relations) const {
     Entity *e = entity.data();
     auto map = QHash<QString, QVariant>();
-    auto relations = e->getRelations();
+    if (relations.isEmpty()) {
+        relations = e->getRelations();
+    }
     auto i = relations.constBegin();
     while (i != relations.constEnd()) {
         Relation r = i.value();
@@ -914,6 +981,13 @@ void QueryBuilder::setSchema(const QSharedPointer<Schema> &value) {
     schema = value;
 }
 
+QueryBuilder::ClassAttributes::ClassAttributes(const QString name,
+        const QHash<QString, QVariant> attributes, QString pk) {
+    this->name = name;
+    this->attributes = attributes;
+    this->pk = pk;
+}
+
 QString QueryBuilder::ClassAttributes::getName() const {
     return name;
 }
@@ -930,3 +1004,12 @@ void QueryBuilder::ClassAttributes::setAttributes(const QHash<QString, QVariant>
         &value) {
     attributes = value;
 }
+
+QString QueryBuilder::ClassAttributes::getPk() const {
+    return pk;
+}
+
+void QueryBuilder::ClassAttributes::setPk(const QString &value) {
+    pk = value;
+}
+
diff --git a/src/querybuilder.h b/src/querybuilder.h
index 82d02fe..339e0f2 100644
--- a/src/querybuilder.h
+++ b/src/querybuilder.h
@@ -21,6 +21,7 @@
 #include <QPointer>
 #include <QSqlQuery>
 #include <QStringList>
+#include <QMetaProperty>
 #include "relation.h"
 namespace CuteEntityManager {
 class Schema;
@@ -118,7 +119,7 @@ class QueryBuilder {
     QSqlQuery count(const QSharedPointer<Entity> &entity, bool ignoreID) const;
     QSqlQuery count(const QString &tableName) const;
     QSqlQuery merge(const QSharedPointer<Entity> &entity) const;
-    QSqlQuery create(const QSharedPointer<Entity> &entity) const;
+    QList<QSqlQuery> create(const QSharedPointer<Entity> &entity) const;
     QSqlQuery oneToMany(const QString &tableName, const QString &attribute,
                         const qint64 &id,
                         const qint64 &limit = 0);
@@ -138,15 +139,22 @@ class QueryBuilder {
 
   protected:
     class ClassAttributes {
-    public:
+      public:
+        ClassAttributes() { }
+        explicit ClassAttributes(const QString name,
+                                 const QHash<QString, QVariant> attributes, QString pk = "id");
         QString getName() const;
         void setName(const QString &value);
 
         QHash<QString, QVariant> getAttributes() const;
         void setAttributes(const QHash<QString, QVariant> &value);
 
-    private:
+        QString getPk() const;
+        void setPk(const QString &value);
+
+      private:
         QString name;
+        QString pk;
         QHash<QString, QVariant> attributes;
     };
 
@@ -162,10 +170,10 @@ class QueryBuilder {
     void insertRelationId(const Entity *e, QHash<QString, QVariant> &map,
                           QString relName) const;
     QString buildColumns(const QStringList &columns) const;
-    QHash<QString, QVariant> getManyToOneAttributes(const
-            QHash<QString, QMetaProperty>
-            &props,
-            const QSharedPointer<Entity> &entity) const;
+    QHash<QString, QVariant> getManyToOneAttributes(QHash<QString, QMetaProperty>
+            props,
+            const QSharedPointer<Entity> &entity,
+            QHash<QString, Relation> relations = QHash<QString, Relation>()) const;
     QHash<QString, QMetaProperty> getMetaProperties(const QSharedPointer<Entity>
             &entity)
     const;
@@ -185,10 +193,16 @@ class QueryBuilder {
     QString attributes(const QHash<QString, QVariant> &m,
                        const QString &conjunction = ",",
                        bool ignoreID = false, const QString &primaryKey = "id") const;
-    QHash<QString, QVariant> saveAttributes(const QSharedPointer<Entity> &entity)
+    QHash<QString, QVariant> saveAttributes(const QSharedPointer<Entity> &entity,
+                                            QHash<QString, QMetaProperty> props = QHash<QString, QMetaProperty> (),
+                                            QHash<QString, Relation> relations = QHash<QString, Relation>())
     const;
+    QHash<QString, QMetaProperty> processProperties(const QSharedPointer<Entity> &e,
+            QHash<QString, QMetaProperty> &usedProperties) const;
+    QHash<QString, Relation> processRelations(const QSharedPointer<Entity> &e,
+            QHash<QString, Relation> &usedRelations) const;
     QList<ClassAttributes> inheritedAttributes(
-            const QSharedPointer<Entity> &entity) const;
+        const QSharedPointer<Entity> &entity) const;
 
     QString leftJoin(const QString &foreignTable, const QString &tableName,
                      const QString &foreignKey = "id", const QString &primaryKey = "id") const;
