Subject: | SimpleDBI::SubProcess may not include all required modules |
Because of the way SubProcess is launched on Linux all modules needed
may not get loaded. There may be other modules that tickle this bug,
but I ran into it with Math::BigInt.
Attached are a simple script to reproduce the problem and a patch file.
The patch file contains a few trivial extras.
checking if ( exists $data->{'PLACEHOLDERS'} and defined
$data->{'PLACEHOLDERS'}) is just redundant. It is enough to just check
if defined. So I removed about a half dozen instances.
I also added a comment at the bottom of the files so emacs will respect
your indentation style regardless of the users settings. This just
makes it easier when people like me want to submit patches. ;-)
Subject: | dbi-simple.pl |
#!/usr/bin/perl
use warnings;
use strict;
# sub POE::Component::SimpleDBI::DEBUG { 1 }
sub DB_NAME () { "test" }
sub DB_USER () { "user" }
sub DB_PASS () { "password" }
use POE;
use POE::Component::SimpleDBI ();
use Data::Dumper;
use Math::BigInt;
# Create the session that will do transactions.
POE::Session->create(
inline_states => {
_start => \&start_session,
DB_connected => \&DB_connected,
simple_res => \&simple_res,
}
);
$poe_kernel->run();
exit 0;
sub start_session {
my ($kernel, $heap) = @_[KERNEL, HEAP];
my ($host, $port, $name) = qw(localhost 3306 SimpleDBI);
warn "connect... $name\n";
POE::Component::SimpleDBI->new( $name );
$_[KERNEL]->post( $name, 'CONNECT',
DSN => "DBI:mysql:database=test;host=$host;port=$port",
USERNAME => DB_USER,
PASSWORD => DB_PASS,
EVENT => 'DB_connected',
NOW => 1,
BAGGAGE => ["$name"],
);
}
sub DB_connected {
if ($_[ARG0]->{ERROR}) {
warn 'DBI : connection failed';
} else{
my $name = 'SimpleDBI';
$_[KERNEL]->post( 'SimpleDBI', 'DO',
SQL => 'CREATE TABLE IF NOT EXISTS `test`.`my_bigint` (`my_int` INTEGER NOT NULL) ENGINE = MyISAM',
PREPARE_CACHED => 0,
EVENT => 'simple_res',
);
my $val = int(rand(42));
my $bi_val = Math::BigInt->new("-$val");
warn "inserting $val and BigInt($bi_val)\n";
$_[KERNEL]->post( 'SimpleDBI', 'DO',
SQL => 'INSERT INTO `test`.`my_bigint` (`my_int`) VALUES (?)',
PREPARE_CACHED => 0,
PLACEHOLDERS => [$val],
EVENT => 'simple_res',
);
$_[KERNEL]->post( 'SimpleDBI', 'DO',
SQL => 'INSERT INTO `test`.`my_bigint` (`my_int`) VALUES (?)',
PREPARE_CACHED => 0,
PLACEHOLDERS => [$bi_val],
EVENT => 'simple_res',
);
$_[KERNEL]->post( 'SimpleDBI', 'shutdown');
}
}
sub simple_res {
if ($_[ARG0]->{ERROR}) {
warn "SimpleDBI : ",$_[ARG0]->{ERROR},"\n";
warn "SimpleDBI : ",$_[ARG0]->{SQL},"\n";
} else {
}
}
Subject: | bigint.patch |
Index: lib/POE/Component/SimpleDBI.pm
===================================================================
--- lib/POE/Component/SimpleDBI.pm (revision 4689)
+++ lib/POE/Component/SimpleDBI.pm (working copy)
@@ -4,7 +4,7 @@
# Initialize our version
use vars qw( $VERSION );
-$VERSION = '1.27';
+$VERSION = '1.27_01';
# Import what we need from the POE namespace
use POE; # For the constants
@@ -1065,10 +1065,25 @@
'StderrFilter' => POE::Filter::Line->new(), # Plain ol' error lines
);
} else {
+ my @mod_list = ();
+ # It might be necessary to add other modules to this
+ # list at some point. The issue is that Math::BigInt
+ # can get serialized on this side of the pipe, but the
+ # SubProcess fails because the BigInt module was never
+ # loaded.
+ for (keys %INC) {
+ if (m/^math\/bigint/i) {
+ my $mod = $_;
+ $mod =~ s/\//::/g;
+ $mod =~ s/.pm$//;
+ push @mod_list, '-M'.$mod;
+ }
+ }
+
# Set up the SubProcess we communicate with
$_[HEAP]->{'WHEEL'} = POE::Wheel::Run->new(
# What we will run in the separate process
- 'Program' => "$^X -MPOE::Component::SimpleDBI::SubProcess -e 'POE::Component::SimpleDBI::SubProcess::main()'",
+ 'Program' => "$^X @mod_list -MPOE::Component::SimpleDBI::SubProcess -e 'POE::Component::SimpleDBI::SubProcess::main()'",
# Kill off existing FD's
'CloseOnCall' => 1,
@@ -2007,3 +2022,11 @@
it under the same terms as Perl itself.
=cut
+
+
+# Local Variables: ***
+# mode:CPerl ***
+# cperl-indent-level:8 ***
+# perl-indent-level:8 ***
+# indent-tabs-mode: t ***
+# End: ***
Index: lib/POE/Component/SimpleDBI/SubProcess.pm
===================================================================
--- lib/POE/Component/SimpleDBI/SubProcess.pm (revision 4689)
+++ lib/POE/Component/SimpleDBI/SubProcess.pm (working copy)
@@ -4,7 +4,7 @@
# Initialize our version
use vars qw( $VERSION );
-$VERSION = '1.27';
+$VERSION = '1.27_01';
# Use Error.pm's try/catch semantics
use Error qw( :try );
@@ -300,7 +300,7 @@
# Execute the query
try {
# Put placeholders?
- if ( exists $data->{'PLACEHOLDERS'} and defined $data->{'PLACEHOLDERS'} ) {
+ if ( defined $data->{'PLACEHOLDERS'} ) {
$sth->execute( @{ $data->{'PLACEHOLDERS'} } );
} else {
$sth->execute();
@@ -398,7 +398,7 @@
# Execute the query
try {
# Put placeholders?
- if ( exists $data->{'PLACEHOLDERS'} and defined $data->{'PLACEHOLDERS'} ) {
+ if ( defined $data->{'PLACEHOLDERS'} ) {
$sth->execute( @{ $data->{'PLACEHOLDERS'} } );
} else {
$sth->execute();
@@ -478,7 +478,7 @@
# Execute the query
try {
# Put placeholders?
- if ( exists $data->{'PLACEHOLDERS'} and defined $data->{'PLACEHOLDERS'} ) {
+ if ( defined $data->{'PLACEHOLDERS'} ) {
$rows_affected = $sth->execute( @{ $data->{'PLACEHOLDERS'} } );
} else {
$rows_affected = $sth->execute();
@@ -494,7 +494,15 @@
};
}
} catch Error with {
- die $sth->errstr;
+ if ($sth->errstr) {
+ die $sth->errstr;
+ } else {
+ # If something other than DBI fails
+ # errstr won't be set. You can get
+ # this if, for example, we need a
+ # module that hasn't been loaded.
+ die "NON DBI ERROR : $@";
+ }
};
}
} catch Error with {
@@ -566,7 +574,7 @@
} else {
# actually execute it!
try {
- if ( exists $data->{'PLACEHOLDERS'} and defined $data->{'PLACEHOLDERS'} and defined $data->{'PLACEHOLDERS'}->[ $idx ] ) {
+ if ( defined $data->{'PLACEHOLDERS'} and defined $data->{'PLACEHOLDERS'}->[ $idx ] ) {
$sth->execute( @{ $data->{'PLACEHOLDERS'}->[ $idx ] } );
} else {
$sth->execute;
@@ -706,3 +714,11 @@
it under the same terms as Perl itself.
=cut
+
+
+# Local Variables: ***
+# mode:CPerl ***
+# cperl-indent-level:8 ***
+# perl-indent-level:8 ***
+# indent-tabs-mode: t ***
+# End: ***