package Subscriber::DB; use base Subscriber; use DBI; use Carp 'croak'; use strict; use warnings; use subs qw( get_address get_anniversary get_longemail get_birthday get_street get_greeting ); use constant FIELDS => qw( _id _salutation _firstname _lastname _company _street1 _street2 _city _state _zipcode _country _phone _email _birthday _anniversary ); my $dbh = DBI->connect('DSN', 'USER', 'PASS'); my %fields = ( greeting => [qw( _salutation _firstname _lastname )], longemail => [qw( _email _firstname _lastname )], ); my %sql; my $new_record = $dbh->prepare(q{ INSERT INTO subscribers VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) }); my $check_id = $dbh->prepare(q{ SELECT 1 FROM subscribers WHERE id = ? }); sub new { my ($class, %args) = @_; $new_record->execute(@args{FIELDS()}); bless { _id => $new_record->{mysql_insertid} }, $class; } sub new_from_id { my ($class, $id) = @_; croak "non-existent id ($id)" unless $check_id->execute($id) == 1; bless { _id => $id }, $class; } AUTOLOAD { our $AUTOLOAD; my $self = $_[0]; (my $meth = $AUTOLOAD) =~ s/.*:://; my $super = "SUPER::$meth"; if ($meth =~ /^get_(\w+)/ and $fields{$1}) { my $what = $1; my @f = @{ $fields{$what} }; my $sql_f = join ", ", map substr($_, 1), @f; $sql{$what} = $dbh->prepare(qq{ SELECT $sql_f FROM subscribers WHERE id = ? }); no strict 'refs'; *$AUTOLOAD = sub { my $s = shift; $sql{$what}->execute($s->get_id); $sql{$what}->bind_columns(\@$s{@f}); $sql{$what}->fetch; $s->$super(@_); }; goto &$AUTOLOAD; } shift->$super(@_); } 1;