Alzabo
view release on metacpan or search on metacpan
lib/Alzabo/MethodMaker.pm view on Meta::CPAN
) or next;
$self->{row_class}->add_method_docs
( Alzabo::MethodDocs->new
( name => $name,
group => 'Methods that update/return a column value',
spec => [ { type => SCALAR } ],
description =>
"returns the value of the " . $c->name . " column for a row. Given a value, it will also update the row first.",
) );
}
}
sub make_foreign_key_methods
{
my $self = shift;
my $t = shift;
foreach my $other_t ( sort { $a->name cmp $b->name } $t->schema->tables )
{
my @fk = $t->foreign_keys_by_table($other_t)
or next;
if ( @fk == 2 && $fk[0]->table_from eq $fk[0]->table_to &&
$fk[1]->table_from eq $fk[1]->table_to )
{
unless ($fk[0]->is_one_to_one)
{
$self->make_self_relation($fk[0]) if $self->{opts}{self_relations};
}
next;
}
foreach my $fk (@fk)
{
$self->_make_fk_method($fk);
}
}
}
sub _make_method
{
my $self = shift;
my %p = validate @_, { type => { type => SCALAR },
class => { type => SCALAR },
returns => { type => SCALAR, optional => 1 },
code => { type => CODEREF },
# Stuff we can pass through to name_maker
foreign_key => { optional => 1 },
foreign_key_2 => { optional => 1 },
column => { optional => 1 },
table => { optional => 1 },
parent => { optional => 1 },
plural => { optional => 1 },
};
my $name = $self->{opts}{name_maker}->( %p )
or return;
my ($code_name, $debug_name) = ("$p{class}::$name",
"$p{class}\->$name");
if ( $p{class}->can($name) )
{
warn "MethodMaker: Creating $p{type} method $debug_name will override"
. " the method of the same name in the parent class\n";
}
no strict 'refs'; # We use symbolic references here
if ( defined &$code_name )
{
# This should probably always be shown to the user, not just
# when debugging mode is turned on, because name clashes can
# cause confusion - whichever subroutine happens first will
# arbitrarily win.
warn "MethodMaker: skipping $p{type} method $debug_name, subroutine already exists\n";
return;
}
if (Alzabo::Debug::METHODMAKER)
{
my $message = "Making $p{type} method $debug_name";
$message .= ": returns $p{returns}" if $p{returns};
print STDERR "$message\n";
}
*$code_name = $p{code};
return $name;
}
sub _make_fk_method
{
my $self = shift;
my $fk = shift;
my $table_to = $fk->table_to->name;
# The table may be a linking or lookup table. If we are
# supposed to make that kind of method we will and then we'll
# skip to the next foreign table.
$self->make_linking_table_method($fk)
if $self->{opts}{linking_tables};
$self->make_lookup_columns_methods($fk)
if $self->{opts}{lookup_columns};
return unless $self->{opts}{foreign_keys};
if ($fk->is_one_to_many)
{
my $name = $self->_make_method
( type => 'foreign_key',
class => $self->{row_class},
returns => 'row cursor',
code => sub { my $self = shift;
return $self->rows_by_foreign_key( foreign_key => $fk, @_ ); },
foreign_key => $fk,
plural => 1,
) or return;
$self->{row_class}->add_method_docs
( Alzabo::MethodDocs->new
( name => $name,
group => 'Methods that return cursors for foreign keys',
description =>
"returns a cursor containing related rows from the " . $fk->table_to->name . " table",
spec => 'same as Alzabo::Runtime::Table->rows_where',
) );
}
# Singular method name
else
{
my $name = $self->_make_method
( type => 'foreign_key',
class => $self->{row_class},
returns => 'single row',
code => sub { my $self = shift;
return $self->rows_by_foreign_key( foreign_key => $fk, @_ ); },
foreign_key => $fk,
plural => 0,
) or return;
$self->{row_class}->add_method_docs
( run in 0.529 second using v1.01-cache-2.11-cpan-39bf76dae61 )