I am trying to set up a system where I can use use
Rose::DB::Object::Loader to auto make my modules any time I make a
schema change. Then I can have manually created classes that use the
auto-generated classes as their base. But, I am running into a problem
with the relationships.
Here is a simple case. I have a MySQL database with 3 tables: foos,
bars, & foo_bar_map:
=========================================================
CREATE TABLE `foos` (
`id` int(10) unsigned NOT NULL auto_increment,
`name` varchar(50) NOT NULL default '',
PRIMARY KEY (`id`),
UNIQUE KEY `name_phone_idx` (`name`)
);
CREATE TABLE `bars` (
`id` int(10) unsigned NOT NULL auto_increment,
`description` varchar(50) NOT NULL default '',
PRIMARY KEY (`id`)
);
CREATE TABLE `foo_bar_map` (
`foo_id` int(10) unsigned NOT NULL default '0',
`bar_id` int(10) unsigned NOT NULL default '0',
PRIMARY KEY (`foo_id`,`bar_id`),
KEY `foo_id` (`foo_id`),
KEY `bar_id` (`bar_id`),
CONSTRAINT `foo_bar_map_ibfk_1` FOREIGN KEY (`foo_id`) REFERENCES
`foos` (`id`),
CONSTRAINT `foo_bar_map_ibfk_2` FOREIGN KEY (`bar_id`) REFERENCES
`bars` (`id`)
)
=========================================================
The idea is to auto-create modules in the 'My::DB' namespace, i.e.
My::DB::Foo. Then I create My::Foo which uses My::DB::Foo as it's base
and allows me to put in all the other methods that I need to create
manually to operate on foos. When I change the schema, I can just
re-generate everything in My::DB, and my other stuff is preserved.
So, I created a script that will generate everything in My::DB. This
script also goes through each generated module and swaps out the classes
for the relationships to point to my 'main' class. i.e. My::Foo
instead of My::DB::Foo. This is to ensure that I get the right class
when I traverse the relationships.
When I run that script, I end up with these 3 modules:
=========================================================
package My::DB::Foo;
use strict;
use base qw(My::DB::DB::Object::AutoBase1);
__PACKAGE__->meta->setup(
table => 'foos',
columns => [
id => { type => 'integer', not_null => 1 },
name => { type => 'varchar', default => '', length => 50,
not_null => 1 },
],
primary_key_columns => [ 'id' ],
unique_key => [ 'name' ],
relationships => [
bars => {
column_map => { foo_id => 'id' },
foreign_class => 'My::Bar',
map_class => 'My::FooBarMap',
map_from => 'foo',
map_to => 'bar',
type => 'many to many',
},
],
);
package My::DB::Bar;
use strict;
use base qw(My::DB::DB::Object::AutoBase1);
__PACKAGE__->meta->setup(
table => 'bars',
columns => [
id => { type => 'integer', not_null => 1 },
description => { type => 'varchar', default => '', length =>
50, not_null => 1 },
],
primary_key_columns => [ 'id' ],
relationships => [
foos => {
column_map => { bar_id => 'id' },
foreign_class => 'My::Foo',
map_class => 'My::FooBarMap',
map_from => 'bar',
map_to => 'foo',
type => 'many to many',
},
],
);
package My::DB::FooBarMap;
use strict;
use base qw(My::DB::DB::Object::AutoBase1);
__PACKAGE__->meta->setup(
table => 'foo_bar_map',
columns => [
foo_id => { type => 'integer', not_null => 1 },
bar_id => { type => 'integer', not_null => 1 },
],
primary_key_columns => [ 'foo_id', 'bar_id' ],
foreign_keys => [
bar => {
class => 'My::Bar',
key_columns => { bar_id => 'id' },
},
foo => {
class => 'My::Foo',
key_columns => { foo_id => 'id' },
},
],
);
=============================================
My::Foo would look something like this:
====
package My::Foo;
use strict;
use base qw(My::Foo);
# class and instance methods here.......
1;
====
Here's where the problem comes in. I have this test script:
====
#!/usr/bin/perl
use My::Foo;
use Data::Dumper;
my $f = My::Foo->new(id => 1);
$f->load;
foreach my $bar (@{$f->bars}) {
print Dumper($bar);
}
====
When I run it I get this error:
Can't locate object method "bars" via package "My::Foo" at
/usr/lib/perl5/site_perl/5.8.5/Rose/DB/Object.pm line 1464
Rose::DB::Object::AUTOLOAD('My::Foo=HASH(0x88a6ee0)') called at
test.pl line 7
If I don't change the classes for the relationships in my auto-generate
script, then it works fine. But, then my $bar objects are of the class
My::DB::Bar and I need them to be My::Bar.
I would assume there are other people trying to do something similar to
this. Am I missing something? or do I just need to suck it up and
manage the meta data manually?
-Bryan
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Rose-db-object mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/rose-db-object