commit f50874826e742fd68c584d9e437b98cce5708a38
Author: Christian Ehringfeld <c.ehringfeld@t-online.de>
Date:   Tue Jun 23 01:25:24 2015 +0200

    some sql and inheritance stuff,debugging entityinstancefactory

diff --git a/example/main.cpp b/example/main.cpp
index e157e07..0632d7d 100644
--- a/example/main.cpp
+++ b/example/main.cpp
@@ -30,7 +30,7 @@ int main(int argc, char *argv[]) {
     qDebug() << e;
     qDebug() << "Tabelle artikel erstellt:" << e->createTable(ep);
     e->create(ep);
-
+    //qDebug() << e->findById<Artikel *>(1); //not working grml!
 //    QSharedPointer<CuteEntityManager::Entity> p = QSharedPointer<CuteEntityManager::Entity>(new Person("Max", "Mustermann", Person::MALE, "", "", "",
 //                               QDate::currentDate()));
 //    auto pptr = p.dynamicCast<CuteEntityManager::Entity>();
@@ -46,7 +46,6 @@ int main(int argc, char *argv[]) {
 //        e->save(a);
 //    }
 //    qDebug() << "Dauer:" << t.elapsed();
-
     Pupil *p = new Pupil();
     auto hash = p->getMetaProperties();
 //    auto iterator = hash.constBegin();
diff --git a/example/models/artikel.h b/example/models/artikel.h
index 1903ca3..4a13e4f 100644
--- a/example/models/artikel.h
+++ b/example/models/artikel.h
@@ -24,7 +24,7 @@
 #include <QHash>
 #include <QVariant>
 
-class Artikel : public CuteEntityManager::Entity {
+class Artikel : virtual public CuteEntityManager::Entity {
     Q_OBJECT
     Q_PROPERTY(double preis READ getPreis WRITE setPreis)
     Q_PROPERTY(QString name READ getName WRITE setName)
diff --git a/src/entity.cpp b/src/entity.cpp
index cf6e6d6..d893488 100644
--- a/src/entity.cpp
+++ b/src/entity.cpp
@@ -38,23 +38,22 @@ const QHash<QString, Relation> Entity::getRelations() const {
     return QHash<QString, Relation>();
 }
 
-const QHash<QString, Relation> Entity::getNonInheritedRelations() const
-{
+const QHash<QString, Relation> Entity::getNonInheritedRelations() const {
     auto relations = this->getRelations();
-        auto superObject = EntityInstanceFactory::newSuperClassInstance(this);
-        if (superObject) {
-            auto superRelations = superObject->getRelations();
-            auto iterator = superRelations.constBegin();
-            while (iterator != relations.constEnd()) {
-                if (relations.contains(iterator.key())) {
-                    relations.remove(iterator.key());
-                }
-                ++iterator;
+    auto superObject = EntityInstanceFactory::newSuperClassInstance(this);
+    if (superObject) {
+        auto superRelations = superObject->getRelations();
+        auto iterator = superRelations.constBegin();
+        while (iterator != relations.constEnd()) {
+            if (relations.contains(iterator.key())) {
+                relations.remove(iterator.key());
             }
-            delete superObject;
-            superObject = 0;
+            ++iterator;
         }
-        return relations;
+        delete superObject;
+        superObject = 0;
+    }
+    return relations;
 }
 
 const QStringList Entity::getTransientAttributes() const {
@@ -73,13 +72,27 @@ QString Entity::getPrimaryKey() const {
     return "id";
 }
 
-const QStack<const QMetaObject *> Entity::superClasses() const {
+const QStack<const QMetaObject *> Entity::superClasses(bool
+        stopAtSingleTableInheritance) const {
     QStack<const QMetaObject *> classes = QStack<const QMetaObject *>();
     auto superMetaObject = this->metaObject()->superClass();
     if (this->getInheritanceStrategy() == JOINED_TABLE) {
-        while (QString(superMetaObject->className()) != QString("Entity")) {
-            classes.push(superMetaObject);
-            superMetaObject = superMetaObject->superClass();
+        Entity *e = 0;
+        while (superMetaObject != 0
+                && QString(superMetaObject->className()) != QString("CuteEntityManager::Entity")) {
+            e = EntityInstanceFactory::createInstance(superMetaObject->className());
+            if (e) {
+                classes.push(superMetaObject);
+                superMetaObject = superMetaObject->superClass();
+                quint8 s = e->getInheritanceStrategy();
+                delete e;
+                e = 0;
+                if (stopAtSingleTableInheritance && s == PER_CLASS_TABLE) {
+                    break;
+                }
+            } else {
+                break;
+            }
         }
     }
     return classes;
@@ -89,11 +102,10 @@ const QHash<QString, QMetaProperty> Entity::getMetaProperties() const {
     return Entity::getMetaProperties(this->metaObject());
 }
 
-const QHash<QString, QMetaProperty> Entity::getSuperMetaProperties() const
-{
+const QHash<QString, QMetaProperty> Entity::getSuperMetaProperties() const {
     auto superMetaObjectPropertyMap = QHash<QString, QMetaProperty>();
     auto superMeta = this->metaObject()->superClass();
-    if (QString(superMeta->className()) != QString("Entity")
+    if (QString(superMeta->className()) != QString("CuteEntityManager::Entity")
             && this->getInheritanceStrategy() == JOINED_TABLE) {
         for (int var = 0; var < superMeta->propertyCount(); ++var) {
             QMetaProperty prop = superMeta->property(var);
@@ -105,7 +117,8 @@ const QHash<QString, QMetaProperty> Entity::getSuperMetaProperties() const
     return superMetaObjectPropertyMap;
 }
 
-const QHash<QString, QMetaProperty> Entity::getMetaProperties(const QMetaObject *object) {
+const QHash<QString, QMetaProperty> Entity::getMetaProperties(
+    const QMetaObject *object) {
     auto h = QHash<QString, QMetaProperty>();
     for (int var = 0; var < object->propertyCount(); ++var) {
         QMetaProperty m = object->property(var);
@@ -119,12 +132,12 @@ const QHash<QString, QMetaProperty> Entity::getMetaProperties(const QMetaObject
 const QHash<QString, QMetaProperty> Entity::getInheritedMetaProperties() const {
     auto classes = this->superClasses();
     auto wholeProperties = QHash<QString, QMetaProperty>();
-    while(!classes.isEmpty()) {
+    while (!classes.isEmpty()) {
         auto metaObject = classes.pop();
         auto properties = Entity::getMetaProperties(metaObject);
         auto iterator = properties.constBegin();
         while (iterator != properties.constEnd()) {
-            wholeProperties.insert(iterator.key(),iterator.value());
+            wholeProperties.insert(iterator.key(), iterator.value());
             ++iterator;
         }
     }
diff --git a/src/entity.h b/src/entity.h
index 9c75b49..319f1b7 100644
--- a/src/entity.h
+++ b/src/entity.h
@@ -57,7 +57,7 @@ class Entity : public QObject {
 
     //return value must be the exact name defined in Q_PROPERTY
     virtual QString getPrimaryKey() const;
-    const QStack<const QMetaObject *> superClasses() const;
+    const QStack<const QMetaObject *> superClasses(bool stopAtSingleTableInheritance = false) const;
     const QHash<QString, QMetaProperty> getMetaProperties() const;
     const QHash<QString, QMetaProperty> getSuperMetaProperties() const;
     static const QHash<QString, QMetaProperty> getMetaProperties(const QMetaObject* object);
diff --git a/src/entityinstancefactory.cpp b/src/entityinstancefactory.cpp
index c0eb691..212f24e 100644
--- a/src/entityinstancefactory.cpp
+++ b/src/entityinstancefactory.cpp
@@ -31,9 +31,16 @@ Entity *EntityInstanceFactory::createInstance(const QString &className) {
 
 Entity *EntityInstanceFactory::createInstance(int metaTypeId) {
     Entity *e = 0;
-    if (metaTypeId != -1) {
+    if (metaTypeId != QMetaType::UnknownType) {
         e = static_cast<Entity *>(QMetaType::create(metaTypeId));
-    }
+        if(!e) {
+            qDebug() << "Entity instance could not created!";
+            throw -2; //testing
+        }
+        } else {
+            qDebug() << metaTypeId <<" is NOT registered! Please register it!";
+            throw -1; //testing
+        }
     return e;
 }
 
@@ -84,7 +91,7 @@ Entity *EntityInstanceFactory::newSuperClassInstance(const Entity *e) {
     Entity *super = 0;
     if (e) {
         auto metaObject = e->metaObject()->superClass();
-        if (QString(metaObject->className()) != QString("Entity")) {
+        if (QString(metaObject->className()) != QString("CuteEntityManager::Entity")) {
             super = EntityInstanceFactory::createInstance(metaObject->className());
         }
     }
diff --git a/src/entitymanager.cpp b/src/entitymanager.cpp
index ae9710c..ebd4efd 100644
--- a/src/entitymanager.cpp
+++ b/src/entitymanager.cpp
@@ -130,23 +130,24 @@ void EntityManager::removeConnectionName(const QString &name) {
     EntityManager::connectionNames.removeOne(name);
 }
 
-QSharedPointer<Entity> EntityManager::findById(const qint64 &id, Entity *&e,
+QSharedPointer<Entity> EntityManager::findById(const qint64 &id,
+        QSharedPointer<Entity> &e,
         const bool refresh) {
     QSharedPointer<Entity> r;
-    if (e) {
-        if (refresh || ((r = this->cache.get(id, QString(e->getClassname())))
+    if (!e.isNull()) {
+        if (refresh || ((r = this->cache.get(id, QString(e.data()->getClassname())))
                         && !r.data())) {
-            auto map  = this->findByPk(id, e->getTablename());
+            auto map  = this->findByPk(e);
             r = this->convert(map, e->getClassname(), refresh);
         }
-        delete e;
     }
     return r;
 }
 
 QSharedPointer<Entity> EntityManager::findById(const qint64 &id,
         const QString &classname) {
-    Entity *e = EntityInstanceFactory::createInstance(classname);
+    QSharedPointer<Entity> e = QSharedPointer<Entity>
+                               (EntityInstanceFactory::createInstance(classname));
     return this->findById(id, e);
 }
 
@@ -568,8 +569,9 @@ QStringList EntityManager::getConnectionNames() {
     return EntityManager::connectionNames;
 }
 
-QHash<QString, QVariant> EntityManager::findByPk(qint64 id, QString tblname) {
-    QSqlQuery q = this->schema.data()->getQueryBuilder().data()->find(id, tblname);
+QHash<QString, QVariant> EntityManager::findByPk(const QSharedPointer<Entity>
+        &e) {
+    QSqlQuery q = this->schema.data()->getQueryBuilder().data()->find(e);
     auto listMap  = this->convertQueryResult(q);
     if (!listMap.isEmpty()) {
         return listMap.at(0);
@@ -627,8 +629,9 @@ QList<QHash<QString, QVariant> > EntityManager::convertQueryResult(
     return listmap;
 }
 
-QList<QHash <QString, QVariant> > EntityManager::findAll(QString tblname) {
-    QSqlQuery q = this->schema.data()->getQueryBuilder().data()->findAll(tblname);
+QList<QHash <QString, QVariant> > EntityManager::findAll(
+    const QSharedPointer<Entity> &e) {
+    QSqlQuery q = this->schema.data()->getQueryBuilder().data()->findAll(e);
     return this->convertQueryResult(q);
 }
 
diff --git a/src/entitymanager.h b/src/entitymanager.h
index d9ef885..cb42808 100644
--- a/src/entitymanager.h
+++ b/src/entitymanager.h
@@ -50,10 +50,10 @@ class EntityManager {
 
   protected:
     void init();
-    QList<QHash<QString, QVariant> > findAll(QString tblname);
+    QList<QHash<QString, QVariant> > findAll(const QSharedPointer<Entity> &e);
     void resolveRelations(const QSharedPointer<Entity> &entity,
                           const QHash<QString, QVariant> &map, const bool refresh = false);
-    QHash<QString, QVariant> findByPk(qint64 id, QString tblname);
+    QHash<QString, QVariant> findByPk(const QSharedPointer<Entity> &e);
     QSharedPointer<Entity> convert(const QHash<QString, QVariant> &map,
                                    const char *classname, const bool refresh = false);
     QList<QSharedPointer<Entity>> convert(QList<QHash<QString, QVariant> > maps,
@@ -78,7 +78,7 @@ class EntityManager {
             QHash<QString, QVariant> &m,
             const QString &tblname,
             bool ignoreID = false);
-    QSharedPointer<Entity> findById(const qint64 &id, Entity *&e,
+    QSharedPointer<Entity> findById(const qint64 &id, QSharedPointer<Entity> &e,
                                     const bool refresh = false);
     void addEntityToListProperty(const QSharedPointer<Entity> &entity,
                                  QSharedPointer<Entity> add, const QMetaProperty &property);
@@ -159,19 +159,19 @@ class EntityManager {
     }
 
     template<class T> QList<QSharedPointer<Entity>> findAll() {
-        Entity *e = EntityInstanceFactory::createInstance<T>();
-        if (e) {
-            auto maps = this->findAll(e->getTablename());
-            const char *className = e->getClassname();
-            delete e;
+        QSharedPointer<Entity> ptr = QSharedPointer<Entity>(EntityInstanceFactory::createInstance<T>());
+        if (!ptr.isNull()) {
+            auto maps = this->findAll(ptr);
+            const char *className = ptr.data()->getClassname();
             return this->convert(maps, className);
         }
         return QList<QSharedPointer<Entity>>();
     }
 
     template<class T> QSharedPointer<Entity> findById(const qint64 &id) {
-        Entity *e = EntityInstanceFactory::createInstance<T>();
-        return this->findById(id, e);
+        auto e = EntityInstanceFactory::createInstance<T>();
+        QSharedPointer<Entity> ptr = QSharedPointer<Entity>(e);
+        return this->findById(id, ptr);
     }
 
     template<class T> QSharedPointer<Entity> findEntityByAttributes(
diff --git a/src/querybuilder.cpp b/src/querybuilder.cpp
index 137c8d6..89fd9e2 100644
--- a/src/querybuilder.cpp
+++ b/src/querybuilder.cpp
@@ -145,7 +145,8 @@ QString QueryBuilder::createFkSuperClass(const Entity *e) const {
     QString r = "";
     auto superMetaObject = e->metaObject()->superClass();
     if (e->getInheritanceStrategy() == JOINED_TABLE
-            && QString(superMetaObject->className()) != QString("Entity")) {
+            && QString(superMetaObject->className()) != QString("CuteEntityManager::Entity")) {
+        qDebug() << superMetaObject->className();
         Entity *superClass  = EntityInstanceFactory::createInstance(
                                   superMetaObject->className());
         if (superClass) {
@@ -383,7 +384,7 @@ const {
             }
         }
     }
-    if (QString(superMetaObject->className()) != QString("Entity")
+    if (QString(superMetaObject->className()) != QString("CuteEntityManager::Entity")
             && entity.data()->getInheritanceStrategy() != JOINED_TABLE) {
         map.insert(entity.data()->getPrimaryKey(), this->schema.data()->TYPE_BIGPK);
     }
@@ -491,13 +492,49 @@ QString QueryBuilder::getColumnType(const QString &type) const {
  * @return
  */
 QSqlQuery QueryBuilder::find(const qint64 &id, const QString &tableName) const {
-    QSqlQuery q = this->database.data()->getQuery("SELECT * FROM " +
-                  this->schema.data()->quoteTableName(
-                      tableName) + " WHERE id= :id LIMIT 1;");
+    QSqlQuery q = this->database.data()->getQuery(this->selectBase(QStringList(
+                      tableName)) + " WHERE id= :id LIMIT 1;");
     q.bindValue(":id", id);
     return q;
 }
 
+QString QueryBuilder::selectBase(const QStringList &tables,
+                                 const QStringList &columns) const {
+    QString r = "SELECT ";
+    if (columns.isEmpty()) {
+        r.append("*");
+    } else {
+        for (int var = 0; var < columns.size(); ++var) {
+            if (var != 0) {
+                r.append(" ");
+            }
+            r.append(this->schema.data()->quoteColumnName(columns.at(var)));
+        }
+    }
+    r.append(" FROM");
+    for (int var = 0; var < tables.size(); ++var) {
+        r.append(" ");
+        r.append(this->schema.data()->quoteTableName(tables.at(var)));
+    }
+    return r;
+}
+
+QSqlQuery QueryBuilder::find(const QSharedPointer<Entity> &entity,
+                             qint64 offset) const {
+    QSqlQuery q = this->database.data()->getQuery(this->selectBase(QStringList(
+                      entity.data()->getTablename())) + " " + this->joinSuperClasses(
+                      entity) + " WHERE id= :id " + this->limit(1, offset));
+    q.bindValue(":id", entity.data()->getId());
+    return q;
+}
+
+QSqlQuery QueryBuilder::findAll(const QSharedPointer<Entity> &entity,
+                                const qint64 limit, qint64 offset) {
+    return this->database->getQuery(this->selectBase(QStringList(
+                                        entity.data()->getTablename())) + " " + this->joinSuperClasses(
+                                        entity) + " " + this->limit(limit, offset) + ";");
+}
+
 /**
  * @brief QueryBuilder::findByAttributes
  * @param m
@@ -508,9 +545,8 @@ QSqlQuery QueryBuilder::find(const qint64 &id, const QString &tableName) const {
 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.data()->getQuery("SELECT * FROM " +
-                  this->schema.data()->quoteTableName(
-                      tableName) + this->where(m, "AND", ignoreID) + this->limit(limit, offset));
+    QSqlQuery q = this->database.data()->getQuery(this->selectBase(QStringList(
+                      tableName)) + this->where(m, "AND", ignoreID) + this->limit(limit, offset));
     this->bindValues(m, q, ignoreID);
     return q;
 }
@@ -526,9 +562,7 @@ QSqlQuery QueryBuilder::findByAttributes(const QSharedPointer<Entity> &e,
 }
 
 QSqlQuery QueryBuilder::findAll(const QString &tableName) const {
-    return this->database->getQuery("SELECT * FROM " +
-                                    this->schema.data()->quoteTableName(
-                                        tableName) + ";");
+    return this->database->getQuery(this->selectBase(QStringList(tableName)) + ";");
 }
 
 QSqlQuery QueryBuilder::remove(const QSharedPointer<Entity> &entity) const {
@@ -544,11 +578,8 @@ QSqlQuery QueryBuilder::findId(const QSharedPointer<Entity> &entity) const {
     QHash<QString, QVariant> values = this->getEntityAttributes(
                                           entity.data()->getMetaProperties(),
                                           entity);
-    QSqlQuery q = this->database.data()->getQuery("SELECT " +
-                  this->schema.data()->quoteColumnName("id")
-                  + " FROM " +
-                  this->schema.data()->quoteTableName(
-                      entity.data()->getTablename()) + this->where(values,
+    QSqlQuery q = this->database.data()->getQuery(this->selectBase(QStringList(
+                      entity.data()->getTablename()), QStringList("id")) + this->where(values,
                               "AND", true) + " LIMIT 1");
     this->bindValues(values, q);
     return q;
@@ -559,18 +590,17 @@ QSqlQuery QueryBuilder::count(const QSharedPointer<Entity> &entity,
     QHash<QString, QVariant> values = this->getEntityAttributes(
                                           entity.data()->getMetaProperties(),
                                           entity);
-    QSqlQuery q = this->database.data()->getQuery("SELECT COUNT(*) FROM " +
-                  this->schema.data()->quoteTableName(
-                      entity.data()->getTablename()) + this->where(
+    QSqlQuery q = this->database.data()->getQuery(this->selectBase(QStringList(
+                      entity.data()->getTablename()),
+                  QStringList(this->countFunction())) + this->where(
                       values, "AND", ignoreID));
     this->bindValues(values, q, ignoreID);
     return q;
 }
 
 QSqlQuery QueryBuilder::count(const QString &tableName) const {
-    QSqlQuery q = this->database.data()->getQuery("SELECT COUNT(*) FROM " +
-                  this->schema.data()->quoteTableName(
-                      tableName) + ";");
+    QSqlQuery q = this->database.data()->getQuery(this->selectBase(QStringList(
+                      tableName), QStringList(this->countFunction())) + ";");
     return q;
 }
 
@@ -613,10 +643,8 @@ QSqlQuery QueryBuilder::manyToMany(const QString &tableName,
                                    const qint64 &id,
                                    const QString &foreignKey, const QString &foreignTable) {
     QSqlQuery q = this->database.data()->getQuery();
-    QString sql = "SELECT " +
-                  this->schema.data()->quoteTableName(
-                      foreignTable) + ".* FROM " +
-                  this->schema.data()->quoteTableName(tableName) + " " + this->leftJoin(
+    QString sql = this->selectBase(QStringList(tableName),
+                                   QStringList(foreignTable + ".*")) + " " + this->leftJoin(
                       foreignTable, tableName,
                       foreignKey) + " WHERE " + this->schema.data()->quoteColumnName(
                       attribute) + "=:id;";
@@ -646,21 +674,46 @@ QSqlQuery QueryBuilder::manyToManyInsert(const QString &tableName,
     return q;
 }
 
-QString QueryBuilder::leftJoin(const QString &foreignTable,
-                               const QString &tableName,
-                               const QString &foreignKey) {
-    return "LEFT JOIN " + this->schema.data()->quoteTableName(
-               foreignTable) + " ON " +
-           this->schema.data()->quoteColumnName(foreignTable + ".id") + "=" +
-           this->schema.data()->quoteColumnName(
-               tableName + "." + foreignKey);
-}
-
 QString QueryBuilder::superClassColumnName(const QMetaObject *&superMeta)
 const {
     return QString(superMeta->className()).toLower();
 }
 
+QString QueryBuilder::joinSuperClasses(const QSharedPointer<Entity> &entity)
+const {
+    auto stack = entity.data()->superClasses();
+    QString joined = "";
+    bool first = true;
+    Entity *e = 0;
+    while (!stack.isEmpty()) {
+        auto metaObject = stack.pop();
+        e = EntityInstanceFactory::createInstance(metaObject->className());
+        if (first) {
+            first = false;
+        } else {
+            if (e) {
+                joined.append(" ");
+            }
+        }
+        if (e) {
+            joined.append(this->leftJoin(e->getTablename(), entity.data()->getTablename(),
+                                         e->getPrimaryKey(), entity.data()->getPrimaryKey()));
+        }
+        delete e;
+        e = 0;
+    }
+    return joined;
+}
+
+QString QueryBuilder::countFunction(const QString &distinctColumn) const {
+    return QString("COUNT(" + distinctColumn.isEmpty() ? "*" : (this->distinct() +
+                   this->schema.data()->quoteColumnName(distinctColumn)) + ")");
+}
+
+QString QueryBuilder::distinct() const {
+    return "DISTINCT";
+}
+
 QString QueryBuilder::limit(const qint64 &limit, const qint64 &offset) const {
     QString s = "";
     if (limit > 0) {
@@ -674,8 +727,7 @@ QString QueryBuilder::limit(const qint64 &limit, const qint64 &offset) const {
 
 QString QueryBuilder::generateManyToManyColumnName(const QSharedPointer<Entity>
         &entity) const {
-    return this->generateColumnNameID(QString(
-                                          entity.data()->metaObject()->className()));
+    return this->generateColumnNameID(entity.data()->getTablename());
 }
 
 QSqlQuery QueryBuilder::getQuery() const {
@@ -695,6 +747,16 @@ QHash<QString, QVariant> QueryBuilder::saveAttributes(const
     return values;
 }
 
+QString QueryBuilder::leftJoin(const QString &foreignTable,
+                               const QString &tableName, const QString &foreignKey,
+                               const QString &primaryKey) const {
+    return "LEFT JOIN " + this->schema.data()->quoteTableName(
+               foreignTable) + " ON " +
+           this->schema.data()->quoteColumnName(foreignTable + "." + primaryKey) + "=" +
+           this->schema.data()->quoteColumnName(
+               tableName + "." + foreignKey);
+}
+
 QHash<QString, QVariant> QueryBuilder::getEntityAttributes(
     const QHash<QString, QMetaProperty>
     &props,
diff --git a/src/querybuilder.h b/src/querybuilder.h
index 3ab4b3f..598edc3 100644
--- a/src/querybuilder.h
+++ b/src/querybuilder.h
@@ -20,14 +20,13 @@
 #include <QSharedPointer>
 #include <QPointer>
 #include <QSqlQuery>
+#include <QStringList>
 #include "relation.h"
 namespace CuteEntityManager {
 class Schema;
 class Entity;
 class Database;
-/**
-  RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL
-*/
+
 enum DbForeignKeyCascade {
     RESTRICT,
     CASCADE,
@@ -102,6 +101,8 @@ class QueryBuilder {
     QString transformAbstractTypeToRealDbType(QString typeName) const;
     QString getColumnType(const QString &type) const;
     QSqlQuery find(const qint64 &id, const QString &tableName) const;
+    QSqlQuery find(const QSharedPointer<Entity> &entity,
+                   qint64 offset = 0) const;
     QSqlQuery findByAttributes(const QHash<QString, QVariant> &m,
                                const QString &tableName,
                                const bool &ignoreID = true, const qint64 limit = 0,
@@ -110,6 +111,8 @@ class QueryBuilder {
                                bool ignoreID = true,
                                const qint64 limit = 0, const qint64 offset = 0);
     QSqlQuery findAll(const QString &tableName) const;
+    QSqlQuery findAll(const QSharedPointer<Entity> &entity, const qint64 limit = 0,
+                      qint64 offset = 0);
     QSqlQuery remove(const QSharedPointer<Entity> &entity) const;
     QSqlQuery findId(const QSharedPointer<Entity> &entity) const;
     QSqlQuery count(const QSharedPointer<Entity> &entity, bool ignoreID) const;
@@ -134,7 +137,10 @@ class QueryBuilder {
     QSqlQuery getQuery() const;
 
   protected:
-    virtual void createRelationFK(QStringList &queries, const QSharedPointer<Entity> &entity, const Relation &relation, const QMetaProperty &metaProperty, const QString &update, const QString &remove) const;
+    virtual void createRelationFK(QStringList &queries,
+                                  const QSharedPointer<Entity> &entity, const Relation &relation,
+                                  const QMetaProperty &metaProperty, const QString &update,
+                                  const QString &remove) const;
     void insertRelationId(const Entity *e, QHash<QString, QVariant> &map,
                           QString relName) const;
     QString buildColumns(const QStringList &columns) const;
@@ -164,9 +170,16 @@ class QueryBuilder {
     QHash<QString, QVariant> saveAttributes(const QSharedPointer<Entity> &entity)
     const;
     QString leftJoin(const QString &foreignTable, const QString &tableName,
-                     const QString &foreignKey);
+                     const QString &foreignKey = "id", const QString &primaryKey = "id") const;
     QString superClassColumnName(const QMetaObject *&superMeta) const;
 
+    QString joinSuperClasses(const QSharedPointer<Entity> &entity) const;
+    virtual QString selectBase(const QStringList &tables,
+                               const QStringList &columns = QStringList()) const;
+    virtual QString countFunction(const QString &distinctColumn = "") const;
+    virtual QString distinct() const;
+
+
     QSharedPointer<Schema> schema;
     QSharedPointer<Database> database;
 };
