1 package Bio
::DB
::GFF
::Adaptor
::dbi
::caching_handle
;
6 use base
qw(Bio::Root::Root);
10 Bio::DB::GFF::Adaptor::dbi::caching_handle -- Cache for database handles
14 use Bio::DB::GFF::Adaptor::dbi::caching_handle;
15 $db = Bio::DB::GFF::Adaptor::dbi::caching_handle->new('dbi:mysql:test');
16 $sth = $db->prepare('select * from foo');
17 @h = $sth->fetch_rowarray;
22 This module handles a pool of database handles. It was motivated by
23 the MYSQL driver's {mysql_use_result} attribute, which dramatically
24 improves query speed and memory usage, but forbids additional query
25 statements from being evaluated while an existing one is in use.
27 This module is a plug-in replacement for vanilla DBI. It
28 automatically activates the {mysql_use_result} attribute for the mysql
29 driver, but avoids problems with multiple active statement handlers by
30 creating new database handles as needed.
34 The object constructor is
35 Bio::DB::GFF::Adaptor::dbi::caching_handle-E<gt>new(). This is called
36 like DBI-E<gt>connect() and takes the same arguments. The returned object
37 looks and acts like a conventional database handle.
39 In addition to all the standard DBI handle methods, this package adds
45 Usage : $string = $db->dbi_quote($sql,@args)
46 Function: perform bind variable substitution
47 Returns : query string
48 Args : the query string and bind arguments
51 This method replaces the bind variable "?" in a SQL statement with
52 appropriately quoted bind arguments. It is used internally to handle
53 drivers that don't support argument binding.
58 Usage : $sth = $db->do_query($query,@args)
59 Function: perform a DBI query
60 Returns : a statement handler
61 Args : query string and list of bind arguments
64 This method performs a DBI prepare() and execute(), returning a
65 statement handle. You will typically call fetch() of fetchrow_array()
66 on the statement handle. The parsed statement handle is cached for
72 Usage : $debug = $db->debug([$debug])
73 Function: activate debugging messages
74 Returns : current state of flag
75 Args : optional new setting of flag
88 $self->dbh || $self->throw("Can't connect to database: " . DBI
->errstr);
93 my($pack,$func_name) = $AUTOLOAD=~/(.+)::([^:]+)$/;
94 return if $func_name eq 'DESTROY';
95 my $self = shift or return DBI
->$func_name(@_);
96 $self->dbh->$func_name(@_);
101 my $d = $self->{debug
};
102 $self->{debug
} = shift if @_;
110 # find a non-busy dbh
111 my $dbh = $self->dbh || $self->throw("Can't connect to database: " . DBI
->errstr);
113 warn "Using prepare_cache\n" if $self->debug;
114 my $sth = $dbh->prepare_cached($query, {}, 3) || $self->throw("Couldn't prepare query $query:\n ".DBI
->errstr."\n");
120 my ($query,@args) = @_;
121 warn $self->dbi_quote($query,@args),"\n" if $self->debug;
122 my $sth = $self->prepare($query);
123 $sth->execute(@args) || $self->throw("Couldn't execute query $query:\n ".DBI
->errstr."\n");
129 foreach (@
{$self->{dbh
}}) {
130 return $_ if $_->inuse == 0;
132 # if we get here, we must create a new one
133 warn "(Re)connecting to database\n" if $self->debug;
134 my $dbh = DBI
->connect(@
{$self->{args
}}) or return;
136 $dbh->{PrintError
} = 0;
138 # for Oracle - to retrieve LOBs, need to define the length (Jul 15, 2002)
139 $dbh->{LongReadLen
} = 100*65535;
140 $dbh->{LongTruncOk
} = 0;
141 $dbh->{mysql_auto_reconnect
} = 1;
143 my $wrapper = Bio
::DB
::GFF
::Adaptor
::dbi
::faux_dbh
->new($dbh);
144 push @
{$self->{dbh
}},$wrapper;
148 # The clone method should only be called in child processes after a fork().
149 # It does two things: (1) it sets the "real" dbh's InactiveDestroy to 1,
150 # thereby preventing the database connection from being destroyed in
151 # the parent when the dbh's destructor is called; (2) it replaces the
152 # "real" dbh with the result of dbh->clone(), so that we now have an
153 # independent handle.
156 foreach (@
{$self->{dbh
}}) { $_->clone };
162 Usage : $value = $db->attribute(AttributeName , [$newvalue])
163 Function: get/set DBI::db handle attribute
164 Returns : current state of the attribute
165 Args : name of the attribute and optional new setting of attribute
168 Under Bio::DB::GFF::Adaptor::dbi::caching_handle the DBI::db
169 attributes that are usually set using hashref calls are unavailable.
170 Use attribute() instead. For example, instead of:
172 $dbh->{AutoCommit} = 0;
176 $dbh->attribute(AutoCommit=>0);
182 my $dbh = $self->dbh->{dbh
};
183 return $dbh->{$_[0]} = $_[1] if @_ == 2;
184 return $dbh->{$_[0]} if @_ == 1;
190 $_ && $_->disconnect foreach @
{$self->{dbh
}};
196 my ($query,@args) = @_;
197 my $dbh = $self->dbh;
198 $query =~ s/\?/$dbh->quote(shift @args)/eg;
202 package Bio
::DB
::GFF
::Adaptor
::dbi
::faux_dbh
;
203 use vars
'$AUTOLOAD';
208 bless {dbh
=>$dbh},$class;
213 my $sth = $self->{dbh
}->prepare(@_) or return;
214 $sth->{mysql_use_result
} = 1 if $self->{dbh
}->{Driver
}{Name
} eq 'mysql';
218 sub prepare_delayed
{
220 my $sth = $self->{dbh
}->prepare(@_) or return;
225 shift->{dbh
}->{ActiveKids
};
228 # The clone method should only be called in child processes after a fork().
229 # It does two things: (1) it sets the "real" dbh's InactiveDestroy to 1,
230 # thereby preventing the database connection from being destroyed in
231 # the parent when the dbh's destructor is called; (2) it replaces the
232 # "real" dbh with the result of dbh->clone(), so that we now have an
233 # independent handle.
236 $self->{dbh
}{InactiveDestroy
} = 1;
237 $self->{dbh
} = $self->{dbh
}->clone;
243 my($pack,$func_name) = $AUTOLOAD=~/(.+)::([^:]+)$/;
244 return if $func_name eq 'DESTROY';
246 if( defined $self->{dbh
} ) {
247 $self->{dbh
}->$func_name(@_);
257 Report to the author.
261 L<DBI>, L<Bio::DB::GFF>, L<bioperl>
265 Lincoln Stein E<lt>lstein@cshl.orgE<gt>.
267 Copyright (c) 2001 Cold Spring Harbor Laboratory.
269 This library is free software; you can redistribute it and/or modify
270 it under the same terms as Perl itself.