Hi all,
Never used Rose::DB before, but I've heard enough good things about it
that I'm giving it a try. Some of what I'm writing is probably clunky,
so pointers welcome.
I'm trying to provide my own metadata class and I've run into a problem
I don't quite understand. Here's my base class:
package Donhost::Model::Object;
use strict;
use warnings;
use base qw(Rose::DB::Object);
use Donhost::Model::Object::Metadata;
use aliased 'Donhost::Model';
Model->default_domain( $ENV{TESTING} ? 'test' : 'cp' );
sub init_db { Model->new('main') }
sub meta_class { 'Donhost::Model::Object::Metadata' }
sub is_public {}
sub is_readonly {}
1;
And here's my metadata class (the problem is in overriding the setup()
method):
package Donhost::Model::Object::Metadata;
use strict;
use warnings;
use base 'Rose::DB::Object::Metadata';
sub overridden_methods {
my $self = shift;
my $table = $self->table;
return ( "delete_$table", "update_$table" );
}
sub make_manager_class {
my $self = shift;
my $class = $self->class;
if ( 1 == @_ && $class->is_readonly ) {
my $result = $self->SUPER::make_manager_class(@_);
my $manager = $class . '::Manager';
foreach my $method ( $self->overridden_methods ) {
my $overridden = $manager . "::$method";
no strict 'refs';
no warnings 'redefine';
*$overridden = sub {
require Carp;
Carp::confess(
"Manager method '$method' not allowed for
readonly objects"
);
};
}
return $result;
}
# Assume they know what they are doing
return $self->SUPER::make_manager_class(@_);
}
sub setup {
my ( $self, %arg_for ) = @_;
$self->SUPER::setup(%arg_for);
foreach my $column ( $self->columns ) {
my $name = $column->name;
# here's the problem
$self->alias_column( $name => "_$name" )
unless $self->class->is_public($column);
}
}
1;
The 'make_manager_class' probably has a better way of overriding
mutators to be read-only, but it's the 'setup' which is causing my
tests to fail. If I comment out the 'alias_column' line, all is well.
However, when I uncomment it, I get this:
not ok 26 - os died (load() - Can't locate object method "" via package
"" at /usr/local/lib/perl5/site_perl/5.8.7/Rose/DB/Object.pm line 1287
Here's the code which throws the error:
can_ok 'Donhost::OS, 'load';
ok Donhost::OS->load, '... and loading a valid OS should succeed';
Those come from the following two lines in the AUTOLOAD method (which
I'm surprised is called):
$AUTOLOAD =~ /^(.+)::(\w+)$/;
Carp::confess qq(Can't locate object method "$2" via package
"$1"$msg);
The value of $AUTOLOAD at that point is 'Donhost::OS::' and the code
which calls this (from the ->load() method)
if($rows > 0)
{
my $methods = $meta->column_mutator_method_names_hash;
# Empty existing object?
#%$self = (db => $self->db, meta => $meta, STATE_LOADING() => 1);
foreach my $name (@$column_names)
{
my $method = $methods->{$name};
$self->$method($row{$name});
}
So somehow, when aliasing a column, column_mutator_method_names_hash()
appears to return incorrect values or, perhaps, @$column_names is
getting incorrect values. I'll dig into this more later, but if anyone
can offer insight, I'd appreciate it.
And for completeness, my Donhost::OS class:
package Donhost::OS;
use strict;
use warnings;
use base 'Donhost::Model::Object::Readonly';
__PACKAGE__->meta->setup(
table => 'os',
columns => [
os => {
type => 'varchar',
length => 31,
primary_key => 1,
not_null => 1
},
type => { type => 'text', not_null => 1 },
plan_part => { type => 'text' },
install_vlan => { type => 'text' },
short_desc => { type => 'text' },
description => { type => 'text' },
upgrade_default => { type => 'tinyint', length => 1, default
=> 1 },
],
unique_key => 'description',
);
# XXX There should be a simpler way to push this into the base class.
I have
# an idea of how to do it, but for now, I'll table it.
__PACKAGE__->meta->make_manager_class('os');
1;
Note: the 'Readonly' class merely makes the mutators throw exceptions
if called.
Does anyone know what I'm doing wrong? I think I'm using alias_column
as documented, but I'm scratching my head over this one.
Cheers,
Ovid
--
Buy the book -- http://www.oreilly.com/catalog/perlhks/
Perl and CGI -- http://users.easystreet.com/ovid/cgi_course/
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Rose-db-object mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/rose-db-object