We are going to introduce now the C++ binding through the same schema
and examples as previously.
There are two ways to use the C++ binding:
To generate the specific C++ binding, run the eyedbodl tool as follow:
% eyedbodl --gencode=C++ --package=person schema.odlThe -package option is mandatory: you may give any name you want, this name will be used as the prefix for generated files names. Without the -package option, the prefix used will be the name of the ODL file without its extension.
class person {
public:
static void init();
static void release();
static eyedb::Status updateSchema(eyedb::Database *db);
static eyedb::Status updateSchema(eyedb::Schema *m);
};
it is used to perform package initialization and schema update.
Before any use of the person package, you need to call
person::init.
eyedb::Status setFirstname(const std::string &); std::string getFirstname(eyedb::Bool *isnull = 0, eyedb::Status * = 0) const; eyedb::Status setFirstname(unsigned int a0, char); char getFirstname(unsigned int a0, eyedb::Bool *isnull = 0, eyedb::Status * = 0) const;The two first methods manipulate the firstname attribute as a string while the two last ones manipulate each character within this string.
#include "person.h"
int
main(int argc, char *argv[])
{
eyedb::init(argc, argv); // initializes EyeDB package
person::init(); // initializes person package
eyedb::Exception::setMode(eyedb::Exception::ExceptionMode); // use exception mode
try {
eyedb::Connection conn;
conn.open(); // opens the connection
personDatabase db(argv[1]); // creates a database handle
db.open(&conn, eyedb::Database::DBRW); // opens the database in read/write mode
}
catch(Exception &e) { // catch any exception and print it
e.print();
}
person::release(); // releases person package
eyedb::release(); // releases EyeDB package
return 0;
}
Note that statement Exception::setMode(...) is mandatory
if you want to use the exception error policy.
#
# Makefile.person
#
# person package
#
# Example of template Makefile that can help you to compile
# the generated C++ file and the template program
# Generated by eyedbodl at Sat Jan 28 17:53:48 2006
#
include <<datadir>>/eyedb/Makefile.eyedb
CXXFLAGS += $(EYEDB_CXXFLAGS) $(EYEDB_CPPFLAGS)
LDFLAGS += ${EYEDB_LDFLAGS}
LDLIBS += ${EYEDB_LDLIBS}
# if you use gcc
GCC_FLAGS = -Wl,-R$(EYEDB_LIBDIR)
# Example for compiling a client program:
client_program = template_person
$(client_program): person.o $(client_program).o
$(CXX) $(LDFLAGS) $(GCC_FLAGS) -o $@ $^ $(LDLIBS)
Important note: you need a recent version of GNU make to use this makefile.
This makefile does not work with the standard SUN make.
% ./persontest fooWe are going now to add a function to manipulate Person instances:
static void
create(eyedb::Database *db)
{
db->transactionBegin(); // starts a new transaction
Person *john = new Person(db);
john->setFirstname("john");
john->setLastname("wayne");
john->setAge(32);
john->getAddr()->setStreet("courcelles");
john->getAddr()->setTown("Paris");
Person *mary = new Person(db);
mary->setFirstname("mary");
mary->setLastname("poppins");
mary->setAge(30);
mary->getAddr()->setStreet("courcelles");
mary->getAddr()->setTown("Paris");
// mary them
john->setSpouse(mary);
// creates children
for (int i = 0; i < 5; i++) {
std::string name = std::string("baby") + str_convert(i+1);
Person *child = new Person(db);
child->setFirstname(name.c_str());
child->setLastname(name.c_str());
child->setAge(1+i);
john->addToChildrenColl(child);
child->release(); // release the allocated pointer
}
// store john and all its related instances within the database
john->store(eyedb::FullRecurs);
// release the allocated pointers
mary->release();
john->release();
db->transactionCommit(); // commits the current transaction
}
A few remarks about this code:
static void
read(eyedb::Database *db, const char *s)
{
db->transactionBegin();
eyedb::OQL q(db, "select Person.lastname ~ \"%s\"", s);
eyedb::ObjectArray obj_arr;
q.execute(obj_arr);
for (int i = 0; i < obj_arr.getCount(); i++) {
Person *p = Person_c(obj_arr[i]);
if (p)
printf("person = %s %s, age = %d\n", p->getFirstname(),
p->getLastname(), p->getAge());
}
db->transactionCommit();
}
An OQL construct can be used within the C++ code using the
OQL(Database *, const char *fmt, ...) constructor.
For instance, in the above example, assuming s is equal to baby, the code:
eyedb::OQL q(db, "select Person.lastname ~ \"%s\"", s);will send the query select Person.lastname "baby" to the OQL interpreter.
eyedb::ObjectArray obj_arr; q.execute(obj_arr);The returned objects are of type eyedb::Object, so you cannot use the Person methods such as getFirstname(), getAge()... To use them, you need to perform a down-cast using the Person_c static function as follows:
for (int i = 0; i < obj_arr.getCount(); i++) {
Person *p = Person_c(obj_arr[i]);
if (p) ...
If the object obj_arr[i] is not of type Person, the returned
pointer will be null. It is why we make a test on the value of p.
If p is not null, we can use all the Person methods as follows:
printf("person = %s %s, age = %d\n", p->getFirstname(),
p->getLastname(), p->getAge());
To have more information about the C++ binding, please refer to the EYEDB C++ binding manual.
EyeDB manual