Project

General

Profile

Wt::Dbo::belongsTo

Added by Stefano Martini almost 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 almost 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 almost 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 almost 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 almost 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

    (1-4/4)