commit fc14f551e996109011e521ef59bbc91226977cbe
Author: Christian Ehringfeld <c.ehringfeld@t-online.de>
Date:   Sun Aug 9 20:57:26 2015 +0200

    validator stuff

diff --git a/EntityManager.pro b/EntityManager.pro
index 9a0bf1b..f1ede1c 100644
--- a/EntityManager.pro
+++ b/EntityManager.pro
@@ -35,7 +35,8 @@ src/entity.h \
     src/validators/param.h \
     src/validators/errormsg.h \
     src/validators/defaultvalidator.h \
-    src/validators/validatorfactory.h
+    src/validators/validatorfactory.h \
+    src/validators/validatorrule.h
 
 SOURCES += \
 src/entity.cpp \
@@ -64,7 +65,8 @@ src/entity.cpp \
     src/validators/param.cpp \
     src/validators/errormsg.cpp \
     src/validators/defaultvalidator.cpp \
-    src/validators/validatorfactory.cpp
+    src/validators/validatorfactory.cpp \
+    src/validators/validatorrule.cpp
 
 CONFIG += c++14
 QMAKE_CXXFLAGS += -std=c++14
diff --git a/samples/example/main.cpp b/samples/example/main.cpp
index 13a08c6..0992e0a 100644
--- a/samples/example/main.cpp
+++ b/samples/example/main.cpp
@@ -106,8 +106,14 @@ int main(int argc, char *argv[]) {
     q.setDistinct(true);
     q.appendOrderBy(OrderBy(QString("birthday"), Direction::SORT_DESC));
     q.setLimit(10);
-    QList<QSharedPointer<Pupil>> list = e->find<Pupil>(q, true,false);
+    QList<QSharedPointer<Pupil>> list = e->find<Pupil>(q, true);
     for (int i = 0; i < list.size(); ++i) {
+//        qWarning() << "-----------------------------";
+//        qWarning() << "Merge Pupil";
+//        qWarning() << "-----------------------------";
+//        list.at(i)->setBirthday(QDate(2222,12,22));
+//        QSharedPointer<Entity> pupilE = list.at(i).objectCast<Entity>();
+//        e->merge(pupilE,true);
         qWarning() << list.at(i)->toString();
     }
     qWarning() << "-----------------------------";
@@ -131,6 +137,10 @@ int main(int argc, char *argv[]) {
     qWarning() << "Remove Group";
     qWarning() << "-----------------------------";
     e->remove(entityGroupFindPtr);
+
+
+
+
     sqliteproc->sqliteDBMemFile(true, "db.sqlite");
     qWarning() << "Duration:" << t.elapsed();
     delete sqliteproc;
diff --git a/src/entity.cpp b/src/entity.cpp
index b0de2ac..59872b9 100644
--- a/src/entity.cpp
+++ b/src/entity.cpp
@@ -57,11 +57,22 @@ QString Entity::slimToString() const {
     r.append("id: ") + this->getId() + "}";
     return r;
 }
+QList<ErrorMsg> Entity::getErrors() const {
+    return errors;
+}
+
+void Entity::setErrors(const QList<ErrorMsg> &value) {
+    errors = value;
+}
 
 Entity::~Entity() {
 
 }
 
+QList<ValidationRule> Entity::validationRules() const {
+    return QList<ValidationRule>();
+}
+
 QString Entity::getTablename() const {
     return QString(this->metaObject()->className()).toLower();
 }
@@ -111,3 +122,7 @@ void Entity::setId(const qint64 &value) {
         emit idChanged();
     }
 }
+
+bool Entity::hasErrors() const {
+    return !this->errors.isEmpty();
+}
diff --git a/src/entity.h b/src/entity.h
index 059bd24..8edfd97 100644
--- a/src/entity.h
+++ b/src/entity.h
@@ -27,6 +27,8 @@
 #include <QStack>
 #include <QQueue>
 #include "entityinstancefactory.h"
+#include "validators/validatorrule.h"
+#include "validators/errormsg.h"
 namespace CuteEntityManager {
 
 /**
@@ -43,6 +45,7 @@ class Entity : public QObject {
   public:
     virtual QString toString() const;
     virtual ~Entity();
+    virtual QList<ValidationRule> validationRules() const;
     virtual QString getTablename() const;
     virtual const QHash<QString, Relation> getRelations() const;
     virtual const QStringList getTransientAttributes() const;
@@ -57,9 +60,15 @@ class Entity : public QObject {
     qint64 getId() const;
     void setId(const qint64 &value);
 
-  protected:
+    bool hasErrors() const;
+
+    QList<ErrorMsg> getErrors() const;
+    void setErrors(const QList<ErrorMsg> &value);
+
+protected:
     explicit Entity (QObject *parent = 0);
     virtual QString slimToString() const;
+    QList<ErrorMsg> errors;
     qint64 id;
 };
 }
diff --git a/src/entitymanager.cpp b/src/entitymanager.cpp
index 5ce5337..b8194c7 100644
--- a/src/entitymanager.cpp
+++ b/src/entitymanager.cpp
@@ -18,6 +18,9 @@
 #include "entitymanager.h"
 #include "enums/databasetype.h"
 #include "databasemigration.h"
+#include "validators/validatorfactory.h"
+#include "validators/validator.h"
+#include "validators/validatorrule.h"
 using namespace CuteEntityManager;
 
 QStringList EntityManager::connectionNames = QStringList();
@@ -158,6 +161,24 @@ qint8 EntityManager::count(Query &query) {
     return rc;
 }
 
+bool EntityManager::validate(QSharedPointer<Entity> &entity) {
+    QList<ValidationRule> rules = entity->validationRules();
+    QList<ErrorMsg> list = QList<ErrorMsg>();
+    for (int i = 0; i < rules.size(); ++i) {
+        ValidationRule rule = rules.at(i);
+        QSharedPointer<Validator> validator = ValidatorFactory::getValidatorObject(
+                rule.getValidatorName());
+        if (validator) {
+            for (int var = 0; var < rule.getAttributes().size(); ++var) {
+                QString attr = rule.getAttributes().at(var);
+                list.append(validator->validate(entity->getProperty(attr), rule.getParams()));
+            }
+        }
+    }
+    entity->setErrors(list);
+    return !entity->hasErrors();
+}
+
 QString EntityManager::createConnection() {
     QStringList l = EntityManager::getConnectionNames();
     QString conName = "";
@@ -604,10 +625,10 @@ QList<QSharedPointer<Entity> > EntityManager::findEntityByAttributes(
  * @return
  */
 bool EntityManager::create(QList<QSharedPointer<Entity> > entities,
-                           const bool persistRelations) {
+                           const bool persistRelations, const bool validate) {
     bool ok = true;
     foreach (QSharedPointer<Entity> ent, entities) {
-        ok = this->create(ent, persistRelations);
+        ok = this->create(ent, persistRelations, validate);
         if (!ok) {
             break;
         }
@@ -616,9 +637,10 @@ bool EntityManager::create(QList<QSharedPointer<Entity> > entities,
 }
 
 bool EntityManager::create(QSharedPointer<Entity> &entity,
-                           const bool persistRelations, const bool checkDuplicate) {
+                           const bool persistRelations, const bool checkDuplicate, const bool validate) {
     bool rc = false;
-    if (this->checkTable(entity) && !(checkDuplicate && this->count(entity) > 0)) {
+    if (this->checkTable(entity) && ((validate && this->validate(entity))
+                                     || !validate) && !(checkDuplicate && this->count(entity) > 0)) {
         if (persistRelations) {
             this->savePrePersistedRelations(entity);
         }
@@ -659,9 +681,11 @@ bool EntityManager::create(QSharedPointer<Entity> &entity,
     return rc;
 }
 
-bool EntityManager::merge(QSharedPointer<Entity> &entity, bool withRelations) {
+bool EntityManager::merge(QSharedPointer<Entity> &entity, bool withRelations,
+                          const bool validate) {
     bool ok = false;
-    if (entity->getId() > -1) {
+    if (entity->getId() > -1 && ((validate && this->validate(entity))
+                                 || !validate)) {
         if (withRelations) {
             this->savePrePersistedRelations(entity);
         }
diff --git a/src/entitymanager.h b/src/entitymanager.h
index ec6863f..0b7819e 100644
--- a/src/entitymanager.h
+++ b/src/entitymanager.h
@@ -33,6 +33,7 @@
 #include "queryinterpreter.h"
 #include "cache.h"
 #include "querybuilder.h"
+#include "validators/errormsg.h"
 namespace CuteEntityManager {
 
 class Logger;
@@ -55,12 +56,13 @@ class EntityManager : public QObject {
                                QSharedPointer<Entity> &entity,
                                bool ignoreID = false);
     bool create(QList<QSharedPointer<Entity>> entities,
-                const bool persistRelations = true);
+                const bool persistRelations = true, const bool validate = true);
     bool create(QSharedPointer<Entity> &entity, const bool persistRelations = true,
-                const bool checkDuplicate = false);
+                const bool checkDuplicate = false, const bool validate = true);
     bool save(QSharedPointer<Entity> &entity, const bool persistRelations = true);
     qint64 findId(QSharedPointer<Entity> &entity);
-    bool merge(QSharedPointer<Entity> &entity, bool withRelations = true);
+    bool merge(QSharedPointer<Entity> &entity, bool withRelations = true,
+               const bool validate = true);
     bool remove(QSharedPointer<Entity> &entity);
     bool removeAll(QString tblname);
     bool createTable(const QSharedPointer<Entity> &entity,
@@ -75,6 +77,7 @@ class EntityManager : public QObject {
     QList<QHash<QString, QVariant> > selectByQuery(Query &query);
     QList<QHash<QString, QVariant> > selectBySql(const QString &sql);
     qint8 count(Query &query);
+    bool validate(QSharedPointer<Entity> &entity);
 
   public:
     EntityManager(QSqlDatabase database, bool logQueries = false);
diff --git a/src/validators/validatorfactory.cpp b/src/validators/validatorfactory.cpp
index c742ec7..7d9390b 100644
--- a/src/validators/validatorfactory.cpp
+++ b/src/validators/validatorfactory.cpp
@@ -1,27 +1,48 @@
 #include "validatorfactory.h"
 #include "defaultvalidator.h"
 using namespace CuteEntityManager;
+
 ValidatorFactory::ValidatorFactory() {
 }
 
-
 QHash<QByteArray, ValidatorFactory::Constructor> ValidatorFactory::instance =
     QHash<QByteArray, ValidatorFactory::Constructor>();
 
+QHash<QString, QSharedPointer<Validator>> ValidatorFactory::validatorInstances =
+        QHash<QString, QSharedPointer<Validator>>();
+
 
-Validator *ValidatorFactory::createValidator(QString shortname) {
+Validator *ValidatorFactory::createValidator(const QString &shortname) {
     if (Validator::builtInValidators().contains(shortname)) {
-        return ValidatorFactory::createObject(shortname.toLatin1());
+        return ValidatorFactory::createObject(Validator::builtInValidators().value(
+                shortname).toLatin1());
     }
     return nullptr;
 }
 
+Validator *ValidatorFactory::createObject(const QByteArray &className) {
+    Constructor constructor = ValidatorFactory::instance.value(className);
+    if ( constructor == nullptr ) {
+        return nullptr;
+    }
+    return (*constructor)();
+}
+
+QSharedPointer<Validator> ValidatorFactory::getValidatorObject(
+    const QString &shortname) {
+    if (!ValidatorFactory::validatorInstances.contains(shortname)) {
+        ValidatorFactory::validatorInstances.insert(shortname,
+                QSharedPointer<Validator>(ValidatorFactory::createValidator(shortname)));
+    }
+    return ValidatorFactory::validatorInstances.value(shortname);
+}
+
 void ValidatorFactory::registerClasses() {
     if (ValidatorFactory::instance.isEmpty()) {
-//        Validator::registerClass<CompareValidator>();
+        //        Validator::registerClass<CompareValidator>();
         ValidatorFactory::registerClass<DefaultValidator>();
-//        Validator::registerClass<EmailValidator>();
-//        Validator::registerClass<ExistValidator>();
+        //        Validator::registerClass<EmailValidator>();
+        //        Validator::registerClass<ExistValidator>();
 //        Validator::registerClass<ImageValidator>();
 //        Validator::registerClass<SizeValidator>();
 //        Validator::registerClass<NumberValidator>();
diff --git a/src/validators/validatorfactory.h b/src/validators/validatorfactory.h
index bda0cd6..28c1526 100644
--- a/src/validators/validatorfactory.h
+++ b/src/validators/validatorfactory.h
@@ -2,12 +2,13 @@
 #define VALIDATORFACTORY_H
 #include <QString>
 #include <QHash>
+#include <QSharedPointer>
 namespace CuteEntityManager {
 class Validator;
 class ValidatorFactory {
   public:
     static void registerClasses();
-    static Validator *createValidator(QString shortname);
+    static Validator *createValidator(const QString &shortname);
     template<typename T>
     static void registerClass() {
         if (!ValidatorFactory::instance.contains(
@@ -17,19 +18,17 @@ class ValidatorFactory {
         }
     }
 
-    static Validator *createObject( const QByteArray &className) {
-        Constructor constructor = ValidatorFactory::instance.value(className);
-        if ( constructor == nullptr ) {
-            return nullptr;
-        }
-        return (*constructor)();
-    }
+    static Validator *createObject( const QByteArray &className);
+
+    static QSharedPointer<Validator> getValidatorObject(const QString &shortname);
+
     typedef Validator *(*Constructor)();
     template<typename T>
     static Validator *constructorHelper() {
         return new T();
     }
     static QHash<QByteArray, Constructor> instance;
+    static QHash<QString, QSharedPointer<Validator>> validatorInstances;
 
   protected:
     ValidatorFactory();
diff --git a/src/validators/validatorrule.cpp b/src/validators/validatorrule.cpp
new file mode 100644
index 0000000..e1d9fe8
--- /dev/null
+++ b/src/validators/validatorrule.cpp
@@ -0,0 +1,100 @@
+#include "validatorrule.h"
+using namespace CuteEntityManager;
+
+ValidationRule::ValidationRule() {
+}
+
+ValidationRule::ValidationRule(QString validatorName,
+                               QString attributeName, QList<Param> params) {
+    this->validatorName = validatorName;
+    this->attributes = QStringList(attributeName);
+    this->params = params;
+}
+
+ValidationRule::ValidationRule(QString validatorName,
+                               QString attributeName, Param param) {
+    this->validatorName = validatorName;
+    this->attributes = QStringList(attributeName);
+    if (!param.getName().isEmpty()) {
+        this->params.append(param);
+    }
+}
+
+ValidationRule::ValidationRule(QString validatorName,
+                               QStringList attributeNames, QList<Param> params) {
+    this->validatorName = validatorName;
+    this->attributes = attributeNames;
+    this->params = params;
+}
+
+ValidationRule::ValidationRule(QString validatorName,
+                               QStringList attributeNames, Param param) {
+    this->validatorName = validatorName;
+    this->attributes = attributeNames;
+    if (!param.getName().isEmpty()) {
+        this->params.append(param);
+    }
+}
+
+ValidationRule::ValidationRule(QString validatorName, QString attributeName,
+                               QString paramName, QString paramValue) {
+    this->validatorName = validatorName;
+    this->attributes = QStringList(attributeName);
+    this->params.append(Param(paramName, paramValue));
+}
+
+ValidationRule::ValidationRule(QString validatorName, QString attributeName,
+                               QString paramName1, QVariant paramValue1, QString paramName2,
+                               QVariant paramValue2) {
+    this->validatorName = validatorName;
+    this->attributes = QStringList(attributeName);
+    params.append(Param(paramName1, paramValue1));
+    params.append(Param(paramName2, paramValue2));
+}
+
+ValidationRule::ValidationRule(QString validatorName,
+                               QStringList attributeNames,
+                               QString paramName, QVariant paramValue) {
+    this->validatorName = validatorName;
+    this->attributes = attributeNames;
+    this->params.append(Param(paramName, paramValue));
+}
+
+ValidationRule::ValidationRule(QString validatorName,
+                               QStringList attributeNames,
+                               QString paramName1, QVariant paramValue1, QString paramName2,
+                               QVariant paramValue2) {
+    this->validatorName = validatorName;
+    this->attributes = attributeNames;
+    params.append(Param(paramName1, paramValue1));
+    params.append(Param(paramName2, paramValue2));
+}
+
+ValidationRule::~ValidationRule() {
+}
+
+QString ValidationRule::getValidatorName() const {
+    return validatorName;
+}
+
+void ValidationRule::setValidatorName(const QString &value) {
+    validatorName = value;
+}
+QStringList ValidationRule::getAttributes() const {
+    return attributes;
+}
+
+void ValidationRule::setAttributes(const QStringList &value) {
+    attributes = value;
+}
+QList<Param> ValidationRule::getParams() const {
+    return params;
+}
+
+void ValidationRule::setParams(const QList<Param> &value) {
+    params = value;
+}
+
+
+
+
diff --git a/src/validators/validatorrule.h b/src/validators/validatorrule.h
new file mode 100644
index 0000000..539f076
--- /dev/null
+++ b/src/validators/validatorrule.h
@@ -0,0 +1,47 @@
+#ifndef VALIDATORATTRIBUTE_H
+#define VALIDATORATTRIBUTE_H
+#include <QString>
+#include <QStringList>
+#include "param.h"
+namespace CuteEntityManager {
+class ValidationRule {
+  public:
+    ValidationRule();
+    explicit ValidationRule(QString validatorName, QString attributeName,
+                            QList<Param> params = QList<Param>());
+    explicit ValidationRule(QString validatorName, QString attributeName,
+                            Param param);
+    explicit ValidationRule(QString validatorName, QStringList attributeNames,
+                            QList<Param> params = QList<Param>());
+    explicit ValidationRule(QString validatorName, QStringList attributeNames,
+                            Param param);
+    explicit ValidationRule(QString validatorName, QString attributeName,
+                            QString paramName, QString paramValue);
+    explicit ValidationRule(QString validatorName, QString attributeName,
+                            QString paramName1, QVariant paramValue1, QString paramName2,
+                            QVariant paramValue2);
+    explicit ValidationRule(QString validatorName, QStringList attributeNames,
+                            QString paramName, QVariant paramValue = QVariant());
+    explicit ValidationRule(QString validatorName, QStringList attributeNames,
+                            QString paramName1, QVariant paramValue1, QString paramName2,
+                            QVariant paramValue2);
+
+    ~ValidationRule();
+    QString getValidatorName() const;
+    void setValidatorName(const QString &value);
+
+    QStringList getAttributes() const;
+    void setAttributes(const QStringList &value);
+
+    QList<Param> getParams() const;
+    void setParams(const QList<Param> &value);
+
+  private:
+    QString validatorName;
+    QStringList attributes;
+    QList<Param> params;
+};
+}
+
+
+#endif // VALIDATORATTRIBUTE_H
