relationManyToMany & inheritance

Forum for posting problems using QxOrm library

relationManyToMany & inheritance

Postby guparan » Tue May 17, 2011 3:21 pm

Hi,

I have some problem with ManyToMany relation.
In my DB, a Receipt concerns several Articles and one Article can be in several Receipts.

My DB :
- a table Article
- a table Receipt
- an extra table Receipt_Article
- a table Estimate
- an extra table Estimate_Article

My code :
- a class Article with a Receipts_list
- an abstract class Action with an Articles_list
- a class Receipt derived from Action abstract class
- a class Estimate derived from Action abstract class

Problem :
I can't put my relation in register_class(QxClass<Action> & t) because I don't have the ExtraTable name yet (it can be "Receipt_Article" or "Estimate_Article").

Do I have to have an Articles_list in each Action derived class to implement my relation ?

Thanks :)
guparan
 

Re: relationManyToMany & inheritance

Postby QxOrm admin » Tue May 17, 2011 6:39 pm

Hi,

I think that the best solution for your case is :
1- keep the definition of your collection 'Articles_list' in your abstract class 'Action'
2- don't register 'Articles_list' in the function 'register_class(QxClass<Action> & t)'
3- register your many-to-many relation 'Receipt_Article' in the function 'register_class(QxClass<Receipt> & t)' (you know here the extra-table name)
4- register your many-to-many relation 'Estimate_Article' in the function 'register_class(QxClass<Estimate> & t)' (you know here the extra-table name)

Moreover, don't forget to register your many-to-many relations 'Receipt_Article' and 'Estimate_Article' in the class 'Article'.
QxOrm admin
 

Re: relationManyToMany & inheritance

Postby guparan » Wed May 18, 2011 7:30 am

I already tried that but I get an error :
Code: Select all
error: no matching function for call to ‘qx::QxClass<Receipt>::relationManyToMany(Article_list Action::*, const char [13], const char [19], const char [15], const char [10])’


Seems that register_class(QxClass<Receipt> & t) cannot access to base properties :|
guparan
 

Re: relationManyToMany & inheritance

Postby QxOrm admin » Wed May 18, 2011 7:43 am

Do you have tried this code in your 'register_class(QxClass<Receipt> & t)' function :
Code: Select all
t.relationManyToMany(& [u]Receipt::Articles_list[/u], "XXX", "YYY", "ZZZ", "???");


Instead of :
Code: Select all
t.relationManyToMany(& Action::Articles_list, "XXX", "YYY", "ZZZ", "???");


I think it should work.
If it doesn't work, could you post your classes definition please ?
I will try to reproduce your problem...
QxOrm admin
 

Re: relationManyToMany & inheritance

Postby guparan » Wed May 18, 2011 9:15 am

I tried this too, it didn't work :(
I omitted to precise that I have a Sale abstract class between Action and Receipt/Estimate.

class Article :
Code: Select all
#ifndef ARTICLE_HPP
#define ARTICLE_HPP

#include "DatabaseElement.hpp"

class Receipt;

class QX_PROJECT_DLL_EXPORT Article : public DatabaseElement
{
    QX_REGISTER_FRIEND_CLASS(Article)

public:
    typedef boost::shared_ptr<Receipt> Receipt_ptr;
    typedef QList<Receipt_ptr> Receipt_list;

protected:
    Receipt_list receipts;
    QString designation;

public:
    Article() {}
    QString toString() {return designation;}
};

QX_REGISTER_HPP_QX_PROJECT(Article, DatabaseElement, 0)

typedef boost::shared_ptr<Article> Article_ptr;
typedef QList<Article_ptr> Article_list;

#endif // ARTICLE_HPP

Code: Select all
#include "precompiled.h"
#include "include/Model/Article.hpp"
#include "include/Model/Receipt.hpp"

#include <QxMemLeak.h>

QX_REGISTER_CPP_QX_PROJECT(Article)

namespace qx {
    template <> void register_class(QxClass<Article> & t)
    {
   t.setName("Article");

   t.data(& Article::designation, "Designation");
   t.relationManyToMany(& Article::receipts, "Receipt_list", "TicketCaisseDetail", "IdArticle", "IdTicketCaisse");
    }
}



class Action :
Code: Select all
#ifndef ACTION_HPP
#define ACTION_HPP

#include "DatabaseElement.hpp"
#include "Article.hpp"

class Action : public DatabaseElement
{
    QX_REGISTER_FRIEND_CLASS(Action)

protected:
    Article_list articles;

public:
    Action() {}
    virtual QString toString() = 0;
};

namespace boost { namespace serialization {
template<> void access::construct(Action * e);
} } // namespace boost::serialization

QX_REGISTER_HPP_QX_PROJECT(Action, DatabaseElement, 0)

typedef boost::shared_ptr<Action> Action_ptr;
typedef QList<Action_ptr> Action_list;

#endif // ACTION_HPP

Code: Select all
#include "precompiled.h"
#include "include/Model/Action.hpp"

#include <QxMemLeak.h>     // Automatic memory leak detection

QX_REGISTER_CPP_QX_PROJECT(Action)

namespace qx {
    template <>
    void register_class(QxClass<Action> & t)
    {
   t.data(& Action::date, "DateCreation");
    }
}

namespace boost { namespace serialization {
template<> void access::construct(Action * e) { Q_UNUSED(e); }
} } // namespace boost::serialization


class Sale :
Code: Select all
#ifndef SALE_HPP
#define SALE_HPP

#include "Action.hpp"

class QX_PROJECT_DLL_EXPORT Sale : public Action
{
    QX_REGISTER_FRIEND_CLASS(Sale)

protected:
    QString state;

public:
    Sale() {}
    virtual QString toString() = 0;
};

namespace boost { namespace serialization {
template<> void access::construct(Sale * e);
} } // namespace boost::serialization

QX_REGISTER_HPP_QX_PROJECT(Sale, Action, 0)

typedef boost::shared_ptr<Sale> Sale_ptr;
typedef QList<Sale_ptr> Sale_list;

#endif // SALE_HPP

Code: Select all
#include "precompiled.h"
#include "include/Model/Sale.hpp"

#include <QxMemLeak.h>     // Automatic memory leak detection

QX_REGISTER_CPP_QX_PROJECT(Sale)

namespace qx {
    template <>
    void register_class(QxClass<Sale> & t)
    {
   t.data(& Sale::state, "Etat");
    }
}


namespace boost { namespace serialization {
template<> void access::construct(Sale * e) { Q_UNUSED(e); }
} } // namespace boost::serialization



class Receipt :
Code: Select all
#ifndef RECEIPT_HPP
#define RECEIPT_HPP

#include "Sale.hpp"

class QX_PROJECT_DLL_EXPORT Receipt : public Sale
{
    QX_REGISTER_FRIEND_CLASS(Receipt)

public:
    Receipt() {}
    QString toString() { return QString("Achat du "+date.toString("dddd dd MMMM yyyy")); }
};

QX_REGISTER_HPP_QX_PROJECT(Receipt, Sale, 0)

typedef boost::shared_ptr<Receipt> Receipt_ptr;
typedef QList<Receipt_ptr> Receipt_list;

#endif // RECEIPT_HPP

Code: Select all
#include "precompiled.h"
#include "include/Model/Receipt.hpp"
#include <QxMemLeak.h>     // Automatic memory leak detection

QX_REGISTER_CPP_QX_PROJECT(Receipt)

namespace qx {
    template <>
    void register_class(QxClass<Receipt> & t)
    {
   t.setName("TicketCaisse");

   t.relationManyToMany(& Action::articles, "Article_list", "TicketCaisseDetail", "IdTicketCaisse", "IdArticle");
    }
}
guparan
 

Re: relationManyToMany & inheritance

Postby QxOrm admin » Wed May 18, 2011 12:15 pm

Your code compile and build without problem with Visual C++ 2008 on Windows.
And I have same error like you compiling with GCC 4.4.1 on Linux.
So, I will try to find a solution for GCC compiler...

For my test, I copy this following code in main.cpp file of qxBlog project (copy just after the line '#include <QxMemLeak.h>') :
Code: Select all
#ifndef ARTICLE_HPP
#define ARTICLE_HPP

class Receipt;

class Article
{
    QX_REGISTER_FRIEND_CLASS(Article)

public:
    typedef boost::shared_ptr<Receipt> Receipt_ptr;
    typedef QList<Receipt_ptr> Receipt_list;

protected:
    Receipt_list receipts;
    QString designation;

public:
    Article() {}
    virtual ~Article() { }
    QString toString() {return designation;}
};

QX_REGISTER_HPP_QX_BLOG(Article, qx::trait::no_base_class_defined, 0)

typedef boost::shared_ptr<Article> Article_ptr;
typedef QList<Article_ptr> Article_list;

#endif // ARTICLE_HPP



#ifndef ACTION_HPP
#define ACTION_HPP

//#include "DatabaseElement.hpp"
//#include "Article.hpp"

class Action
{
    QX_REGISTER_FRIEND_CLASS(Action)

protected:
    Article_list articles;

public:
    Action() {}
    virtual ~Action() { }
    virtual QString toString() = 0;
};

namespace boost { namespace serialization {
template<> void access::construct(Action * e);
} } // namespace boost::serialization

QX_REGISTER_HPP_QX_BLOG(Action, qx::trait::no_base_class_defined, 0)

typedef boost::shared_ptr<Action> Action_ptr;
typedef QList<Action_ptr> Action_list;

#endif // ACTION_HPP



#ifndef SALE_HPP
#define SALE_HPP

//#include "Action.hpp"

class Sale : public Action
{
    QX_REGISTER_FRIEND_CLASS(Sale)

protected:
    QString state;

public:
    Sale() {}
    virtual QString toString() = 0;
};

namespace boost { namespace serialization {
template<> void access::construct(Sale * e);
} } // namespace boost::serialization

QX_REGISTER_HPP_QX_BLOG(Sale, Action, 0)

typedef boost::shared_ptr<Sale> Sale_ptr;
typedef QList<Sale_ptr> Sale_list;

#endif // SALE_HPP



#ifndef RECEIPT_HPP
#define RECEIPT_HPP

//#include "Sale.hpp"

class Receipt : public Sale
{
    QX_REGISTER_FRIEND_CLASS(Receipt)

public:
    Receipt() {}
    QString toString() { return ""; /*QString("Achat du "+date.toString("dddd dd MMMM yyyy"));*/ }
};

QX_REGISTER_HPP_QX_BLOG(Receipt, Sale, 0)

typedef boost::shared_ptr<Receipt> Receipt_ptr;
typedef QList<Receipt_ptr> Receipt_list;

#endif // RECEIPT_HPP



QX_REGISTER_CPP_QX_BLOG(Article)

namespace qx {
    template <> void register_class(QxClass<Article> & t)
    {
   t.setName("Article");

   t.data(& Article::designation, "Designation");
   t.relationManyToMany(& Article::receipts, "Receipt_list", "TicketCaisseDetail", "IdArticle", "IdTicketCaisse");
    }
}


QX_REGISTER_CPP_QX_BLOG(Action)

namespace qx {
    template <>
    void register_class(QxClass<Action> & t)
    { Q_UNUSED(t);
   //t.data(& Action::date, "DateCreation");
    }
}

namespace boost { namespace serialization {
template<> void access::construct(Action * e) { Q_UNUSED(e); }
} } // namespace boost::serialization



QX_REGISTER_CPP_QX_BLOG(Sale)

namespace qx {
    template <>
    void register_class(QxClass<Sale> & t)
    {
   t.data(& Sale::state, "Etat");
    }
}


namespace boost { namespace serialization {
template<> void access::construct(Sale * e) { Q_UNUSED(e); }
} } // namespace boost::serialization



QX_REGISTER_CPP_QX_BLOG(Receipt)

namespace qx {
    template <>
    void register_class(QxClass<Receipt> & t)
    {
   t.setName("TicketCaisse");

   t.relationManyToMany(& Action::articles, "Article_list", "TicketCaisseDetail", "IdTicketCaisse", "IdArticle");
    }
}
QxOrm admin
 

Re: relationManyToMany & inheritance

Postby guparan » Wed May 18, 2011 12:52 pm

Ok, thanks for your help :)
guparan
 

Re: relationManyToMany & inheritance

Postby QxOrm admin » Wed May 18, 2011 1:10 pm

Ok I have seen the problem with GCC compiler.
I'm afraid that there is no good solution for your error without modify some files in QxOrm library.

You can workaround with this trick :
Code: Select all
class Receipt : public Sale
{
    QX_REGISTER_FRIEND_CLASS(Receipt)

private:
    Article_list * ref_articles;

public:
   Receipt() : ref_articles(& articles) {}
   //...
};


===> You define a private dummy pointer 'ref_articles' in your derived class and initialized it in your constructor : 'Receipt() : ref_articles(& articles) {}'
===> Then in your register function : 't.relationManyToMany(& Receipt::ref_articles, "Article_list", "TicketCaisseDetail", "IdTicketCaisse", "IdArticle");'

To correct properly your case, I need to add a template parameter in all methods of QxClass and QxDataMemberX because GCC compiler is less permissive (or less smart) than VC++ compiler.
QxOrm admin
 

Re: relationManyToMany & inheritance

Postby QxOrm admin » Wed May 18, 2011 2:07 pm

Ok I have patched QxOrm library : it works for me with both VC++ and GCC compiler without using any trick.
I will give you a link to download the patch in few hours...
QxOrm admin
 

Re: relationManyToMany & inheritance

Postby guparan » Wed May 18, 2011 3:15 pm

Fine, it works but don't really resolve the problem (I need now to have an Articles_ref* in each derived class) :mrgreen:

Waiting for your patch, thank you for your impressive reactivity ! 8-)
guparan
 

Next

Return to QxOrm - Help

Who is online

Users browsing this forum: No registered users and 28 guests