I'm trying to learn how to use C++ and ODB following this tutorial:
http://www.codesynthesis.com/products/odb/doc/manual.xhtml#2
I've created a Person.hxx file where there is the declaration of class Person as persistent, then I've got thre files Person-odb: .cxx, .hxx, .ixx
Now I should compile Person-odb.cxx with
g++ -I/usr/lib/odb/i686-linux-gnu/include Person-odb.cxx
but it end with:
fatal error: odb/pgsql/version.hxx: No such file or directory. compilation terminated.
I see that there is a file version.hxx but there's no odb/pgsql directory... what's wrong?
this is Person.hxx where I have defined the persistent class Person:
#ifndef PERSON_HXX
#define PERSON_HXX
#include <string>
#include <odb/core.hxx>
using namespace std;
#pragma db object
class Person {
private:
Person() {
}
friend class odb::access;
#pragma db id auto
unsigned long id_;
std::string email_;
std::string first_;
std::string last_;
unsigned short age_;
public:
Person(const std::string& first, const std::string& last,
unsigned short age);
/* getters */
const std::string& first() const;
const std::string& last() const;
unsigned short age() const;
const std::string& email() const;
/* setters */
void setAge(unsigned short);
void setFirst(const std::string&);
void setLast(const std::string&);
void setEmail(const std::string&);
};
#endif
then I must compile Person.hxx with odb compiler:
odb -d mysql --generate-query --generate-schema Person.hxx
and I get 4 files Person.odb.hxx, .cxx, .sql, .ixx this is driver.cxx where I have the main program which persists objects:
#include <memory>
#include <iostream>
#include <odb/database.hxx>
#include <odb/transaction.hxx>
#include <odb/mysql/database.hxx>
#include "Person.hxx"
#include "Person-odb.hxx"
using namespace std;
using namespace odb;
int main(int argc, char* argv[]) {
try {
auto_ptr<database> db (new odb::mysql::database (argc, argv));
unsigned long marcoID, loryID, lucaID;
/*Create some persistent Person objects */
Person marco ("Marco", "Di Nicola", 26);
Person luca ("Luca", "La Sala", 22);
Person lory ("Lorenzo", "Vinci", 24);
transaction t (db->begin());
marcoID = db->persist(marco);
lucaID = db->persist(luca);
loryID = db->persist(lory);
t.commit();
} catch (const odb::exception& e) {
cerr << e.what() << endl;
return 1;
}
}
and this is the file Person-odb.hxx
// This file was generated by ODB, object-relational mapping (ORM)
// compiler for C++.
//
#ifndef PERSON_ODB_HXX
#define PERSON_ODB_HXX
#include <odb/version.hxx>
#if (ODB_VERSION != 20200UL)
#error ODB runtime version mismatch
#endif
#include <odb/pre.hxx>
#include "Person.hxx"
#include <memory>
#include <cstddef>
#include <odb/core.hxx>
#include <odb/traits.hxx>
#include <odb/callback.hxx>
#include <odb/wrapper-traits.hxx>
#include <odb/pointer-traits.hxx>
#include <odb/container-traits.hxx>
#include <odb/no-op-cache-traits.hxx>
#include <odb/result.hxx>
#include <odb/simple-object-result.hxx>
#include <odb/details/unused.hxx>
#include <odb/details/shared-ptr.hxx>
namespace odb
{
// Person
template <>
struct class_traits< ::Person >
{
static const class_kind kind = class_object;
};
template <>
class access::object_traits< ::Person >
{
...
#include "Person-odb.ixx"
#include <odb/post.hxx>
#endif // PERSON_ODB_HXX
everything seems to work fine when I perform:
c++ -c Person-odb.cxx
c++ -c driver.cxx
but in the end when I have to link all together with:
c++ -o driver driver.o Person-odb.o -lodb-mysql -lodb
I get:
"undefined reference to `Person::Person(std::basic_string, std::allocator > const&, std::basic_string, std::allocator > const&, unsigned short)'"
What seems to be your problem is that you didn't install ODB. The Installing ODB page should get you up and running.
You see a version.hxx file, but that's an input file for the ODB compilation process, not for including in your programs.
If you did install it, find out where on your system and add that folder to your compiler include path. Your compilation command then becomes
g++ -I/usr/lib/odb/i686-linux-gnu/include -I/path/to/odb/install/include Person-odb.cxx
Following your edits, I think the issue is that you're not linking to the Person
object file, only the Person-odb one.
Compile Person.cxx
with
g++ -c Person.cxx
and change your linking command to
g++ -o driver driver.o Person.o Person-odb.o -lodb-mysql -lodb
and the error should be fixed.
Please note that I don't know ODB. I'm trying to figure this out from a pure C++ perspective.