commit 28d2f01abb8a0130364394432ca605f538c26f14
Author: Christian Ehringfeld <c.ehringfeld@t-online.de>
Date:   Tue Aug 11 19:18:28 2015 +0200

    validators

diff --git a/samples/example/main.cpp b/samples/example/main.cpp
index ae1f0f1..c1b5e31 100644
--- a/samples/example/main.cpp
+++ b/samples/example/main.cpp
@@ -26,6 +26,7 @@ int main(int argc, char *argv[]) {
 //                                     QDir::currentPath() + "/db.sqlite", "", "", "", 0, true);
     CuteEntityManager::EntityManager("QSQLITE",
                                      ":memory:", "", "", "", "", true, "foreign_keys = ON");
+    qDebug() << "EntityManagerObjectName:" << e->objectName();
     SqliteBackupProcessor *sqliteproc = new SqliteBackupProcessor(e->getDb(),
             QDir::currentPath());
     qWarning() << "DB Loaded:" << sqliteproc->sqliteDBMemFile(false, "db.sqlite");
diff --git a/src/entitymanager.cpp b/src/entitymanager.cpp
index bb09c81..283bc12 100644
--- a/src/entitymanager.cpp
+++ b/src/entitymanager.cpp
@@ -25,6 +25,9 @@ using namespace CuteEntityManager;
 
 QStringList EntityManager::connectionNames = QStringList();
 
+QHash<QString, EntityManager *> EntityManager::instances =
+    QHash<QString, EntityManager *>();
+
 QStringList EntityManager::getConnectionNames() {
     return EntityManager::connectionNames;
 }
@@ -58,10 +61,12 @@ void EntityManager::init() {
     this->schema->setTables(this->schema->getTableSchemas());
     this->queryInterpreter = QSharedPointer<QueryInterpreter>(new QueryInterpreter(
                                  this->schema->getQueryBuilder()));
+    this->appendToInstanceList();
 }
 
 EntityManager::~EntityManager() {
     EntityManager::removeConnectionName(this->db->getConnectionName());
+    EntityManager::instances.remove(this->objectName());
 }
 
 bool EntityManager::startup(QString version, QStringList toInitialize,
@@ -446,6 +451,42 @@ bool EntityManager::isRelationPropertyValid(const QMetaProperty &prop,
     return propertyIsValid;
 }
 
+QString EntityManager::generateObjectName() {
+    int i = 0;
+    QString name = "em[";
+    while (true) {
+        if (!EntityManager::instances.contains(name + QString::number(i) + "]")) {
+            name += QString::number(i) + "]";
+            break;
+        }
+    }
+    return name;
+}
+
+void EntityManager::appendToInstanceList() {
+    this->setObjectName(this->generateObjectName());
+    EntityManager::instances.insert(this->objectName(), this);
+}
+QHash<QString, EntityManager *> EntityManager::getInstances() {
+    return instances;
+}
+
+EntityManager *EntityManager::getDefaultInstance() {
+    for (auto i = EntityManager::instances.constBegin();
+            i != EntityManager::instances.constEnd(); ++i) {
+        return i.value();
+    }
+    return nullptr;
+}
+
+EntityManager *EntityManager::getInstance(QString name) {
+    if (EntityManager::instances.contains(name)) {
+        return EntityManager::instances.value(name);
+    }
+    return nullptr;
+}
+
+
 bool EntityManager::shouldBeSaved(QSharedPointer<Entity> &entity,
                                   const Relation &r) {
     return entity && (r.getCascadeType().contains(CascadeType::ALL)
diff --git a/src/entitymanager.h b/src/entitymanager.h
index 7d4143b..c184c05 100644
--- a/src/entitymanager.h
+++ b/src/entitymanager.h
@@ -50,7 +50,6 @@ class EntityManager : public QObject {
     bool startup(QString version, QStringList toInitialize,
                  bool createIndices = false);
     bool executeQuery(const QString &query);
-    static void removeConnectionName(const QString &name);
     QSharedPointer<Entity> findById(const qint64 &id, const QString &classname);
     QList<QSharedPointer<Entity>> findEntityByAttributes(const
                                QSharedPointer<Entity> &entity,
@@ -59,7 +58,8 @@ class EntityManager : public QObject {
                 const bool persistRelations = true, const bool validate = true);
     bool create(QSharedPointer<Entity> &entity, const bool persistRelations = true,
                 const bool checkDuplicate = false, const bool validate = true);
-    bool save(QSharedPointer<Entity> &entity, const bool persistRelations = true, const bool ignoreHasChanged=true);
+    bool save(QSharedPointer<Entity> &entity, const bool persistRelations = true,
+              const bool ignoreHasChanged = true);
     qint64 findId(QSharedPointer<Entity> &entity);
     bool merge(QSharedPointer<Entity> &entity, bool withRelations = true,
                const bool validate = true);
@@ -88,8 +88,12 @@ class EntityManager : public QObject {
                   QString username = "",
                   QString password = "", QString port = "", bool logQueries = false,
                   QString databaseOptions = "");
-    ~EntityManager();
+    virtual ~EntityManager();
     static QStringList getConnectionNames();
+    static void removeConnectionName(const QString &name);
+    static QHash<QString, EntityManager *> getInstances();
+    static EntityManager *getDefaultInstance();
+    static EntityManager *getInstance(QString name);
     QSharedPointer<QueryBuilder> getQueryBuilder() const;
 
     template<class T> QList<QSharedPointer<T>> find(Query &q,
@@ -268,9 +272,13 @@ class EntityManager : public QObject {
                                 const QSharedPointer<Entity> &e, const Relation &r);
     bool isRelationPropertyValid(const QMetaProperty &prop, const Relation &r,
                                  const QSharedPointer<Entity> &e, const QSharedPointer<Entity> &relatedEntity);
+    QString generateObjectName();
+    void appendToInstanceList();
 
   private:
     static QStringList connectionNames;
+    static QHash<QString, EntityManager *> instances;
+    QString id;
     QSharedPointer<Schema> schema;
     static void setConnectionNames(QStringList list);
     QSharedPointer<Database> db;
diff --git a/src/query.cpp b/src/query.cpp
index b6b9f1f..1cf9727 100644
--- a/src/query.cpp
+++ b/src/query.cpp
@@ -38,6 +38,22 @@ Query::Query(QStringList from, QList<Expression> where, QList<Join> joins,
     this->having = having;
 }
 
+Query::Query(QString from, Expression where, Join join,
+             QHash<QString, QVariant> params, quint64 limit, quint64 offset,
+             Expression select, QString groupBy, bool distinct, QList<Expression> having) {
+    this->from.append(from);
+    this->where.append(where);
+    this->joins.append(join);
+    this->params = params;
+    this->limit = limit;
+    this->offset = offset;
+    this->select.append(select);
+    this->groupBy.append(groupBy);
+    this->distinct = distinct;
+    this->having = having;
+
+}
+
 void Query::appendWhere(const QString &condition) {
     this->where.append(Expression(condition));
 }
diff --git a/src/query.h b/src/query.h
index 8e0b54b..1adc513 100644
--- a/src/query.h
+++ b/src/query.h
@@ -30,13 +30,21 @@ class Query {
   public:
     Query();
     ~Query();
-    Query(QStringList from, QList<Expression> where = QList<Expression>(),
-          QList<Join> joins = QList<Join>(),
-          QHash<QString, QVariant> params = QHash<QString, QVariant>(), quint64 limit = 0,
-          quint64 offset = 0,
-          QList<Expression> select = QList<Expression>(),
-          QStringList groupBy = QStringList(), bool distinct = false,
-          QList<Expression> having = QList<Expression>());
+    explicit Query(QStringList from, QList<Expression> where = QList<Expression>(),
+                   QList<Join> joins = QList<Join>(),
+                   QHash<QString, QVariant> params = QHash<QString, QVariant>(), quint64 limit = 0,
+                   quint64 offset = 0,
+                   QList<Expression> select = QList<Expression>(),
+                   QStringList groupBy = QStringList(), bool distinct = false,
+                   QList<Expression> having = QList<Expression>());
+
+    explicit Query(QString from, Expression where = Expression(),
+                   Join join = Join(),
+                   QHash<QString, QVariant> params = QHash<QString, QVariant>(), quint64 limit = 0,
+                   quint64 offset = 0,
+                   Expression select = Expression(),
+                   QString groupBy = "", bool distinct = false,
+                   QList<Expression> having = QList<Expression>());
 
     QString getSelectOption() const;
     void setSelectOption(const QString &value);
diff --git a/src/validators/comparevalidator.h b/src/validators/comparevalidator.h
index 5b2011d..a24df9c 100644
--- a/src/validators/comparevalidator.h
+++ b/src/validators/comparevalidator.h
@@ -6,11 +6,11 @@ class CompareValidator : public Validator {
     Q_OBJECT
   public:
     CompareValidator();
-    ErrorMsg validateParam(QVariant value, Param param) const final override;
     QString getDefaultOperator() const;
     void setDefaultOperator(const QString &value);
 
   protected:
+    ErrorMsg validateParam(QVariant value, Param param) const final override;
     QString defaultOperator = QStringLiteral("==");
 };
 }
diff --git a/src/validators/datevalidator.h b/src/validators/datevalidator.h
index c98119d..81d0f00 100644
--- a/src/validators/datevalidator.h
+++ b/src/validators/datevalidator.h
@@ -6,6 +6,7 @@ class DateValidator : public Validator {
     Q_OBJECT
   public:
     DateValidator();
+  protected:
     ErrorMsg validateParam(QVariant value, Param param) const final override;
 };
 }
diff --git a/src/validators/defaultvalidator.h b/src/validators/defaultvalidator.h
index 5ffa39a..ecb18fb 100644
--- a/src/validators/defaultvalidator.h
+++ b/src/validators/defaultvalidator.h
@@ -6,6 +6,7 @@ class DefaultValidator : public Validator {
     Q_OBJECT
   public:
     DefaultValidator();
+  protected:
     ErrorMsg validateParam(QVariant value, Param param) const final override;
 };
 }
diff --git a/src/validators/emailvalidator.h b/src/validators/emailvalidator.h
index eb396b4..b4972f0 100644
--- a/src/validators/emailvalidator.h
+++ b/src/validators/emailvalidator.h
@@ -6,7 +6,6 @@ class EmailValidator : public Validator {
     Q_OBJECT
   public:
     EmailValidator();
-    ErrorMsg validateParam(QVariant value, Param param) const final override;
     QString getPattern() const;
     void setPattern(const QString &value);
 
@@ -14,6 +13,7 @@ class EmailValidator : public Validator {
     void setFullPattern(const QString &value);
 
   protected:
+    ErrorMsg validateParam(QVariant value, Param param) const final override;
     QString pattern =
         QStringLiteral("/^[a-zA-Z0-9!#$%&\'*+\\/=?^_`{|}~-]+(?:\\\\.[a-zA-Z0-9!#$%&\'*+\\\\/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$/");
     QString fullPattern =
diff --git a/src/validators/existvalidator.cpp b/src/validators/existvalidator.cpp
index 9c07953..bdc9888 100644
--- a/src/validators/existvalidator.cpp
+++ b/src/validators/existvalidator.cpp
@@ -1,9 +1,16 @@
 #include "existvalidator.h"
+#include "../entity.h"
+#include "../entityinstancefactory.h"
 using namespace CuteEntityManager;
 ExistValidator::ExistValidator() : Validator() {
 }
 
 ErrorMsg ExistValidator::validateParam(QVariant value, Param param) const {
-
+    Q_UNUSED(param)
+    QSharedPointer<Entity> entity = EntityInstanceFactory::castQVariant(value);
+    if (!entity || entity->getId() <= -1) {
+        return ErrorMsg("", "<property> is invalid.");
+    }
+    return ErrorMsg();
 }
 
diff --git a/src/validators/existvalidator.h b/src/validators/existvalidator.h
index 1aaccef..cb2ac39 100644
--- a/src/validators/existvalidator.h
+++ b/src/validators/existvalidator.h
@@ -6,6 +6,7 @@ class ExistValidator : public Validator {
     Q_OBJECT
   public:
     ExistValidator();
+  protected:
     ErrorMsg validateParam(QVariant value, Param param) const final override;
 };
 }
diff --git a/src/validators/filevalidator.h b/src/validators/filevalidator.h
index a4391f3..d9b0b8f 100644
--- a/src/validators/filevalidator.h
+++ b/src/validators/filevalidator.h
@@ -7,6 +7,7 @@ class FileValidator : public Validator {
     Q_OBJECT
   public:
     FileValidator();
+  protected:
     virtual ErrorMsg validateParam(QVariant value, Param param) const override;
     virtual ErrorMsg validateMIMEType(const QFileInfo &file,
                                       const Param &param) const;
diff --git a/src/validators/imagevalidator.h b/src/validators/imagevalidator.h
index 47f4068..413e9f1 100644
--- a/src/validators/imagevalidator.h
+++ b/src/validators/imagevalidator.h
@@ -6,6 +6,7 @@ class ImageValidator : public FileValidator {
     Q_OBJECT
   public:
     ImageValidator();
+  protected:
     ErrorMsg validateParam(QVariant value, Param param) const final override;
     virtual ErrorMsg validateImage(QVariant value, Param param) const;
 };
diff --git a/src/validators/numbervalidator.h b/src/validators/numbervalidator.h
index e1733cd..dde1606 100644
--- a/src/validators/numbervalidator.h
+++ b/src/validators/numbervalidator.h
@@ -6,6 +6,7 @@ class NumberValidator : public Validator {
     Q_OBJECT
   public:
     NumberValidator();
+  protected:
     ErrorMsg validateParam(QVariant value, Param param) const final override;
 };
 }
diff --git a/src/validators/patternvalidator.h b/src/validators/patternvalidator.h
index 6b1475a..bd1aedf 100644
--- a/src/validators/patternvalidator.h
+++ b/src/validators/patternvalidator.h
@@ -6,6 +6,7 @@ class PatternValidator : public Validator {
     Q_OBJECT
   public:
     PatternValidator();
+  protected:
     ErrorMsg validateParam(QVariant value, Param param) const final override;
 };
 }
diff --git a/src/validators/requiredvalidator.h b/src/validators/requiredvalidator.h
index 4e17dd7..bdea3b4 100644
--- a/src/validators/requiredvalidator.h
+++ b/src/validators/requiredvalidator.h
@@ -6,6 +6,7 @@ class RequiredValidator : public Validator {
     Q_OBJECT
   public:
     RequiredValidator();
+  protected:
     ErrorMsg validateParam(QVariant value, Param param) const final override;
 };
 }
diff --git a/src/validators/uniquevalidator.cpp b/src/validators/uniquevalidator.cpp
index 63379a7..5c00a4c 100644
--- a/src/validators/uniquevalidator.cpp
+++ b/src/validators/uniquevalidator.cpp
@@ -1,10 +1,56 @@
 #include "uniquevalidator.h"
-
+#include "src/entitymanager.h"
 using namespace CuteEntityManager;
-UniqueValidator::UniqueValidator() {
+UniqueValidator::UniqueValidator() : Validator() {
+}
 
+QList<ErrorMsg> UniqueValidator::validate(QVariant value,
+        QList<Param> params) const {
+    QList<ErrorMsg> msgs = QList<ErrorMsg>();
+    if (!params.isEmpty()) {
+        QString targetAttribute = "";
+        QString targetClass = "";
+        QString entityManagerID = "";
+        for (int i = 0; i < params.size(); ++i) {
+            if (params.at(i).getName() == "targetAttribute") {
+                targetAttribute = params.at(i).getValue().toString();
+            } else if (params.at(i).getName() == "entityManagerID") {
+                entityManagerID = params.at(i).getValue().toString();
+            } else if (params.at(i).getName() == "targetClass") {
+                targetClass = params.at(i).getValue().toString();
+            }
+        }
+        EntityManager *em = nullptr;
+        if (entityManagerID.isEmpty()) {
+            em = EntityManager::getDefaultInstance();
+        } else {
+            em = EntityManager::getInstance(entityManagerID);
+        }
+        if (!em) {
+            msgs.append(ErrorMsg("", "No entitymanager."));
+        } else {
+            Query q = Query();
+            auto e = EntityInstanceFactory::createInstance(
+                         targetClass.toLatin1().constData());
+            q.appendFrom(e->getTablename());
+            delete e;
+            e = nullptr;
+            QHash<QString, QVariant> params = QHash<QString, QVariant>();
+            params.insert(targetAttribute, value);
+            q.appendWhere(Expression(targetAttribute, params));
+            if (em->count(q) > 0) {
+                msgs.append(ErrorMsg("",
+                                     "<property> \"" + value.toString() + "\" has already been taken."));
+            }
+        }
+    } else {
+        msgs.append(ErrorMsg("", "UniqueValidator has not enough parameters."));
+    }
+    return msgs;
 }
 
 ErrorMsg UniqueValidator::validateParam(QVariant value, Param param) const {
-
+    Q_UNUSED(value)
+    Q_UNUSED(param)
+    return ErrorMsg();
 }
diff --git a/src/validators/uniquevalidator.h b/src/validators/uniquevalidator.h
index a1936af..2e377fb 100644
--- a/src/validators/uniquevalidator.h
+++ b/src/validators/uniquevalidator.h
@@ -6,6 +6,8 @@ class UniqueValidator : public Validator {
     Q_OBJECT
   public:
     UniqueValidator();
+    virtual QList<ErrorMsg> validate(QVariant value, QList<Param> params) const override;
+  protected:
     ErrorMsg validateParam(QVariant value, Param param) const final override;
 };
 }
