9 Do not use
this class directly.
10 It will automatically be used by the
Bio::EnsEMBL::Hive::DBSQL::DBConnection class.
14 This class extends DBI::st via containment, intercepts possible "gone away" errors,
15 automatically reconnects and re-prepares the statement. It should take much less resources
16 than pinging or worrying
about disconnecting before and reconnecting after external processes
17 whose duration we do not control.
21 Copyright [1999-2015] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute
22 Copyright [2016-2024] EMBL-European Bioinformatics Institute
24 Licensed under the Apache License,
Version 2.0 (the "License"); you may not use this file except in compliance with the License.
25 You may obtain a copy of the License at
29 Unless required by applicable law or agreed to in writing, software distributed under the License
30 is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31 See the License for the specific language governing permissions and limitations under the License.
35 Please subscribe to the
Hive mailing list: http:
50 my ($class, $dbc, $sql, $attr) = @_;
54 $dbi_sth = $dbc->protected_prepare( $sql, $attr );
57 throw(
"FAILED_SQL(".$dbc->dbname.
"): " . join(
' ', $sql,
stringify($attr)) .
"\nGot: ".$@.
"\n" );
60 my $self = bless {}, $class;
63 # $self will remain empty whereas $real_self will actually have all the data
64 # Its only purpose is to offer a hash-reference on which perl allows
65 # calling hash accessors, e.g. $sth->{Active}
66 tie %$self,
'DBIstHashProxy', $dbi_sth, $real_self;
72 $self->dbi_sth( $dbi_sth );
77 ## Since $self is a tied hash and doesn't have any data,
78 ## real_self returns the real underlying hash and is used
79 ## in most of the function calls below
83 return (tied %$self)->[1];
89 $self = $self->real_self;
90 $self->{
'_dbc'} = shift
if(@_);
91 return $self->{
'_dbc'};
97 $self = $self->real_self;
98 $self->{
'_sql'} = shift
if(@_);
99 return $self->{
'_sql'};
105 $self = $self->real_self;
106 $self->{
'_attr'} = shift
if(@_);
107 return $self->{
'_attr'};
111 ## dbi_sth is the exception since it has to be in the first position
112 ## of the tied structure for Tie::ExtraHash to work.
115 my $self_array = tied %$self;
116 $self_array->[0] = shift
if(@_);
117 return $self_array->[0];
124 $AUTOLOAD=~/^.+::(\w+)$/;
125 my $method_name = $1;
127 # warn "[AUTOLOAD instantiating '$method_name'] ($AUTOLOAD)\n";
130 # warn "[AUTOLOADed method '$method_name' running] ($AUTOLOAD)\n";
133 my $dbi_sth = $self->dbi_sth() or
throw(
"dbi_sth returns false" );
134 my $wantarray = wantarray;
139 @retval = $dbi_sth->$method_name( @_ );
141 $retval[0] = $dbi_sth->$method_name( @_ );
146 my $dbc = $self->dbc();
149 my $sql = $self->sql();
150 my $attr = $self->attr();
152 warn
"trying to reconnect...";
155 warn
"trying to re-prepare [$sql". ($attr ? (
', '.stringify($attr)) :
'') .
"]...";
156 # NOTE: parameters set via the hash interface of $sth will be lost
157 $dbi_sth = $dbc->db_handle->prepare( $sql, $attr );
158 $self->dbi_sth( $dbi_sth );
160 warn
"trying to re-$method_name...";
162 @retval = $dbi_sth->$method_name( @_ );
164 $retval[0] = $dbi_sth->$method_name( @_ );
171 return $wantarray ? @retval : $retval[0];
177 sub DESTROY { # note AUTOLOAD/DESTROY interdependence!
180 my $dbc = $self->dbc;
183 my $sql = $self->sql;
186 $self->dbi_sth( undef ); # make sure it goes through its own DESTROY *now*
189 # Forgetting $dbi_sth gets it out of scope, which decrements $db_handle->{Kids} .
190 # If as the result the $db_handle has no more Kids, we can safely trigger the disconnect if it was requested.
194 && $dbc->disconnect_when_inactive()
196 && ( $dbc->db_handle->{Kids} == 0 ) ) {
198 if ( $dbc->disconnect_if_idle() ) {
199 warn(
"Problem disconnect $self around sql = $sql\n");
205 ## Just like AUTOLOAD for function calls, we need to redirect
206 ## the HASH methods to the DBI::st instance
207 ## We can conveniently use Tie::ExtraHash, which maps the methods
208 ## to the first element of the array, allowing us to store
209 ## other things in the other elements.
211 package DBIstHashProxy;
214 use base (
'Tie::ExtraHash');
216 # Pass the target hash as the first argument