To start refactoring my application, I started by refactoring BeerDB
and wrote it up. The updated pod is on the wiki. The new section is
below. I would appreciate comments or suggestions.
A couple of questions though.
I note from the documentation in Maypole::Model::CDBI::Plain that
(for the BeerDB) we're asked to create our model classes in
BeerDB::Beer, BeerDB::Style etc. What If I don't want to do that?
How do I configure CDBI::Plain/Maypole to look for say the classes qw/
Beer Beer::Brewery Beer::Style/ etc?
My brief experiment showed me that the untaint statements don't work
if they're moved into the model classes, so for example the statement
BeerDB::Brewery->untaint_columns( printable => [qw/name notes url/]);
in Brewery.pm doesn't work (the error message is something like:
BeerDB::Beer can't load BeerDB::Brewery: Can't locate object method
"untaint_columns" via package "BeerDB::Brewery" at /usr/local/src/
beer/lib//BeerDB/Brewery.pm line 6.\nCompilation failed in require
at /Library/Perl/5.8.6/Class/DBI.pm line 1208. at /Library/Perl/5.8.6/
Class/DBI/Relationship/HasA.pm line 22\nCompilation failed in require
at /usr/local/src/beer/lib//BeerDB.pm line 3.\nBEGIN failed--
compilation aborted at /usr/local/src/beer/lib//BeerDB.pm line 3.
\nCompilation failed in require at (eval 19) line 3.\n
I've kept it in BeerDB.pm for now, but it seems to me that this stuff
would be better with the model than the driver. Is there an easy way
to fix this, or have I misunderstood?
Cheers
kd
^-^-^-^ Updated docs
=head1 Structuring your code.
At this point, you should have a working Beer database. In about 20
lines of code.
The standard BeerDB contains four tables: beer, brewery, pub and
style. Each of these tables has an associated class which are
BeerDB::Beer, BeerDB::Brewery, BeerDB::Pub, BeerDB::Style. Although
this is a simple database, and Maypole works well, out of the box
with the BeerDB, it's worth separating out each class into separate
files. Initially, this process is a bit of a fiddle, but it results
in much more maintainable code later. Here's how to do it with the
standard beeerdb.
BeerDB.pm lives in /usr/local/src/beer/lib, we can create a directory
called BeerDB, and then create the following files:
=over
=item DBI.pm
=item Beer.pm
=item Brewery.pm
=item Handpump.pm
=item Pub.pm
=item Style.pm
=back
=head2 The database driver code code
=over
=item DBI.pm
package BeerDB::DBI;
use base 'Class::DBI';
BeerDB::DBI->connection('dbi:mysql:beer', 'root', '');
1;
=item Beer.pm
package BeerDB::Beer;
use base 'BeerDB::DBI';
BeerDB::Beer->table('beer');
BeerDB::Beer->columns(All => qw/brewery style name url score price/);
BeerDB::Beer->has_a(brewery => 'BeerDB::Brewery');
BeerDB::Beer->has_a(style => 'BeerDB::Style');
BeerDB::Beer->has_many(beers => [BeerDB::Handpump => 'beer']);
BeerDB::Beer->has_many(pubs => [BeerDB::Handpump => 'pub']);
1;
=item Brewery.pm
package BeerDB::Brewery;
use base 'BeerDB::DBI';
BeerDB::Brewery->table('brewery');
BeerDB::Brewery->columns(All => qw/name url notes/);
BeerDB::Brewery->has_many(beers => "BeerDB::Beer");
1;
=item Handpump.pm
package BeerDB::Handpump;
use base 'BeerDB::DBI';
BeerDB::Handpump->table('handpump');
BeerDB::Handpump->columns(All => qw/beer pub/);
BeerDB::Handpump->has_a(beer => 'BeerDB::Beer');
BeerDB::Handpump->has_a(pub => 'BeerDB::Pub');
1;
=item Pub.pm
package BeerDB::Pub;
use base 'BeerDB::DBI';
BeerDB::Pub->table('pub');
BeerDB::Pub->columns(All => qw/name url notes/);
1;
=item Style.pm
package BeerDB::Style;
use base 'BeerDB::DBI';
BeerDB::Style->table('style');
BeerDB::Style->columns(All => qw/name notes/);
BeerDB::Style->has_many(beers => 'BeerDB::Beer');
1;
=back
So that's quite a lot of code (for a trivial Maypole application).
Now we need to wrap it all up in a driver class fro Maypole: this
lives (according to my scheme) in /usr/local/src/beer/lib
=over
=item BeerDB.pm
package BeerDB;
use base 'Maypole::Application';
use BeerDB::Beer;
use BeerDB::Brewery;
use BeerDB::Handpump;
use BeerDB::Pub;
use BeerDB::Style;
BeerDB->config->model('Maypole::Model::CDBI::Plain');
BeerDB->setup([qw/BeerDB::Beer BeerDB::Brewery BeerDB::Handpump
BeerDB::Pub Beer
DB::Style/]);
BeerDB->config->uri_base("http://localhost/beer");
BeerDB->config->template_root("/usr/local/src/beer/templates/");
BeerDB->config->rows_per_page(10);
BeerDB->config->display_tables([qw[beer brewery pub style]]);
BeerDB::Beer->untaint_columns(
printable => [qw/abv name price notes/],
integer => [qw/style brewery score/],
date => [ qw/date/],
);
BeerDB::Brewery->untaint_columns( printable => [qw/name notes url/]);
BeerDB::Style->untaint_columns( printable => [qw/name notes/] );
1;
=back
-------------------------------------------------------
SF.Net email is sponsored by:
Tame your development challenges with Apache's Geronimo App Server. Download
it for free - -and be entered to win a 42" plasma tv or your very own
Sony(tm)PSP. Click here to play: http://sourceforge.net/geronimo.php
_______________________________________________
Maypole-users mailing list
Maypole-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/maypole-users