AW: [odb-users] Multi-Database Support - Cannot integrate
Multi-Database Support / Bug report for the compiler:
odb-2.2.1-i686-windows
Benjamin Schudel
benjamin.schudel at nexirius.com
Thu May 23 09:44:55 EDT 2013
Hi Boris,
you will find the classes as attachments.
Thanks in advance,
Benjamin
-----Ursprüngliche Nachricht-----
Von: Boris Kolpackov [mailto:boris at codesynthesis.com]
Gesendet: Donnerstag, 23. Mai 2013 15:11
An: Benjamin Schudel
Cc: odb-users at codesynthesis.com
Betreff: Re: [odb-users] Multi-Database Support - Cannot integrate
Multi-Database Support / Bug report for the compiler:
odb-2.2.1-i686-windows
Hi Benjamin,
Benjamin Schudel <benjamin.schudel at nexirius.com> writes:
> Now we stumble over a compile problem, which somehow seems to be
> related to the use of inheritance of the persisted classes. The
> Compiler complains of a missing static member 'table_name' within our
> abstract base class (BaseBO).
Can you send me the definition of the BaseBO class (and maybe one of its
derived classes as well, e.g., User)? Or, better yet, a small but complete
test that reproduces the problem.
Boris
-------------- next part --------------
///////////////////////////////////////////////////////////
// User.h
// Implementation of the Class User
// Created on: 29-Nov-2012 18:20:21
// Original author: David Posva
///////////////////////////////////////////////////////////
#if !defined(EA_0FA84639_6280_4cf2_B369_4E88785C6532__INCLUDED_)
#define EA_0FA84639_6280_4cf2_B369_4E88785C6532__INCLUDED_
#include "BaseBO.h"
#include "UserGroup.h"
#include <vector>
#ifndef ODB_COMPILER
#include "LogManager.h"
#include "DatabaseManager.h"
#endif
//#pragma db value(QString) type("VARCHAR")
#pragma db object pointer(shared_ptr)
#pragma db object optimistic
class User :
#ifndef ODB_COMPILER
public std::enable_shared_from_this< User >,
#endif
public BaseBO
{
public:
User();
User(QString name, QString password);
virtual ~User();
vector<shared_ptr<UserGroup> > getGroups() const;
void setGroups(vector<shared_ptr<UserGroup> > val);
QString getName() const;
void setName(QString val);
QString getPassword() const;
void setPassword(QString val);
virtual void save();
virtual void remove();
private:
friend class odb::access;
vector<shared_ptr<UserGroup> > groups;
QString name;
QString password;
#ifndef ODB_COMPILER
#pragma db transient
shared_ptr<LogManager> log;
#pragma db transient
shared_ptr<DatabaseManager> dbManager;
#endif
};
#endif // !defined(EA_0FA84639_6280_4cf2_B369_4E88785C6532__INCLUDED_)
-------------- next part --------------
///////////////////////////////////////////////////////////
// BaseBO.h
// Implementation of the Class BaseBO
// Created on: 27-Nov-2012 18:49:06
// Original author: David Posva
///////////////////////////////////////////////////////////
#if !defined(EA_741592B4_4C31_44b7_9FD1_A2299286834F__INCLUDED_)
#define EA_741592B4_4C31_44b7_9FD1_A2299286834F__INCLUDED_
#define NOMINMAX
#include "BoIF.h"
#ifndef ODB_COMPILER
#include "Uuid.h"
#include "LogManager.h"
#include "ObjectSerializeContainerIF.h"
#endif
#ifdef ODB_COMPILER
#include <odb/core.hxx>
#endif
#include <vector>
#include <iostream>
#include <QtCore/QString>
#include <QtCore/QDateTime>
#include <odb/tr1/memory.hxx>
//#include <memory>
using std::tr1::shared_ptr;
//using std::shared_ptr;
using std::vector;
using std::cerr;
//using odb::tr1::lazy_shared_ptr; //no odb lazy loading -> use hand made delayed loading, so it works also with detached objects
//#pragma warning (push)
//#pragma warning (disable:4068)
//#pragma db value(Uuid) type("VARCHAR")
#pragma db value(QString) type("VARCHAR") mysql:type("VARCHAR(100)")
#pragma db value(QDateTime) type("DATETIME") sqlite:type("TEXT")
//
#pragma db object /*pointer(*)*/ abstract
#pragma db object optimistic
/**
* Base implementation of all Business Objects.
*/
/*abstract*/ class BaseBO : public BoIF
{
friend class BoLoaderFactory;
protected:
//BaseBO(Uuid id);
public:
BaseBO();
virtual ~BaseBO();
#ifndef ODB_COMPILER
#pragma db transient
virtual void serialize(ObjectSerializeContainerIF* output); //impl BoIF
virtual void deserialize(ObjectSerializeContainerIF* input); //impl BoIF
virtual void save() = 0;
virtual void remove() = 0;
#endif
//#pragma db transient
//virtual QString toString();
//TODO ref to db connection / bo source
//not via singleton to DbConnection => to be able to have more than one BO sources in one application
/**
* The ID for the BO.
* Consisting of a random UUID - with first 3 chars for the class identifier.
*/
virtual QString get_id() const; //impl BoIF //lazy initializer -> fixing the "wrong type in base c'tor" issue - and saving some time if never used
void setReadOnly(bool readOnly);
bool getReadOnly();
void setPersistable(bool persistable);
bool getPersistable();
void setPersisted(bool persisted);
bool getPersisted();
void setDeleted(bool deleted);
bool getDeleted();
void setCreationDate(QDateTime creationDate);
QDateTime getCreationDate();
void setCreationUser(QString creationUser);
QString getCreationUser();
void setModificationDate(QDateTime modificationDate);
QDateTime getModificationDate();
void setModificationUser(QString modificationUser);
QString getModificationUser();
int getVersionNr();
private:
friend class odb::access;
/**
* Random UUID - with first 3 chars for the class identifier.
*/
#pragma db id type("VARCHAR") mysql:type("VARCHAR(100)")
#pragma db get(get_id) // Uses by-reference modifier.
mutable QString id; //UUId-String from Uuid::createUuidString()
bool readOnly;
/**
* Can be stored into the DB. (see also persisted & deleted)
* BOs that should get written into the DB (due to no mapping to a table or because they are just temporary) should get constructed with false.
*/
bool persistable;
/**
* is already in the DB
*/
bool persisted;
bool deleted;
/**
* -> does also set the modificationDate (if that is null)
*/
QDateTime creationDate;
/**
* "weak" reference to the user - via name not via userId.
* -> does also set the modificationUser (if that is null)
*/
QString creationUser;
/**
* is >= creationDate = never null
*/
QDateTime modificationDate;
/**
* "weak" reference to the user - via name not via userId.
* if modificationDate == creationDate -> modificationUser == creationUser
*/
QString modificationUser;
/**
* Used to compare if the version in the DB is the one that was loaded.
* Will be automatically incremented everytime it is stored. See Chapter 11 "Optimistic Concurrency" #pragma db version
* If the version isn't the same as the one in memory a reload is needed & a save must be prohibited.
* (= someone else was faster with changing and writing the data => odb::object_changed exception - "catch (const object_changed&)")
* The initialization and increment is managed by ODB. A value of 0 means = not saved yet / transient.
* ! Don't change this value in business logic!!!
*/
#pragma db version
const unsigned int versionNr; //!const is NOT forced by ODB: see chapter 11 Optimistic Concurrency
///*abstract*/ list</*Property*/QString>* getProperties();
#ifndef ODB_COMPILER
#pragma db transient
shared_ptr<LogManager> log;
#endif
};
#endif // !defined(EA_741592B4_4C31_44b7_9FD1_A2299286834F__INCLUDED_)
-------------- next part --------------
///////////////////////////////////////////////////////////
// BaseBO.cpp
// Implementation of the Class BaseBO
// Created on: 29-Nov-2012 18:20:07
// Original author: David Posva
///////////////////////////////////////////////////////////
#include "BaseBO.h"
#include "Uuid.h"
#include "ObjectSerializeContainerIF.h"
#include "Exception.h"
//BaseBO::BaseBO(Uuid existingId){
// idx = existingId;
//}
//QString BaseBO::toString(){
// return QString::number(idx);
//}
BaseBO::BaseBO()
://id(Uuid::createUuidString(QString(typeid(this).name()))),
creationDate(QDateTime::currentDateTime()),
modificationDate(QDateTime::currentDateTime()),
creationUser(QString("me")),
modificationUser(QString("me")),
versionNr(0),
persisted(false),
deleted(false)
{
log = LogManager::getCentralInstance();
}
BaseBO::~BaseBO(){
}
void BaseBO::serialize(ObjectSerializeContainerIF* output) {
log->log(QString("BaseBO::serialize").append(" type: ").append(typeid(*this).name()));
output->writeAttribute("id",get_id(),true);
output->writeAttribute("readOnly",readOnly);
output->writeAttribute("persistable",persistable);
output->writeAttribute("persisted",persisted);
output->writeAttribute("deleted",deleted);
output->writeAttribute("creationDate",creationDate);
output->writeAttribute("creationUser",creationUser);
output->writeAttribute("modificationDate",modificationDate);
output->writeAttribute("modificationUser",modificationUser);
output->writeAttribute("versionNr",versionNr);
}
void BaseBO::deserialize(ObjectSerializeContainerIF* input){
log->log(QString("BaseBO::deserialize").append(" type: ").append(typeid(*this).name()));
this->id = input->readAttribute("id");
this->readOnly = input->readAttributeBool("readOnly");
this->persistable = input->readAttributeBool("persistable");
this->persisted = input->readAttributeBool("persisted");
this->deleted = input->readAttributeBool("deleted");
this->creationDate = input->readAttributeQDateTime("creationDate");
this->creationUser = input->readAttribute("creationUser");
this->modificationDate = input->readAttributeQDateTime("modificationDate");
this->modificationUser = input->readAttribute("modificationUser");
//TODO check does this work?! this->versionNr const_cast - !const is NOT forced by ODB, but suggested: see chapter 11 Optimistic Concurrency
//http://stackoverflow.com/questions/583076/c-c-changing-the-value-of-a-const
//http://stackoverflow.com/questions/357600/is-const-cast-safe
//http://www.cplusplus.com/forum/general/17155/
unsigned int versionNrDeserialized = input->readAttributeUInt("versionNr");
//log->log(this->versionNr);
//log->log(versionNrDeserialized);
unsigned int * versionNr_Ptr = const_cast<unsigned int* > (&this->versionNr);
*versionNr_Ptr = versionNrDeserialized;
//log->log(this->versionNr); //it seems to work with M$-VisualStudio compiler...
}
void BaseBO::save(){
throw new Exception("BaseBO::save not implemented!");
}
void BaseBO::remove(){
throw new Exception("BaseBO::remove not implemented!");
}
QString BaseBO::get_id() const {
//lazy initializer -> fixing the "wrong type in base c'tor" (type is always BaseBO) issue - and saving some time if never used
// - with id / UUID generation in BaseBO we had: "!derived classes have to overload empty c'tor including idx = Uuid::createUuidString(idx,QString(typeid(this).name())); because the typeid(this) in the baseBO is still BaseBO and not the later type!"
if (id.length()==0) {
log->log("id old");
log->log(id);
//mutable QString id; -> nicht mehr nötig: const_cast<BaseBO*>(this)->id = Uuid::createUuidString(QString(typeid(*this).name()));
//id = Uuid::createUuidString(QString(typeid(*this).name()));
id = Uuid::createUuidString(QString(typeid(*this).name()));
log->log("id new");
log->log(id);
}
return id;
}
void BaseBO::setReadOnly( bool readOnly )
{
this->readOnly = readOnly;
}
bool BaseBO::getReadOnly()
{
return this->readOnly;
}
void BaseBO::setPersistable( bool persistable )
{
this->persistable = persistable;
}
bool BaseBO::getPersistable()
{
return this->persistable;
}
void BaseBO::setPersisted( bool persisted )
{
this->persisted = persisted;
}
bool BaseBO::getPersisted()
{
return this->persisted;
}
void BaseBO::setDeleted( bool deleted )
{
this->deleted = deleted;
}
bool BaseBO::getDeleted()
{
return this->deleted;
}
void BaseBO::setCreationDate( QDateTime creationDate )
{
this->creationDate = creationDate;
}
QDateTime BaseBO::getCreationDate()
{
return this->creationDate;
}
void BaseBO::setCreationUser( QString creationUser )
{
this->creationUser = creationUser;
}
QString BaseBO::getCreationUser()
{
return this->creationUser;
}
void BaseBO::setModificationDate( QDateTime modificationDate )
{
this->modificationDate = modificationDate;
}
QDateTime BaseBO::getModificationDate()
{
return this->modificationDate;
}
void BaseBO::setModificationUser( QString modificationUser )
{
this->modificationUser = modificationUser;
}
QString BaseBO::getModificationUser()
{
return this->modificationUser;
}
int BaseBO::getVersionNr()
{
return this->versionNr;
}
//list</*Property*/QString>* BaseBO::getProperties(){
// return new list<QString>();
//}
-------------- next part --------------
///////////////////////////////////////////////////////////
// User.cpp
// Implementation of the Class User
// Created on: 29-Nov-2012 18:20:21
// Original author: David Posva
///////////////////////////////////////////////////////////
#include "User.h"
#include "User-odb.hxx"
#include "Transaction.h"
#include "Exception.h"
#include "SoapServiceManager.h"
User::User(){
log = LogManager::getCentralInstance();
dbManager = DatabaseManager::getUniqueInstance();
}
User::User(QString name, QString password) : name(name), password(password){
log = LogManager::getCentralInstance();
dbManager = DatabaseManager::getUniqueInstance();
}
User::~User(){
}
void User::save(){
try
{
if (SettingsManager::getUniqueInstance()->getDirectDbConnection()) {
log->log(QString("Persist User. -> direct in DB"));
shared_ptr<odb::database> db (dbManager->openDatabaseConnection());
Transaction t(db);
if(this->getPersisted())
{
db->update(*this);
}
else
{
this->setPersisted(true);
db->persist(*this);
}
t.commit();
log->log(QString("User persisted"));
} else {
log->log(QString("Persist User. -> via SOAP"));
SoapServiceManager::getUniqueInstance()->doBusinessTask(this->shared_from_this(), "save");
}
}
catch (const Exception& e)
{
cerr << e.what() << endl;
log->log("save User Exception: ");
log->log(e.getProblem());
}
catch (const odb::exception& e)
{
cerr << e.what() << endl;
log->log("save User Exception: ");
log->log(e.what());
}
catch (const std::exception& e)
{
cerr << e.what() << endl;
log->log("save User Exception: ");
log->log(e.what());
}
}
void User::remove()
{
try
{
if (SettingsManager::getUniqueInstance()->getDirectDbConnection()) {
shared_ptr<odb::database> db (dbManager->openDatabaseConnection());
Transaction t(db);
log->log(QString("Remove User. -> direct in DB"));
db->erase(*this);
t.commit();
} else{
log->log(QString("Remove User. -> via SOAP"));
SoapServiceManager::getUniqueInstance()->doBusinessTask(this->shared_from_this(), "remove");
}
}
catch (const Exception& e)
{
cerr << e.what() << endl;
log->log("remove User Exception: ");
log->log(e.getProblem());
}
catch (const odb::exception& e)
{
cerr << e.what() << endl;
log->log("remove User Exception: ");
log->log(e.what());
}
catch (const std::exception& e)
{
cerr << e.what() << endl;
log->log("remove User Exception: ");
log->log(e.what());
}
}
vector<shared_ptr<UserGroup> > User::getGroups() const
{
return groups;
}
void User::setGroups( vector<shared_ptr<UserGroup> > val )
{
groups = val;
}
QString User::getName() const
{
return name;
}
void User::setName( QString val )
{
name = val;
}
QString User::getPassword() const
{
return password;
}
void User::setPassword( QString val )
{
password = val;
}
More information about the odb-users
mailing list