[odb-users] Reuse inheritance and id column names

Boris Kolpackov boris at codesynthesis.com
Sun May 22 20:08:35 EDT 2016


Hi Artem,

Артём Бодрин <abodrin at gmail.com> writes:
 
> Is this an odb-compiler bug, or i must do something else to meet my needs?

It's what we call a "limitation", a bug that will be very hard to fix
and which we probably won't do ;-). The problem has to do with the way
all the pragma values are saved: in this case the column values are
saved in the data member nodes. And since the two derived classes
inherit the same data member, we get this override behavior.

There is a fairly easy, if a bit messy, workaround. Here is the revised
version of your example (I replaced Qt types with int's for testing):

class CommonBase {
public:
    int id;
    int class_id;
};

class Object : public CommonBase {
public:
    int num1;
};

#ifdef ODB_COMPILER
#pragma db object( Object ) table( "object" )
#pragma db member( Object::id_ ) virtual (int) access(id) column( "id" ) id
#pragma db member( Object::class_id_ ) virtual (int) access(class_id) column( "class_id" )
#endif


class Extension : public CommonBase {
public:
    int  num2;
};

#ifdef ODB_COMPILER
#pragma db object( Extension ) table( "extension" )
#pragma db member( Extension::id_ ) virtual(int) access (id) column( "object_id" ) id
#pragma db member( Extension::class_id_ ) virtual(int) access (class_id) column( "object_class_id" )
#endif

The idea is to make CommonBase transient and then use virtual data members
feature to make them persistent with different column names in each derived
case.

As a side note, this change actually makes quite a bit of sense,
conceptually: since you map CommonBase to the database differently in each
derived class, it is not really a persistent object, in ODB sense. Rather,
it's just a group of common data members.

With this change you get the schema that you expect, almost. The only
drawback of this approach is that the *id columns will come after the
num* columns. If you don't like that (and don't want to move the member
pragmas into the class body), then you will need the 2.5.0 pre-release
which support the before/after pragmas:

#pragma db member( Object::id_ ) virtual(int) after ... // Means first.
#pragma db member( Object::class_id_ ) virtual(int) after(Object::id_) ...

Boris



More information about the odb-users mailing list