Hi,
I experimented with making the comment class in the qxBlog example abstract. I made it subclass qx::IxPersistable and used the QX_REGISTER_ABSTRACT_CLASS macro. When I compile, it dies in the invocation of the macro QX_PERSISTABLE_CPP, with:
../../../QxOrm/include/QxDao/../../inl/QxDao/QxDao_Count.inl:36: error: cannot declare variable 't' to be of abstract type 'comment'
Using
qx::IxPersistable interface (
http://www.qxorm.com/qxorm_en/faq.html#faq_260) and an abstract class, you don't have to write
QX_PERSISTABLE_HPP and
QX_PERSISTABLE_CPP macros : it doesn't make sense (those macros must be used only with concretes types).
qx::IxPersistable interface provides a way to persist an instance without knowing its real type (so typically using a base class pointer).
QX_PERSISTABLE_HPP and
QX_PERSISTABLE_CPP macros are used to implement all persistables methods (
qxFetch,
qxSave, etc...).
Since a C++ abstract class cannot have a table associated into the database (because the class cannot be instantiated), you can't implement persistables methods.
So here is the idea if I use your example :
- Code: Select all
class Table : public qx::IxPersistable {
QX_PERSISTABLE_HPP(Table)
Shape* top;
};
class Shape : public qx::IxPersistable {
// Don't use QX_PERSISTABLE_HPP macro in the abstract class !!!
public:
virtual float getWidth() = 0;
};
class Square : public Shape {
QX_PERSISTABLE_HPP(Square)
virtual float getWidth();
};
class Circle : public Shape {
QX_PERSISTABLE_HPP(Circle)
virtual float getWidth();
};
Now your problem : you have a persistent class named
Table. This class contains a pointer to a persistent base class named
Shape.
And when you save an instance of
Table, if
Shape is a
Square, then save it to the
Square table, else if
Shape is a
Circle, then save it to the
Circle table, etc...
Don't forget that there is a database associated with your C++ code.What is your database schema in this case ?
In your
Table table, you need an extra-information to manage you base class pointer : the real type associated to the pointer.
QxOrm library will not manage automatically this extra-information, but I think that you could try something like this using QxOrm triggers (
http://www.qxorm.com/qxorm_en/faq.html#faq_130) and C++
dynamic_cast function :
1- to store a
Shape, your
Table table must have a column to store the ID
Shape + another column to store the real type of
Shape ;
2- then create some triggers, for example :
- Code: Select all
void onAfterFetch(Table * t, qx::dao::detail::IxDao_Helper * dao)
{
if (t->myShapeType == "Square") { t->top = new Square(); }
else if (t->myShapeType == "Circle") { t->top = new Circle(); }
else if (etc...) { etc... }
if ((t->top != NULL) && (t->myShapeID > 0))
{
t->top->setId(t->myShapeID);
QSqlError daoErr = t->top->qxFetchById();
}
}
void onBeforeUpdate(Table * t, qx::dao::detail::IxDao_Helper * dao)
{
if (dynamic_cast<Square *>(t->top) != NULL) { t->myShapeType = "Square"; }
else if (dynamic_cast<Circle *>(t->top) != NULL) { t->myShapeType = "Circle"; }
else if (etc...) { etc... }
if (t->top)
{
t->myShapeID = t->top->getId();
QSqlError daoErr = t->top->qxSave();
}
}
// etc...