use IO::File;
use Scalar::Util 'blessed';
-__PACKAGE__->mk_group_accessors(
- 'simple' =>
- qw/_connect_info _dbh _sql_maker _sql_maker_opts _conn_pid _conn_tid
- disable_sth_caching cursor on_connect_do transaction_depth/
+__PACKAGE__->mk_group_accessors('simple' =>
+ qw/_connect_info _dbi_connect_info _dbh _sql_maker _sql_maker_opts
+ _conn_pid _conn_tid disable_sth_caching cursor on_connect_do
+ transaction_depth/
);
BEGIN {
# the new set of options
$self->_sql_maker(undef);
$self->_sql_maker_opts({});
+ $self->_connect_info([@$info_arg]); # copy for _connect_info
- my $info = [ @$info_arg ]; # copy because we can alter it
- my $last_info = $info->[-1];
+ my $dbi_info = [@$info_arg]; # copy for _dbi_connect_info
+
+ my $last_info = $dbi_info->[-1];
if(ref $last_info eq 'HASH') {
for my $storage_opt (qw/on_connect_do disable_sth_caching/) {
if(my $value = delete $last_info->{$storage_opt}) {
}
# Get rid of any trailing empty hashref
- pop(@$info) if !keys %$last_info;
- }
-
- if(ref $info->[0] ne 'CODE') {
- # Extend to 3 arguments with undefs, if necessary
- while(scalar(@$info) < 3) { push(@$info, undef) }
-
- # Complain if 4th argument is defined and is not a HASH
- if(defined $info->[3] && ref $info->[3] ne 'HASH') {
- warn "4th argument of DBI connect info is defined "
- . " but is not a hashref!";
- }
-
- # Set AutoCommit to 1 if not specified manually
- else {
- $info->[3] ||= {};
- if(!defined $info->[3]->{AutoCommit}) {
- $info->[3]->{AutoCommit} = 1;
- }
- }
+ pop(@$dbi_info) if !keys %$last_info;
}
+ $self->_dbi_connect_info($dbi_info);
- $self->_connect_info($info);
+ $self->_connect_info;
}
=head2 on_connect_do
sub _populate_dbh {
my ($self) = @_;
- my @info = @{$self->_connect_info || []};
+ my @info = @{$self->_dbi_connect_info || []};
$self->_dbh($self->_connect(@info));
# Always set the transaction depth on connect, since
$DBI::connect_via = $old_connect_via if $old_connect_via;
- if (!$dbh || $@) {
- $self->throw_exception("DBI Connection failed: " . ($@ || $DBI::errstr));
- }
+ $self->throw_exception("DBI Connection failed: " . ($@||$DBI::errstr))
+ if !$dbh || $@;
$dbh;
}
# easier to override in NoBindVars without duping the rest. It takes up
# all of _execute's args, and emits $sql, @bind.
sub _prep_for_execute {
- my ($self, $op, $extra_bind, $ident, @args) = @_;
+ my ($self, $op, $extra_bind, $ident, $args) = @_;
- my ($sql, @bind) = $self->sql_maker->$op($ident, @args);
+ my ($sql, @bind) = $self->sql_maker->$op($ident, @$args);
unshift(@bind,
map { ref $_ eq 'ARRAY' ? $_ : [ '!!dummy', $_ ] } @$extra_bind)
if $extra_bind;
- @bind = map { ref $_ ? ''.$_ : $_ } @bind; # stringify args
- return ($sql, @bind);
+ return ($sql, \@bind);
}
sub _execute {
if( blessed($ident) && $ident->isa("DBIx::Class::ResultSource") ) {
$ident = $ident->from();
}
-
- my ($sql, @bind) = $self->sql_maker->$op($ident, @args);
- unshift(@bind,
- map { ref $_ eq 'ARRAY' ? $_ : [ '!!dummy', $_ ] } @$extra_bind)
- if $extra_bind;
+
+ my ($sql, $bind) = $self->_prep_for_execute($op, $extra_bind, $ident, \@args);
+
if ($self->debug) {
my @debug_bind =
- map { defined ($_ && $_->[1]) ? qq{'$_->[1]'} : q{'NULL'} } @bind;
+ map { defined ($_ && $_->[1]) ? qq{'$_->[1]'} : q{'NULL'} } @$bind;
$self->debugobj->query_start($sql, @debug_bind);
}
- my ($rv, $sth);
- RETRY: while (1) {
- $sth = eval { $self->sth($sql,$op) };
+ my $sth = eval { $self->sth($sql,$op) };
+ $self->throw_exception("no sth generated via sql ($@): $sql") if $@;
- if (!$sth || $@) {
- $self->throw_exception(
- 'no sth generated via sql (' . ($@ || $self->_dbh->errstr) . "): $sql"
- );
- }
+ my $rv = eval {
+ my $placeholder_index = 1;
- if ($sth) {
- my $time = time();
- $rv = eval {
- my $placeholder_index = 1;
+ foreach my $bound (@$bind) {
+ my $attributes = {};
+ my($column_name, @data) = @$bound;
- foreach my $bound (@bind) {
-
- my $attributes = {};
- my($column_name, @data) = @$bound;
-
- if( $bind_attributes ) {
- $attributes = $bind_attributes->{$column_name}
- if defined $bind_attributes->{$column_name};
- }
+ if ($bind_attributes) {
+ $attributes = $bind_attributes->{$column_name}
+ if defined $bind_attributes->{$column_name};
+ }
- foreach my $data (@data)
- {
- $data = ref $data ? ''.$data : $data; # stringify args
+ foreach my $data (@data) {
+ $data = ref $data ? ''.$data : $data; # stringify args
- $sth->bind_param($placeholder_index, $data, $attributes);
- $placeholder_index++;
- }
- }
- $sth->execute();
- };
-
- if ($@ || !$rv) {
- $self->throw_exception("Error executing '$sql': ".($@ || $sth->errstr))
- if $self->connected;
- $self->_populate_dbh;
- } else {
- last RETRY;
+ $sth->bind_param($placeholder_index, $data, $attributes);
+ $placeholder_index++;
}
- } else {
- $self->throw_exception("'$sql' did not generate a statement.");
}
- } # While(1) to retry if disconencted
+ $sth->execute();
+ };
+
+ $self->throw_exception("Error executing '$sql': " . ($@ || $sth->errstr))
+ if $@ || !$rv;
if ($self->debug) {
my @debug_bind =
- map { defined ($_ && $_->[1]) ? qq{'$_->[1]'} : q{'NULL'} } @bind;
+ map { defined ($_ && $_->[1]) ? qq{'$_->[1]'} : q{'NULL'} } @$bind;
$self->debugobj->query_end($sql, @debug_bind);
}
- return (wantarray ? ($rv, $sth, @bind) : $rv);
+ return (wantarray ? ($rv, $sth, @$bind) : $rv);
}
sub insert {
my $ident = $source->from;
my $bind_attributes = $self->source_bind_attributes($source);
+ eval { $self->_execute('insert' => [], $source, $bind_attributes, $to_insert) };
$self->throw_exception(
"Couldn't insert ".join(', ',
map "$_ => $to_insert->{$_}", keys %$to_insert
- )." into ${ident}"
- ) unless ($self->_execute('insert' => [], $source, $bind_attributes, $to_insert));
+ )." into ${ident}: $@"
+ ) if $@;
+
return $to_insert;
}
? $dbh->prepare($sql)
: $dbh->prepare_cached($sql, {}, 3);
- $self->throw_exception(
- 'no sth generated via sql (' . ($@ || $dbh->errstr) . "): $sql"
- ) if !$sth;
+ # XXX You would think RaiseError would make this impossible,
+ # but apparently that's not true :(
+ die $dbh->errstr if !$sth;
$sth;
}
next if($_ =~ /^COMMIT/m);
next if $_ =~ /^\s+$/; # skip whitespace only
$self->debugobj->query_start($_) if $self->debug;
- $self->dbh->do($_) or warn "SQL was:\n $_"; # XXX exceptions?
+ $self->dbh->do($_); # shouldn't be using ->dbh ?
$self->debugobj->query_end($_) if $self->debug;
}
}