Commit ca4171b2 authored by Matthieu Muffato's avatar Matthieu Muffato
Browse files

Moved Utils::dbc_to_cmd() (static method) to DBConnection::to_cmd() (instance method)

parent cc0e3549
......@@ -203,5 +203,92 @@ sub protected_prepare_execute { # try to resolve certain mysql "Deadlocks" b
return $retval;
}
our $pass_internal_counter = 0;
sub to_cmd {
my ($self, $executable, $prepend, $append, $sqlcmd, $hide_password_in_env) = @_;
my $driver = $self->driver || 'mysql';
my $dbname = $self->dbname;
if($sqlcmd) {
if($sqlcmd =~ /(DROP\s+DATABASE(?:\s+IF\s+EXISTS)?\s*?)(?:\s+(\w+))?/i) {
$dbname = $2 if $2;
if($driver eq 'sqlite') {
return ['rm', '-f', $dbname];
} elsif(!$2) {
$sqlcmd = "$1 $dbname";
$dbname = '';
}
} elsif($sqlcmd =~ /(CREATE\s+DATABASE\s*?)(?:\s+(\w+))?/i ) {
$dbname = $2 if $2;
if($driver eq 'sqlite') {
return ['touch', $dbname];
} elsif(!$2) {
my %limits = ( 'mysql' => 64, 'pgsql' => 63 );
if (length($dbname) > $limits{$driver}) {
die "Database name '$dbname' is too long (> $limits{$driver}). Cannot create the database\n";
}
$sqlcmd = "$1 $dbname";
$dbname = '';
}
}
}
my @cmd;
my $hidden_password;
if ($self->password) {
if ($hide_password_in_env) {
my $pass_variable = "EHIVE_TMP_PASSWORD_${pass_internal_counter}";
$pass_internal_counter++;
$ENV{$pass_variable} = $self->password;
$hidden_password = '$'.$pass_variable;
} else {
$hidden_password = $self->password;
}
}
if($driver eq 'mysql') {
$executable ||= 'mysql';
push @cmd, $executable;
push @cmd, @$prepend if ($prepend && @$prepend);
push @cmd, '-h'.$self->host if $self->host;
push @cmd, '-P'.$self->port if $self->port;
push @cmd, '-u'.$self->username if $self->username;
push @cmd, '-p'.$hidden_password if $self->password;
push @cmd, ('-e', $sqlcmd) if $sqlcmd;
push @cmd, $dbname if $dbname;
push @cmd, @$append if ($append && @$append);
} elsif($driver eq 'pgsql') {
$executable ||= 'psql';
push @cmd, ('env', 'PGPASSWORD='.$hidden_password) if ($self->password);
push @cmd, $executable;
push @cmd, @$prepend if ($prepend && @$prepend);
push @cmd, ('-h', $self->host) if defined($self->host);
push @cmd, ('-p', $self->port) if defined($self->port);
push @cmd, ('-U', $self->username) if defined($self->username);
push @cmd, ('-c', $sqlcmd) if $sqlcmd;
push @cmd, @$append if ($append && @$append);
push @cmd, $dbname if $dbname;
} elsif($driver eq 'sqlite') {
$executable ||= 'sqlite3';
die "sqlite requires a database (file) name\n" unless $dbname;
push @cmd, $executable;
push @cmd, @$prepend if ($prepend && @$prepend);
push @cmd, @$append if ($append && @$append);
push @cmd, $dbname;
push @cmd, $sqlcmd if $sqlcmd;
}
return \@cmd;
}
1;
......@@ -82,7 +82,7 @@ package Bio::EnsEMBL::Hive::RunnableDB::DatabaseDumper;
use strict;
use warnings;
use Bio::EnsEMBL::Hive::Utils ('go_figure_dbc', 'dbc_to_cmd');
use Bio::EnsEMBL::Hive::Utils ('go_figure_dbc');
use base ('Bio::EnsEMBL::Hive::Process');
......@@ -181,12 +181,12 @@ sub run {
$output = sprintf('> %s', $self->param('output_file'));
}
} else {
$output = join(' ', '|', @{ dbc_to_cmd($self->param('real_output_db'), undef, undef, undef, undef, 1) } );
$output = join(' ', '|', @{ $self->param('real_output_db')->to_cmd(undef, undef, undef, undef, 1) } );
};
# Must be joined because of the redirection / the pipe
my $cmd = join(' ',
@{ dbc_to_cmd($src_dbc, 'mysqldump', undef, undef, undef, 1) },
@{ $src_dbc->to_cmd('mysqldump', undef, undef, undef, 1) },
'--skip-lock-tables',
@$tables,
(map {sprintf('--ignore-table=%s.%s', $src_dbc->dbname, $_)} @$ignores),
......
......@@ -10,9 +10,9 @@ Bio::EnsEMBL::Hive::RunnableDB::DbCmd
=head1 DESCRIPTION
This RunnableDB module acts as a wrapper around db_cmd.pl. It allows to run any command line that would involve an occurrence of db_cmd.pl,
with the advantage of not having to hardcode the database connection details in the command line in the PipeConfig file itself.
The database connection is instead reused from the "data_dbc" parameter, which defaults to the current hive database.
This RunnableDB module acts as a wrapper around a database connection. It interfaces with the database the same way as you would
on the command line (i.e. with redirections and / or pipes to other commands) but with hive parameters instead.
The database connection is created from the "data_dbc" parameter, if provided, or the current hive database.
=head1 CONFIGURATION EXAMPLE
......@@ -85,9 +85,7 @@ package Bio::EnsEMBL::Hive::RunnableDB::DbCmd;
use strict;
use warnings;
# This runnable is simply a SystemCmd made aware of db_cmd (which is interfaced by dbc_to_cmd())
use Bio::EnsEMBL::Hive::Utils ('dbc_to_cmd');
# This runnable is simply a SystemCmd specialized for database commands
use base ('Bio::EnsEMBL::Hive::RunnableDB::SystemCmd');
......@@ -135,8 +133,7 @@ sub fetch_input {
die "'output_file' and 'command_out' cannot be set together\n";
}
my @cmd = @{ dbc_to_cmd(
$self->data_dbc,
my @cmd = @{ $self->data_dbc->to_cmd(
$self->param('executable'),
[grep {defined $_} @{$self->param('prepend')}],
[grep {defined $_} @{$self->param('append')}],
......@@ -150,7 +147,7 @@ sub fetch_input {
if ($self->param('input_file')) {
push @cmd, '<', $self->param('input_file');
} elsif ($self->param('input_query')) {
# the query as already been fed into @cmd by dbc_to_cmd()
# the query as already been fed into @cmd by to_cmd()
} elsif ($self->param('command_in')) {
unshift @cmd, (ref($self->param('command_in')) ? @{$self->param('command_in')} : $self->param('command_in')), '|';
}
......
......@@ -41,7 +41,7 @@ package Bio::EnsEMBL::Hive::RunnableDB::MySQLTransfer;
use strict;
use warnings;
use Bio::EnsEMBL::Hive::Utils ('go_figure_dbc', 'dbc_to_cmd');
use Bio::EnsEMBL::Hive::Utils ('go_figure_dbc');
use base ('Bio::EnsEMBL::Hive::Process');
......@@ -124,12 +124,12 @@ sub run {
# Must be joined because of the pipe
my $cmd = join(' ',
@{dbc_to_cmd($src_dbc, 'mysqldump', $mode_options, undef, undef, 1)},
@{$src_dbc->to_cmd('mysqldump', $mode_options, undef, undef, 1)},
$table,
(defined($where) ? "--where '$where' " : ''),
'|',
($filter_cmd ? "$filter_cmd | " : ''),
@{dbc_to_cmd($dest_dbc, undef, undef, undef, undef, 1)}
@{$dest_dbc->to_cmd(undef, undef, undef, undef, 1)}
);
print "$cmd\n" if $self->debug;
......
......@@ -59,7 +59,7 @@ use Scalar::Util qw(looks_like_number);
#use Bio::EnsEMBL::Hive::DBSQL::DBConnection; # causes warnings that all exported functions have been redefined
use Exporter 'import';
our @EXPORT_OK = qw(stringify destringify dir_revhash parse_cmdline_options find_submodules load_file_or_module script_usage url2dbconn_hash go_figure_dbc report_versions throw dbc_to_cmd join_command_args);
our @EXPORT_OK = qw(stringify destringify dir_revhash parse_cmdline_options find_submodules load_file_or_module script_usage url2dbconn_hash go_figure_dbc report_versions throw join_command_args);
no warnings ('once'); # otherwise the next line complains about $Carp::Internal being used just once
$Carp::Internal{ (__PACKAGE__) }++;
......@@ -354,94 +354,6 @@ sub throw {
}
our $pass_internal_counter = 0;
sub dbc_to_cmd {
my ($dbc, $executable, $prepend, $append, $sqlcmd, $hide_password_in_env) = @_;
my $driver = $dbc->driver || 'mysql';
my $dbname = $dbc->dbname;
if($sqlcmd) {
if($sqlcmd =~ /(DROP\s+DATABASE(?:\s+IF\s+EXISTS)?\s*?)(?:\s+(\w+))?/i) {
$dbname = $2 if $2;
if($driver eq 'sqlite') {
return ['rm', '-f', $dbname];
} elsif(!$2) {
$sqlcmd = "$1 $dbname";
$dbname = '';
}
} elsif($sqlcmd =~ /(CREATE\s+DATABASE\s*?)(?:\s+(\w+))?/i ) {
$dbname = $2 if $2;
if($driver eq 'sqlite') {
return ['touch', $dbname];
} elsif(!$2) {
my %limits = ( 'mysql' => 64, 'pgsql' => 63 );
if (length($dbname) > $limits{$driver}) {
die "Database name '$dbname' is too long (> $limits{$driver}). Cannot create the database\n";
}
$sqlcmd = "$1 $dbname";
$dbname = '';
}
}
}
my @cmd;
my $hidden_password;
if ($dbc->password) {
if ($hide_password_in_env) {
my $pass_variable = "EHIVE_TMP_PASSWORD_${pass_internal_counter}";
$pass_internal_counter++;
$ENV{$pass_variable} = $dbc->password;
$hidden_password = '$'.$pass_variable;
} else {
$hidden_password = $dbc->password;
}
}
if($driver eq 'mysql') {
$executable ||= 'mysql';
push @cmd, $executable;
push @cmd, @$prepend if ($prepend && @$prepend);
push @cmd, '-h'.$dbc->host if $dbc->host;
push @cmd, '-P'.$dbc->port if $dbc->port;
push @cmd, '-u'.$dbc->username if $dbc->username;
push @cmd, '-p'.$hidden_password if $dbc->password;
push @cmd, ('-e', $sqlcmd) if $sqlcmd;
push @cmd, $dbname if $dbname;
push @cmd, @$append if ($append && @$append);
} elsif($driver eq 'pgsql') {
$executable ||= 'psql';
push @cmd, ('env', 'PGPASSWORD='.$hidden_password) if ($dbc->password);
push @cmd, $executable;
push @cmd, @$prepend if ($prepend && @$prepend);
push @cmd, ('-h', $dbc->host) if defined($dbc->host);
push @cmd, ('-p', $dbc->port) if defined($dbc->port);
push @cmd, ('-U', $dbc->username) if defined($dbc->username);
push @cmd, ('-c', $sqlcmd) if $sqlcmd;
push @cmd, @$append if ($append && @$append);
push @cmd, $dbname if $dbname;
} elsif($driver eq 'sqlite') {
$executable ||= 'sqlite3';
die "sqlite requires a database (file) name\n" unless $dbname;
push @cmd, $executable;
push @cmd, @$prepend if ($prepend && @$prepend);
push @cmd, @$append if ($append && @$append);
push @cmd, $dbname;
push @cmd, $sqlcmd if $sqlcmd;
}
return \@cmd;
}
=head2 join_command_args
Argument[0]: String or Arrayref of Strings
......
......@@ -14,7 +14,7 @@ BEGIN {
use Getopt::Long;
use Bio::EnsEMBL::Hive::DBSQL::DBConnection;
use Bio::EnsEMBL::Hive::Utils ('script_usage', 'report_versions', 'dbc_to_cmd');
use Bio::EnsEMBL::Hive::Utils ('script_usage', 'report_versions');
sub main {
......@@ -87,7 +87,7 @@ sub main {
warn qq{In db_cmd.pl, final arguments don't have to be declared with --append any more. All the remaining arguments are considered to be appended.\n};
}
my @cmd = @{ dbc_to_cmd( $dbc, $executable, \@prepend, [@append, @ARGV], $sqlcmd ) };
my @cmd = @{ $dbc->to_cmd( $executable, \@prepend, [@append, @ARGV], $sqlcmd ) };
if( $verbose ) {
my $flat_cmd = join(' ', map { ($_=~/^-?\w+$/) ? $_ : "\"$_\"" } @cmd);
......
......@@ -22,7 +22,6 @@ use Test::More;
use Data::Dumper;
use File::Temp qw{tempdir};
use Bio::EnsEMBL::Hive::Utils qw(dbc_to_cmd);
use Bio::EnsEMBL::Hive::Utils::Test qw(init_pipeline runWorker);
# eHive needs this to initialize the pipeline (and run db_cmd.pl)
......@@ -71,7 +70,7 @@ warn "\nInitializing the $long_mult_version pipeline ...\n\n";
# disconnect to be able to drop the database (some drivers like PostgreSQL do not like dropping connected databases):
$hive_dba->dbc->disconnect_if_idle;
system( @{ dbc_to_cmd($hive_dba->dbc, undef, undef, undef, 'DROP DATABASE') } );
system( @{ $hive_dba->dbc->to_cmd(undef, undef, undef, 'DROP DATABASE') } );
}
}
......
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