Bonjour à tous,

Je viens de mettre en ligne une première version BETA de la future version de QxOrm (qui sera nommée QxOrm 1.2.2) : http://www.qxorm.com/version/QxOrm_1.2.2_BETA_17.zip

La principale nouveauté de cette version est l'apparition d'un nouveau module : QxValidator. Ce nouveau module permet de définir des règles de validation afin de vérifier une instance de classe avant qu'elle soit insérée ou mise à jour en BDD. Ça ressemble fortement à ce que propose NHibernate (et d'autres ORM) : http://nhforge.org/wikis/validator/n...mentation.aspx

Il n'y a pas de doc encore pour utiliser ce module, mais voici un exemple pour ceux qui veulent tester (exemple du dossier ./test/qxDllSample/dll1/ du package QxOrm) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#ifndef _QX_CLASS_PERSON_H_
#define _QX_CLASS_PERSON_H_
 
#ifdef _MSC_VER
#pragma once
#endif
 
namespace qx {
namespace test {
 
class QX_DLL1_EXPORT CPerson : public QObject
{
 
   Q_OBJECT
   QX_REGISTER_FRIEND_CLASS(qx::test::CPerson)
 
public:
 
   enum sex { male, female, unknown };
 
protected:
 
   long     m_lPersonId;
   QString  m_sFirstName;
   QString  m_sLastName;
   double   m_dDouble;
   sex      m_eSex;
 
public:
 
   CPerson() : QObject(), m_lPersonId(0), m_sFirstName("toto"), m_dDouble(4.5678), m_eSex(unknown) { ; }
   CPerson(long lId) : QObject(), m_lPersonId(lId), m_sFirstName("toto"), m_dDouble(4.5678), m_eSex(unknown) { ; }
   virtual ~CPerson() { ; }
 
   long getPersonId() const      { return m_lPersonId; }
   QString getFirstName() const  { return m_sFirstName; }
   QString getLastName() const   { return m_sLastName; }
   double getDouble() const      { return m_dDouble; }
   sex getSex() const            { return m_eSex; }
 
   void setPersonId(long l)               { m_lPersonId = l; }
   void setFirstName(const QString & s)   { m_sFirstName = s; }
   void setLastName(const QString & s)    { m_sLastName = s; }
   void setDouble(double d)               { m_dDouble = d; }
   void setSex(sex e)                     { m_eSex = e; }
 
private:
 
   void isValid(qx::QxInvalidValueX & invalidValues);
 
};
 
} // namespace test
} // namespace qx
 
QX_REGISTER_COMPLEX_CLASS_NAME_HPP_QX_DLL1(qx::test::CPerson, QObject, 0, qx_test_CPerson)
 
#endif // _QX_CLASS_PERSON_H_
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include "../include/precompiled.h"
 
#include "../include/CPerson.h"
 
#include <QxMemLeak.h>
 
void myGlobalValidator_1(const QVariant & value, const qx::IxValidator * validator, qx::QxInvalidValueX & invalidValues);
void myGlobalValidator_2(const QString & value, const qx::IxValidator * validator, qx::QxInvalidValueX & invalidValues);
 
QX_REGISTER_COMPLEX_CLASS_NAME_CPP_QX_DLL1(qx::test::CPerson, qx_test_CPerson)
 
namespace qx {
template <> void register_class(QxClass<qx::test::CPerson> & t)
{
   IxDataMember * pData = NULL;
   IxFunction * pFct = NULL;
   IxValidator * pValidator = NULL;
 
   t.setName("CPerson");
 
   pData = t.id(& qx::test::CPerson::m_lPersonId, "idPerson", 0);
 
   pData = t.data(& qx::test::CPerson::m_sFirstName, "firstName", 0);
   pData = t.data(& qx::test::CPerson::m_sLastName, "lastName", 0);
   pData = t.data(& qx::test::CPerson::m_dDouble, "double", 0);
   pData = t.data(& qx::test::CPerson::m_eSex, "sex", 0);
 
   pFct = t.fct_0<long>(& qx::test::CPerson::getPersonId, "fct_getPersonId");
   pFct = t.fct_0<QString>(& qx::test::CPerson::getFirstName, "fct_getFirstName");
   pFct = t.fct_1<void, long>(& qx::test::CPerson::setPersonId, "fct_setPersonId");
 
   QxValidatorX<qx::test::CPerson> * pAllValidator = t.getAllValidator();
   if (! pAllValidator) { qAssert(false); return; }
   pValidator = pAllValidator->add_NotEmpty("firstName", "a person must have a firstname");
   pValidator = pAllValidator->add_NotEmpty("lastName");
   pValidator = pAllValidator->add_MinDecimal("double", 0.5, "'double' field must be greater than or equal to '0.5'");
   pValidator = pAllValidator->add_MaxDecimal("double", 103.19);
   pValidator = pAllValidator->add_CustomValidator(& qx::test::CPerson::isValid);
   pValidator = pAllValidator->add_CustomValidator_QVariant(& myGlobalValidator_1, "firstName");
   pValidator = pAllValidator->add_CustomValidator_DataType<QString>(& myGlobalValidator_2, "lastName");
}}
 
namespace qx {
namespace test {
 
void CPerson::isValid(qx::QxInvalidValueX & invalidValues)
{
   // This method is called automatically by 'QxValidator' module (validator engine of QxOrm library) :
   // - when you try to insert or update using 'qx::dao::xxx' functions
   // - when you call 'qx::validate()' function
 
   // For registration, see 'pAllValidator->add_CustomValidator(& qx::test::CPerson::isValid);' into 'qx::register_class<T>()' function
 
   // Here, you can verify some values of your instance
   // If a value is not valid, you must add an invalid value into the collection 'invalidValues'
 
   if ((m_sFirstName == "admin") || (m_sLastName == "admin"))
   { invalidValues.insert("you cannot set 'admin' for the name of a person"); }
}
 
} // namespace test
} // namespace qx
 
// ********************************************************************************************************
// ********************************************************************************************************
 
// Example of global functions 'myGlobalValidator_1' and 'myGlobalValidator_2' used by 'QxValidator' module
// Those functions will be called automatically by validator engine of QxOrm library :
// - when you try to insert or update using 'qx::dao::xxx' functions
// - when you call 'qx::validate()' function
 
void myGlobalValidator_1(const QVariant & value, const qx::IxValidator * validator, qx::QxInvalidValueX & invalidValues)
{
   // Here you can test the value (converted to QVariant type)
   // If an invalid value is detected, just add a message into 'invalidValues' collection
 
   Q_UNUSED(value); Q_UNUSED(validator); Q_UNUSED(invalidValues);
}
 
void myGlobalValidator_2(const QString & value, const qx::IxValidator * validator, qx::QxInvalidValueX & invalidValues)
{
   // Here you can test the value (with its real type, in this example, the data-member is a 'QString' type)
   // If an invalid value is detected, just add a message into 'invalidValues' collection
 
   Q_UNUSED(value); Q_UNUSED(validator); Q_UNUSED(invalidValues);
}
 
// ********************************************************************************************************
// ********************************************************************************************************
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
boost::shared_ptr<qx::test::CPerson> personValidate;
personValidate.reset(new qx::test::CPerson());
personValidate->setLastName("admin");
personValidate->setDouble(305.86);
qx::QxInvalidValueX invalidValues = qx::validate(personValidate);
QString sInvalidValues = invalidValues.text();
qDebug("[QxOrm] test 'QxValidator' module :\n%s", qPrintable(sInvalidValues));
Sinon, la BETA contient également une évolution pour retourner le vrai ID (à la place de l'OID) avec une BDD PostgreSQL et la fonction qx::dao::insert() : on utilise le mot-clé RETURNING dans la requête SQL pour gérer ça car la classe QSqlQuery de Qt retourne l'OID (méthode lastInsertId()).

Merci d'avance à tous ceux qui pourront tester cette version BETA...