DBIx-VersionedSubs
view release on metacpan or search on metacpan
lib/DBIx/VersionedSubs/AutoLoad.pm view on Meta::CPAN
=head2 C<< __PACKAGE__->init_code >>
Overridden to just install the AUTOLOAD handler.
=cut
sub init_code {
my ($package) = @_;
no strict 'refs';
if (! defined &{"$package\::AUTOLOAD"}) {
*{"$package\::AUTOLOAD"} = sub {
use vars qw($AUTOLOAD);
if ($AUTOLOAD !~ /::(\w+)$/) {
croak "Undecipherable subroutine '$AUTOLOAD' called";
};
my $name = $1;
$package->install_and_invoke($name,@_);
};
} else {
carp "$package->init_code called, but there already is an AUTOLOAD handler installed.";
};
my $begin = $package->retrieve_code('BEGIN');
if (defined $begin) {
eval "{ $begin }";
carp "$package\::BEGIN: $@" if $@
};
};
=head2 C<< __PACKAGE__->install_and_invoke NAME, ARGS >>
Loads code from the database, installs it
into the namespace and immediately calls it
with the remaining arguments via C<< goto &code; >>.
If no row with a matching name exists, an
error is raised.
=cut
sub install_and_invoke {
my ($package,$name) = splice @_,0,2;
my $code = $package->load_code($name);
if (defined $code) {
goto &$code;
} else {
croak "Undefined subroutine $package\::$name called";
};
};
=head2 C<< __PACKAGE__->update_code >>
Overridden to do lazy updates. It wipes all code that
is out of date from the namespace and lets the AUTOLOAD
handler sort out the reloading.
=cut
sub update_code {
my ($package) = @_;
my $version = $package->code_version || 0;
my $sth = $package->dbh->prepare_cached(sprintf <<'SQL', $package->code_history);
SELECT distinct name,version FROM %s
WHERE version > ?
ORDER BY version DESC
SQL
$sth->execute($version);
# If update is needed, wipe the touched elements:
my %seen;
my $current_version = $version || 0;
while (my ($name,$new_version) = $sth->fetchrow()) {
next if $seen{$name}++;
$current_version = $current_version < $new_version
? $new_version
: $current_version;
delete $package->code_source->{$name};
# This manual AUTOLOAD is less than ideal
no strict 'refs';
no warnings 'redefine';
*{"$package\::$name"} = sub {
local *AUTOLOAD = "$package\::$name";
goto &{"$package\::AUTOLOAD"};
};
# = sub { $package->install_and_invoke( $name, @_ ); };
}
$package->code_version($current_version);
};
=head2 C<< __PACKAGE__->load_code NAME >>
Retrieves the code for the subroutine C<NAME>
from the database and calls
C<< __PACKAGE__->install_code $name,$code >>
to install it.
=cut
sub load_code {
my ($package,$name) = @_;
my $code = $package->retrieve_code($name);
if (! defined $code) {
# let caller decide whether to croak or to ignore
return;
};
$package->create_sub($name,$code);
};
=head2 C<< __PACKAGE__->retrieve_code NAME >>
Retrieves the code for the subroutine C<NAME>
from the database and returns it as a string.
( run in 0.537 second using v1.01-cache-2.11-cpan-39bf76dae61 )