Commit 0b44297b authored by Leo Gordon's avatar Leo Gordon
Browse files

dbh(): centrally managed db_handle for universal building blocks

parent 269dce3f
......@@ -85,6 +85,9 @@
package Bio::EnsEMBL::Hive::Process;
use strict;
use warnings;
use DBI;
use Bio::EnsEMBL::Hive::Utils ('url2dbconn_hash');
use Bio::EnsEMBL::Utils::Argument;
use Bio::EnsEMBL::Utils::Exception qw(throw);
use Bio::EnsEMBL::Hive::AnalysisJob;
......@@ -257,6 +260,57 @@ sub dbc {
return $self->queen->dbc;
}
=head2 dbh
Title : dbh
Usage : my $dbh = $self->dbh;
Function: returns DBI handle to a database (the "current" one by default, but can be set up otherwise)
Returns : DBI handle
=cut
sub dbh {
my $self = shift;
if(@_ or !$self->{'_dbh'}) {
$self->{'_dbh'} = $self->go_figure_dbh( shift @_ || $self->param('db_conn') || $self->dbc );
}
return $self->{'_dbh'};
}
sub go_figure_dbh {
my ($self, $foo) = @_;
if(UNIVERSAL::isa($foo, 'DBI::db')) { # it is already a DBI handle, just return it:
return $foo;
} elsif(UNIVERSAL::isa($foo, 'Bio::EnsEMBL::DBSQL::DBConnection')) { # an EnsEMBL DBConnection
return $foo->db_handle;
} elsif(UNIVERSAL::isa($foo, 'Bio::EnsEMBL::Hive::DBSQL::DBAdaptor')) { # a Hive adaptor
return $foo->dbc->db_handle;
} elsif(my $db_conn = (ref($foo) eq 'HASH') ? $foo : url2dbconn_hash( $foo ) ) { # either a hash or a URL
$db_conn->{-driver} ||= 'mysql';
return ($db_conn->{-driver} eq 'sqlite'
? DBI->connect("DBI:SQLite:$db_conn->{-dbname}", '', '', { RaiseError => 1 })
: DBI->connect("DBI:$db_conn->{-driver}:host=$db_conn->{-host}:port=$db_conn->{-port}:database=$db_conn->{-dbname}", $db_conn->{-user}, $db_conn->{-pass}, { RaiseError => 1 })
) or die "Couldn't connect to database: " . DBI->errstr;
} else {
die "Sorry, could not figure out how to make a DBI handle out of $foo";
}
}
=head2 analysis
Title : analysis
......
......@@ -39,7 +39,6 @@ whose count is automatically set to the number of fan jobs that it will be waiti
package Bio::EnsEMBL::Hive::RunnableDB::JobFactory;
use strict;
use DBI;
use Bio::EnsEMBL::Hive::Utils ('dir_revhash'); # import dir_revhash
use base ('Bio::EnsEMBL::Hive::Process');
......@@ -177,17 +176,8 @@ sub write_output { # nothing to write out, but some dataflow to perform:
sub _make_list_from_query {
my ($self, $inputquery) = @_;
my $dbc;
if(my $db_conn = $self->param('db_conn')) {
$db_conn->{-driver} ||= 'mysql';
$dbc = DBI->connect("DBI:$db_conn->{-driver}:$db_conn->{-dbname}:$db_conn->{-host}:$db_conn->{-port}", $db_conn->{-user}, $db_conn->{-pass}, { RaiseError => 1 });
} else {
$dbc = $self->db->dbc;
}
my @list = ();
my $sth = $dbc->prepare($inputquery);
my $sth = $self->dbh()->prepare($inputquery);
$sth->execute();
while (my @cols = $sth->fetchrow_array()) {
push @list, scalar(@cols)==1 ? $cols[0] : \@cols;
......
......@@ -40,10 +40,10 @@ The SQL command(s) can be given using two different syntaxes:
package Bio::EnsEMBL::Hive::RunnableDB::SqlCmd;
use strict;
use DBI;
use base ('Bio::EnsEMBL::Hive::Process');
=head2 strict_hash_format
Description : Implements strict_hash_format() interface method of Bio::EnsEMBL::Hive::Process that is used to set the strictness level of the parameters' parser.
......@@ -55,6 +55,7 @@ sub strict_hash_format {
return 0;
}
=head2 fetch_input
Description : Implements fetch_input() interface method of Bio::EnsEMBL::Hive::Process that is used to read in parameters and load data.
......@@ -82,18 +83,9 @@ sub fetch_input {
# Store the sql command array:
#
$self->param('sqls', (ref($sql) eq 'ARRAY') ? $sql : [$sql] );
# Use connection parameters to another database if supplied, otherwise use the current database as default:
#
if(my $db_conn = $self->param('db_conn')) {
$db_conn->{-driver} ||= 'mysql';
$self->param('dbh', DBI->connect("DBI:$db_conn->{-driver}:$db_conn->{-dbname}:$db_conn->{-host}:$db_conn->{-port}", $db_conn->{-user}, $db_conn->{-pass}, { RaiseError => 1 }) );
} else {
$self->param('dbh', $self->db->dbc->db_handle );
}
}
=head2 run
Description : Implements run() interface method of Bio::EnsEMBL::Hive::Process that is used to perform the main bulk of the job (minus input and output).
......@@ -105,23 +97,22 @@ sub fetch_input {
sub run {
my $self = shift;
my $dbh = $self->param('dbh');
my $sqls = $self->param('sqls');
my $dbh = $self->dbh();
my %output_id;
# What would be a generic way of indicating an error in (My)SQL statement, that percolates through PerlDBI?
my $counter = 0;
foreach my $unsubst_sql (@$sqls) {
# Perform parameter substitution:
my $sql = $self->param_substitute($unsubst_sql);
$dbh->do( $sql );
$dbh->do( $sql ) or die "Could not run '$sql': ".$dbh->errstr;
my $insert_id_name = '_insert_id_'.$counter++;
#my $insert_id_value = ($dbh->driver eq 'sqlite') ? $dbh->func('last_insert_rowid') : $dbh->{'mysql_insertid'}; # <---- this approach worked
my $insert_id_value = $dbh->last_insert_id(undef, undef, undef, undef); # <---- this one should work, but watch out
my $insert_id_value = $dbh->last_insert_id(undef, undef, undef, undef);
$output_id{$insert_id_name} = $insert_id_value;
$self->param($insert_id_name, $insert_id_value); # for templates
}
......@@ -129,6 +120,7 @@ sub run {
$self->param('output_id', \%output_id);
}
=head2 write_output
Description : Implements write_output() interface method of Bio::EnsEMBL::Hive::Process that is used to deal with job's output after the execution.
......
......@@ -43,7 +43,7 @@ use warnings;
use Data::Dumper;
use Exporter 'import';
our @EXPORT_OK = qw( stringify destringify dir_revhash parse_cmdline_options load_file_or_module script_usage);
our @EXPORT_OK = qw( stringify destringify dir_revhash parse_cmdline_options load_file_or_module script_usage url2dbconn_hash);
=head2 stringify
......@@ -222,5 +222,24 @@ sub script_usage {
}
sub url2dbconn_hash {
my $url = pop @_;
if( my ($driver, $user, $pass, $host, $port, $dbname) =
$url =~ m{^(\w*)://(?:(\w+)(?:\:([^/\@]*))?\@)?(?:([\w\-\.]+)(?:\:(\d+))?)?/(\w*)} ) {
return {
'-driver' => $driver || 'mysql',
'-host' => $host || 'localhost',
'-port' => $port || 3306,
'-user' => $user || '',
'-pass' => $pass || '',
'-dbname' => $dbname,
};
} else {
return 0;
}
}
1;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment