commit 82442988060ef72cfc197d57e4161ab6c12bdb77
Author: Christian Ehringfeld <c.ehringfeld@t-online.de>
Date:   Fri Aug 7 14:40:34 2015 +0200

    ...

diff --git a/EntityManager.pro b/EntityManager.pro
index 577110b..6b6ab79 100644
--- a/EntityManager.pro
+++ b/EntityManager.pro
@@ -54,12 +54,19 @@ src/entity.cpp \
     src/expression.cpp \
     src/orderby.cpp
 
+CONFIG += c++14
+QMAKE_CXXFLAGS += -std=c++14
+
 unix {
     target.path = /usr/lib
     INSTALLS += target
     QMAKE_CXXFLAGS += -Wall -Wextra -Wmaybe-uninitialized -Wsuggest-final-types -Wsuggest-final-methods -Wsuggest-override -Wunsafe-loop-optimizations -pedantic -Wfloat-equal -Wundef -Wpointer-arith -Wcast-align -Wunreachable-code -O
 }
-CONFIG += c++14
-QMAKE_CXXFLAGS += -std=c++14
+
+win32-g++ {
+    CONFIG += c++11
+    QMAKE_CXXFLAGS += -std=c++11 -Wall
+}
+
 #QMAKE_CXXFLAGS +=  -Winit-self
 CONFIG(release, debug|release):DEFINES += QT_NO_DEBUG_OUTPUT
diff --git a/samples/example/Example.pro b/samples/example/Example.pro
index 8239cf6..8add32a 100644
--- a/samples/example/Example.pro
+++ b/samples/example/Example.pro
@@ -44,4 +44,10 @@ DEPENDPATH += $$PWD/../../src
 unix {
 QMAKE_CXXFLAGS += -Wall -Wextra -Wmaybe-uninitialized -Wsuggest-final-types -Wsuggest-final-methods -Wsuggest-override -Wunsafe-loop-optimizations -pedantic -Wfloat-equal -Wundef -Wpointer-arith -Wcast-align -Wunreachable-code -O -Winit-self
 }
+
+win32-g++ {
+    CONFIG += c++11
+    QMAKE_CXXFLAGS += -std=c++11 -Wall
+}
+
 CONFIG(release, debug|release):DEFINES += QT_NO_DEBUG_OUTPUT
diff --git a/samples/example/main.cpp b/samples/example/main.cpp
index 30caed8..2d19f21 100644
--- a/samples/example/main.cpp
+++ b/samples/example/main.cpp
@@ -104,10 +104,11 @@ int main(int argc, char *argv[]) {
      */
     Query q = Query();
     q.appendWhere(e->getQueryBuilder()->like(QString("firstname"), QString("Tim")));
+    q.appendJoin(Join("person","pupil.id = person.id"));
     q.setDistinct(true);
     q.appendOrderBy(OrderBy(QString("birthday"), Direction::SORT_DESC));
     q.setLimit(10);
-    QList<QSharedPointer<Person>> list = e->find<Person>(q);
+    QList<QSharedPointer<Pupil>> list = e->find<Pupil>(q);
     for (int i = 0; i < list.size(); ++i) {
         qDebug() << list.at(i)->toString();
     }
diff --git a/samples/example/models/faker/createfakemodeldata.cpp b/samples/example/models/faker/createfakemodeldata.cpp
index 080222e..f0063e6 100644
--- a/samples/example/models/faker/createfakemodeldata.cpp
+++ b/samples/example/models/faker/createfakemodeldata.cpp
@@ -6,9 +6,9 @@
 #include "../group.h"
 
 void CreateFakeModelData::fillGroup(Group* group) {
-    group->addPerson(new Person("Tim","Berg",Person::Gender::MALE,"Tim Berg.jpg",QString(),QString(),QDate(2000,7,13),0));
-    group->addPerson(new Person("Lena","Conrad",Person::Gender::FEMALE,"Lena Conrad.jpg",QString(),QString(),QDate(2000,7,13),0));
-    group->addPerson(new Person("Marcel","Dunst",Person::Gender::MALE,"Marcel Dunst.jpg",QString(),QString(),QDate(2000,7,13),0));
+    group->addPerson(new Person("Thomas","Berg",Person::Gender::MALE,"",QString(),QString(),QDate(1971,7,13),0));
+    group->addPerson(new Person("Teresa","Conrad",Person::Gender::FEMALE,"",QString(),QString(),QDate(1970,7,13),0));
+    group->addPerson(new Person("Heinz","Dunst",Person::Gender::MALE,"",QString(),QString(),QDate(1972,7,13),0));
 
     group->addPupil(new Pupil("Tim","Berg",Person::Gender::MALE,"Tim Berg.jpg",QString(),QString(),QDate(2000,7,13),"05c",0));
     group->addPupil(new Pupil("Lena","Conrad",Person::Gender::FEMALE,"Lena Conrad.jpg",QString(),QString(),QDate(2000,7,13),"05c",0));
@@ -22,10 +22,10 @@ void CreateFakeModelData::fillGroup(Group* group) {
     group->addPupil(new Pupil("Birthe","Jäger",Person::Gender::FEMALE,"Birthe Jaeger.jpg",QString(),QString(),QDate(2000,2,14),"05c",0));
 
     group->pupilAt(0)->addAddress(new Address("Erzieher","Bukesweg 473","33330","Gütersloh"));
-    group->pupilAt(1)->addAddress(new Address("Erzieher","Bukesweg 473","33330","Gütersloh"));
-    group->pupilAt(2)->addAddress(new Address("Erzieher","Bukesweg 473","33330","Gütersloh"));
-    group->pupilAt(3)->addAddress(new Address("Erzieher","Bukesweg 473","33330","Gütersloh"));
-    group->pupilAt(4)->addAddress(new Address("Erzieher","Bukesweg 473","33330","Gütersloh"));
+    group->pupilAt(1)->addAddress(new Address("Erzieher","Bukesweg 474","33330","Gütersloh"));
+    group->pupilAt(2)->addAddress(new Address("Erzieher","Bukesweg 47","33330","Gütersloh"));
+    group->pupilAt(3)->addAddress(new Address("Erzieher","Bukesweg 4","33330","Gütersloh"));
+    group->pupilAt(4)->addAddress(new Address("Erzieher","Bukesweg 43","33330","Gütersloh"));
     group->pupilAt(5)->addAddress(new Address("Erzieher","Auguste-Viktoria-Platz 193","77652","Offenburg"));
     group->pupilAt(6)->addAddress(new Address("Erzieher","Bullenwinkel 467","74074","Heilbronn"));
     group->pupilAt(7)->addAddress(new Address("Erzieher","Schinkelplatz 389","46236","Bottrop"));
diff --git a/src/entity.cpp b/src/entity.cpp
index 6093257..b0de2ac 100644
--- a/src/entity.cpp
+++ b/src/entity.cpp
@@ -16,6 +16,7 @@
 
 #include "entity.h"
 #include "entityhelper.h"
+#include "entityinstancefactory.h"
 using namespace CuteEntityManager;
 
 Entity::Entity(QObject *parent) : QObject(parent) {
@@ -33,11 +34,12 @@ QString Entity::toString() const {
         if (var.value().isEnumType()) {
             val = var.value().enumerator().valueToKey(var.value().read(this).toInt());
         } else if (value.canConvert<QList<QVariant>>()) {
-            auto list = value.toList();
             val.append("[");
-            for (int i = 0; i < list.size(); ++i) {
-                val = list.at(i).toString();
-            }
+            auto list = EntityInstanceFactory::castQVariantList(value);
+            int size = list.size();
+            val.append(QString::number(size));
+            val.append(" ");
+            val.append(size == 1 ? "element" : "elements");
             val.append("]");
         } else {
             val = value.toString();
diff --git a/src/entitymanager.cpp b/src/entitymanager.cpp
index f18920b..969b64e 100644
--- a/src/entitymanager.cpp
+++ b/src/entitymanager.cpp
@@ -18,7 +18,6 @@
 #include "entitymanager.h"
 #include "enums/databasetype.h"
 #include "databasemigration.h"
-#include "queryinterpreter.h"
 using namespace CuteEntityManager;
 
 QStringList EntityManager::connectionNames = QStringList();
diff --git a/src/entitymanager.h b/src/entitymanager.h
index 134b443..a004ab8 100644
--- a/src/entitymanager.h
+++ b/src/entitymanager.h
@@ -24,15 +24,15 @@
 #include <QObject>
 #include <QSharedPointer>
 #include <QDebug>
-#include "schema.h"
 #include <QtSql/QSqlError>
 #include <QMetaType>
+#include "schema.h"
 #include "entity.h"
 #include "database.h"
 #include "entityinstancefactory.h"
-#include "cache.h"
 #include "queryinterpreter.h"
-
+#include "cache.h"
+#include "querybuilder.h"
 namespace CuteEntityManager {
 
 class Logger;
diff --git a/src/expression.h b/src/expression.h
index c338fc1..c833f6a 100644
--- a/src/expression.h
+++ b/src/expression.h
@@ -44,5 +44,9 @@ class Expression {
     QHash<QString, QVariant> params;
     bool onlyColumn;
 };
+
+inline bool operator==(const Expression &e1, const Expression &e2) {
+    return e1.getExpression() == e2.getExpression();
+}
 }
 #endif // EXPRESSION_H
diff --git a/src/join.h b/src/join.h
index 0ed32ea..3dbc2ac 100644
--- a/src/join.h
+++ b/src/join.h
@@ -35,11 +35,17 @@ class Join {
     Expression getExpression() const;
     void setExpression(const Expression &value);
 
+
   private:
     QString type = QStringLiteral("LEFT JOIN");
     QString foreignTable;
     Expression expression;
 
 };
+inline bool operator==(const Join &e1, const Join &e2) {
+    return e1.getForeignTable() == e2.getForeignTable()
+           && e1.getExpression() == e2.getExpression();
+}
+
 }
 #endif // JOIN_H
diff --git a/src/query.cpp b/src/query.cpp
index 64c37f8..7930deb 100644
--- a/src/query.cpp
+++ b/src/query.cpp
@@ -20,6 +20,9 @@ using namespace CuteEntityManager;
 Query::Query() {
 }
 
+Query::~Query() {
+}
+
 Query::Query(QStringList from, QList<Expression> where, QList<Join> joins,
              QHash<QString, QVariant> params, quint64 limit, quint64 offset,
              QList<Expression> select, QStringList groupBy, bool distinct,
@@ -82,6 +85,12 @@ void Query::setDistinct(bool value) {
     distinct = value;
 }
 
+void Query::appendFrom(const QString &value) {
+    if (!this->from.contains(value)) {
+        this->from.append(value);
+    }
+}
+
 QStringList Query::getFrom() const {
     return from;
 }
@@ -90,6 +99,12 @@ void Query::setFrom(const QStringList &value) {
     from = value;
 }
 
+void Query::appendJoin(const Join &value) {
+    if (!this->joins.contains(value)) {
+        this->joins.append(value);
+    }
+}
+
 QStringList Query::getGroupBy() const {
     return groupBy;
 }
@@ -175,3 +190,9 @@ QList<OrderBy> Query::getOrderBy() const {
 void Query::setOrderBy(const QList<OrderBy> &value) {
     orderBy = value;
 }
+
+void Query::appendGroupBy(const QString &value) {
+    if (!this->groupBy.contains(value)) {
+        this->groupBy.append(value);
+    }
+}
diff --git a/src/query.h b/src/query.h
index 5cd8421..27391e4 100644
--- a/src/query.h
+++ b/src/query.h
@@ -29,6 +29,7 @@ enum class Direction;
 class Query {
   public:
     Query();
+    ~Query();
     Query(QStringList from, QList<Expression> where,
           QList<Join> joins = QList<Join>(),
           QHash<QString, QVariant> params = QHash<QString, QVariant>(), quint64 limit = 0,
@@ -43,9 +44,11 @@ class Query {
     bool getDistinct() const;
     void setDistinct(bool value);
 
+    void appendFrom(const QString &value);
     QStringList getFrom() const;
     void setFrom(const QStringList &value);
 
+    void appendJoin(const Join &value);
     QList<Join> getJoins() const;
     void setJoins(const QList<Join> &value);
 
@@ -60,17 +63,12 @@ class Query {
     quint64 getOffset() const;
     void setOffset(const quint64 &value);
 
-    void appendWhere(const QString &condition);
-    void appendWhere(const Expression &condition);
-
-    void appendHaving(const QString &condition);
-    void appendHaving(const Expression &condition);
-
     void appendOrderBy(const OrderBy &orderBy);
     void appendOrderBy(const QString &column, const Direction &direction);
     QList<OrderBy> getOrderBy() const;
     void setOrderBy(const QList<OrderBy> &value);
 
+    void appendGroupBy(const QString &value);
     QStringList getGroupBy() const;
     void setGroupBy(const QStringList &value);
 
@@ -80,9 +78,13 @@ class Query {
     void setSelect(const QList<Expression> &value);
     void setSelect(const QStringList &value);
 
+    void appendWhere(const QString &condition);
+    void appendWhere(const Expression &condition);
     QList<Expression> getWhere() const;
     void setWhere(const QList<Expression> &value);
 
+    void appendHaving(const QString &condition);
+    void appendHaving(const Expression &condition);
     QList<Expression> getHaving() const;
     void setHaving(const QList<Expression> &value);
 
diff --git a/src/querybuilder.h b/src/querybuilder.h
index 1992a97..46ee948 100644
--- a/src/querybuilder.h
+++ b/src/querybuilder.h
@@ -23,8 +23,8 @@
 #include <QStringList>
 #include <QMetaProperty>
 #include "relation.h"
-#include "query.h"
 #include "expression.h"
+#include "query.h"
 namespace CuteEntityManager {
 class Schema;
 class Entity;
@@ -100,10 +100,10 @@ class QueryBuilder {
     QString transformTypeToAbstractDbType(QString typeName) const;
     QString transformAbstractTypeToRealDbType(QString typeName) const;
     QString getColumnType(const QString &type) const;
+    virtual QString placeHolder(const QString &key) 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;
     Expression where(QString column, QVariant value);
     /**
      * @brief where
@@ -159,10 +159,6 @@ class QueryBuilder {
                     QString conjunction = "AND",
                     JokerPosition jp = JokerPosition::BOTH, QChar wildcard = '%');
 
-    QStringList quoteTableNames(const QStringList &tables);
-    QString getSeparator() const;
-    void setSeparator(const QString &value);
-
   protected:
     class ClassAttributes {
       public:
@@ -183,6 +179,10 @@ class QueryBuilder {
         QString pk;
         QHash<QString, QVariant> attributes;
     };
+
+    QStringList quoteTableNames(const QStringList &tables);
+    QString getSeparator() const;
+    void setSeparator(const QString &value);
     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;
diff --git a/src/schema.h b/src/schema.h
index 5d380c3..a56586e 100644
--- a/src/schema.h
+++ b/src/schema.h
@@ -15,11 +15,11 @@
  */
 #ifndef SCHEMA_H
 #define SCHEMA_H
-#include "tableschema.h"
 #include <QStringList>
 #include <QHash>
 #include <QSharedPointer>
 #include <QSqlField>
+#include "tableschema.h"
 #include "querybuilder.h"
 namespace CuteEntityManager {
 class Database;
