[odb-users] modified polymorphism example trouble...

Burton, Craig crburton at tnsi.com
Wed May 30 18:04:31 EDT 2012


Hi ODB-Users,

I am encountering a compilation issue with some 'static' prototyping, in which I am attempting to use the 'polymorphism inheritance' approach.  By 'static' prototyping, I am presently attempting only to reproduce (with ODB and Oracle) an existing class structure that currently exists in an object-oriented database.  I was able to recreate the issue with a subtle modification of the polymorphism example in 2.0.

Please excuse the verbosity of this email; I wasn't sure how to convey the problem without showing all of the details...

The nature of the problem stems from my goal to keep all class definition files separate from one another.  For instance, in the polymorphism example, the person and employee class definitions both exist in the same file.  I am able to build the example files successfully in the unmodified form in an environment outside the example file hierarchy using this Makefile:

CC=g++
ODB_INCLUDES=-I/usr/local/odb/include -I/usr/local/oracle/instantclient_11_2/sdk/include -I/usr/local/boost/boost_1_49_0 -I'.'
CFLAGS=-DDATABASE_ORACLE $(ODB_INCLUDES) -c
LFLAGS=-lodb -lodb-oracle -lodb-boost -lboost_date_time

ODB=odb
ODBFLAGS=--database oracle --generate-schema --generate-query --profile boost/date-time

all: driver

driver: driver.o employee.o employee-odb.o
        $(CC) $(LFLAGS) driver.o employee.o employee-odb.o \
        -o driver

driver.o: driver.cxx employee.hxx employee.cxx employee-odb.cxx
        $(CC) $(CFLAGS) driver.cxx


employee-odb.cxx: employee.hxx
        $(ODB) $(ODBFLAGS) $(ODB_INCLUDES) employee.hxx


employee-odb.o: employee.hxx employee-odb.cxx
        $(CC) $(CFLAGS) employee-odb.cxx

employee.o: employee.cxx employee.hxx
        $(CC) $(CFLAGS) employee.cxx


clean:
        rm -rf *.o *-odb.cxx *-odb.hxx *-odb.ixx *.sql driver

================================================

cburton at deep-thought: make
odb --database oracle --generate-schema --generate-query --profile boost/date-time -I/usr/local/odb/include -I/usr/local/oracle/instantclient_11_2/sdk/include -I/usr/local/boost/boost_1_49_0 -I'.' employee.hxx
g++ -DDATABASE_ORACLE -I/usr/local/odb/include -I/usr/local/oracle/instantclient_11_2/sdk/include -I/usr/local/boost/boost_1_49_0 -I'.' -c driver.cxx
g++ -DDATABASE_ORACLE -I/usr/local/odb/include -I/usr/local/oracle/instantclient_11_2/sdk/include -I/usr/local/boost/boost_1_49_0 -I'.' -c employee.cxx
g++ -DDATABASE_ORACLE -I/usr/local/odb/include -I/usr/local/oracle/instantclient_11_2/sdk/include -I/usr/local/boost/boost_1_49_0 -I'.' -c employee-odb.cxx
g++ -lodb -lodb-oracle -lodb-boost -lboost_date_time driver.o employee.o employee-odb.o \
        -o driver

So the unmodified code compiles successfully.  However, when I attempt to break the employee files into person.hxx, person.cxx, employee.hxx and employee.cxx, I see the same behavior as in my separate, static prototype.  Here are the files:

Person.hxx:
#ifndef PERSON_HXX
#define PERSON_HXX

#include <string>

#include <odb/core.hxx>

#pragma db object polymorphic
class person
{
public:
  person (const std::string& first, const std::string& last)
      : first_ (first), last_ (last)
  {
  }

  const std::string&
  first () const
  {
    return first_;
  }

  const std::string&
  last () const
  {
    return last_;
  }

  virtual
  ~person () = 0;

  virtual void
  print () = 0;

protected:
  friend class odb::access;
  person () {}

  #pragma db id auto
  unsigned long id_;

  std::string first_;
  std::string last_;
};

#endif // PERSON_HXX

================================================

person.cxx:
#include <iostream>

#include "person.hxx"

using namespace std;

person::
~person ()
{
}

================================================

employee.hxx:
// file      : inheritance/polymorphism/employee.hxx
// copyright : not copyrighted - public domain

#ifndef EMPLOYEE_HXX
#define EMPLOYEE_HXX

#include <string>

#include <odb/core.hxx>

#include "person.hxx"

// moved to its own file
/*
#pragma db object polymorphic
class person
...
  std::string last_;
};
*/

#pragma db object
class employee: public person
{
public:
  employee (const std::string& first,
            const std::string& last,
            bool temporary)
      : person (first, last), temporary_ (temporary)
  {
  }
(everything from here down is unmodified)

================================================

employee.cxx
// file      : inheritance/polymorphism/employee.cxx
// copyright : not copyrighted - public domain

#include <iostream>

#include "employee.hxx"

using namespace std;

// moved to its own file
//person::
//~person ()
//{
//}

void employee::
print ()
{
  cout << first_ << ' ' << last_
       << (temporary_ ? " temporary " : " permanent ")
       << "employee" << endl;
}

void contractor::
print ()
{
  cout << first_ << ' ' << last_ << ' ' << email_ << " contractor" << endl;
}

================================================

Makefile:
CC=g++
ODB_INCLUDES=-I/usr/local/odb/include -I/usr/local/oracle/instantclient_11_2/sdk/include -I/usr/local/boost/boost_1_49_0 -I'.'
CFLAGS=-DDATABASE_ORACLE $(ODB_INCLUDES) -c
LFLAGS=-lodb -lodb-oracle -lodb-boost -lboost_date_time

ODB=odb
ODBFLAGS=--database oracle --generate-schema --generate-query --profile boost/date-time

all: driver

driver: driver.o person.o person-odb.o employee.o employee-odb.o
        $(CC) $(LFLAGS) driver.o person.o person-odb.o employee.o employee-odb.o \
        -o driver

driver.o: driver.cxx person.hxx person.cxx person-odb.cxx employee.hxx employee.cxx employee-odb.cxx
        $(CC) $(CFLAGS) driver.cxx


person-odb.cxx: person.hxx
        $(ODB) $(ODBFLAGS) $(ODB_INCLUDES) person.hxx

employee-odb.cxx: employee.hxx
        $(ODB) $(ODBFLAGS) $(ODB_INCLUDES) employee.hxx


person-odb.o: person.hxx person-odb.cxx
        $(CC) $(CFLAGS) person-odb.cxx

employee-odb.o: employee.hxx employee-odb.cxx
        $(CC) $(CFLAGS) employee-odb.cxx

person.o: person.cxx person.hxx
        $(CC) $(CFLAGS) person.cxx

employee.o: employee.cxx employee.hxx
        $(CC) $(CFLAGS) employee.cxx


clean:
        rm -rf *.o *-odb.cxx *-odb.hxx *-odb.ixx *.sql driver

Lastly, here is the result of 'make':

cburton at deep-thought: make
odb --database oracle --generate-schema --generate-query --profile boost/date-time -I/usr/local/odb/include -I/usr/local/oracle/instantclient_11_2/sdk/include -I/usr/local/boost/boost_1_49_0 -I'.' person.hxx
odb --database oracle --generate-schema --generate-query --profile boost/date-time -I/usr/local/odb/include -I/usr/local/oracle/instantclient_11_2/sdk/include -I/usr/local/boost/boost_1_49_0 -I'.' employee.hxx
g++ -DDATABASE_ORACLE -I/usr/local/odb/include -I/usr/local/oracle/instantclient_11_2/sdk/include -I/usr/local/boost/boost_1_49_0 -I'.' -c driver.cxx
g++ -DDATABASE_ORACLE -I/usr/local/odb/include -I/usr/local/oracle/instantclient_11_2/sdk/include -I/usr/local/boost/boost_1_49_0 -I'.' -c person.cxx
g++ -DDATABASE_ORACLE -I/usr/local/odb/include -I/usr/local/oracle/instantclient_11_2/sdk/include -I/usr/local/boost/boost_1_49_0 -I'.' -c person-odb.cxx
g++ -DDATABASE_ORACLE -I/usr/local/odb/include -I/usr/local/oracle/instantclient_11_2/sdk/include -I/usr/local/boost/boost_1_49_0 -I'.' -c employee.cxx
g++ -DDATABASE_ORACLE -I/usr/local/odb/include -I/usr/local/oracle/instantclient_11_2/sdk/include -I/usr/local/boost/boost_1_49_0 -I'.' -c employee-odb.cxx
In file included from /usr/local/odb/include/odb/oracle/polymorphic-object-statements.hxx:23:0,
                 from employee-odb.cxx:27:
/usr/local/odb/include/odb/oracle/simple-object-statements.hxx: In instantiation of 'odb::oracle::object_statements<person>':
/usr/local/odb/include/odb/oracle/polymorphic-object-statements.hxx:35:5:   instantiated from 'odb::oracle::polymorphic_root_object_statements<person>'
/usr/local/odb/include/odb/oracle/polymorphic-object-statements.hxx:176:56:   instantiated from 'odb::oracle::polymorphic_derived_object_statements<employee>'
employee-odb.cxx:147:21:   instantiated from here
/usr/local/odb/include/odb/oracle/simple-object-statements.hxx:396:38: error: 'odb::oracle::object_statements<T>::container_statement_cache_' has incomplete type
person-odb.hxx:263:12: error: forward declaration of 'struct odb::oracle::object_statements<person>::container_statement_cache_type'
In file included from /usr/local/odb/include/odb/oracle/simple-object-statements.hxx:492:0,
                 from /usr/local/odb/include/odb/oracle/polymorphic-object-statements.hxx:23,
                 from employee-odb.cxx:27:
/usr/local/odb/include/odb/oracle/simple-object-statements.txx: In constructor 'odb::oracle::object_statements<T>::object_statements(odb::oracle::statements_base::connection_type&) [with T = person, odb::oracle::statements_base::connection_type = odb::oracle::connection]':
/usr/local/odb/include/odb/oracle/polymorphic-object-statements.txx:36:59:   instantiated from 'odb::oracle::polymorphic_root_object_statements<T>::polymorphic_root_object_statements(odb::oracle::polymorphic_root_object_statements<T>::connection_type&) [with T = person, odb::oracle::polymorphic_root_object_statements<T>::connection_type = odb::oracle::connection]'
/usr/local/odb/include/odb/oracle/statement-cache.txx:21:54:   instantiated from 'typename odb::object_traits<T>::statements_type& odb::oracle::statement_cache::find_object() [with T = person, typename odb::object_traits<T>::statements_type = odb::oracle::polymorphic_root_object_statements<person>]'
/usr/local/odb/include/odb/oracle/polymorphic-object-statements.txx:69:71:   instantiated from 'odb::oracle::polymorphic_derived_object_statements<T>::polymorphic_derived_object_statements(odb::oracle::statements_base::connection_type&) [with T = employee, odb::oracle::statements_base::connection_type = odb::oracle::connection]'
/usr/local/odb/include/odb/oracle/statement-cache.txx:21:54:   instantiated from 'typename odb::object_traits<T>::statements_type& odb::oracle::statement_cache::find_object() [with T = employee, typename odb::object_traits<T>::statements_type = odb::oracle::polymorphic_derived_object_statements<employee>]'
employee-odb.cxx:232:57:   instantiated from here
/usr/local/odb/include/odb/oracle/simple-object-statements.txx:53:56: error: using invalid field 'odb::oracle::object_statements<T>::container_statement_cache_'
make: *** [employee-odb.o] Error 1

It appears that the person template code is in a file that is separate from the employee template code and that the employee templates can't access the person templates.  Is there a way around this other than including all class definitions in one file?  Any assistance would be appreciated.  Below are additional environment details.

Thank you in advance!
Craig


Environment:
Solaris 10
gcc 4.5.2

Environment Variables:
export CPPFLAGS='-I/usr/local/odb/include -I/usr/local/mysql/include -I/usr/local/sqlite/include -I/usr/local/oracle/instantclient_11_2/sdk/in
clude -I/usr/local/boost/boost_1_49_0'
export LDFLAGS='-L/usr/local/odb/lib -L/usr/local/mysql/lib -L/usr/local/oracle/instantclient_11_2 -L/usr/local/boost/boost_1_49_0/stage/lib'
export PATH=/usr/local/dist/gcc-4.5.2/bin:/opt/SUNWspro/bin:/usr/local/odb/bin:/usr/local/oracle/instantclient_11_2:/usr/dt/bin:/usr/sbin:/usr
/local/bin:/usr/bin:/usr/ucb:/etc:/usr/openwin/bin:/usr/ccs/bin:/usr/local/j2sdk1.4.2/bin:/usr/local/ssl-lnp/bin:.
export LD_LIBRARY_PATH=/usr/local/dist/gcc-4.5.2/lib/gcc/sparc-sun-solaris2.10:/usr/local/dist/gcc-4.5.2/lib:/usr/local/oracle/instantclient_1
1_2:/usr/local/boost/boost_1_49_0/stage/lib:/usr/local/odb/lib:/usr/local/lib:/usr/openwin/lib:/usr/lib:/usr/dt/lib:/usr/dt/lib



This e-mail message is for the sole use of the intended recipient(s)and may
contain confidential and privileged information of Transaction Network Services.
Any unauthorised review, use, disclosure or distribution is prohibited. If you
are not the intended recipient, please contact the sender by reply e-mail and destroy all copies of the original message.




More information about the odb-users mailing list