X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FStorage%2FDBI.pm;h=8a0b8cc6b4bca4842080fdedef49fc7d86bd9a63;hb=d68d84f81423572b0551f1ed14b1c6da627fbaea;hp=7a7bd6046f24f94f5aae262eb4aac8d07347e8a9;hpb=84ccbc01107eeadbbac452d5368b4dd74f12ab8e;p=dbsrgits%2FDBIx-Class-Historic.git diff --git a/lib/DBIx/Class/Storage/DBI.pm b/lib/DBIx/Class/Storage/DBI.pm index 7a7bd60..8a0b8cc 100644 --- a/lib/DBIx/Class/Storage/DBI.pm +++ b/lib/DBIx/Class/Storage/DBI.pm @@ -441,14 +441,17 @@ sub connect_info { # _connect() never looks past $args[0] in this case %attrs = () } else { - %attrs = (%{ $self->_dbi_connect_attributes }, %attrs); + %attrs = ( + %{ $self->_default_dbi_connect_attributes || {} }, + %attrs, + ); } $self->_dbi_connect_info([@args, keys %attrs ? \%attrs : ()]); $self->_connect_info; } -sub _dbi_connect_attributes { +sub _default_dbi_connect_attributes { return { AutoCommit => 1 }; } @@ -598,7 +601,7 @@ sub txn_do { my $exception = $@; if(!$exception) { return $want_array ? @result : $result[0] } - if($tried++ > 0 || $self->connected) { + if($tried++ || $self->connected) { eval { $self->txn_rollback }; my $rollback_exception = $@; if($rollback_exception) { @@ -667,6 +670,22 @@ sub with_deferred_fk_checks { $sub->(); } +=head2 connected + +=over + +=item Arguments: none + +=item Return Value: 1|0 + +=back + +Verifies that the the current database handle is active and ready to execute +an SQL statement (i.e. the connection did not get stale, server is still +answering, etc.) This method is used internally by L. + +=cut + sub connected { my ($self) = @_; @@ -718,7 +737,9 @@ sub ensure_connected { =head2 dbh -Returns the dbh - a data base handle of class L. +Returns a C<$dbh> - a data base handle of class L. The returned handle +is guaranteed to be healthy by implicitly calling L, and if +necessary performing a reconnection before returning. =cut @@ -733,12 +754,19 @@ sub dbh { return $self->_dbh; } -sub _get_dbh { - my $self = shift; +=head2 last_dbh - if (not $self->_dbh) { - $self->_populate_dbh; - } +This returns the B available C<$dbh> if any, or attempts to +connect and returns the resulting handle. This method differs from +L by not validating if a preexisting handle is still healthy +via L. Make sure you take appropriate precautions +when using this method, as the C<$dbh> may be useless at this point. + +=cut + +sub last_dbh { + my $self = shift; + $self->_populate_dbh unless $self->_dbh; return $self->_dbh; } @@ -748,7 +776,7 @@ sub _sql_maker_args { return ( bindtype=>'columns', array_datatypes => 1, - limit_dialect => $self->_get_dbh, + limit_dialect => $self->last_dbh, %{$self->_sql_maker_opts} ); } @@ -797,17 +825,18 @@ sub _determine_driver { my ($self) = @_; if (not $self->_driver_determined) { - if (ref($self) eq __PACKAGE__) { - my $driver; my $started_unconnected = 0; local $self->{_in_determine_driver} = 1; + if (ref($self) eq __PACKAGE__) { + my $driver; if ($self->_dbh) { # we are connected $driver = $self->_dbh->{Driver}{Name}; } else { # try to use dsn to not require being connected, the driver may still # force a connection in _rebless to determine version ($driver) = $self->_dbi_connect_info->[0] =~ /dbi:([^:]+):/i; + $started_unconnected = 1; } my $storage_class = "DBIx::Class::Storage::DBI::${driver}"; @@ -816,7 +845,6 @@ sub _determine_driver { bless $self, $storage_class; $self->_rebless(); } - $started_unconnected = 1; } $self->_driver_determined(1); @@ -1025,10 +1053,14 @@ sub txn_begin { if($self->{transaction_depth} == 0) { $self->debugobj->txn_begin() if $self->debug; - # this isn't ->_dbh-> because - # we should reconnect on begin_work - # for AutoCommit users - $self->dbh_do(sub { $_[1]->begin_work }); + + # being here implies we have AutoCommit => 1 + # if the user is utilizing txn_do - good for + # him, otherwise we need to ensure that the + # $dbh is healthy on BEGIN + my $dbh_method = $self->{_in_dbh_do} ? '_dbh' : 'dbh'; + $self->$dbh_method->begin_work; + } elsif ($self->auto_savepoint) { $self->svp_begin; } @@ -1203,7 +1235,7 @@ sub insert { $updated_cols->{$col} = $to_insert->{$col} = $self->_sequence_fetch( 'nextval', $col_info->{sequence} || - $self->_dbh_get_autoinc_seq($self->_get_dbh, $source) + $self->_dbh_get_autoinc_seq($self->last_dbh, $source) ); } } @@ -1993,7 +2025,7 @@ Returns the database driver name. =cut -sub sqlt_type { shift->_get_dbh->{Driver}->{Name} } +sub sqlt_type { shift->last_dbh->{Driver}->{Name} } =head2 bind_attribute_by_data_type @@ -2240,7 +2272,7 @@ See L for a list of values for C<$sqlt_args>. sub deployment_statements { my ($self, $schema, $type, $version, $dir, $sqltargs) = @_; # Need to be connected to get the correct sqlt_type - $self->_get_dbh() unless $type; + $self->last_dbh() unless $type; $type ||= $self->sqlt_type; $version ||= $schema->schema_version || '1.x'; $dir ||= './'; @@ -2285,7 +2317,10 @@ sub deploy { return if $line =~ /^\s+$/; # skip whitespace only $self->_query_start($line); eval { - $self->_get_dbh->do($line); + # a previous error may invalidate $dbh - thus we need to use dbh() + # to guarantee a healthy $dbh (this is temporary until we get + # proper error handling on deploy() ) + $self->dbh->do($line); }; if ($@) { carp qq{$@ (running "${line}")}; @@ -2314,7 +2349,7 @@ Returns the datetime parser class sub datetime_parser { my $self = shift; return $self->{datetime_parser} ||= do { - $self->_get_dbh; + $self->last_dbh; $self->build_datetime_parser(@_); }; } @@ -2398,7 +2433,7 @@ sub DESTROY { DBIx::Class can do some wonderful magic with handling exceptions, disconnections, and transactions when you use C<< AutoCommit => 1 >> -combined with C for transaction support. +(the default) combined with C for transaction support. If you set C<< AutoCommit => 0 >> in your connect info, then you are always in an assumed transaction between commits, and you're telling us you'd @@ -2410,7 +2445,6 @@ cases if you choose the C<< AutoCommit => 0 >> path, just as you would be with raw DBI. - =head1 AUTHORS Matt S. Trout