Wt::Dbo::belongsTo
Added by Stefano Martini over 8 years ago
Hi all,
I am writing a simple program which needs to read data from a mysql database.
The database has 2 tables:
create table hosts (
hostid int(4) auto_increment,
mac varchar(20) not null,
intid int(4) not null,
primary key (hostid),
foreign key (intid) references interface(intid) on update cascade on delete cascade
);
create table interfaces (
intid int(4) auto_increment,
name varchar(255) not null,
state int(1) default 0,
primary key (intid)
);
I wrote the corresponding classes for the two tables and everything worked fine without One-to-many reference.
Since one interface can have many hosts I wrote the code for one-to-many reference.
This is the code I wrote:
#include
#include
namespace dbo = Wt::Dbo;
class DbHost;
class DbInterface;
namespace Wt {
namespace Dbo {
template<>
struct dbo_traits : public dbo_default_traits {
// Disabling the "version" field
static const char *versionField() {
return 0;
}
// Chenge the "id" primary key to "hostsid"
static const char *surrogateIdField() {
return "hostsid";
}
};
template<>
struct dbo_traits : public dbo_default_traits {
// Disabling the "version" field
static const char *versionField() {
return 0;
}
// Chenge the "id" primary key to "intid"
static const char *surrogateIdField() {
return "intid";
}
};
}
}
class DbHost {
public:
DbHost() {};
DbHost(const DbHost& orig) {};
virtual ~DbHost() {};
std::string mac;
int permission;
dbo::ptr interface;
template
void persist(Action& a) {
dbo::field(a, mac, "mac");
dbo::field(a, permission, "status");
dbo::belongsTo(a, interface, "intid");
}
};
class DbInterface {
public:
DbInterface() {};
DbInterface(const DbInterface& orig) {};
virtual ~DbInterface() {};
std::string interface;
std::string description;
int type;
int intid;
dbo::collection< dbo::ptr > hosts;
template
void persist(Action& a) {
dbo::field(a, interface, "interface");
dbo::field(a, description, "descr");
dbo::field(a, type, "type");
dbo::hasMany(a, hosts, dbo::ManyToOne, "intid");
}
};
Whan I run the program I get this error:
terminate called after throwing an instance of 'Wt::Dbo::backend::MySQLException'
what(): error creating prepared statement: 'select "hostsid", "mac", "status", "intid_intid" from "hosts" ': Unknown column 'intid_intid' in 'field list'
Aborted (core dumped)
That is because Wt::Dbo::belongsTo acts as described in the documentation: "This function binds the pointer field value to the database foreign key field(s) name + "_\" + (C's primary key(s))\".
Is it possible to disable such a behaviour?
I need the Wt::Dbo::belongsTo not to concat reference name and key name.
Thanks in advance
Stefano
Replies (4)
RE: Wt::Dbo::belongsTo - Added by Koen Deforche over 8 years ago
Unfortunately, the current behaviour is motivated by the possibility that the primary key of the referenced table could be a composite key, and thus be multiple fields.
In your case we could perhaps have a special handling of an empty foreign key name, in which case the primary key name(s) of the referenced table are used as foreign key:
dbo::hasMany(a, hosts, dbo::ManyToOne, "");
Would that solve your mapping problem?
RE: Wt::Dbo::belongsTo - Added by Stefano Martini over 8 years ago
Hello,
thank you for the reply.
Unfortunately that do not sole the problem.
This is the error:
terminate called after throwing an instance of 'Wt::Dbo::Exception'
what(): Relation mismatch for table 'interface': no matching belongsTo() found in table 'hosts' with name 'interface', but did find with name 'intid'?
Aborted (core dumped)
Maybe the Wt::Dbo module is designed for situations in which the database has to be made from scratch. Tht is not my case since the database already exists and I can't modify its schema.
Thanks
Stefano
RE: Wt::Dbo::belongsTo - Added by Koen Deforche over 8 years ago
Stefano,
There are some assumptions inside Wt::Dbo but we nevertheless would like it to be applicable to an existing schema.
This is one case where we know we have a problem.
Perhaps we should work with a special character in the field name, e.g. '>intid' as a hint that the id should be taken as-is, without concatenation of primary IDs.
Koen
RE: Wt::Dbo::belongsTo - Added by Stefano Martini over 8 years ago
Hi Koen.
That could be a solution.
In the meantime I develop my applications without Wt::Dbo.
Thank for the reply
Bye
Stefano