Alzabo
view release on metacpan or search on metacpan
lib/Alzabo/Intro.pod view on Meta::CPAN
The method names are quite verbose, so let's redo the example using
L<C<Alzabo::MethodMaker>|Alzabo::MethodMaker>:
# Assume that the method_namer() subroutine pluralizes things as one
# would expect.
use Alzabo::MethodMaker( schema => 'movies',
all => 1,
name_maker => \&method_namer );
my $schema = Alzabo::Runtime::Schema->load_from_file( name => 'movies' );
# instantiates a row representing this person.
my $person = $schema->Person->row_by_pk( pk => 42 );
# all the rows in the credit table that have the person_id of 42.
my $cursor = $person->Credits;
print $person->name, " was in the following films:\n\n";
while (my $credit = $cursor->next)
{
my $movie = $credit->Movie;
my $job = $credit->Job;
print $movie->title, " released in ", $movie->release_year, "\n";
print ' ', $job->job, "\n";
}
=head2 Updating data
Updates are done by calling the C<update()> method on a row object:
$movie->update( title => 'Chungking Express',
year => 1994 );
If you are using C<Alzabo::MethodMaker>, the per-column accessors it
generates for row objects can be used to set a column's value:
$movie->title('Chungking Express');
Be careful with this, though, because updates are done immediately
against the RDBMS, meaning each call to a setter method issues an
C<UPDATE> query. It's much more efficient to call the C<update()>
method once with multiple values.
=head2 Deleting data
To delete a row, just call it's C<delete()> method:
$movie->delete;
=head2 Validating data
Let's assume that we've been passed a hash of values representing an
update to the location table. Here's a way of making sure that that
this update won't lead to a loop in terms of the parent/child
relationships.
sub update_location
{
my $self = shift; # this is the row object
my %data = @_;
if ( $data{parent_location_id} )
{
my $parent_location_id = $data{parent_location_id};
my $location_t = $schema->table('Location');
while ( my $location =
$location_t->row_by_pk( pk => $parent_location_id ) )
{
die "Insert into location would create loop"
if $location->select('parent_location_id') == $data{location_id};
$parent_location_id = $location->select('parent_location_id');
}
}
}
Once again, let's rewrite the code to use
L<C<Alzabo::MethodMaker>|Alzabo::MethodMaker>:
sub update_location
{
my $self = shift; # this is the row object
my %data = @_;
if ( $data{parent_location_id} )
{
my $location = $self;
while ( my $location = $location->parent )
{
die "Insert into location would create loop"
if $location->parent_location_id == $data{location_id};
}
}
}
=head2 Using SQL functions
Each subclass of Alzabo::SQLMaker is capable of exporting functions
that allow you to use all the SQL functions that your RDBMS provides.
These functions are normal Perl functions. They take as arguments
normal scalars (strings and numbers), C<Alzabo::Column> objects, or
the return value of another SQL function. They may be used to select
data via the C<select()> and C<function()> methods in both the
L<C<Alzabo::Runtime::Table>|Alzabo::Runtime::Table/"function and
select"> and
L<C<Alzabo::Runtime::Schema>|Alzabo::Runtime::Schema/"function and
select"> classes. They may also be used as part of updates, inserts,
and where clauses in any place that is valid SQL.
Examples:
use Alzabo::SQLMaker::MySQL qw(MAX NOW PI);
my $max =
$table->function( select => MAX( $table->column('budget') ),
where => [ $table->column('country'), '=', 'USA' ] );
$table->insert( values => { create_date => NOW() } );
$row->update( pi => PI() );
my $cursor =
$table->rows_where( where =>
[ $table->column('expire_date'), '<=', NOW() ] );
my $cursor =
$table->rows_where( where =>
[ LENGTH( $table->column('password') ), '<=', 5 ] );
The documentation for the Alzabo::SQLMaker subclass for your RDBMS
will contain a detailed list of all exportable functions.
=head2 Row Objects Not in the Database
Sometimes you'll want to create an object with the row object API, but
which does not represent a row in the database. See the
L<C<Alzabo::Runtime::Row> documentation|Alzabo::Runtime::Row/POTENTIAL
ROWS> for details on how these objects can be created.
( run in 0.663 second using v1.01-cache-2.11-cpan-98e64b0badf )