Wt::Dbo -> "create table 'delete from xxx' and create table 'integer not null'"
Added by Christian Meyer over 1 year ago
I tried to build a templated Table to enable Polymorphism in Dbo
And it seems that with that I found 2 problems
If
Wt::Dbo::hasOne
is used in aOneToOne
Relation, my App crashes on a call toSession::tableCreationSql()
which can of course be related to 2...Somehow the Tablename is mangled up somewhere along the way and while I am still trying to figure out whats happening, the tablecreateSql changed from
create table \"delete from \"\" where \"id\" = ?\"
tocreate table \"integer not null\"
If you have any Idea as to what is happening I would be really exited to read about it =)
Here is my code
Template Class
//t.h
template <class Base, class Derived>
class ConnectorTable
{
protected:
Wt::Dbo::ptr<Base> basePtr;
Wt::Dbo::ptr<Derived> derivedPtr;
public:
static std::string fieldName()
{
return Wt::WString("derived_{1}_to_{2}")
.arg(Base::refName())
.arg(Derived::refName())
.toUTF8();
}
ConnectorTable() { }
ConnectorTable(Wt::Dbo::ptr<Base> bPtr, Wt::Dbo::ptr<Derived> dPtr);
virtual ~ConnectorTable() {}
Wt::Dbo::ptr<Derived> getDerived() const { return derivedPtr; }
Wt::Dbo::ptr<Base> getBase() const { return basePtr; }
template <class Action>
void persist(Action &a)
{
Wt::Dbo::field(a, basePtr, "base");
Wt::Dbo::belongsTo(
a,
derivedPtr,
fieldName(),
Wt::Dbo::OnDeleteCascade | Wt::Dbo::OnUpdateCascade
);
}
};
template <class Base, class Derived>
ConnectorTable<Base, Derived>::ConnectorTable(Wt::Dbo::ptr<Base> bPtr, Wt::Dbo::ptr<Derived> dPtr)
: basePtr(bPtr), derivedPtr(dPtr)
{}
The Base Class
//b.h:
class BasePtr : public Wt::Dbo::Dbo<BasePtr>
{
public:
BasePtr(bool derived = false);
virtual ~BasePtr(){}
static std::string refName() { return {"BasePtr"}; }
virtual std::string getName() const;
template <class Action>
void persist(Action &a);
protected:
bool has_derived;
};
//b.cpp:
BasePtr::BasePtr(bool derived)
{
has_derived = derived;
}
std::string BasePtr::getName() const
{
return "BasePtr";
}
template <class Action>
void BasePtr::persist(Action &a)
{
Wt::Dbo::field(a, has_derived, "b_derived");
}
The Derived Class
//s.h
#include "t.h"
class SpecialPtr;
typedef ConnectorTable<BasePtr,SpecialPtr> BaseSpecialConnector;
class SpecialPtr : public BasePtr
{
public:
SpecialPtr() : BasePtr(true) {}
virtual ~SpecialPtr(){}
static std::string refName() { return {"SpecialPtr"}; }
virtual std::string getName() const { return "SpecialPtr"; }
template <class Action>
void persist(Action &a);
private:
Wt::Dbo::weak_ptr<BaseSpecialConnector> baseConPtr;
Wt::Dbo::ptr<BasePtr> basePtr;
};
DBO_EXTERN_TEMPLATES(Test::Dbo::BaseSpecialConnector)
DBO_EXTERN_TEMPLATES(Test::Dbo::SpecialPtr)
//s.cpp
DBO_INSTANTIATE_TEMPLATES(Test::Dbo::SpecialPtr)
DBO_INSTANTIATE_TEMPLATES(Test::Dbo::BaseSpecialConnector)
template <class Action>
void SpecialPtr::persist(Action &a)
{
// // Adding this, crashes the App - Segfault
// Wt::Dbo::hasOne(
// a,
// baseConPtr,
// BaseSpecialConnector::fieldName()
// );
Wt::Dbo::belongsTo(a, basePtr);
}
Mapping the Classes in Session
session->mapClass<BasePtr>("Test_BasePtr");
session->mapClass<SpecialPtr>("Test_SpecialPtr");
auto mapClassName =
BasePtr::refName()
+ "_"
+ SpecialPtr::refName()
+"_Connector";
// Wt::WString::fromUTF8("{1}_{2}_Connector")
// .arg(BasePtr::refName())
// .arg(SpecialPtr::refName())
// .toUTF8();
Wt::log("info") << "MapClasses" << ": Name(string): " << mapClassName;
Wt::log("info") << "MapClasses" << ": Name(char*): " << mapClassName.c_str();
session->mapClass<BaseSpecialConnector>(mapClassName.c_str());
Maybe there are some obvious flaws in the code that I did not see...
the mapClassName
check seems to work now, but did give weird text or just two random values.
wt-4.8.0
Replies (2)
RE: Wt::Dbo -> "create table 'delete from xxx' and create table 'integer not null'" - Added by Christian Meyer over 1 year ago
Found the problem for 2:
mapClass does not seem to store the content of the char* as the tableName, but the Adress of the pointer.
Therefore, mapClass needs to be called with the spelled out name in qoutes -> mapClass<BaseSpecialConnector>("Test_BaseSpecialConnector");
[SOLVED]: Wt::Dbo -> "create table 'delete from xxx' and create table 'integer not null'" - Added by Christian Meyer over 1 year ago
hasOne does not crash anymore, after #2 was fixed