From: Matt S Trout Date: Tue, 21 Aug 2007 18:25:33 +0000 (+0000) Subject: Merge 'on_disconnect_do' into 'trunk' X-Git-Tag: v0.08010~80 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=5322ea52d80043df028d7b7670bc0db5aeafc8a1;hp=-c;p=dbsrgits%2FDBIx-Class.git Merge 'on_disconnect_do' into 'trunk' --- 5322ea52d80043df028d7b7670bc0db5aeafc8a1 diff --combined lib/DBIx/Class/Storage/DBI.pm index 82859f2,bc63abf..9e621ab --- a/lib/DBIx/Class/Storage/DBI.pm +++ b/lib/DBIx/Class/Storage/DBI.pm @@@ -13,12 -13,10 +13,12 @@@ use Scalar::Util qw/blessed weaken/ __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 + _conn_pid _conn_tid disable_sth_caching on_connect_do - transaction_depth unsafe _dbh_autocommit/ + on_disconnect_do transaction_depth unsafe _dbh_autocommit/ ); +__PACKAGE__->cursor_class('DBIx::Class::Storage::DBI::Cursor'); + BEGIN { package DBIC::SQL::Abstract; # Would merge upstream, but nate doesn't reply :( @@@ -313,6 -311,7 +313,6 @@@ documents DBI-specific methods and beha sub new { my $new = shift->next::method(@_); - $new->cursor("DBIx::Class::Storage::DBI::Cursor"); $new->transaction_depth(0); $new->_sql_maker_opts({}); $new->{_in_dbh_do} = 0; @@@ -347,9 -346,30 +347,30 @@@ connection-specific options =item on_connect_do - This can be set to an arrayref of literal sql statements, which will - be executed immediately after making the connection to the database - every time we [re-]connect. + Specifies things to do immediately after connecting or re-connecting to + the database. Its value may contain: + + =over + + =item an array reference + + This contains SQL statements to execute in order. Each element contains + a string or a code reference that returns a string. + + =item a code reference + + This contains some code to execute. Unlike code references within an + array reference, its return value is ignored. + + =back + + =item on_disconnect_do + + Takes arguments in the same for as L and executes them + immediately before disconnecting from the database. + + Note, this only runs if you explicitly call L on the + storage object. =item disable_sth_caching @@@ -481,9 -501,9 +502,10 @@@ sub connect_info my $last_info = $dbi_info->[-1]; if(ref $last_info eq 'HASH') { $last_info = { %$last_info }; # so delete is non-destructive - for my $storage_opt ( - qw/on_connect_do disable_sth_caching unsafe cursor_class/ - ) { - my @storage_option = - qw/on_connect_do on_disconnect_do disable_sth_caching unsafe/; ++ my @storage_option = qw( ++ on_connect_do on_disconnect_do disable_sth_caching unsafe cursor_class ++ ); + for my $storage_opt (@storage_option) { if(my $value = delete $last_info->{$storage_opt}) { $self->$storage_opt($value); } @@@ -650,6 -670,9 +672,9 @@@ sub disconnect my ($self) = @_; if( $self->connected ) { + my $connection_do = $self->on_disconnect_do; + $self->_do_connection_actions($connection_do) if ref($connection_do); + $self->_dbh->rollback unless $self->_dbh_autocommit; $self->_dbh->disconnect; $self->_dbh(undef); @@@ -668,7 -691,6 +693,7 @@@ sub connected } else { $self->_verify_pid; + return 0 if !$self->_dbh; } return ($dbh->FETCH('Active') && $dbh->ping); } @@@ -742,17 -764,42 +767,42 @@@ sub _populate_dbh } } - # if on-connect sql statements are given execute them - foreach my $sql_statement (@{$self->on_connect_do || []}) { - $self->_query_start($sql_statement); - $self->_dbh->do($sql_statement); - $self->_query_end($sql_statement); - } + my $connection_do = $self->on_connect_do; + $self->_do_connection_actions($connection_do) if ref($connection_do); $self->_conn_pid($$); $self->_conn_tid(threads->tid) if $INC{'threads.pm'}; } + sub _do_connection_actions { + my $self = shift; + my $connection_do = shift; + + if (ref $connection_do eq 'ARRAY') { + $self->_do_query($_) foreach @$connection_do; + } + elsif (ref $connection_do eq 'CODE') { + $connection_do->(); + } + + return $self; + } + + sub _do_query { + my ($self, $action) = @_; + + if (ref $action eq 'CODE') { + $action->($self); + } + else { + $self->debugobj->query_start($action) if $self->debug(); + $self->_dbh->do($action); + $self->debugobj->query_end($action) if $self->debug(); + } + + return $self; + } + sub _connect { my ($self, @info) = @_; @@@ -774,7 -821,7 +824,7 @@@ $dbh = DBI->connect(@info); } - if(!$self->unsafe) { + if($dbh && !$self->unsafe) { my $weak_self = $self; weaken($weak_self); $dbh->{HandleError} = sub { @@@ -868,40 -915,6 +918,40 @@@ sub _prep_for_execute return ($sql, \@bind); } +sub _fix_bind_params { + my ($self, @bind) = @_; + + ### Turn @bind from something like this: + ### ( [ "artist", 1 ], [ "cdid", 1, 3 ] ) + ### to this: + ### ( "'1'", "'1'", "'3'" ) + return + map { + if ( defined( $_ && $_->[1] ) ) { + map { qq{'$_'}; } @{$_}[ 1 .. $#$_ ]; + } + else { q{'NULL'}; } + } @bind; +} + +sub _query_start { + my ( $self, $sql, @bind ) = @_; + + if ( $self->debug ) { + @bind = $self->_fix_bind_params(@bind); + $self->debugobj->query_start( $sql, @bind ); + } +} + +sub _query_end { + my ( $self, $sql, @bind ) = @_; + + if ( $self->debug ) { + @bind = $self->_fix_bind_params(@bind); + $self->debugobj->query_end( $sql, @bind ); + } +} + sub _dbh_execute { my ($self, $dbh, $op, $extra_bind, $ident, $bind_attributes, @args) = @_; @@@ -911,7 -924,11 +961,7 @@@ 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; - $self->debugobj->query_start($sql, @debug_bind); - } + $self->_query_start( $sql, @$bind ); my $sth = $self->sth($sql,$op); @@@ -938,7 -955,11 +988,7 @@@ my $rv = $sth->execute(); $self->throw_exception($sth->errstr) if !$rv; - if ($self->debug) { - my @debug_bind = - map { defined ($_ && $_->[1]) ? qq{'$_->[1]'} : q{'NULL'} } @$bind; - $self->debugobj->query_end($sql, @debug_bind); - } + $self->_query_end( $sql, @$bind ); return (wantarray ? ($rv, $sth, @$bind) : $rv); } @@@ -970,7 -991,10 +1020,7 @@@ sub insert_bulk @colvalues{@$cols} = (0..$#$cols); my ($sql, @bind) = $self->sql_maker->insert($table, \%colvalues); - if ($self->debug) { - my @debug_bind = map { defined $_->[1] ? qq{$_->[1]} : q{'NULL'} } @bind; - $self->debugobj->query_start($sql, @debug_bind); - } + $self->_query_start( $sql, @bind ); my $sth = $self->sth($sql); # @bind = map { ref $_ ? ''.$_ : $_ } @bind; # stringify args @@@ -1008,7 -1032,10 +1058,7 @@@ my $rv = $sth->execute_array({ArrayTupleStatus => $tuple_status}); $self->throw_exception($sth->errstr) if !$rv; - if ($self->debug) { - my @debug_bind = map { defined $_ ? qq{`$_'} : q{`NULL'} } @bind; - $self->debugobj->query_end($sql, @debug_bind); - } + $self->_query_end( $sql, @bind ); return (wantarray ? ($rv, $sth, @bind) : $rv); } @@@ -1085,7 -1112,7 +1135,7 @@@ Handle a SQL select statement sub select { my $self = shift; my ($ident, $select, $condition, $attrs) = @_; - return $self->cursor->new($self, \@_, $attrs); + return $self->cursor_class->new($self, \@_, $attrs); } sub select_single { @@@ -1438,14 -1465,14 +1488,14 @@@ sub deploy next if($line =~ /^BEGIN TRANSACTION/m); next if($line =~ /^COMMIT/m); next if $line =~ /^\s+$/; # skip whitespace only - $self->debugobj->query_start($line) if $self->debug; + $self->_query_start($line); eval { $self->dbh->do($line); # shouldn't be using ->dbh ? }; if ($@) { warn qq{$@ (running "${line}")}; } - $self->debugobj->query_end($line) if $self->debug; + $self->_query_end($line); } } }