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 :

Problème lors de l'utilisation du repository


Sujet :

QxOrm

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    151
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 151
    Points : 49
    Points
    49
    Par défaut Problème lors de l'utilisation du repository
    Hello,

    Je ne parviens pas à utiliser la notion de repository, ci-joint, un exemple vraiment minimal reproduisant le bug probable (ou bien la mauvaise utilisation).

    Le problème survient à l'appel d'un _fetchAll tel que:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        qx::IxRepository * pRepository = qx::QxRepositoryX::get( "issue::db::Person" );
        if ( pRepository )
        {
            qx::QxCollection<long, issue::db::Person::Ptr > lstObj;
            QSqlError err = pRepository->_fetchAll( &lstObj );
        }
    Fichiers attachés Fichiers attachés

  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
    Si tu avais mis un try catch, tu aurais vu ce qu'il se passait

    En fait, tu as défini la collection comme ceci :
    qx::QxCollection<long, boost::shared_ptr<issue::db:: Person> > lstObj;

    Mais pour utiliser les repository avec des collections d'objets, il faut définir ta collection comme ceci :
    qx::QxCollection<long, QSharedPointer<issue::db:: Person> > lstObj;

    Je vais améliorer le mécanisme des repository pour que le code que tu as écris fonctionne quand même dans la prochaine version...
    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
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    151
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 151
    Points : 49
    Points
    49
    Par défaut
    Citation Envoyé par QxOrm Voir le message
    Si tu avais mis un try catch, tu aurais vu ce qu'il se passait

    En fait, tu as défini la collection comme ceci :
    qx::QxCollection<long, boost::shared_ptr<issue::db:: Person> > lstObj;

    Mais pour utiliser les repository avec des collections d'objets, il faut définir ta collection comme ceci :
    qx::QxCollection<long, QSharedPointer<issue::db:: Person> > lstObj;

    Je vais améliorer le mécanisme des repository pour que le code que tu as écris fonctionne quand même dans la prochaine version...
    Ah ok, merci !
    (j'avais mis un try catch dans mon appli, mais le what() de l'exception était vide)

    Et est ce que je peux utiliser ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    qx::QxCollection<long, QSharedPointer<QObect> > lstObj;

  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
    j'avais mis un try catch dans mon appli, mais le what() de l'exception était vide
    En effet, ce n'est pas normal, c'est un petit bug que je vais corriger...
    Juste pour me rappeler, il faudra que je modifie les fichiers IxPersistable.h, QxRepository.h et QxSqlError.h (il faut typer l'erreur en mettant QSqlError::UnknownError).

    Et est ce que je peux utiliser ça : qx::QxCollection<long, QSharedPointer<QObject> > lstObj;
    Non ça ne marchera pas, désolé !
    Je pense savoir où tu veux en venir mais ce n'est pas les repository qui vont résoudre cette problématique.
    Peut-être que l'interface IxPersistable et sa méthode qxNewPersistableCollection() pourrait répondre à ton problème, à voir...
    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
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    151
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 151
    Points : 49
    Points
    49
    Par défaut
    Hello !

    Je viens d'essayer avec qxNewPersistableCollection, mais hélas, je crois que j'atteins une des limites du moteur actuel. Voici un bout de code, qui fonctionne (juste pour information):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    qx::IxPersistable *obj = static_cast<qx::IxPersistable *>( qx::create_void_ptr( "issue::db::Person" ) );
    boost::shared_ptr<qx::IxCollection> lstObj = obj->qxNewPersistableCollection();
    obj->qxFetchAll( *lstObj );
    Le problème, c'est que maintenant, j'aimerais accéder aux éléments de la collection, mais toujours avec la contrainte de ne pas connaître le type issue::db:: Person. Donc du coup, je ne peux pas simplement faire ça (qui fonctionnerait):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    typedef qx::QxCollection<long, boost::shared_ptr<Person> > CollectionType;
    boost::shared_ptr<CollectionType> collection( boost::dynamic_pointer_cast<CollectionType>( lstObj ) );

    Tu aurais une idée pour m'éclairer ?

    Ce qui aurait été pas mal, c'est de mettre quelques accesseurs génériques pour l'interface IxCollection, pour pouvoir ensuite passer les élements obtenus à un getValue d'un IxDataMember.
    Pour pouvoir faire qqchose de ce style:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    qx::IxPersistable *obj = static_cast<qx::IxPersistable *>( qx::create_void_ptr( "myClass" ) );
    boost::shared_ptr<qx::IxCollection> lstObj = obj->qxNewPersistableCollection();
    obj->qxFetchAll( *lstObj );
    Q_ASSERT( lstObj.size() != 0 );
    qx::IxDataMember * pProperty = qx::QxClassX::getDataMember( "myClass", "myProperty" );
    QString value = pProperty->getValue<QString>( lstObj.at( 0 ) );

  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
    j'aimerais accéder aux éléments de la collection...
    mettre quelques accesseurs génériques pour l'interface IxCollection...
    Oui, j'avais déjà réfléchis à cette problématique sans trouver de bonnes solutions. C'est pour ça que pour le moment, il n'y a aucune méthode dans l'interface qx::IxCollection (bon ok j'aurai pu au moins mettre le count() ).
    L'idéal serait d'utiliser boost::any dans l'interface, mais boost::any et le polymorphisme ne font pas bon ménages ! Donc ça ne résoudrait pas ton problème.

    J'ai peut-être une idée pour essayer de mettre en place un truc, une sorte de boost::any_cast_dynamic qui n'existe pas aujourd'hui mais qu'on pourrait peut-être écrire avec QxOrm.
    Si tu as d'autres idées pour résoudre cette problématique, n'hésite pas !!!
    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
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    151
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 151
    Points : 49
    Points
    49
    Par défaut
    Ok

    Pour l'instant comme ça, il faudrait que je réfléchisse... Ce genre de problème n'est pas simple à résoudre... Pourquoi ne pas utiliser une ptr_list ? Ou bien un ptr_map ? Après, c'est ultra simple, il suffit que tous tes objets aient une interface commune (QObject), et que tu fasses un dynamic_cast au moment de l'accès (genre faire un getter templaté qui le fait).

    Par contre, j'ai un peu peur que tu ailles dans une mauvaise direction en mettant le fetchAll et le qxNewPersistableCollection directement dans l'interface IxPersistable (contrairement aux autres méthodes qui ont du sens), pour les collections, il faudrait quelque chose de plus externe à la classe (si seulement on pouvait faire du virtual sur du static, je sais pas si on peut). Car le problème, c'est que du coup, il faut que je crée une instance d'objet pour faire un fetchAll, et en soit l'instance n'a pas beaucoup de sens.
    Quelque chose comme ça serait peut être mieux:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    boost::shared_ptr<qx::IxCollection> lstObj = qx::newPersistableCollection();
    qx::dao::fetchAll( *lstObj, "Person" );

  8. #8
    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
    Voici une version BETA que tu peux télécharger :
    http://www.qxorm.com/version/QxOrm_1.2.3_BETA_11.zip

    Dans cette version, j'ai corrigé le petit bug sur la description de l'erreur après un try catch.

    Pour les collections des repository, tu peux maintenant utiliser au choix :
    qx::QxCollection<long, boost::shared_ptr<issue::db:: Person> > lstObj;
    qx::QxCollection<long, QSharedPointer<issue::db:: Person> > lstObj;

    Enfin, l'interface qx::IxCollection possède maintenant certaines méthodes.
    Tu pourras parcourir la collection à partir de l'interface et écrire quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    qx::IxPersistable * obj = static_cast<qx::IxPersistable *>( qx::create_void_ptr( "myClass" ) );
    qx::IxCollection_ptr lstObj = obj->qxNewPersistableCollection();
    obj->qxFetchAll( * lstObj );
    Q_ASSERT( lstObj->_count() != 0 );
    qx::IxPersistable_ptr value = lstObj->_get<qx::IxPersistable_ptr>(0);
    Par contre, j'ai un peu peur que tu ailles dans une mauvaise direction en mettant le fetchAll et le qxNewPersistableCollection directement dans l'interface IxPersistable (contrairement aux autres méthodes qui ont du sens), pour les collections, il faudrait quelque chose de plus externe à la classe (si seulement on pouvait faire du virtual sur du static, je sais pas si on peut). Car le problème, c'est que du coup, il faut que je crée une instance d'objet pour faire un fetchAll, et en soit l'instance n'a pas beaucoup de sens.
    Tu as raison, mais pour le moment, je ne vois pas d'autres moyens.
    Et je ne veux surtout pas imposer une classe de base pour utiliser QxOrm (les repository étant un cas particulier d'utilisation).
    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.

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    151
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 151
    Points : 49
    Points
    49
    Par défaut
    Génial ! Ça a l'air parfait

    Je comprends pour la classe de base...

  10. #10
    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
    Par contre, j'ai un peu peur que tu ailles dans une mauvaise direction en mettant le fetchAll et le qxNewPersistableCollection directement dans l'interface IxPersistable (contrairement aux autres méthodes qui ont du sens), pour les collections, il faudrait quelque chose de plus externe à la classe (si seulement on pouvait faire du virtual sur du static, je sais pas si on peut). Car le problème, c'est que du coup, il faut que je crée une instance d'objet pour faire un fetchAll, et en soit l'instance n'a pas beaucoup de sens.
    J'ai essayé de prendre en compte ta remarque.
    Tu peux télécharger la dernière version BETA ici :
    http://www.qxorm.com/version/QxOrm_1.2.3_BETA_14.zip

    Dans cette version, quand tu travailles avec des classes implémentant l'interface qx::IxPersistable, tu n'as plus besoin d'utiliser une instance bidon pour récupérer la liste des éléments d'une table. Tu peux à présent écrire quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    qx::IxCollection_ptr lst = qx::IxPersistable::qxFetchAll("myClass");
    for (long l = 0; l < lst->_count(); l++)
    { qx::IxPersistable_ptr ptr = lst->_get<qx::IxPersistable_ptr>(l); /* etc... */ }
    Attention, le type myClass doit dériver de qx::IxPersistable, sinon ça plantera (je n'ai aucun moyen de le vérifier à l'exécution)...
    De plus, il vaut mieux mettre un bloc try catch quand on appelle cette nouvelle fonction car si une erreur se produit, une exception de type qx::dao::sql_error est levée.
    Dernière remarque, il y a également dans le même esprit la méthode qx::IxPersistable::qxFetchByQuery().

    Si pour toi c'est mieux comme ça et que tout est ok, je pense qu'on se rapproche de la version finale de QxOrm 1.2.3...

    A voir également : dans le projet ./test/qxDllSample/dll1/, j'ai également ajouté la classe qx::QxPersistable. C'est une sorte de super classe de base qui implémente qx::IxPersistable et hérite de QObject. Cette classe facilite notamment la notion de trigger en utilisant des méthodes virtuelles et utilise la notion de signal-slot de Qt (merci QObject ). Pour le moment, je préfère ne pas l'intégrer dans la bibliothèque, mais il est tout à fait possible de la copier-coller dans ton projet et de t'en servir comme classe de base pour toutes tes classes persistantes...
    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.

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    151
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 151
    Points : 49
    Points
    49
    Par défaut
    Et bien écoute, c'est super

    Je suis sur une autre partie pour l'instant, mais je pense que ce que tu viens de faire rend les choses plus intuitives.

    Merci beaucoup !

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

Discussions similaires

  1. Réponses: 27
    Dernier message: 25/10/2006, 12h10
  2. problème lors de l'utilisation de mon application
    Par dododi dans le forum Bases de données
    Réponses: 2
    Dernier message: 01/10/2006, 19h35
  3. Réponses: 3
    Dernier message: 16/08/2006, 10h26
  4. Problème lors de l'utilisation de opennreport
    Par willytito dans le forum Access
    Réponses: 1
    Dernier message: 20/07/2006, 21h00
  5. Problème lors de l'utilisation de FOP
    Par llaurentt dans le forum XML/XSL et SOAP
    Réponses: 7
    Dernier message: 12/05/2006, 15h49

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