commit 94bf67c708c1655c33401c950d3ed9213c80b2a4
Author: Christian Ehringfeld <c.ehringfeld@t-online.de>
Date:   Fri Jul 24 17:51:26 2015 +0200

    improvements

diff --git a/src/database.cpp b/src/database.cpp
index cf39462..f2e14d3 100644
--- a/src/database.cpp
+++ b/src/database.cpp
@@ -65,20 +65,6 @@ QString Database::getConnectionName() {
     return this->connectionName;
 }
 
-bool Database::transaction(const QString &query) {
-    bool rc = false;
-    if (supportTransactions) {
-        this->startTransaction();
-        QSqlQuery sqlquery = QSqlQuery(this->database);
-        sqlquery.exec(query);
-        this->commitTransaction();
-    } else {
-        rc = this->exec(query);
-    }
-    qDebug() << "Executed Query:" << query;
-    return rc;
-}
-
 QSqlQuery Database::getQuery() {
     return QSqlQuery(this->database);
 }
@@ -104,13 +90,6 @@ bool Database::transaction(const QStringList &queries) {
     return ok;
 }
 
-bool Database::transaction(QSqlQuery &query) {
-    this->startTransaction();
-    query.exec();
-    this->debugQuery(query);
-    return this->commitTransaction();
-}
-
 bool Database::transaction(QList<QSqlQuery> &queries) {
     this->startTransaction();
     QSqlQuery q;
diff --git a/src/database.h b/src/database.h
index c3d45d7..b923323 100644
--- a/src/database.h
+++ b/src/database.h
@@ -47,9 +47,7 @@ class Database {
     QString getConnectionName();
     QSqlQuery getQuery();
     QSqlQuery getQuery(const QString &prepare);
-    bool transaction(const QString &query);
     bool transaction(const QStringList &queries);
-    bool transaction(QSqlQuery &query);
     bool transaction(QList<QSqlQuery> &queries);
     bool exec(const QString &query);
     bool exec(QStringList queries);
diff --git a/src/entitymanager.cpp b/src/entitymanager.cpp
index 3089b96..5e09bde 100644
--- a/src/entitymanager.cpp
+++ b/src/entitymanager.cpp
@@ -84,7 +84,7 @@ bool EntityManager::startup(QString version, QStringList toInitialize) {
 }
 
 bool EntityManager::executeQuery(const QString &query) {
-    return this->db->transaction(query);
+    return this->db->exec(query);
 }
 
 bool EntityManager::checkTable(const QSharedPointer<Entity> &entity) {
@@ -355,14 +355,14 @@ void EntityManager::persistMappedByRelation(const QList<QSharedPointer<Entity> >
         item = list.at(var);
         if (item->getProperty(item->getPrimaryKey()).toLongLong() > -1) {
             q.bindValue(1, item->getProperty(ptr->getPrimaryKey()));
-            q.exec();
+            this->schema->getDatabase()->exec(q);
             if (prop.isReadable()) {
                 this->addEntityToListProperty(entity, ptr, prop);
             } else {
                 qDebug() << "Query exec for many to many relation failed." <<
                          q.lastError().text();
                 qDebug() << "Involved entities: " << entity->getClassname() <<
-                         "(MainEntitiy) and "  << entity->getClassname();
+                         "(MainEntitiy) and "  << ptr->getClassname();
                 qDebug() << "Relation:" << r.getPropertyName();
             }
         }
@@ -495,7 +495,7 @@ void EntityManager::removeManyToManyEntityList(const QSharedPointer<Entity> &e,
                                || r.getCascadeType().contains(CascadeType::ALL);
                 bool remove = r.getCascadeType().contains(CascadeType::REMOVE)
                               || r.getCascadeType().contains(CascadeType::ALL);
-                if (q.exec()) {
+                if (this->schema->getDatabase()->exec(q)) {
                     for (int var = 0; var < list.size(); ++var) {
                         auto entity = list.at(var);
                         if (remove) {
@@ -539,7 +539,7 @@ void EntityManager::persistManyToMany(const QSharedPointer<Entity> &entity,
             QSqlQuery q = builder->manyToManyDelete(
                               tblName, builder->generateManyToManyColumnName(entity),
                               entity->getProperty(entity->getPrimaryKey()).toLongLong());
-            if (this->db->transaction(q)) {
+            if (this->db->exec(q)) {
                 auto nList = EntityInstanceFactory::castQVariantList(property);
                 this->persistMappedByRelation(nList, q, entity, ptr, r, tblName);
             }
@@ -619,8 +619,12 @@ bool EntityManager::create(QSharedPointer<Entity> &entity,
         QList<QSqlQuery> q = this->schema->getQueryBuilder()->create(
                                  entity);
         bool first = true;
+        QVariant id = -1;
         for (int var = 0; var < q.size(); ++var) {
             auto query = q.at(var);
+            if (!first) {
+                this->schema->getQueryBuilder()->bindValue(entity->getPrimaryKey(), id, query);
+            }
             rc = this->db->exec(query);
             if (!rc) {
                 qDebug() << "Query failed:" << query.lastError().text() << " of class " <<
@@ -628,7 +632,8 @@ bool EntityManager::create(QSharedPointer<Entity> &entity,
                 break;
             }
             if (first) {
-                entity->setProperty(entity->getPrimaryKey(), query.lastInsertId());
+                id = query.lastInsertId();
+                entity->setProperty(entity->getPrimaryKey(), id);
                 first = false;
             }
         }
diff --git a/src/querybuilder.cpp b/src/querybuilder.cpp
index 50d26d4..0259690 100644
--- a/src/querybuilder.cpp
+++ b/src/querybuilder.cpp
@@ -41,7 +41,7 @@ bool QueryBuilder::createTable(const QSharedPointer<Entity> &entity,
         if (!rc) {
             QSqlQuery q = this->database->getQuery(this->createTable(tableName,
                                                    tableDefinition));
-            if (this->database->transaction(q)) {
+            if (this->database->exec(q)) {
                 if (createRelationTables) {
                     auto relTables = this->generateRelationTables(entity);
                     auto i = relTables.constBegin();
@@ -354,7 +354,7 @@ QString QueryBuilder::buildCreateQuery(QHash<QString, QVariant>::const_iterator
             first = false;
         }
         p1 += this->schema->quoteColumnName(i.key());
-        p2 += ":" + i.key();
+        p2 += this->placeHolder(i.key());
         ++i;
     }
     p1 += ")";
@@ -509,9 +509,10 @@ QString QueryBuilder::getColumnType(const QString &type) const {
  * @return
  */
 QSqlQuery QueryBuilder::find(const qint64 &id, const QString &tableName) const {
+    QString pk = "id";
     QSqlQuery q = this->database->getQuery(this->selectBase(QStringList(
-            tableName)) + " WHERE id= :id LIMIT 1;");
-    q.bindValue(":id", id);
+            tableName)) + " WHERE " + pk + " = " + this->placeHolder(pk) + " LIMIT 1;");
+    this->bindValue(pk, id, q);
     return q;
 }
 
@@ -541,8 +542,8 @@ QSqlQuery QueryBuilder::find(const qint64 &id,
     QSqlQuery q = this->database->getQuery(this->selectBase(QStringList(
             entity->getTablename())) + this->joinSuperClasses(
                     entity) + " WHERE " + this->schema->quoteColumnName(
-                            pk) + "= :id" + this->limit(1, offset));
-    q.bindValue(":id", id);
+                            pk) + "= " + this->placeHolder(pk) + this->limit(1, offset));
+    this->bindValue(pk, id, q);
     return q;
 }
 
@@ -611,8 +612,9 @@ QSqlQuery QueryBuilder::remove(const QString &tableName,
     QSqlQuery q = this->database->getQuery("DELETE FROM " +
                                            this->schema->quoteTableName(
                                                    tableName) + " WHERE " +
-                                           this->schema->quoteColumnName(primaryKey) + "=:id;");
-    q.bindValue(":id", id);
+                                           this->schema->quoteColumnName(primaryKey) + "=" + this->placeHolder(
+                                                   primaryKey) + ";");
+    this->bindValue(primaryKey, id, q);
     return q;
 }
 
@@ -657,11 +659,15 @@ QList<QSqlQuery> QueryBuilder::createOrMerge(const QSharedPointer<Entity>
         &entity, bool insert) const {
     const QList<ClassAttributes> attrs = this->inheritedAttributes(entity);
     auto queries = QList<QSqlQuery>();
+    bool first = true;
     for (int var = 0; var < attrs.size(); ++var) {
         auto attr = attrs.at(var);
         auto attrHash = attr.getAttributes();
         queries.append(insert ? this->insert(attr.getName(), attrHash,
-                                             attr.getPk()) : this->update(attr.getName(), attrHash, attr.getPk()));
+                                             attr.getPk(), !first) : this->update(attr.getName(), attrHash, attr.getPk()));
+        if (first) {
+            first = false;
+        }
     }
     return queries;
 }
@@ -676,12 +682,11 @@ QSqlQuery QueryBuilder::removeAll(const QString &tableName) const {
 }
 
 QSqlQuery QueryBuilder::insert(const QString &tableName,
-                               QHash<QString, QVariant> &attributes, const QString &primaryKey) const {
-    //if(attributes.size() == 1) {
-    // attributes.insert(primaryKey,QVariant("null"));
-    //  } else {
-    attributes.remove(primaryKey);
-//    }
+                               QHash<QString, QVariant> &attributes, const QString &primaryKey,
+                               bool withId) const {
+    if (!withId) {
+        attributes.remove(primaryKey);
+    }
     QSqlQuery q = this->database->getQuery();
     QString p1 = "INSERT INTO " + this->schema->quoteTableName(
                      tableName) + "(";
@@ -696,10 +701,10 @@ QSqlQuery QueryBuilder::insert(const QString &tableName,
 
 QSqlQuery QueryBuilder::update(const QString &tableName,
                                QHash<QString, QVariant> &attributes, const QString &primaryKey) const {
-    QSqlQuery q = this->database->getQuery("UPDATE " +
-                                           this->schema->quoteTableName(tableName) + " SET " + this->attributes(
-                                                   attributes) + " WHERE " + this->schema->quoteColumnName(
-                                                           primaryKey) + "=:id;");
+    QSqlQuery q = this->database->getQuery("UPDATE " + this->schema->quoteTableName(
+            tableName) + " SET " + this->attributes(attributes) + " WHERE " +
+                                           this->schema->quoteColumnName(primaryKey) + " = " + this->placeHolder(
+                                                   primaryKey) + ";");
     this->bindValues(attributes, q);
     return q;
 }
@@ -719,23 +724,25 @@ QSqlQuery QueryBuilder::manyToMany(const QString &tableName,
                                    const qint64 &id) {
     QSqlQuery q = this->database->getQuery();
     QString sql = this->selectBase(QStringList(tableName), QStringList("*"));
+    QString pk = "id";
     sql += " WHERE ";
     sql += this->schema->quoteColumnName(
                attribute);
-    sql += " = :id;";
+    sql += " = " + this->placeHolder(pk) + ";";
     q.prepare(sql);
-    q.bindValue(":id", id);
+    this->bindValue(pk, id, q);
     return q;
 }
 
 QSqlQuery QueryBuilder::manyToManyDelete(const QString &tableName,
         const QString &attribute, const qint64 &id) {
     QSqlQuery q = this->database->getQuery();
+    QString pkCol = "id";
     QString sql = "DELETE FROM " + this->schema->quoteTableName(
                       tableName) + " WHERE " + this->schema->quoteColumnName(
-                      attribute) + "=:id";
+                      attribute) + "=" + this->placeHolder(pkCol);
     q.prepare(sql);
-    q.bindValue(":id", id);
+    this->bindValue(pkCol, id, q);
     return q;
 }
 
@@ -970,12 +977,21 @@ void QueryBuilder::bindValues(const QHash<QString, QVariant> &h, QSqlQuery &q,
     QHash<QString, QVariant>::const_iterator i = h.constBegin();
     while (i != h.constEnd()) {
         if (!ignoreID || (ignoreID && !(i.key() == primaryKey))) {
-            q.bindValue(":" + i.key(), i.value());
+            this->bindValue(i.key(), i.value(), q);
         }
         ++i;
     }
 }
 
+void QueryBuilder::bindValue(const QString &key, const QVariant &value,
+                             QSqlQuery &q) const {
+    q.bindValue(this->placeHolder(key), value);
+}
+
+QString QueryBuilder::placeHolder(const QString &key) const {
+    return QString(":" + key);
+}
+
 QString QueryBuilder::where(const QSharedPointer<Entity> &entity,
                             QString conjunction,
                             bool ignoreID) const {
@@ -1004,7 +1020,7 @@ QString QueryBuilder::attributes(const QHash<QString, QVariant> &m,
                 if (!(rc == "")) {
                     rc += " " + conjunction + " ";
                 }
-                rc += this->schema->quoteColumnName(i.key()) + "=:" + i.key();
+                rc += this->schema->quoteColumnName(i.key()) + "=" + this->placeHolder(i.key());
             }
             ++i;
         }
diff --git a/src/querybuilder.h b/src/querybuilder.h
index 723d99b..510f063 100644
--- a/src/querybuilder.h
+++ b/src/querybuilder.h
@@ -136,6 +136,11 @@ class QueryBuilder {
     QString generateManyToManyColumnName(const QSharedPointer<Entity> &entity)
     const;
     QSqlQuery getQuery() const;
+    void bindValues(const QHash<QString, QVariant> &h, QSqlQuery &q,
+                    bool ignoreID = false, const QString &primaryKey = "id") const;
+    void bindValue(const QString &key, const QVariant &value, QSqlQuery &q) const;
+    virtual QString placeHolder(const QString &key) const;
+
 
   protected:
     class ClassAttributes {
@@ -161,7 +166,7 @@ class QueryBuilder {
     QSqlQuery remove(const QString &tableName, const qint64 &id,
                      const QString &primaryKey = "id") const;
     QSqlQuery insert(const QString &tableName, QHash<QString, QVariant> &attributes,
-                     const QString &primaryKey = "id") const;
+                     const QString &primaryKey = "id", bool withId = false) const;
     QSqlQuery update(const QString &tableName, QHash<QString, QVariant> &attributes,
                      const QString &primaryKey = "id") const;
     QList<QSqlQuery> createOrMerge(const QSharedPointer<Entity> &entity,
@@ -186,8 +191,6 @@ class QueryBuilder {
     QString buildCreateQuery(QHash<QString, QVariant>::const_iterator i,
                              QHash<QString, QVariant>::const_iterator end,
                              QString &p1, QString &p2) const;
-    void bindValues(const QHash<QString, QVariant> &h, QSqlQuery &q,
-                    bool ignoreID = false, const QString &primaryKey = "id") const;
     QString where(const QSharedPointer<Entity> &entity, QString conjunction = ",",
                   bool ignoreID = false) const;
     QString where(const QHash<QString, QVariant> &m,
