IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

QxOrm Discussion :

Des relations "à la main" (sans le code de QxEE, mais avec son aide)


Sujet :

QxOrm

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Paysan
    Inscrit en
    Juin 2015
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2015
    Messages : 45
    Points : 39
    Points
    39
    Par défaut Des relations "à la main" (sans le code de QxEE, mais avec son aide)
    Bonjour,

    Comme dit dans mon trait précédent, j'ai une application qui tourne très bien, mais dans laquelle,
    pour commencer, je n'ai pas exprimé les relations (dans mes objets, la relation à un autre objet
    est un "long IdXXX" de l'IdObj -clé primaire- dans l'autre table, et apparait donc comme un nombre
    dans les colonnes de l'interface utilisateur -et les "model/view", ...-)

    Je suis en train de rajouter les relations dans ce code, car, finalement, je trouve que Qxee me génère
    beaucoup trop de types (avec des nos parfois) pour ma petite application (et peut-être ma petite tête).
    Par exemple (on verra plus bas) un type de pointeur vers le même objet oParam est defini pour chaque relation.
    Je ne sais pas si il est possible d'arriver au bout, mais je me suis inspiré de ce que génère Qxee, en
    regroupant les types identiques (simplifiant ??), en en mettant peut-être trop (par crainte aveugle
    de "verifyColumns" et de son assert(false) ), peut-être parfois pas assez, mais j'obtiens une
    compilation et par contre une erreur à l'éxécution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [QxOrm] qx::QxDataMemberX<T> id (primary key) already defined 'IdObj'
    Faut-il que les clés primaire dans des tables différentes aient des noms différents ?
    (les miens s'appelent tous "IdObj")
    Je n'active pour l'instant que les relations entre deux objets oStIntOb et oParam.
    Lorsque je n'ai modifié que oStIntOb, j'ai eu un chargement correct des oParam, mais une erreur sur les oStIntOb:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Démarrage de /home/cs/Bureau/AteliersLogiciels/CaChaBanPer/build-CaChaBanPer-Desktop_Qt_5_3_GCC_32bit-Debug/CaChaBanPer...
    [QxOrm] qx::QxSqlDatabase : create new database connection in thread '0xb1651740' with key '{7d592a7f-f3c0-49ec-8902-d482abd7212a}'
    [QxOrm] sql query (73 ms) : SELECT oParam.IdObj AS oParam_IdObj_0, oParam.TypeParam AS oParam_TypeParam_0, oParam.Libelle AS oParam_Libelle_0, oParam.Abrege AS oParam_Abrege_0 FROM oParam WHERE TypeParam=1
    [QxOrm] sql query (1 ms) : SELECT oParam.IdObj AS oParam_IdObj_0, oParam.TypeParam AS oParam_TypeParam_0, oParam.Libelle AS oParam_Libelle_0, oParam.Abrege AS oParam_Abrege_0 FROM oParam WHERE TypeParam=2
    [QxOrm] sql query (0 ms) : SELECT oParam.IdObj AS oParam_IdObj_0, oParam.TypeParam AS oParam_TypeParam_0, oParam.Libelle AS oParam_Libelle_0, oParam.Abrege AS oParam_Abrege_0 FROM oParam WHERE TypeParam=3
    [QxOrm] sql query (1 ms) : SELECT oCulture.IdObj AS oCulture_IdObj_0, oCulture.Abrege AS oCulture_Abrege_0, oCulture.dtDebut AS oCulture_dtDebut_0, oCulture.dtFinPrevue AS oCulture_dtFinPrevue_0, oCulture.NbUeK_Rang AS oCulture_NbUeK_Rang_0, oCulture.Sem_Plant_Rang AS oCulture_Sem_Plant_Rang_0, oCulture.idUniteSem_Plant AS oCulture_idUniteSem_Plant_0, oCulture.Prod_Rang AS oCulture_Prod_Rang_0, oCulture.idUniteProd AS oCulture_idUniteProd_0, oCulture.Libelle AS oCulture_Libelle_0 FROM oCulture WHERE KType=1
    [QxOrm] sql query (2 ms) : SELECT oCulture.IdObj AS oCulture_IdObj_0, oCulture.Attr AS oCulture_Attr_0, oCulture.KType AS oCulture_KType_0, oCulture.Abrege AS oCulture_Abrege_0, oCulture.dtDebut AS oCulture_dtDebut_0, oCulture.dtFinPrevue AS oCulture_dtFinPrevue_0, oCulture.NbUeK_Rang AS oCulture_NbUeK_Rang_0, oCulture.Sem_Plant_Rang AS oCulture_Sem_Plant_Rang_0, oCulture.idUniteSem_Plant AS oCulture_idUniteSem_Plant_0, oCulture.Prod_Rang AS oCulture_Prod_Rang_0, oCulture.idUniteProd AS oCulture_idUniteProd_0, oCulture.IdSchema AS oCulture_IdSchema_0, oCulture.IdBP AS oCulture_IdBP_0, oCulture.NoUeK AS oCulture_NoUeK_0, oCulture.NbRang AS oCulture_NbRang_0, oCulture.dtFinEffective AS oCulture_dtFinEffective_0, oCulture.Libelle AS oCulture_Libelle_0 FROM oCulture WHERE KType=2
    ASSERT: "false" in file ../../Libs/QxOrm/include/QxDao/QxSqlQueryBuilder.h, line 228
    Le programme s'est terminé subitement.
    /home/cs/Bureau/AteliersLogiciels/CaChaBanPer/build-CaChaBanPer-Desktop_Qt_5_3_GCC_32bit-Debug/CaChaBanPer a planté
    Ce n'était pas malin de ma part de modifier un côté de la relation (oStIntOb) et pas l'autre (oParam) !!
    J' ai modifié le deuxième, je compile, et j'obtiens à l'éxécution (sur le chargement des oParam):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Démarrage de /home/cs/Bureau/AteliersLogiciels/CaChaBanPer/build-CaChaBanPer-Desktop_Qt_5_3_GCC_32bit-Debug/CaChaBanPer...
    [QxOrm] qx::QxSqlDatabase : create new database connection in thread '0xb161c740' with key '{4602dea7-1a58-4399-a162-30d8615d1db0}'
    [QxOrm] qx::QxDataMemberX<T> id (primary key) already defined 'IdObj'
    ASSERT: "false" in file ../../Libs/QxOrm/include/QxDataMember/../../inl/QxDataMember/QxDataMemberX.inl, line 113
    Le programme s'est terminé subitement.
    /home/cs/Bureau/AteliersLogiciels/CaChaBanPer/build-CaChaBanPer-Desktop_Qt_5_3_GCC_32bit-Debug/CaChaBanPer a planté
    Le code de oparam.h est:
    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
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
     
    #ifndef OPARAM_H
    #define OPARAM_H
     
    #include "ostintob.h"
     
    class oParam
    {
        QX_REGISTER_FRIEND_CLASS(oParam);
    protected:
        long m_IdObj; // dans TGENCCBP
        long m_Attr;  // dans TGENCCBP
        int m_TypeParam;
        QString m_Libelle;
        QString m_Abrege;
        //list_of_oStIntOb m_oStIntOb_use;
        list_of_oStIntOb m_StType;
        list_of_oStIntOb m_StClasse;
        list_of_oStIntOb m_UnitDate_Delai;
        list_of_oStIntOb m_UnitDuree;
        list_of_oStIntOb m_UnitValeur;
        //type_list_of_oCulture m_list_of_oCulture;
        //type_list_of_oCulture_1 m_list_of_oCulture_1;
        //bool m_Modif;
        //QString GetCaption(); // override;
        //void SetType(int aType){m_TypeParam=aType;}
        //void SetLibelle(QString aLibelle){m_Libelle=aLibelle;}
        //void SetAbrege(QString aAbrege){m_Abrege=aAbrege;}
    public:
        oParam():m_IdObj(0){;}
        oParam(const long & id): m_IdObj(id), m_TypeParam(0) { ; }
        oParam(int aType, QString aAbrege, QString aLibelle): m_IdObj(0)
              {m_TypeParam=aType; m_Libelle=aLibelle; m_Abrege=aAbrege;}
        virtual ~oParam(){;}
     
        list_of_oStIntOb getlist_of_oStIntOb_StType() const { return m_StType; }
        list_of_oStIntOb & list_of_oStIntOb_StType() { return m_StType; }
        const list_of_oStIntOb & list_of_oStIntOb_StType() const { return m_StType; }
        list_of_oStIntOb getlist_of_oStIntOb_StClasse() const { return m_StClasse; }
        list_of_oStIntOb & list_of_oStIntOb_StClasse() { return m_StClasse; }
        const list_of_oStIntOb & list_of_oStIntOb_StClasse() const { return m_StClasse; }
        list_of_oStIntOb getlist_of_oStIntOb_UnitDate_Delai() const { return m_UnitDate_Delai; }
        list_of_oStIntOb & list_of_oStIntOb_UnitDate_Delai() { return m_UnitDate_Delai; }
        const list_of_oStIntOb & list_of_oStIntOb_UnitDate_Delai() const { return m_UnitDate_Delai; }
        list_of_oStIntOb getlist_of_oStIntOb_UnitDuree() const { return m_UnitDuree; }
        list_of_oStIntOb & list_of_oStIntOb_UnitDuree() { return m_UnitDuree; }
        const list_of_oStIntOb & list_of_oStIntOb_UnitDuree() const { return m_UnitDuree; }
        list_of_oStIntOb getlist_of_oStIntOb_UnitValeur() const { return m_UnitValeur; }
        list_of_oStIntOb & list_of_oStIntOb_UnitValeur() { return m_UnitValeur; }
        const list_of_oStIntOb & list_of_oStIntOb_UnitValeur() const { return m_UnitValeur; }
        //type_list_of_oCulture getlist_of_oCulture() const;
        //type_list_of_oCulture & list_of_oCulture();
        //const type_list_of_oCulture & list_of_oCulture() const;
        //type_list_of_oCulture_1 getlist_of_oCulture_1() const;
        //type_list_of_oCulture_1 & list_of_oCulture_1();
        //const type_list_of_oCulture_1 & list_of_oCulture_1() const;
     
        list_of_oStIntOb getlist_of_oStIntOb_StType(bool bLoadFromDatabase, const QString & sAppendRelations = QString(), QSqlDatabase * pDatabase = NULL, QSqlError * pDaoError = NULL);
        list_of_oStIntOb & list_of_oStIntOb_StType(bool bLoadFromDatabase, const QString & sAppendRelations = QString(), QSqlDatabase * pDatabase = NULL, QSqlError * pDaoError = NULL);
        list_of_oStIntOb getlist_of_oStIntOb_StClasse(bool bLoadFromDatabase, const QString & sAppendRelations = QString(), QSqlDatabase * pDatabase = NULL, QSqlError * pDaoError = NULL);
        list_of_oStIntOb & list_of_oStIntOb_StClasse(bool bLoadFromDatabase, const QString & sAppendRelations = QString(), QSqlDatabase * pDatabase = NULL, QSqlError * pDaoError = NULL);
        list_of_oStIntOb getlist_of_oStIntOb_UnitDate_Delai(bool bLoadFromDatabase, const QString & sAppendRelations = QString(), QSqlDatabase * pDatabase = NULL, QSqlError * pDaoError = NULL);
        list_of_oStIntOb & list_of_oStIntOb_UnitDate_Delai(bool bLoadFromDatabase, const QString & sAppendRelations = QString(), QSqlDatabase * pDatabase = NULL, QSqlError * pDaoError = NULL);
        list_of_oStIntOb getlist_of_oStIntOb_UnitDuree(bool bLoadFromDatabase, const QString & sAppendRelations = QString(), QSqlDatabase * pDatabase = NULL, QSqlError * pDaoError = NULL);
        list_of_oStIntOb & list_of_oStIntOb_UnitDuree(bool bLoadFromDatabase, const QString & sAppendRelations = QString(), QSqlDatabase * pDatabase = NULL, QSqlError * pDaoError = NULL);
        list_of_oStIntOb getlist_of_oStIntOb_UnitValeur(bool bLoadFromDatabase, const QString & sAppendRelations = QString(), QSqlDatabase * pDatabase = NULL, QSqlError * pDaoError = NULL);
        list_of_oStIntOb & list_of_oStIntOb_UnitValeur(bool bLoadFromDatabase, const QString & sAppendRelations = QString(), QSqlDatabase * pDatabase = NULL, QSqlError * pDaoError = NULL);
        //type_list_of_oCulture getlist_of_oCulture(bool bLoadFromDatabase, const QString & sAppendRelations = QString(), QSqlDatabase * pDatabase = NULL, QSqlError * pDaoError = NULL);
        //type_list_of_oCulture & list_of_oCulture(bool bLoadFromDatabase, const QString & sAppendRelations = QString(), QSqlDatabase * pDatabase = NULL, QSqlError * pDaoError = NULL);
        //type_list_of_oCulture_1 getlist_of_oCulture_1(bool bLoadFromDatabase, const QString & sAppendRelations = QString(), QSqlDatabase * pDatabase = NULL, QSqlError * pDaoError = NULL);
        //type_list_of_oCulture_1 & list_of_oCulture_1(bool bLoadFromDatabase, const QString & sAppendRelations = QString(), QSqlDatabase * pDatabase = NULL, QSqlError * pDaoError = NULL);
     
        static QString relation_list_of_oStIntOb_StType() { return "list_of_oStIntOb_StType"; }
        static QString relation_list_of_oStIntOb_StClasse() { return "list_of_oStIntOb_StClasse"; }
        static QString relation_list_of_oStIntOb_UnitDate_Delai() { return "list_of_oStIntOb_UnitDate_Delai"; }
        static QString relation_list_of_oStIntOb_UnitDuree() { return "list_of_oStIntOb_UnitDuree"; }
        static QString relation_list_of_oStIntOb_UnitValeur() { return "list_of_oStIntOb_UnitValeur"; }
        //static QString relation_list_of_oCulture() { return "list_of_oCulture"; }
        //static QString relation_list_of_oCulture_1() { return "list_of_oCulture_1"; }
        static QString column_IdObj() { return "IdObj"; }
        static QString column_TypeParam() { return "TypeParam"; }
        static QString column_Libelle() { return "Libelle"; }
        static QString column_Abrege() { return "Abrege"; }
        static QString table_name() { return "oParam"; }
     
    //    Q_PROPERTY(long IdObj READ m_IdObj )
    //    Q_PROPERTY(long TypeParam READ m_TypeParam WRITE SetType )   //(int aType)) WRITE à virer -afaire-
    //    Q_PROPERTY(QString Libelle READ m_Libelle WRITE SetLibelle ) //(QString aLibelle))
    //    Q_PROPERTY(QString Abrege READ m_Abrege WRITE SetAbrege )    //(QString aAbrege))
    //    Q_PROPERTY(QString Caption READ GetCaption )
    //    QSqlError Enreg();
    //    QSqlError Lire();
    };
     
    typedef boost::shared_ptr<oParam> oparam_ptr;
    typedef qx::QxCollection<long,oParam> list_of_oParam;
    typedef boost::shared_ptr<list_of_oParam> list_of_oParam_ptr;
    typedef std::vector<oparam_ptr> oparam_lst;
     
    QX_REGISTER_HPP_MY_TEST_EXE(oParam,qx::trait::no_base_class_defined,1);
     
    const int ParamType_Unites       =1;
    const int ParamType_Classes      =2; // Préparations, Semis/Plantations, Végétation, Récoltes
    const int ParamType_StIntOb      =3; // Stades-St, Interventions-Int, Observations-Ob
     
    #endif // OPARAM_H
    On y voit que le même type "list_of_oStIntOb" est utilisé pour les 5 utilisations de oParam dans oStIntOb;
    en fait comme mes relations "fonctionnelles" (vues par l'utilisateur) sont toujours des n-1, je n'aurais
    même pas besoin de ces relations, seulement une liste comme écrite en commentaire juste au dessus pour
    savoir si un paramètre (une définition d'unité de mesure par exemple) est utilisé quelque part.
    (sans avoir même besoin de savoir où; un lstUse.count=0 en quelque sorte)

    Le code de oparam.cpp est:
    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
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
     
    #include "precompiled.h"   // Precompiled-header with '#include <QxOrm.h>' and '#include "export.h"'
    #include "oparam.h"
    #include <QxMemLeak.h>     // Automatic memory leak detection
    //#include <QtSql/qsql.h>
     
    #include "ostintob.h"
    //#include "oculture.h"
     
    QX_REGISTER_CPP_MY_TEST_EXE(oParam)   // This macro is necessary to register any class in QxOrm context
     
    namespace qx
    {
    template <> void register_class(QxClass<oParam> & t)
    {
    /*
    t.id(& oParam::m_IdObj, "IdObj");             // Register 'oParam::m_IdObj' <=> primary key IdObj
    t.data(& oParam::m_TypeParam, "TypeParam");
    t.data(& oParam::m_Libelle, "Libelle");
    t.data(& oParam::m_Abrege, "Abrege");
    */
    /*
    qx::IxDataMember * pData = NULL; Q_UNUSED(pData);
    qx::IxSqlRelation * pRelation = NULL; Q_UNUSED(pRelation);
    qx::IxFunction * pFct = NULL; Q_UNUSED(pFct);
    qx::IxValidator * pValidator = NULL; Q_UNUSED(pValidator);
    */
    t.setName("oParam"); //t.setPropertyBag("QX_EE_GENERATED_BY_SQLITE_IMPORT_PLUGIN", "1");
     
    t.id(& oParam::m_IdObj, "IdObj", 0); //pData->setPropertyBag("QX_EE_GENERATED_BY_SQLITE_IMPORT_PLUGIN", "1");
    t.id(& oParam::m_Attr, "Attr", 0);
     
    t.data(& oParam::m_TypeParam, "TypeParam", 0, true, true); //pData->setPropertyBag("QX_EE_GENERATED_BY_SQLITE_IMPORT_PLUGIN", "1");
    t.data(& oParam::m_Libelle, "Libelle", 0, true, true); //pData->setPropertyBag("QX_EE_GENERATED_BY_SQLITE_IMPORT_PLUGIN", "1");
    t.data(& oParam::m_Abrege, "Abrege", 0, true, true); //pData->setPropertyBag("QX_EE_GENERATED_BY_SQLITE_IMPORT_PLUGIN", "1");
     
    t.relationOneToMany(& oParam::m_StType, "list_of_oStIntOb_StType", "StType", 0);          // IdObj dans oStIntOb:StType
    t.relationOneToMany(& oParam::m_StClasse, "list_of_oStIntOb_StClasse", "StClasse", 0);    // IdObj dans oStIntOb:StClasse
    t.relationOneToMany(& oParam::m_UnitDate_Delai, "list_of_oStIntOb_UniteDate_Delai", "UniteDate_Delai", 0);
    t.relationOneToMany(& oParam::m_UnitDuree, "list_of_oStIntOb_UniteDuree", "UniteDuree", 0);
    t.relationOneToMany(& oParam::m_UnitValeur, "list_of_oStIntOb_UniteValeur", "UniteValeur", 0);
    //pRelation = t.relationOneToMany(& oParam::m_list_of_oCulture, "list_of_oCulture", "idUniteSem_Plant", 0);
    //pRelation = t.relationOneToMany(& oParam::m_list_of_oCulture_1, "list_of_oCulture_1", "idUniteProd", 0);
     
    qx::QxValidatorX<oParam> * pAllValidator = t.getAllValidator(); Q_UNUSED(pAllValidator);
    }
    }//namespace qx
     
    list_of_oStIntOb oParam::getlist_of_oStIntOb_StType(bool bLoadFromDatabase, const QString & sAppendRelations /* = QString() */, QSqlDatabase * pDatabase /* = NULL */, QSqlError * pDaoError /* = NULL */)
    {
       if (pDaoError) { (* pDaoError) = QSqlError(); }
       if (! bLoadFromDatabase) { return getlist_of_oStIntOb_StType(); }
       QString sRelation = "list_of_oStIntOb_StType";
       if (! sAppendRelations.isEmpty() && ! sAppendRelations.startsWith("->") && ! sAppendRelations.startsWith(">>")) { sRelation += "->" + sAppendRelations; }
       else if (! sAppendRelations.isEmpty()) { sRelation += sAppendRelations; }
       oParam tmp;
       tmp.m_IdObj = this->m_IdObj;
       QSqlError daoError = qx::dao::fetch_by_id_with_relation(sRelation, tmp, pDatabase);
       if (! daoError.isValid()) { this->m_StType = tmp.m_StType; }
       if (pDaoError) { (* pDaoError) = daoError; }
       return m_StType;
    }
     
    list_of_oStIntOb & oParam::list_of_oStIntOb_StType(bool bLoadFromDatabase, const QString & sAppendRelations /* = QString() */, QSqlDatabase * pDatabase /* = NULL */, QSqlError * pDaoError /* = NULL */)
    {
       if (pDaoError) { (* pDaoError) = QSqlError(); }
       if (! bLoadFromDatabase) { return list_of_oStIntOb_StType(); }
       QString sRelation = "list_of_oStIntOb_StType";
       if (! sAppendRelations.isEmpty() && ! sAppendRelations.startsWith("->") && ! sAppendRelations.startsWith(">>")) { sRelation += "->" + sAppendRelations; }
       else if (! sAppendRelations.isEmpty()) { sRelation += sAppendRelations; }
       oParam tmp;
       tmp.m_IdObj = this->m_IdObj;
       QSqlError daoError = qx::dao::fetch_by_id_with_relation(sRelation, tmp, pDatabase);
       if (! daoError.isValid()) { this->m_StType = tmp.m_StType; }
       if (pDaoError) { (* pDaoError) = daoError; }
       return m_StType;
    }
     
    list_of_oStIntOb oParam::getlist_of_oStIntOb_StClasse(bool bLoadFromDatabase, const QString & sAppendRelations /* = QString() */, QSqlDatabase * pDatabase /* = NULL */, QSqlError * pDaoError /* = NULL */)
    {
       if (pDaoError) { (* pDaoError) = QSqlError(); }
       if (! bLoadFromDatabase) { return getlist_of_oStIntOb_StClasse(); }
       QString sRelation = "list_of_oStIntOb_StClasse";
       if (! sAppendRelations.isEmpty() && ! sAppendRelations.startsWith("->") && ! sAppendRelations.startsWith(">>")) { sRelation += "->" + sAppendRelations; }
       else if (! sAppendRelations.isEmpty()) { sRelation += sAppendRelations; }
       oParam tmp;
       tmp.m_IdObj = this->m_IdObj;
       QSqlError daoError = qx::dao::fetch_by_id_with_relation(sRelation, tmp, pDatabase);
       if (! daoError.isValid()) { this->m_StClasse = tmp.m_StClasse; }
       if (pDaoError) { (* pDaoError) = daoError; }
       return m_StClasse;
    }
     
    list_of_oStIntOb & oParam::list_of_oStIntOb_StClasse(bool bLoadFromDatabase, const QString & sAppendRelations /* = QString() */, QSqlDatabase * pDatabase /* = NULL */, QSqlError * pDaoError /* = NULL */)
    {
       if (pDaoError) { (* pDaoError) = QSqlError(); }
       if (! bLoadFromDatabase) { return list_of_oStIntOb_StClasse(); }
       QString sRelation = "list_of_oStIntOb_StClasse";
       if (! sAppendRelations.isEmpty() && ! sAppendRelations.startsWith("->") && ! sAppendRelations.startsWith(">>")) { sRelation += "->" + sAppendRelations; }
       else if (! sAppendRelations.isEmpty()) { sRelation += sAppendRelations; }
       oParam tmp;
       tmp.m_IdObj = this->m_IdObj;
       QSqlError daoError = qx::dao::fetch_by_id_with_relation(sRelation, tmp, pDatabase);
       if (! daoError.isValid()) { this->m_StClasse = tmp.m_StClasse; }
       if (pDaoError) { (* pDaoError) = daoError; }
       return m_StClasse;
    }
     
    list_of_oStIntOb oParam::getlist_of_oStIntOb_UnitDate_Delai(bool bLoadFromDatabase, const QString & sAppendRelations /* = QString() */, QSqlDatabase * pDatabase /* = NULL */, QSqlError * pDaoError /* = NULL */)
    {
       if (pDaoError) { (* pDaoError) = QSqlError(); }
       if (! bLoadFromDatabase) { return getlist_of_oStIntOb_UnitDate_Delai(); }
       QString sRelation = "list_of_oStIntOb_UnitDate_Delai";
       if (! sAppendRelations.isEmpty() && ! sAppendRelations.startsWith("->") && ! sAppendRelations.startsWith(">>")) { sRelation += "->" + sAppendRelations; }
       else if (! sAppendRelations.isEmpty()) { sRelation += sAppendRelations; }
       oParam tmp;
       tmp.m_IdObj = this->m_IdObj;
       QSqlError daoError = qx::dao::fetch_by_id_with_relation(sRelation, tmp, pDatabase);
       if (! daoError.isValid()) { this->m_UnitDate_Delai = tmp.m_UnitDate_Delai; }
       if (pDaoError) { (* pDaoError) = daoError; }
       return m_UnitDate_Delai;
    }
     
    list_of_oStIntOb & oParam::list_of_oStIntOb_UnitDate_Delai(bool bLoadFromDatabase, const QString & sAppendRelations /* = QString() */, QSqlDatabase * pDatabase /* = NULL */, QSqlError * pDaoError /* = NULL */)
    {
       if (pDaoError) { (* pDaoError) = QSqlError(); }
       if (! bLoadFromDatabase) { return list_of_oStIntOb_UnitDate_Delai(); }
       QString sRelation = "list_of_oStIntOb_UnitDate_Delai";
       if (! sAppendRelations.isEmpty() && ! sAppendRelations.startsWith("->") && ! sAppendRelations.startsWith(">>")) { sRelation += "->" + sAppendRelations; }
       else if (! sAppendRelations.isEmpty()) { sRelation += sAppendRelations; }
       oParam tmp;
       tmp.m_IdObj = this->m_IdObj;
       QSqlError daoError = qx::dao::fetch_by_id_with_relation(sRelation, tmp, pDatabase);
       if (! daoError.isValid()) { this->m_UnitDate_Delai = tmp.m_UnitDate_Delai; }
       if (pDaoError) { (* pDaoError) = daoError; }
       return m_UnitDate_Delai;
    }
     
    list_of_oStIntOb oParam::getlist_of_oStIntOb_UnitDuree(bool bLoadFromDatabase, const QString & sAppendRelations /* = QString() */, QSqlDatabase * pDatabase /* = NULL */, QSqlError * pDaoError /* = NULL */)
    {
       if (pDaoError) { (* pDaoError) = QSqlError(); }
       if (! bLoadFromDatabase) { return getlist_of_oStIntOb_UnitDuree(); }
       QString sRelation = "list_of_oStIntOb_UnitDuree";
       if (! sAppendRelations.isEmpty() && ! sAppendRelations.startsWith("->") && ! sAppendRelations.startsWith(">>")) { sRelation += "->" + sAppendRelations; }
       else if (! sAppendRelations.isEmpty()) { sRelation += sAppendRelations; }
       oParam tmp;
       tmp.m_IdObj = this->m_IdObj;
       QSqlError daoError = qx::dao::fetch_by_id_with_relation(sRelation, tmp, pDatabase);
       if (! daoError.isValid()) { this->m_UnitDuree = tmp.m_UnitDuree; }
       if (pDaoError) { (* pDaoError) = daoError; }
       return m_UnitDuree;
    }
     
    list_of_oStIntOb & oParam::list_of_oStIntOb_UnitDuree(bool bLoadFromDatabase, const QString & sAppendRelations /* = QString() */, QSqlDatabase * pDatabase /* = NULL */, QSqlError * pDaoError /* = NULL */)
    {
       if (pDaoError) { (* pDaoError) = QSqlError(); }
       if (! bLoadFromDatabase) { return list_of_oStIntOb_UnitDuree(); }
       QString sRelation = "list_of_oStIntOb_UnitDuree";
       if (! sAppendRelations.isEmpty() && ! sAppendRelations.startsWith("->") && ! sAppendRelations.startsWith(">>")) { sRelation += "->" + sAppendRelations; }
       else if (! sAppendRelations.isEmpty()) { sRelation += sAppendRelations; }
       oParam tmp;
       tmp.m_IdObj = this->m_IdObj;
       QSqlError daoError = qx::dao::fetch_by_id_with_relation(sRelation, tmp, pDatabase);
       if (! daoError.isValid()) { this->m_UnitDuree = tmp.m_UnitDuree; }
       if (pDaoError) { (* pDaoError) = daoError; }
       return m_UnitDuree;
    }
     
    list_of_oStIntOb oParam::getlist_of_oStIntOb_UnitValeur(bool bLoadFromDatabase, const QString & sAppendRelations /* = QString() */, QSqlDatabase * pDatabase /* = NULL */, QSqlError * pDaoError /* = NULL */)
    {
       if (pDaoError) { (* pDaoError) = QSqlError(); }
       if (! bLoadFromDatabase) { return getlist_of_oStIntOb_UnitValeur(); }
       QString sRelation = "list_of_oStIntOb_UnitValeur";
       if (! sAppendRelations.isEmpty() && ! sAppendRelations.startsWith("->") && ! sAppendRelations.startsWith(">>")) { sRelation += "->" + sAppendRelations; }
       else if (! sAppendRelations.isEmpty()) { sRelation += sAppendRelations; }
       oParam tmp;
       tmp.m_IdObj = this->m_IdObj;
       QSqlError daoError = qx::dao::fetch_by_id_with_relation(sRelation, tmp, pDatabase);
       if (! daoError.isValid()) { this->m_UnitValeur = tmp.m_UnitValeur; }
       if (pDaoError) { (* pDaoError) = daoError; }
       return m_UnitValeur;
    }
     
    list_of_oStIntOb & oParam::list_of_oStIntOb_UnitValeur(bool bLoadFromDatabase, const QString & sAppendRelations /* = QString() */, QSqlDatabase * pDatabase /* = NULL */, QSqlError * pDaoError /* = NULL */)
    {
       if (pDaoError) { (* pDaoError) = QSqlError(); }
       if (! bLoadFromDatabase) { return list_of_oStIntOb_UnitValeur(); }
       QString sRelation = "list_of_oStIntOb_UnitValeur";
       if (! sAppendRelations.isEmpty() && ! sAppendRelations.startsWith("->") && ! sAppendRelations.startsWith(">>")) { sRelation += "->" + sAppendRelations; }
       else if (! sAppendRelations.isEmpty()) { sRelation += sAppendRelations; }
       oParam tmp;
       tmp.m_IdObj = this->m_IdObj;
       QSqlError daoError = qx::dao::fetch_by_id_with_relation(sRelation, tmp, pDatabase);
       if (! daoError.isValid()) { this->m_UnitValeur = tmp.m_UnitValeur; }
       if (pDaoError) { (* pDaoError) = daoError; }
       return m_UnitValeur;
    }
    Je me demande si mes "simplifications" ne sont pas des "complications pour arriver au bout"; si tout cela est possible ...
    Pour l'immédiat, j'aimerai bien savoir ce qui peut générer cette erreur dans QxDataMemberX,
    et qu'est-ce qu'il faut (au minimum) pour satisfaire "verifyColumns" ?

  2. #2
    Expert confirmé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    481
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 481
    Points : 4 238
    Points
    4 238
    Par défaut


    Dans la méthode qx::register_class<T>, tu as utilisé 2 fois t.id :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    t.id(& oParam::m_IdObj, "IdObj", 0); //pData->setPropertyBag("QX_EE_GENERATED_BY_SQLITE_IMPORT_PLUGIN", "1");
    t.id(& oParam::m_Attr, "Attr", 0);
    Je pense que c'est ça qui génère ton assert.

    Si tu as besoin de définir une clé primaire sur plusieurs colonnes, tu as la réponse ici : http://www.qxorm.com/qxorm_fr/faq.html#faq_101
    Le site de la bibliothèque QxOrm : bibliothèque C++ de gestion de données (Mapping Objet Relationnel ou ORM) basée sur les frameworks Qt et boost.
    QxEntityEditor : éditeur graphique pour la bibliothèque QxOrm (application multi-plateforme pour gérer graphiquement le modèle d'entités).

    Tutoriel : installer un environnement de développement avec QxOrm sous Windows.
    Tutoriel qxBlog : gestion de blogs en C++/Qt.
    Tutoriel qxClientServer : création d'un serveur d'applications en C++/Qt.

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Paysan
    Inscrit en
    Juin 2015
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2015
    Messages : 45
    Points : 39
    Points
    39
    Par défaut
    Citation Envoyé par QxOrm Voir le message
    Dans la méthode qx::register_class<T>, tu as utilisé 2 fois t.id :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    t.id(& oParam::m_IdObj, "IdObj", 0); //pData->setPropertyBag("QX_EE_GENERATED_BY_SQLITE_IMPORT_PLUGIN", "1");
    t.id(& oParam::m_Attr, "Attr", 0);
    Je pense que c'est ça qui génère ton assert.
    Bon sang; que je suis bête; je te dis pas le nombre de fois que j'ai relu ce bout de code ...

    Si tu as besoin de définir une clé primaire sur plusieurs colonnes, tu as la réponse ici : http://www.qxorm.com/qxorm_fr/faq.html#faq_101
    Non, non, merci ... du moins pas aujourd'hui (je l'ai vu au début en cherchant comment démarrer)

    Donc le assert dans QxDataMemberX a disparu (est résolu) et retour au assert de verifyColums (ligne 228)
    J'obtiens: (pour les lectures des oParam qui ne plantent pas mais qui ne se font pas, je vais chercher; par contre,
    je serais heureux de savoir ce qu'il faut (au minimum) pour satisfaire "verifyColumns" ? Déja, plein de merci!)
    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
     
    Démarrage de /home/cs/Bureau/AteliersLogiciels/CaChaBanPer/build-CaChaBanPer-Desktop_Qt_5_3_GCC_32bit-Debug/CaChaBanPer...
    [QxOrm] qx::QxSqlDatabase : create new database connection in thread '0xb1671740' with key '{74f21bd0-f94d-4300-88f1-4e5d7c556f58}'
    [QxOrm] execute sql query failed : SELECT oParam.IdObj AS oParam_IdObj_0, oParam.Attr AS oParam_Attr_0, oParam.TypeParam AS oParam_TypeParam_0, oParam.Libelle AS oParam_Libelle_0, oParam.Abrege AS oParam_Abrege_0 FROM oParam WHERE TypeParam=1
    Unable to fetch row
    No query
    err: ParamUnites
    [QxOrm] execute sql query failed : SELECT oParam.IdObj AS oParam_IdObj_0, oParam.Attr AS oParam_Attr_0, oParam.TypeParam AS oParam_TypeParam_0, oParam.Libelle AS oParam_Libelle_0, oParam.Abrege AS oParam_Abrege_0 FROM oParam WHERE TypeParam=2
    Unable to fetch row
    No query
    err: ParamClasses
    [QxOrm] execute sql query failed : SELECT oParam.IdObj AS oParam_IdObj_0, oParam.Attr AS oParam_Attr_0, oParam.TypeParam AS oParam_TypeParam_0, oParam.Libelle AS oParam_Libelle_0, oParam.Abrege AS oParam_Abrege_0 FROM oParam WHERE TypeParam=3
    Unable to fetch row
    No query
    err: ParamStIntOb
    [QxOrm] sql query (2 ms) : SELECT oCulture.IdObj AS oCulture_IdObj_0, oCulture.Abrege AS oCulture_Abrege_0, oCulture.dtDebut AS oCulture_dtDebut_0, oCulture.dtFinPrevue AS oCulture_dtFinPrevue_0, oCulture.NbUeK_Rang AS oCulture_NbUeK_Rang_0, oCulture.Sem_Plant_Rang AS oCulture_Sem_Plant_Rang_0, oCulture.idUniteSem_Plant AS oCulture_idUniteSem_Plant_0, oCulture.Prod_Rang AS oCulture_Prod_Rang_0, oCulture.idUniteProd AS oCulture_idUniteProd_0, oCulture.Libelle AS oCulture_Libelle_0 FROM oCulture WHERE KType=1
    [QxOrm] sql query (1 ms) : SELECT oCulture.IdObj AS oCulture_IdObj_0, oCulture.Attr AS oCulture_Attr_0, oCulture.KType AS oCulture_KType_0, oCulture.Abrege AS oCulture_Abrege_0, oCulture.dtDebut AS oCulture_dtDebut_0, oCulture.dtFinPrevue AS oCulture_dtFinPrevue_0, oCulture.NbUeK_Rang AS oCulture_NbUeK_Rang_0, oCulture.Sem_Plant_Rang AS oCulture_Sem_Plant_Rang_0, oCulture.idUniteSem_Plant AS oCulture_idUniteSem_Plant_0, oCulture.Prod_Rang AS oCulture_Prod_Rang_0, oCulture.idUniteProd AS oCulture_idUniteProd_0, oCulture.IdSchema AS oCulture_IdSchema_0, oCulture.IdBP AS oCulture_IdBP_0, oCulture.NoUeK AS oCulture_NoUeK_0, oCulture.NbRang AS oCulture_NbRang_0, oCulture.dtFinEffective AS oCulture_dtFinEffective_0, oCulture.Libelle AS oCulture_Libelle_0 FROM oCulture WHERE KType=2
    ASSERT: "false" in file ../../Libs/QxOrm/include/QxDao/QxSqlQueryBuilder.h, line 228
    Le programme s'est terminé subitement.
    /home/cs/Bureau/AteliersLogiciels/CaChaBanPer/build-CaChaBanPer-Desktop_Qt_5_3_GCC_32bit-Debug/CaChaBanPer a planté

  4. #4
    Expert confirmé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    481
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 481
    Points : 4 238
    Points
    4 238
    Par défaut
    verifyColumns est une méthode utilisée uniquement en mode debug (en mode release, l'implémentation de la méthode est vide, donc elle ne fait rien).

    Elle vérifie que les colonnes renvoyées par le SGBD ont bien un champ C++ associé.
    Si pas de champ C++ associé ==> assert !

    En regardant le code de cette fonction, il faudrait ajouter des traces pour avoir plus de détails sur ce qui ne va pas (quelle colonne est en erreur, pour telle classe C++) : j'ajouterai cette trace dans le prochaine version.

    Avec ton éditeur (Qt Creator ? Autre chose ?) : est-ce que tu arrives à récupérer cette assert ?
    Par exemple avec MSVC++ c'est très simple de remonter dans la pile d'appel pour obtenir les valeurs des différentes variables.

    D'après tes logs, l'assert semble se déclencher sur la table oCulture : peux-tu stp fournir le code source de cette classe ?

    je trouve que Qxee me génère beaucoup trop de types
    QxEntityEditor génère des typedef : mais au final ça reste le même type dans ton cas.
    Du coup, je ne comprends pas pourquoi tu essayes de modifier les classes générées par QxEntityEditor : est-ce que ton assert se produit également si tu gardes le code généré par QxEntityEditor ?
    Le site de la bibliothèque QxOrm : bibliothèque C++ de gestion de données (Mapping Objet Relationnel ou ORM) basée sur les frameworks Qt et boost.
    QxEntityEditor : éditeur graphique pour la bibliothèque QxOrm (application multi-plateforme pour gérer graphiquement le modèle d'entités).

    Tutoriel : installer un environnement de développement avec QxOrm sous Windows.
    Tutoriel qxBlog : gestion de blogs en C++/Qt.
    Tutoriel qxClientServer : création d'un serveur d'applications en C++/Qt.

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Paysan
    Inscrit en
    Juin 2015
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2015
    Messages : 45
    Points : 39
    Points
    39
    Par défaut
    Citation Envoyé par QxOrm Voir le message
    verifyColumns est une méthode utilisée uniquement en mode debug (en mode release, l'implémentation de la méthode est vide, donc elle ne fait rien).
    C'est ce que j'ai vu dans le code; je suis en mode debug et soucieux de comprendre.

    Elle vérifie que les colonnes renvoyées par le SGBD ont bien un champ C++ associé.
    Si pas de champ C++ associé ==> assert !
    Ok; ça parait simple; je sais à priori où chercher.

    En regardant le code de cette fonction, il faudrait ajouter des traces pour avoir plus de détails sur ce qui ne va pas (quelle colonne est en erreur, pour telle classe C++) : j'ajouterai cette trace dans le prochaine version.
    Je l'ai tracée sous Qt. Mais je n'ai pas pris assez de notes. Je refais cela et je reviens.
    De mémoire, il boucle dans la fonction où verifyColumns est appelé (ligne 228) par les if récurrents
    et je reconnais la liste de champs qu'il remplit ... puis cela finit mal ... par le assert ...
    Avec ton éditeur (Qt Creator ? Autre chose ?) : est-ce que tu arrives à récupérer cette assert ?
    Par exemple avec MSVC++ c'est très simple de remonter dans la pile d'appel pour obtenir les valeurs des différentes variables.
    Qt
    D'après tes logs, l'assert semble se déclencher sur la table oCulture : peux-tu stp fournir le code source de cette classe ?
    Non; c'est après la lecture des oCulture au début de la lecture des oStIntOb (je mettrais cette classe en code)
    QxEntityEditor génère des typedef : mais au final ça reste le même type dans ton cas.
    Du coup, je ne comprends pas pourquoi tu essayes de modifier les classes générées par QxEntityEditor : est-ce que ton assert se produit également si tu gardes le code généré par QxEntityEditor ?
    Oui. J'ai bien pensé que ce serait intéressant d'avoir ce test. C'est ce que j'avais commencé avec BaseAgri. Mais je m'y suis perdu.
    Il faudrait que je recommence un test sans model/view (avec l'export C++ de base)
    Je me pose une autre question qui pèse sur mes choix: Est-ce que je réussirai à faire des "Delegate" en dialogue avec les qx::IxModel
    que j'utilise ? Je dois mettre des combos pour choisir l'unité dans des colonnes des Qtableview.
    Je cerne tout cela en clair et je reviens ... demain probablement.

  6. #6
    Expert confirmé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    481
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 481
    Points : 4 238
    Points
    4 238
    Par défaut
    Fichier QxSqlQueryBuilder.h du package QxOrm, remplace la méthode verifyColumns() avec ce code (ce code fera partie de la prochaine version de QxOrm pour ajouter des infos avant déclenchement de l'assert), puis fait un rebuild sur ton projet :
    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
    #ifndef _QX_MODE_RELEASE
       inline bool verifyColumns(const QStringList & columns) const
       {
          if (! m_pDataMemberX) { return false; }
          for (int i = 0; i < columns.count(); i++)
          {
             if (! m_pDataMemberX->exist_WithDaoStrategy(columns.at(i)))
             {
                QString sColumn = columns.at(i);
                qDebug("[QxOrm] Error in qx::QxSqlQueryBuilder<T>::verifyColumns() : column '%s' not found in table '%s'", qPrintable(sColumn), qPrintable(m_sTableName));
                return false;
             }
          }
          return true;
       }
    #else // _QX_MODE_RELEASE
       inline bool verifyColumns(const QStringList & columns) const
       { Q_UNUSED(columns); return true; }
    #endif // _QX_MODE_RELEASE
    Je pense que le soucis est peut-être quand tu définis les colonnes de ton modèle avec la méthode : qx::IxModel::setListOfColumns().

    Il faudrait que je recommence un test sans model/view
    Peut-être oui, avec model/view, tu t'attaques directement à une partie pas simple à appréhender.
    Tu pourrais par exemple dans un 1er temps utiliser les méthodes du namespace qx::dao pour récupérer les données, puis pour vérifier tes données, utiliser la méthode qx::dump() qui affiche un flux XML de ton instance.

    Je me pose une autre question qui pèse sur mes choix: Est-ce que je réussirai à faire des "Delegate" en dialogue avec les qx::IxModel que j'utilise ?
    A priori oui, tes modèles basés sur qx::IxModel sont des QAbstractItemModel : donc on est bien sur du standard Qt.
    Concernant les relations, le code généré par QxEntityEditor et le module QxModelView sont basés sur le notion de modèles imbriqués : en gros tu as un modèle parent, puis une liste de modèles enfants.
    Tu as un excellent tutoriel disponible ici pour expliquer cette notion de "nested models" : http://christophe-dumez.developpez.c...les-imbriques/
    Comme tu pourras le voir dans ce tuto, ça permet une intégration simple avec QML, mais c'est utilisable aussi avec les classiques QtWidgets.
    Le site de la bibliothèque QxOrm : bibliothèque C++ de gestion de données (Mapping Objet Relationnel ou ORM) basée sur les frameworks Qt et boost.
    QxEntityEditor : éditeur graphique pour la bibliothèque QxOrm (application multi-plateforme pour gérer graphiquement le modèle d'entités).

    Tutoriel : installer un environnement de développement avec QxOrm sous Windows.
    Tutoriel qxBlog : gestion de blogs en C++/Qt.
    Tutoriel qxClientServer : création d'un serveur d'applications en C++/Qt.

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Paysan
    Inscrit en
    Juin 2015
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2015
    Messages : 45
    Points : 39
    Points
    39
    Par défaut
    Bonjour,

    Bon; on y voit plus clair sur les deux volets:
    1) mon projet au nom barbare CaChaBanPer (Carnet de champ des bandes permanentes) où je rajoute les relations "à la main"
    2) le test BaseAgri qui utilise directement ce que génère QxEE

    Je reprends là ou nous en étions lors de mon précédent message avec ce que je devais fournir;
    je prendrais ensuite en compte ton nouveau message.
    (de façon générale, il est clair que, ne connaissant pas la bibliothèque, je vais imaginer des
    raisons compliquées là ou les choses sont simples; je vais essayer de m'améliorer ...)

    1) mon projet CaChaBanPer où je rajoute les relations "à la main"
    * la trace: le contexte est dans QxSqlQueryBuilder, dans fetchall, à l'appel de verifyColumns (ligne 228)
    et dans le verifyColumns appelé
    Contrairement à ce que j'approchais de mémoire précédemment "il tourne sur le liste et cela se finit mal"
    - il tourne pour la table oCulture (où je n'ai pas encore mis les relations) et cela se fini bien
    - il démarre pour la table oStIntOb et dès l'indice 0 (i=0 dans le for)
    Avec m_sTablename "oStIntOb"
    columns <8 éléments> idType, idClasse, Abrege, dtDate_Delai, idUniteDate_Delai, dtDuree, idUniteDuree, Libelle
    dans { if (! m_pDataMemberX->exist_WithDaoStrategy(columns.at(i))) { return false; } }
    on a le return false (et derrière le assert)
    Donc c'est sur idType qui fait l'objet d'une relation à oParam qu'est le problème
    (alors qu'on vient d'assister à la lecture sans problème de 4 "models" sur oParam)
    Si je supprime dans "oParam" la relation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    //t.relationOneToMany(& oParam::m_UnitValeur, "list_of_oStIntOb_UniteValeur", "UniteValeur", 0);
    anticipation facheuse non présente dans la base de test, je n'ai plus le problème.
    ("Assert de verifyColumns" résolu!)

    Est-il nécessaire de poser toutes les relations même si on ne les utilise pas ?
    J'entends par là si on pose la relation "t.relationManyToOne(& oStIntOb:..." vers oParam, (qu'on utilise),
    est-on obligé de poser la relation "t.relationOneToMany(& oParam:..." vers oStIntOb ?

    J'en suis donc (sur cette piste) à faire fonctionner les "Delegate" pour mettre des combobox sur les relations
    dans qx::IxModel.
    Je viens de trouver un exposé très voisin de ce que je veux faire "QSqlRelationalTableModel Class"
    http://doc.qt.io/qt-4.8/qsqlrelationaltablemodel.html

    Ici comme promis la classe oStIntOb (à noter dans le .cpp que, contrairement à ce qui est exposé dans tous
    les tutoriaux sur l'ordre "id-datas-relations" dans la template, j'intercale les relations et les datas
    et cela ordonne les colonnes dans le model et dans la view ...)

    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
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    #ifndef OSTINTOB_H
    #define OSTINTOB_H
     
    class oParam;
    //class oCulture;
     
    class oStIntOb
    {
        QX_REGISTER_FRIEND_CLASS(oStIntOb);
       typedef boost::shared_ptr<oParam> oparam_ptr;
     
    protected:
        long m_IdObj; // dans TGENCCBP
        long m_Attr;  // dans TGENCCBP
        oparam_ptr m_StType;
        oparam_ptr m_StClasse;
        //oCulture_ptr m_Culture;
        long m_Culture;          // IdObj provisoire
        QString m_Abrege;
        QString m_Libelle;
        long m_dtDate_Delai;
        oparam_ptr m_UnitDate_Delai;
        long m_Duree;
        oparam_ptr m_UnitDuree;
        //double m_Valeur;
        //oparam_ptr m_UnitValeur;
     
    public:
        oStIntOb():m_IdObj(0), m_Attr(0), m_dtDate_Delai(0), m_Duree(0)/*, m_Valeur(0.0)*/{;}
        oStIntOb(const long & id):m_IdObj(id), m_Attr(0), m_dtDate_Delai(0), m_Duree(0)/*, m_Valeur(0.0)*/ {;}
        oStIntOb(oparam_ptr aType, oparam_ptr aClasse, /*oCulture_ptr*/long aCulture, QString aLibelle, QString aAbrege,
                 long aDelai, oparam_ptr aUntDelai, long aDuree, oparam_ptr aUntDuree):m_IdObj(0), m_Attr(0)//, m_Valeur(0.0)
        {m_StType=aType; m_StClasse=aClasse; m_Culture=aCulture; m_Libelle=aLibelle; m_Abrege=aAbrege;
         m_dtDate_Delai=aDelai; m_UnitDate_Delai=aUntDelai; m_Duree=aDuree; m_UnitDuree=aUntDuree; /* m_UnitValeur=nullptr;*/}
        virtual ~oStIntOb(){;}
     
        //oCulture_ptr getCulture() const { return m_Culture; }
        oparam_ptr getStType() const { return m_StType; }
        oparam_ptr getStClasse() const { return m_StClasse; }
        oparam_ptr getUnitDuree() const { return m_UnitDuree; }
        oparam_ptr getUnitDate_Delai() const { return m_UnitDate_Delai; }
        //oparam_ptr getUnitValeur() const { return m_UnitValeur; }
     
        //oCulture_ptr getCulture(bool bLoadFromDatabase, const QString & sAppendRelations = QString(), QSqlDatabase * pDatabase = NULL, QSqlError * pDaoError = NULL);
        oparam_ptr getStType(bool bLoadFromDatabase, const QString & sAppendRelations = QString(), QSqlDatabase * pDatabase = NULL, QSqlError * pDaoError = NULL);
        oparam_ptr getStClasse(bool bLoadFromDatabase, const QString & sAppendRelations = QString(), QSqlDatabase * pDatabase = NULL, QSqlError * pDaoError = NULL);
        oparam_ptr getUnitDuree(bool bLoadFromDatabase, const QString & sAppendRelations = QString(), QSqlDatabase * pDatabase = NULL, QSqlError * pDaoError = NULL);
        oparam_ptr getUnitDate_Delai(bool bLoadFromDatabase, const QString & sAppendRelations = QString(), QSqlDatabase * pDatabase = NULL, QSqlError * pDaoError = NULL);
        //oparam_ptr getUnitValeur(bool bLoadFromDatabase, const QString & sAppendRelations = QString(), QSqlDatabase * pDatabase = NULL, QSqlError * pDaoError = NULL);
     
        static QString relation_StType() { return "StType"; }
        static QString relation_StClasse() { return "StClasse"; }
        static QString relation_Culture() { return "Culture"; }
        static QString relation_UnitDuree() { return "UnitDuree"; }
        static QString relation_UnitDate_Delai() { return "UnitDate_Delai"; }
        static QString relation_UnitValeur() { return "UnitValeur"; }
        static QString column_IdObj() { return "IdObj"; }
        static QString column_Attr() { return "Attr"; }
        static QString column_Libelle() { return "Libelle"; }
        static QString column_Abrege() { return "Abrege"; }
        static QString column_dtDate_Delai() { return "dtDate_Delai"; }
        static QString column_dtDuree() { return "Duree"; }
        static QString column_Valeur() { return "Valeur"; }
        static QString table_name() { return "oStIntOb"; }
     
    /*
        long getIdObj() const;
        long getAttr() const;
        QString getLibelle() const;
        QString getAbrege() const;
        long getdtDate_Delai() const;
        long getdtDuree() const;
        type_IdType getIdType() const;
        type_idClasse getidClasse() const;
        type_idCulture getidCulture() const;
        type_idUniteDuree getidUniteDuree() const;
        type_idUniteDate_Delai getidUniteDate_Delai() const;
     
        void setIdObj(const long & val);
        void setAttr(const long & val);
        void setLibelle(const QString & val);
        void setAbrege(const QString & val);
        void setdtDate_Delai(const long & val);
        void setdtDuree(const long & val);
        void setIdType(const type_IdType & val);
        void setidClasse(const type_idClasse & val);
        void setidCulture(const type_idCulture & val);
        void setidUniteDuree(const type_idUniteDuree & val);
        void setidUniteDate_Delai(const type_idUniteDate_Delai & val);
    */
    };
     
    //typedef std::vector<oStIntOb_ptr> oStIntOb_lst;
    typedef boost::shared_ptr<oStIntOb> oStIntOb_ptr;
    typedef qx::QxCollection<long, oStIntOb_ptr> list_of_oStIntOb;
    typedef boost::shared_ptr<list_of_oStIntOb> list_of_oStIntOb_ptr;
     
    QX_REGISTER_HPP_MY_TEST_EXE(oStIntOb,qx::trait::no_base_class_defined,1);
    //QX_REGISTER_COMPLEX_CLASS_NAME_HPP_BASEAGRI(oStIntOb, qx::trait::no_base_class_defined, 1, oStIntOb);
     
    #include "oparam.h"
    //#include "oculture.h"
     
    //#include "oParam.gen.h"
    //#include "oCulture.gen.h"
    //#include "../custom/include/oStIntOb.h"
     
    #endif // OSTINTOB_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
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    #include "precompiled.h"   // Precompiled-header with '#include <QxOrm.h>' and '#include "export.h"'
    #include "ostintob.h"
     
    //#include "../include/oStIntOb.gen.h"
    //#include "../include/oParam.gen.h"
    //#include "../include/oCulture.gen.h"
     
    #include <QxMemLeak.h>     // Automatic memory leak detection
     
    QX_REGISTER_CPP_MY_TEST_EXE(oStIntOb)   // This macro is necessary to register any class in QxOrm context
    //QX_REGISTER_COMPLEX_CLASS_NAME_CPP_BASEAGRI(oStIntOb, oStIntOb);
     
    namespace qx
    {
    template <> void register_class(QxClass<oStIntOb> & t)
    {
    t.setName("oStIntOb");
     
    t.id(& oStIntOb::m_IdObj, "IdObj", 0);             // Register 'oStIntOb::m_IdObj' <=> primary key IdObj
    t.data(& oStIntOb::m_Attr, "Attr", 0, true, true);
    t.data(& oStIntOb::m_Culture, "idCulture", 0, true, true);
    t.relationManyToOne(/*oParam*/   & oStIntOb::m_StType, "idType", 0);              // IdObj de oParam:StIntOb
    t.relationManyToOne(/*oParam*/   & oStIntOb::m_StClasse, "idClasse", 0);             // IdObj de oParam:Classes
    t.data(& oStIntOb::m_Abrege, "Abrege", 0, true, true);
    t.data(& oStIntOb::m_dtDate_Delai, "dtDate_Delai", 0, true, true);
    t.relationManyToOne(/*oParam*/   & oStIntOb::m_UnitDate_Delai, "idUniteDate_Delai", 0); // IdObj de oParam:Unites
    t.data(& oStIntOb::m_Duree, "dtDuree", 0, true, true);
    t.relationManyToOne(/*oParam*/   & oStIntOb::m_UnitDuree, "idUniteDuree", 0);           // IdObj de oParam:Unites
    //t.data(& oStIntOb::m_Valeur, "Valeur", 0, true, true);
    t.data(& oStIntOb::m_Libelle, "Libelle", 0, true, true);
     
    //template <typename V, typename U> IxSqlRelation * relationManyToOne(V U::* pData, const QString & sKey, long lVersion);
     
    //t.relationManyToOne(/*oCulture*/ & oStIntOb::m_Culture, "idCulture", 0);               // IdObj de oCulture
    //t.relationManyToOne(/*oParam*/   & oStIntOb::m_UnitValeur, "UnitValeur", 0);         // IdObj de oParam:Unites
    }
    }//namespace qx
     
    //-----------------------------------------------------------------------------------------  oStIntOb  ---
    // Pour l'objet oStIntOb
    //--------------------------------------------------------------------------------------------------------
    /*
    oCulture_ptr oStIntOb::getCulture(bool bLoadFromDatabase, const QString & sAppendRelations /* = QString() * /, QSqlDatabase * pDatabase /* = NULL * /, QSqlError * pDaoError /* = NULL * /)
    {
       if (pDaoError) { (* pDaoError) = QSqlError(); }
       if (! bLoadFromDatabase) { return getCulture(); }
       QString sRelation = "Culture";
       if (! sAppendRelations.isEmpty() && ! sAppendRelations.startsWith("->") && ! sAppendRelations.startsWith(">>")) { sRelation += "->" + sAppendRelations; }
       else if (! sAppendRelations.isEmpty()) { sRelation += sAppendRelations; }
       oStIntOb tmp;
       tmp.m_IdObj = this->m_IdObj;
       QSqlError daoError = qx::dao::fetch_by_id_with_relation(sRelation, tmp, pDatabase);
       if (! daoError.isValid()) { this->m_Culture = tmp.m_Culture; }
       if (pDaoError) { (* pDaoError) = daoError; }
       return m_Culture;
    }
    */
    oparam_ptr oStIntOb::getStType(bool bLoadFromDatabase, const QString & sAppendRelations /* = QString() */, QSqlDatabase * pDatabase /* = NULL */, QSqlError * pDaoError /* = NULL */)
    {
       if (pDaoError) { (* pDaoError) = QSqlError(); }
       if (! bLoadFromDatabase) { return getStType(); }
       QString sRelation = "StType";
       if (! sAppendRelations.isEmpty() && ! sAppendRelations.startsWith("->") && ! sAppendRelations.startsWith(">>")) { sRelation += "->" + sAppendRelations; }
       else if (! sAppendRelations.isEmpty()) { sRelation += sAppendRelations; }
       oStIntOb tmp;
       tmp.m_IdObj = this->m_IdObj;
       QSqlError daoError = qx::dao::fetch_by_id_with_relation(sRelation, tmp, pDatabase);
       if (! daoError.isValid()) { this->m_StType = tmp.m_StType; }
       if (pDaoError) { (* pDaoError) = daoError; }
       return m_StType;
    }
     
    oparam_ptr oStIntOb::getStClasse(bool bLoadFromDatabase, const QString & sAppendRelations /* = QString() */, QSqlDatabase * pDatabase /* = NULL */, QSqlError * pDaoError /* = NULL */)
    {
       if (pDaoError) { (* pDaoError) = QSqlError(); }
       if (! bLoadFromDatabase) { return getStClasse(); }
       QString sRelation = "StClasse";
       if (! sAppendRelations.isEmpty() && ! sAppendRelations.startsWith("->") && ! sAppendRelations.startsWith(">>")) { sRelation += "->" + sAppendRelations; }
       else if (! sAppendRelations.isEmpty()) { sRelation += sAppendRelations; }
       oStIntOb tmp;
       tmp.m_IdObj = this->m_IdObj;
       QSqlError daoError = qx::dao::fetch_by_id_with_relation(sRelation, tmp, pDatabase);
       if (! daoError.isValid()) { this->m_StClasse = tmp.m_StClasse; }
       if (pDaoError) { (* pDaoError) = daoError; }
       return m_StClasse;
    }
     
    oparam_ptr oStIntOb::getUnitDuree(bool bLoadFromDatabase, const QString & sAppendRelations /* = QString() */, QSqlDatabase * pDatabase /* = NULL */, QSqlError * pDaoError /* = NULL */)
    {
       if (pDaoError) { (* pDaoError) = QSqlError(); }
       if (! bLoadFromDatabase) { return getUnitDuree(); }
       QString sRelation = "UnitDuree";
       if (! sAppendRelations.isEmpty() && ! sAppendRelations.startsWith("->") && ! sAppendRelations.startsWith(">>")) { sRelation += "->" + sAppendRelations; }
       else if (! sAppendRelations.isEmpty()) { sRelation += sAppendRelations; }
       oStIntOb tmp;
       tmp.m_IdObj = this->m_IdObj;
       QSqlError daoError = qx::dao::fetch_by_id_with_relation(sRelation, tmp, pDatabase);
       if (! daoError.isValid()) { this->m_UnitDuree = tmp.m_UnitDuree; }
       if (pDaoError) { (* pDaoError) = daoError; }
       return m_UnitDuree;
    }
     
    oparam_ptr oStIntOb::getUnitDate_Delai(bool bLoadFromDatabase, const QString & sAppendRelations /* = QString() */, QSqlDatabase * pDatabase /* = NULL */, QSqlError * pDaoError /* = NULL */)
    {
       if (pDaoError) { (* pDaoError) = QSqlError(); }
       if (! bLoadFromDatabase) { return getUnitDate_Delai(); }
       QString sRelation = "UnitDate_Delai";
       if (! sAppendRelations.isEmpty() && ! sAppendRelations.startsWith("->") && ! sAppendRelations.startsWith(">>")) { sRelation += "->" + sAppendRelations; }
       else if (! sAppendRelations.isEmpty()) { sRelation += sAppendRelations; }
       oStIntOb tmp;
       tmp.m_IdObj = this->m_IdObj;
       QSqlError daoError = qx::dao::fetch_by_id_with_relation(sRelation, tmp, pDatabase);
       if (! daoError.isValid()) { this->m_UnitDate_Delai = tmp.m_UnitDate_Delai; }
       if (pDaoError) { (* pDaoError) = daoError; }
       return m_UnitDate_Delai;
    }
     
    /*
    oparam_ptr oStIntOb::getUnitValeur(bool bLoadFromDatabase, const QString & sAppendRelations /* = QString() * /, QSqlDatabase * pDatabase /* = NULL * /, QSqlError * pDaoError /* = NULL * /)
    {
       if (pDaoError) { (* pDaoError) = QSqlError(); }
       if (! bLoadFromDatabase) { return getUnitValeur(); }
       QString sRelation = "UnitValeur";
       if (! sAppendRelations.isEmpty() && ! sAppendRelations.startsWith("->") && ! sAppendRelations.startsWith(">>")) { sRelation += "->" + sAppendRelations; }
       else if (! sAppendRelations.isEmpty()) { sRelation += sAppendRelations; }
       oStIntOb tmp;
       tmp.m_IdObj = this->m_IdObj;
       QSqlError daoError = qx::dao::fetch_by_id_with_relation(sRelation, tmp, pDatabase);
       if (! daoError.isValid()) { this->m_UnitValeur = tmp.m_UnitValeur; }
       if (pDaoError) { (* pDaoError) = daoError; }
       return m_UnitValeur;
    }
    */

    2) le test BaseAgri qui utilise directement ce que génère QxEE

    Je viens de réaliser que mon test est incomplet ... je reviendrai sur ce point ...

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    Paysan
    Inscrit en
    Juin 2015
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2015
    Messages : 45
    Points : 39
    Points
    39
    Par défaut
    Précédent:
    2) le test BaseAgri qui utilise directement ce que génère QxEE
    Je viens de réaliser que mon test est incomplet ... je reviendrai sur ce point ...
    J'y reviens donc:
    Pour la partie export C++ (sans model) (répertoire QxBase)
    J'ai dans le traitement par qmake:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    16:21:50: Exécution des étapes pour le projet BaseAgri.gen...
    16:21:50: Débute : "/home/cs/Qt/5.3/gcc/bin/qmake" /home/cs/Bureau/AteliersLogiciels/BaseAgri/QxBase/BaseAgri.gen.pro -r -spec linux-g++ CONFIG+=debug
    Cannot read /home/cs/Bureau/AteliersLogiciels/Libs/QxOrm/lib/QxOrm.pri: No such file or directory
    16:21:50: Le processus "/home/cs/Qt/5.3/gcc/bin/qmake" s'est terminé normalement.
    16:21:50: Temps écoulé : 00:00.
    Ce qui est juste, QxOrm.pri est dans Libs/QxOrm/ et non Libs/QxOrm/lib
    Mais cela ne parait pas gênant, j'obtiens une compilation et la génération de la librairie libBaseAgrid.so.1.0.0 dans ./bin

    Pour la partie export C++ model/view (répertoire QxModel)
    J'ai pareil dans le traitement par qmake (c'est toujours normal)(mais est-ce ici sans incidence ??)

    Par contre, je ne parviens pas à compiler:
    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
     
    g++ -c -pipe -g -Wall -W -D_REENTRANT -fPIC -D_BUILDING_MODEL_VIEW_BASEAGRI -DQT_GUI_LIB -DQT_CORE_LIB -I/home/cs/Qt/5.3/gcc/mkspecs/linux-g++ -I../../QxModel -I/home/cs/Bureau/AteliersLogiciels/Libs/QxOrm/lib/include -I/home/cs/Qt/5.3/gcc/include -I/home/cs/Qt/5.3/gcc/include/QtGui -I/home/cs/Qt/5.3/gcc/include/QtCore -I. -I. -o moc_oBande.model_view.gen.o moc_oBande.model_view.gen.cpp
    In file included from ../include/oBande.model_view.gen.h:14:0,
                     from moc_oBande.model_view.gen.cpp:9:
    ../include/../../QxBase/include/oBande.gen.h:10:23: error: variable 'BASEAGRI_EXPORT oBande' has initializer but incomplete type
     class BASEAGRI_EXPORT oBande
                           ^
    ../include/../../QxBase/include/oBande.gen.h:11:1: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
     {
     ^
    Makefile:661: recipe for target 'moc_oBande.model_view.gen.o' failed
    ../include/../../QxBase/include/oBande.gen.h:13:35: error: 'QX_REGISTER_FRIEND_CLASS' was not declared in this scope
        QX_REGISTER_FRIEND_CLASS(oBande)
                                       ^
    ../include/../../QxBase/include/oBande.gen.h:15:1: error: expected '}' before 'public'
     public:
     ^
    Je me suis pourtant permis de rajouter dans "BaseAgri.model_view.gen.pro"
    CONFIG += C++11 (bien que ": please, do NOT modify this file !")
    mais cela ne change rien.
    (je pense qu'après la première erreur, gros "malentendu" et il "débloque" sur n'importe quoi.)
    Mais je ne parviens pas à corriger.
    Je comprends que ce n'est pas un point lié à QxOrm, mais un manque de culture Qt de ma part,
    mais si tu me débloquais, je pourrais avancer sur QxOrm.
    J'ai bien dans le BaseAgri.model_view.gen.pro
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    LIBS += -L"$$PWD/../QxBase/bin"
    correctement généré par QxEE et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CONFIG(debug, debug|release) {
    LIBS += -l"QxOrmd"
    LIBS += -l"BaseAgrid"
    } else {
    LIBS += -l"QxOrm"
    LIBS += -l"BaseAgri"
    } # CONFIG(debug, debug|release)
    qui me parait conforme à libBaseAgrid.so.1.0.0 dans ./bin (avec le lib rajouté systématiquement)

    Je teste ta modification de code sur verifyColumns ...

  9. #9
    Expert confirmé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    481
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 481
    Points : 4 238
    Points
    4 238
    Par défaut
    C'est assez difficile à suivre car tu mélanges plusieurs problématiques dans le même sujet (essaye de séparer tes problématiques dans plusieurs sujets la prochaine fois ) :
    • définition des relations et assert sur la méthode verifyColumns() ;
    • notion de "Delegate" pour mettre des combobox sur les relations dans qx::IxModel ;
    • problème de compilation de ton projet BaseAgri qui semble être un export direct depuis QxEntityEditor.


    Si je supprime dans "oParam" la relation .... je n'ai plus le problème ("Assert de verifyColumns" résolu!) .... Est-il nécessaire de poser toutes les relations même si on ne les utilise pas ? J'entends par là si on pose la relation "t.relationManyToOne(& oStIntOb:..." vers oParam, (qu'on utilise), est-on obligé de poser la relation "t.relationOneToMany(& oParam:..." vers oStIntOb ?
    Excellente question !
    C'est important de comprendre les impacts d'une relation sur les classes C++ et les tables de la base de données.
    Je te conseille de lire : un exemple de relation 1-n du tutoriel qxBlog.
    Ainsi que : un exemple de relation n-1.

    Une relation n-1 peut être définie toute seule (pas nécessaire de définir la relation inverse 1-n) : en effet, une relation n-1 ajoute une colonne au niveau de ta table (une clé étrangère vers une autre table).
    Tout se passe au niveau de la même table, c'est pourquoi tu n'as pas besoin de la relation inverse.

    Une relation 1-n ne peut pas être définie toute seule : il faut forcément définir la relation inverse n-1.
    En effet, quand tu écris : t.relationOneToMany(& oParam::m_UnitValeur, "list_of_oStIntOb_UniteValeur", "UniteValeur", 0);
    Tu t'attends à ce qu'il y a une propriété/colonne nommée "UniteValeur" dans la classe/table associée à cette relation.
    Si "UniteValeur" n'est pas définie dans la classe associée ==> oui il y a un problème : ça pourrait expliquer effectivement ton assert.

    Remarque : QxEntityEditor définit par défaut "les 2 côtés" d'une relation.

    Cannot read /home/cs/Bureau/AteliersLogiciels/Libs/QxOrm/lib/QxOrm.pri: No such file or directory
    Ce n'est pas normal : tu ne dois pas avoir cette erreur.
    Normalement tu dois définir le dossier où se trouve QxOrm (et donc QxOrm.pri qui est à la racine du package QxOrm) directement dans QxEntityEditor : menu "Tools >> Global Settings", paramètre "QxOrm library path".
    Donc il faudrait que tu corriges ça, ou bien que tu modifies à la main les fichiers générés pour indiquer le bon emplacement.

    cela ne parait pas gênant, j'obtiens une compilation et la génération de la librairie libBaseAgrid.so.1.0.0 dans ./bin
    Si c'est gênant, à mon avis tu as une ancienne version de ton fichier car tu n'as pas fait un clean ou quelque chose comme ça.

    je ne parviens pas à compiler .... error: variable 'BASEAGRI_EXPORT oBande' has initializer but incomplete type
    Je pense que c'est un peu la même problématique que pour QxOrm.pri : le dossier ./include/ de QxOrm ne doit pas être bien définie dans les fichiers .pro générés.
    Du coup, ton precompiled header ne doit pas inclure correctement le fichier QxOrm.h ==> les macros de QxOrm ne sont alors pas définies.

    CONFIG += C++11
    Tu veux faire du C++11 ?
    Si oui, alors il y a une section dédiée à ça dans le fichier QxOrm.pri (et un exemple avec le projet ./test/qxBlogCpp11/) :
    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
    #######################################
    # C++11 smart pointers and containers #
    #######################################
     
    # By default, QxOrm library supports smart pointers and containers of Qt library and boost library : QHash, QList, QSharedPointer, boost::shared_ptr, boost::unordered_map, etc...
    # QxOrm library supports also by default containers of previous C++03 standard library : std::vector, std::list, std::map, std::set
    # If you want to enable smart pointers and containers of the new C++11 standard library, you can define the compilation options _QX_CPP_11_SMART_PTR, _QX_CPP_11_CONTAINER and _QX_CPP_11_TUPLE :
    # - With _QX_CPP_11_SMART_PTR : std::unique_ptr, std::shared_ptr, std::weak_ptr
    # - With _QX_CPP_11_CONTAINER : std::unordered_map, std::unordered_set, std::unordered_multimap, std::unordered_multiset
    # - With _QX_CPP_11_TUPLE : std::tuple
     
    # CONFIG += c++11
    # DEFINES += _QX_CPP_11_SMART_PTR
    # DEFINES += _QX_CPP_11_CONTAINER
    # DEFINES += _QX_CPP_11_TUPLE
    Le site de la bibliothèque QxOrm : bibliothèque C++ de gestion de données (Mapping Objet Relationnel ou ORM) basée sur les frameworks Qt et boost.
    QxEntityEditor : éditeur graphique pour la bibliothèque QxOrm (application multi-plateforme pour gérer graphiquement le modèle d'entités).

    Tutoriel : installer un environnement de développement avec QxOrm sous Windows.
    Tutoriel qxBlog : gestion de blogs en C++/Qt.
    Tutoriel qxClientServer : création d'un serveur d'applications en C++/Qt.

  10. #10
    Nouveau membre du Club
    Homme Profil pro
    Paysan
    Inscrit en
    Juin 2015
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2015
    Messages : 45
    Points : 39
    Points
    39
    Par défaut
    Citation Envoyé par QxOrm Voir le message
    C'est assez difficile à suivre car tu mélanges plusieurs problématiques dans le même sujet (essaye de séparer tes problématiques dans plusieurs sujets la prochaine fois ) :
    • définition des relations et assert sur la méthode verifyColumns() ;
    • notion de "Delegate" pour mettre des combobox sur les relations dans qx::IxModel ;
    • problème de compilation de ton projet BaseAgri qui semble être un export direct depuis QxEntityEditor.
    Oui; bien vu; je vais fermer la question sur les relations "à la main" puisque "ça marche" et que tes explications ci-dessous
    sur n-1/1-n me confirme dans la souplesse de la bibliothèque par rapport à ce qui m'est nécessaire.
    Je vais ouvrir une autre question sur "compilation des générations de QxEE" si je ne m'en sort pas.
    Pour les Delegate, ce n'était qu'une explication du contexte, on verra après ...

    J'ai dit que je testerai ton code sur "assert sur la méthode verifyColumns()", qui me parait bien plus sympathique,
    on signale et on utilise pas, sans "planter"; en fait je n'ai pas pu ... parce que je n'ai pas pu reproduire le défaut!
    Tous cela me parait plus brouillon (de mon côté) que ce dont j'ai l'habitude ...

    Remarque : QxEntityEditor définit par défaut "les 2 côtés" d'une relation.
    C'est bien ce que j'ai vu; mais "à la main", la bibliothèque n'oblige pas à suivre QxEE (donc pas de contrainte; c'était ma question)

    Ce n'est pas normal : tu ne dois pas avoir cette erreur.
    ...
    Donc il faudrait que tu corriges ça, ou bien que tu modifies à la main les fichiers générés pour indiquer le bon emplacement.
    ...
    Ok; j'ai raté le "Global setting", ou indiqué Libs/QxOrm/lib à la place de Libs/QxOrm ... ou pas assez de "clean ... je vais corriger.

    Tu veux faire du C++11 ?
    Pas spécialement dans ce contexte, c'est le message du compilateur qui m'y poussait; mais sur ce coup il "débloque" ...
    Par contre, mon applications avec "relations à la main" compile en C++11 (de tête je ne sais plus pourquoi);
    donc tes explications qui suivent (sur le QxOrm.pri) sont importantes dans ce contexte et je vais étudier cela.
    (encore merci! je le dis plus, cela va de soi)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. VIDEO sans image mais avec son
    Par funckfot dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 07/06/2007, 11h38
  2. Peut-on importer des relations (sans les tables)
    Par clemasson dans le forum Access
    Réponses: 2
    Dernier message: 10/12/2006, 15h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo