commit 373a84e242baf1174447cb6837b0082cdc5c57c3
Author: Christian Ehringfeld <c.ehringfeld@t-online.de>
Date:   Thu Mar 24 03:19:59 2016 +0100

    wip

diff --git a/src/entitymanager.cpp b/src/entitymanager.cpp
index 96cb062..207a25f 100644
--- a/src/entitymanager.cpp
+++ b/src/entitymanager.cpp
@@ -321,10 +321,10 @@ QSharedPointer<Schema> EntityManager::getSchema() const {
     return schema;
 }
 
-void EntityManager::refresh(QSharedPointer<Entity> &entity) {
+void EntityManager::refresh(QSharedPointer<Entity> &entity, const bool resolveRelations) {
     if(entity) {
         auto map  = this->findByPk(entity->getId(), entity);
-        this->convert(map, entity, true);
+        this->convert(map, entity, true, resolveRelations);
     }
 }
 
@@ -438,10 +438,10 @@ QSharedPointer<Entity> EntityManager::findById(const qint64 &id,
 }
 
 QSharedPointer<Entity> EntityManager::findById(const qint64 &id,
-        const QString &classname) {
+        const QString &classname, const bool refresh) {
     QSharedPointer<Entity> e = QSharedPointer<Entity>
                                (EntityInstanceFactory::createInstance(classname));
-    return this->findById(id, e);
+    return this->findById(id, e, refresh);
 }
 
 void EntityManager::manyToOne(const QSharedPointer<Entity> &entity,
@@ -454,7 +454,7 @@ void EntityManager::manyToOne(const QSharedPointer<Entity> &entity,
         QSharedPointer<Entity> ptr = QSharedPointer<Entity>();
         if (refresh || !(this->cache.contains(convertedId, className)
                          && (ptr = this->cache.get(convertedId, className)))) {
-            ptr = this->findById(convertedId, className);
+            ptr = this->findById(convertedId, className, refresh);
         }
         EntityHelper::setProperty(entity, ptr, attr->getMetaProperty());
     }
@@ -465,8 +465,10 @@ void EntityManager::oneToMany(const QSharedPointer<Entity> &entity,
     if (entity.data() && entity->getId() > -1) {
         auto e = QSharedPointer<Entity>(EntityInstanceFactory::createInstance(attr));
         if (e) {
-            QSqlQuery q = this->schema->getQueryBuilder()->oneToMany(attr->getRelatedTable(),
-                          attr->getRelatedColumnName(), entity->getId());
+            Query query = this->schema->getQueryBuilder()->oneToMany(
+                        attr->getRelatedTable(),
+                        attr->getRelatedColumnName(), entity->getId());
+            QSqlQuery q = this->queryInterpreter->build(query);
             auto listMap = this->convertQueryResult(q);
             auto entities = this->convert(listMap, EntityHelper::getClassname(e.data()),
                                           refresh);
@@ -484,11 +486,12 @@ void EntityManager::oneToOne(const QSharedPointer<Entity> &entity,
     } else {
         auto e = QSharedPointer<Entity>(EntityInstanceFactory::createInstance(attr));
         if (e) {
-            QSqlQuery q = this->schema->getQueryBuilder()->oneToMany(
+            Query query = this->schema->getQueryBuilder()->oneToMany(
                               e->getTablename(),
                               this->schema->getQueryBuilder()->generateColumnNameID(
                                   attr->getRelation().getMappedBy()),
                               entity->getProperty(entity->getPrimaryKey()).toLongLong(), 1);
+            QSqlQuery q = this->queryInterpreter->build(query);
             auto listMap = this->convertQueryResult(q);
             auto entities = this->convert(listMap, EntityHelper::getClassname(e.data()),
                                           refresh);
@@ -868,15 +871,17 @@ QList<QHash<QString, QVariant>> EntityManager::findAllByAttributes(
                                  const QSharedPointer<Entity>
                                  &entity,
 bool ignoreID) {
-    QSqlQuery q = this->schema->getQueryBuilder()->findByAttributes(
+    Query query = this->schema->getQueryBuilder()->findByAttributes(
                       entity, ignoreID);
+    QSqlQuery q = this->queryInterpreter->build(query);
     return this->convertQueryResult(q);
 }
 
 QList<QHash <QString, QVariant>> EntityManager::findAllByAttributes(
 const QHash<QString, QVariant> &m, const QString &tblname, bool ignoreID) {
-    QSqlQuery q = this->schema->getQueryBuilder()->findByAttributes(m,
+    Query query = this->schema->getQueryBuilder()->findByAttributes(m,
                   tblname, ignoreID);
+    QSqlQuery q = this->queryInterpreter->build(query);
     return this->convertQueryResult(q);
 }
 
diff --git a/src/entitymanager.h b/src/entitymanager.h
index c69d879..2b6e922 100644
--- a/src/entitymanager.h
+++ b/src/entitymanager.h
@@ -59,7 +59,7 @@ class EntityManager : public QObject {
     bool startup(QString version, QStringList toInitialize,
                  bool createIndices = false);
     bool executeQuery(const QString &query);
-    QSharedPointer<Entity> findById(const qint64 &id, const QString &classname);
+    QSharedPointer<Entity> findById(const qint64 &id, const QString &classname, const bool refresh=false);
     QList<QSharedPointer<Entity>> findEntityByAttributes(const
                                QSharedPointer<Entity> &entity,
                                bool ignoreID = false, const bool refresh = false, const bool resolveRelations = true);
@@ -121,7 +121,7 @@ class EntityManager : public QObject {
      * fetches an entity again from the database
      * @param entity
      */
-    void refresh(QSharedPointer<Entity> &entity);
+    void refresh(QSharedPointer<Entity> &entity, const bool resolveRelations=true);
     QList<QHash<QString, QVariant>> selectByQuery(Query &query);
     QList<QHash<QString, QVariant>> selectBySql(const QString &sql);
     quint32 count(Query &query);
@@ -209,7 +209,7 @@ class EntityManager : public QObject {
         &attributes, const bool joinBaseClasses = false,
         const bool resolveRelations = true, const bool refresh=false) {
         auto list = this->findAllEntitiesByAttributes<T>(attributes, 1, 0,
-                    joinBaseClasses, resolveRelations, refresh);
+                    joinBaseClasses, resolveRelations,refresh);
         if (list.isEmpty()) {
             return QSharedPointer<T>();
         }
@@ -234,8 +234,7 @@ class EntityManager : public QObject {
             query.setOffset(offset);
             QSqlQuery q = this->queryInterpreter->build(query);
             auto results = this->convertQueryResult(q);
-            auto list = this->convert(results, EntityHelper::getClassname(e.data()), refresh,
-                                      resolveRelations);
+            auto list = this->convert(results, EntityHelper::getClassname(e.data()),refresh,resolveRelations);
             return EntityManager::convertList<T>(list);
         }
         return QList<QSharedPointer<T>>();
diff --git a/src/expression.cpp b/src/expression.cpp
index 57345b2..fe84fdb 100644
--- a/src/expression.cpp
+++ b/src/expression.cpp
@@ -22,7 +22,8 @@ Expression::Expression() {
 Expression::Expression(QString expression, QHash<QString, QVariant> params,
                        bool onlyColumn) {
     for(auto i = params.begin(); i != params.end(); ++i) {
-        expression.replace(":" + i.key(),":" + this->generateParam());
+        QString ikey = i.key();
+        expression.replace(":" + ikey.replace('.','_'),":" + this->generateParam());
         this->appendParam(i.key(),i.value());
     }
     this->expression = expression;
@@ -30,7 +31,7 @@ Expression::Expression(QString expression, QHash<QString, QVariant> params,
 }
 
 Expression::Expression(QString expression, QString key, QVariant value, bool onlyColumn) {
-    this->expression = expression.replace(":" + key, ":" + this->generateParam());
+    this->expression = expression.replace(":" + key.replace('.','_'), ":" + this->generateParam());
     this->appendParam(key, value);
     this->onlyColumn = onlyColumn;
 }
@@ -66,6 +67,9 @@ QString Expression::generateParam() {
 
 void Expression::appendParam(QString key, const QVariant &value) {
     this->params.insert(this->generateParam(), value);
+    /**
+      @todo remove
+      */
     this->params.insert(key.replace('.','_'), value);
 }
 
diff --git a/src/querybuilder.cpp b/src/querybuilder.cpp
index 5d6acbb..6c66c92 100644
--- a/src/querybuilder.cpp
+++ b/src/querybuilder.cpp
@@ -527,8 +527,11 @@ QSqlQuery QueryBuilder::find(const qint64 &id, const QString &tableName) const {
 }
 
 QString QueryBuilder::selectBase(const QStringList &tables,
-                                 const QStringList &columns) const {
-    QString r = "SELECT ";
+                                 const QStringList &columns, bool withKeyword) const {
+    QString r = "";
+    if(withKeyword) {
+        r = "SELECT ";
+    }
     if (columns.isEmpty()) {
         r += "*";
     } else {
@@ -564,20 +567,26 @@ QSqlQuery QueryBuilder::findAll(const QSharedPointer<Entity> &entity,
                                         entity) + this->limit(limit, offset) + ";");
 }
 
-QSqlQuery QueryBuilder::findByAttributes(const QHash<QString, QVariant> &m,
-        const QString &tableName,
-        const bool &ignoreID, const qint64 limit, const qint64 offset) const {
-    QSqlQuery q = this->database->getQuery(this->selectBase(QStringList(
-            tableName)) + this->where(m, this->andKeyword(), ignoreID) + this->limit(limit,
-                                           offset));
-    this->bindValues(m, q, ignoreID);
+Query QueryBuilder::findByAttributes(const QHash<QString, QVariant> &m,
+                                     const QString &tableName,
+                                     const bool &ignoreID, const qint64 limit, const qint64 offset) const {
+    Query q = Query();
+    q.setSelect(QStringList(this->selectBase(QStringList(
+                                tableName),QStringList(),false)));
+    q.appendWhere(Expression(this->where(m, this->andKeyword(), ignoreID, "id", false), m));
+    q.setLimit(limit);
+    q.setOffset(offset);
+//    QSqlQuery q = this->database->getQuery(this->selectBase(QStringList(
+//            tableName)) + this->where(m, this->andKeyword(), ignoreID) + this->limit(limit,
+//                                           offset));
+//    this->bindValues(m, q, ignoreID);
     return q;
 }
 
-QSqlQuery QueryBuilder::findByAttributes(const QSharedPointer<Entity> &e,
-        bool ignoreID,
-        const qint64 limit,
-        const qint64 offset) {
+Query QueryBuilder::findByAttributes(const QSharedPointer<Entity> &e,
+                                     bool ignoreID,
+                                     const qint64 limit,
+                                     const qint64 offset) {
     QHash<QString, QVariant> values = EntityHelper::getEntityAttributes(
                                           EntityHelper::getMetaProperties(e.data()), e);
     return this->findByAttributes(values, e->getTablename(), ignoreID, limit,
@@ -706,10 +715,10 @@ QSqlQuery QueryBuilder::update(const QString &tableName,
 }
 
 
-QSqlQuery QueryBuilder::oneToMany(const QString &tableName,
-                                  const QString &attribute,
-                                  const qint64 &id,
-                                  const qint64 &limit) {
+Query QueryBuilder::oneToMany(const QString &tableName,
+                              const QString &attribute,
+                              const qint64 &id,
+                              const qint64 &limit) {
     QHash<QString, QVariant> values = QHash<QString, QVariant>();
     values.insert(attribute, id);
     return this->findByAttributes(values, tableName, false, limit);
@@ -1098,8 +1107,7 @@ void QueryBuilder::bindValue(const QString &key, const QVariant &value,
 }
 
 QString QueryBuilder::placeHolder(QString key) const {
-    //return QString(":" + key.replace('.', '_'));
-    return QString(":" + key);
+    return QString(":" + key.replace('.', '_'));
 }
 
 QString QueryBuilder::where(const QHash<QString, QVariant> &m,
@@ -1330,7 +1338,7 @@ Expression QueryBuilder::where(QString c, QVariant value) {
 }
 
 Expression QueryBuilder::equal(QString &key, QVariant &value) {
-    Expression exp = Expression(this->where(key, value, false, true, false),key,value);
+    Expression exp = Expression(this->where(key, value, false, true, false), key, value);
     return exp;
 }
 
diff --git a/src/querybuilder.h b/src/querybuilder.h
index 80d6a97..b0a2d6f 100644
--- a/src/querybuilder.h
+++ b/src/querybuilder.h
@@ -201,11 +201,11 @@ class QueryBuilder {
     QSqlQuery find(const qint64 &id, const QString &tableName) const;
     QSqlQuery find(const qint64 &id, const QSharedPointer<Entity> &entity,
                    qint64 offset = 0, QString pk = "id") const;
-    QSqlQuery findByAttributes(const QHash<QString, QVariant> &m,
+    Query findByAttributes(const QHash<QString, QVariant> &m,
                                const QString &tableName,
                                const bool &ignoreID = true, const qint64 limit = 0,
                                const qint64 offset = 0) const;
-    QSqlQuery findByAttributes(const QSharedPointer<Entity> &e,
+    Query findByAttributes(const QSharedPointer<Entity> &e,
                                bool ignoreID = true,
                                const qint64 limit = 0, const qint64 offset = 0);
     QSqlQuery findAll(const QString &tableName) const;
@@ -217,7 +217,7 @@ class QueryBuilder {
     QList<QSqlQuery> merge(const QSharedPointer<Entity> &entity) const;
     QList<QSqlQuery> create(const QSharedPointer<Entity> &entity) const;
     QSqlQuery removeAll(const QString &tableName) const;
-    QSqlQuery oneToMany(const QString &tableName, const QString &attribute,
+    Query oneToMany(const QString &tableName, const QString &attribute,
                         const qint64 &id,
                         const qint64 &limit = 0);
     QSqlQuery manyToMany(const QString &tableName, const QString &attribute,
@@ -297,7 +297,7 @@ class QueryBuilder {
 
     QString joinSuperClasses(const QSharedPointer<Entity> &entity) const;
     virtual QString selectBase(const QStringList &tables,
-                               const QStringList &columns = QStringList()) const;
+                               const QStringList &columns = QStringList(), bool withKeyword=true) const;
     virtual QString countFunction(const QString &distinctColumn = "") const;
     virtual QString distinct() const;
     virtual QString notKeyword() const;
diff --git a/tests/em/tst_querybuilder.cpp b/tests/em/tst_querybuilder.cpp
index eb0bf2b..0b87b35 100644
--- a/tests/em/tst_querybuilder.cpp
+++ b/tests/em/tst_querybuilder.cpp
@@ -277,7 +277,9 @@ void QuerybuilderTest::testQueryBuilderManyToOneRelation() {
     QCOMPARE(list.size(), 1);
     QCOMPARE(list.at(0)->getNickName(), QString("Lotta"));
     q = Query();
-    q.appendWhere(q.equal(qb, "leader", QVariant(list.at(0))));
+    QVariant var;
+    var.setValue<QSharedPointer<Employee>>(list.at(0));
+    q.appendWhere(q.equal(qb, "leader", var));
     QList<QSharedPointer<Group>> groupList = e->find<Group>(q, false);
     QCOMPARE(groupList.size(), 1);
     QCOMPARE(groupList.at(0)->getName(), QString("Group Health"));
@@ -316,3 +318,16 @@ void QuerybuilderTest::testQueryBuilderManyToManyRelationAttribute() {
     QCOMPARE(groupList.at(0)->getName(), QString("Group Psy"));
     QCOMPARE(groupList.at(0)->getPersons().size(), 3);
 }
+
+void QuerybuilderTest::testRefresh() {
+    auto persons = e->findAll<Person>(false);
+    QCOMPARE(persons.first()->getGroups().size(), 0);
+    QHash<QString, QVariant> attributes;
+    attributes["name"] = QString("Group Health");
+    QSharedPointer<Group> g = this->e->findEntityByAttributes<Group>(attributes, false, false,
+                              false);
+    QCOMPARE(g->getPersons().count(), 0);
+    auto entity = g.objectCast<Entity>();
+    e->refresh(entity, true);
+    QCOMPARE(g->getPersons().count(), 1);
+}
diff --git a/tests/em/tst_querybuilder.h b/tests/em/tst_querybuilder.h
index 4b39fb6..ef6d054 100644
--- a/tests/em/tst_querybuilder.h
+++ b/tests/em/tst_querybuilder.h
@@ -34,6 +34,7 @@ class QuerybuilderTest : public QObject {
     void testQueryBuilderManyToOneRelationAttribute();
     void testQueryBuilderManyToManyRelation();
     void testQueryBuilderManyToManyRelationAttribute();
+    void testRefresh();
 
   private:
     CuteEntityManager::EntityManager *e;
