|
|||
Brad Oaks
Introduction to Class::DBIClass::DBI provides a convenient abstraction layer to a database.
from the module's documentation:
It not only provides a simple database to object mapping layer,
but can be used to implement several higher order database functions
(triggers, referential integrity, cascading delete etc.), at the
application level, rather than at the database.
|
|||
|
|||
Disclaimer and Sources
|
|||
|
|||
Where to get more Info
|
|||
|
|||
Reasons to use Class::DBI over regular DBI
|
|||
|
|||
Reasons NOT to use Class::DBI over regular DBI
|
|||
|
|||
Installing Class::DBI and Class::DBI::mysql
|
|||
|
|||
DonorMgmt/DBI.pm
|
|||
|
|||
DonorMgmt/Donor.pm
package DonorMgmt::Donor;
use base 'DonorMgmt::DBI';
use strict;
use Carp;$
$
sub name { &read_only; $_[0]->firstname . " " . $_[0]->lastname; }$
$
sub read_only {$
croak "Can't change the value of read-only attribute " . (caller 1)[3]$
if @_ > 1;$
}$
__PACKAGE__->set_up_table( "donor" );
__PACKAGE__->has_many( "donations", "DonorMgmt::Donation" => "donor" );
1;
continued... |
|||
|
|||
DonorMgmt/Donor.pm
package DonorMgmt::Donor;
use base 'DonorMgmt::DBI';
use strict;
use Carp;$
$
sub name { &read_only; $_[0]->firstname . " " . $_[0]->lastname; }$
$
sub read_only {$
croak "Can't change the value of read-only attribute " . (caller 1)[3]$
if @_ > 1;$
}$
__PACKAGE__->set_up_table( "donor" );
__PACKAGE__->has_many( "donations", "DonorMgmt::Donation" => "donor" );
1;
. . .
CREATE TABLE IF NOT EXISTS donor (
uid MEDIUMINT unsigned NOT NULL auto_increment,
firstname varchar(50),
lastname varchar(50),
ts_update timestamp NOT NULL,
PRIMARY KEY (uid)
)
|
|||
|
|||
DonorMgmt/Donation.pm
package DonorMgmt::Donation;
use base 'DonorMgmt::DBI';
use strict;
__PACKAGE__->set_up_table( "donation" );
__PACKAGE__->has_a( donor => "DonorMgmt::Donor" );
1;
continued... |
|||
|
|||
DonorMgmt/Donation.pm
package DonorMgmt::Donation;
use base 'DonorMgmt::DBI';
use strict;
__PACKAGE__->set_up_table( "donation" );
__PACKAGE__->has_a( donor => "DonorMgmt::Donor" );
1;
. . .
CREATE TABLE IF NOT EXISTS donation (
uid MEDIUMINT unsigned NOT NULL auto_increment,
donor MEDIUMINT unsigned, # references donor.uid
amount integer,
type ENUM('check','cash','credit','money order'),
date DATE,
notes MEDIUMTEXT,
PRIMARY KEY (uid)
)
|
|||
|
|||
DonorMgmt/Setup.pm
|
|||
|
|||
DonorMgmt/t/main.t
#!/usr/bin/perl -w
use Test::More 'no_plan';
use strict;
use_ok( "DonorMgmt::Donor" );
use_ok( "DonorMgmt::Donation" );
continued... |
|||
|
|||
DonorMgmt/t/main.t
#!/usr/bin/perl -w
use Test::More 'no_plan';
use strict;
use_ok( "DonorMgmt::Donor" );
use_ok( "DonorMgmt::Donation" );
my $donor = DonorMgmt::Donor->create({ firstname => "Brad", lastname => "Oaks" });
isa_ok( $donor, "DonorMgmt::Donor" );
continued... |
|||
|
|||
DonorMgmt/t/main.t
#!/usr/bin/perl -w
use Test::More 'no_plan';
use strict;
use_ok( "DonorMgmt::Donor" );
use_ok( "DonorMgmt::Donation" );
my $donor = DonorMgmt::Donor->create({ firstname => "Brad", lastname => "Oaks" });
isa_ok( $donor, "DonorMgmt::Donor" );
my $donation = DonorMgmt::Donation->create({ amount => 25.00 , donor => $donor });
isa_ok( $donation, "DonorMgmt::Donation" );
continued... |
|||
|
|||
DonorMgmt/t/main.t
#!/usr/bin/perl -w
use Test::More 'no_plan';
use strict;
use_ok( "DonorMgmt::Donor" );
use_ok( "DonorMgmt::Donation" );
my $donor = DonorMgmt::Donor->create({ firstname => "Brad", lastname => "Oaks" });
isa_ok( $donor, "DonorMgmt::Donor" );
my $donation = DonorMgmt::Donation->create({ amount => 25.00 , donor => $donor });
isa_ok( $donation, "DonorMgmt::Donation" );
is( $donation->donor->firstname, "Brad", "correct donor" );
is( $donation->donor->name, "Brad Oaks", "'name' method works" );
$donation->delete;
$donor->delete;
continued... |
|||
|
|||
DonorMgmt/t/main.t
#!/usr/bin/perl -w
use Test::More 'no_plan';
use strict;
use_ok( "DonorMgmt::Donor" );
use_ok( "DonorMgmt::Donation" );
my $donor = DonorMgmt::Donor->create({ firstname => "Brad", lastname => "Oaks" });
isa_ok( $donor, "DonorMgmt::Donor" );
my $donation = DonorMgmt::Donation->create({ amount => 25.00 , donor => $donor });
isa_ok( $donation, "DonorMgmt::Donation" );
is( $donation->donor->firstname, "Brad", "correct donor" );
is( $donation->donor->name, "Brad Oaks", "'name' method works" );
$donation->delete;
$donor->delete;
. . .
perl DonorMgmt/t/main.t
ok 1 - use DonorMgmt::Donor;
ok 2 - use DonorMgmt::Donation;
ok 3 - The object isa DonorMgmt::Donor
ok 4 - The object isa DonorMgmt::Donation
ok 5 - right donor
ok 6 - name method works
1..6
|
|||
|
|||
Updating a Record
my $donor = DonorMgmt::Donor->retreive(4);
$donor->lastname('Oaks, Sr.');
$donor->update;
|
|||
|
|||
Deleting Recordsindividual records
my $donor = DonorMgmt::Donor->retreive(8);
$donor->delete;
continued... |
|||
|
|||
Deleting Recordsindividual records
my $donor = DonorMgmt::Donor->retreive(8);
$donor->delete;
a range of records
DonorMgmt::Donation->delete( date => '2004-01-15', type => 'credit' );
|
|||
|
|||
Searching for Records
my @smiths = DonorMgmt::Donor->search(lastname => 'Smith');
see also Class::DBI::AbstractSearch
Class::DBI::AbstractSearch allows "arbitrarily complex searches using perl data structures, rather than SQL."
|
|||
|
|||
Other Class Methods
#!/usr/bin/perl -w
use strict;
use DonorMgmt::Donor;
use DonorMgmt::Donation;
my $type = DonorMgmt::Donor->column_type('uid');
my @allowed = DonorMgmt::Donation->enum_vals('type');
print "uid type: $type\n";
print "allowed: \n\t", join("\n\t",@allowed), "\n";
__END__
uidtype: mediumint(8) unsigned
allowed:
check
cash
credit
money order
|
|||
|
|||
Triggers
__PACKAGE__->add_trigger(after_create => \&call_after_create);
before_create (also used for deflation)
after_create
before_set_$column (also used by add_constraint)
after_set_$column (also used for inflation and by has_a)
before_update (also used for deflation and by might_have)
after_update
before_delete
after_delete
select (also used for inflation and by construct and _flesh)
|
|||
|
|||
If we're feeling lucky (with enough time)A Group ExerciseMulti Table Relationships
|
|||