[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