Skip to content
Snippets Groups Projects
Commit d5ed5250 authored by Andreas Kusalananda Kähäri's avatar Andreas Kusalananda Kähäri
Browse files

If external_db.db_release is anything else than NULL or '1' in the

existing database, save these values before wiping the table.  When
reading the new external_db table is read from file, instead of writing
the db_release column from the file, use the saved values.

Formatting.
parent 9cdfca6f
No related branches found
No related tags found
No related merge requests found
#!/software/bin/perl -w
#
# updates the external db tables on all of the core databases on a given host
#
use strict;
use Getopt::Long;
use DBI;
use IO::File;
my ( $host, $user, $pass, $port,@dbnames, $file, $release_num, $master, $force);
my ( $host, $user, $pass, $port, @dbnames,
$file, $release_num, $master, $force );
GetOptions( "host=s", \$host,
"user=s", \$user,
"pass=s", \$pass,
"port=i", \$port,
"file=s", \$file,
"user=s", \$user,
"pass=s", \$pass,
"port=i", \$port,
"file=s", \$file,
"dbnames=s@", \@dbnames,
"release_num=i", \$release_num,
"master=s", \$master,
"force", \$force
);
"release_num=i", \$release_num,
"master=s", \$master,
"force", \$force );
$port ||= 3306;
$file ||= "external_dbs.txt";
usage("[DIE] Need a host\n\n") if(!$host);
usage("[DIE] Need a host") if(!$host);
#release num XOR dbname are required
usage("[DIE] Need either both a release number and database names or neither\n\n") if(($release_num && @dbnames) || (!$release_num && !@dbnames));
usage( "[DIE] Need either both a release number and "
. "database names or neither" )
if ( ( $release_num && @dbnames ) || ( !$release_num && !@dbnames ) );
# master database is required
usage("[DIE] Master database required\n\n") if (!$master);
usage("[DIE] Master database required") if (!$master);
my $dsn = "DBI:mysql:host=$host;port=$port";
......@@ -52,8 +55,10 @@ if($release_num) {
# make sure the user wishes to continue
#
print STDERR "Please make sure you've updated $file from CVS!\n";
print STDERR "The following databases will have their external_db tables updated if necessary:\n ";
print join("\n ", @dbnames);
print STDERR
"The following databases will have their external_db tables "
. "updated if necessary:\n ";
print join( "\n ", @dbnames );
print "\nContinue with update (yes/no)> ";
my $input = lc(<STDIN>);
......@@ -74,25 +79,33 @@ while ($row = <$fh>) {
chomp($row);
next if ($row =~ /^#/); # skip comments
next if ($row =~ /^$/); # and blank lines
next if ($row =~ /^\s+/); # and whitespace-only lines
next if ($row =~ /^\s+$/); # and whitespace-only lines
my @a = split(/\t/, $row);
push @rows, {'external_db_id' => $a[0],
'db_name' => $a[1],
'release' => $a[2],
'status' => $a[3],
'dbprimary_acc_linkable' => $a[4],
'display_label_linkable' => $a[5],
'priority' => $a[6],
'db_display_name' => $a[7],
'type' => $a[8]};
if ($a[1] =~ /-/) {
print STDERR "Database name " . $a[1] . " contains - characters which will break Mart, please replace them with _ until Mart is fixed\n";
push @rows, {
'external_db_id' => $a[0],
'db_name' => $a[1],
'release' => $a[2],
'status' => $a[3],
'dbprimary_acc_linkable' => $a[4],
'display_label_linkable' => $a[5],
'priority' => $a[6],
'db_display_name' => $a[7],
'type' => $a[8] };
if ( $a[1] =~ /-/ ) {
print STDERR "Database name "
. $a[1]
. " contains '-' characters "
. "which will break Mart, "
. "please replace them with '_' until Mart is fixed\n";
exit(1);
}
if ($a[1] =~ /^$/ || $a[1] =~ /^\s+$/ || $a[1] =~ /^\d+$/) {
print STDERR "Cannot parse the following line:\n$row\nIt probably has spaces separating the fields rather than tabs.\n";
if ( $a[1] =~ /^$/ || $a[1] =~ /^\s+$/ || $a[1] =~ /^\d+$/ ) {
print STDERR "Cannot parse the following line:\n"
. $row
. "\nIt probably has spaces separating the fields "
. "rather than tabs.\n";
exit(1);
}
}
......@@ -111,17 +124,20 @@ foreach my $dbname (@dbnames) {
if ($force) {
print STDERR "Forcing overwrite of external_db table in $dbname from $file\n";
load_database($db, $dbname, @rows);
print STDERR "Forcing overwrite of external_db table in "
. "$dbname from $file\n";
load_database( $db, $dbname, @rows );
} elsif (compare_external_db($db, $master, $dbname)) {
print STDERR "$dbname has no additional rows. Overwriting external_db table from $file\n";
load_database($db, $dbname, @rows);
print STDERR "$dbname has no additional rows. "
. "Overwriting external_db table from $file\n";
load_database( $db, $dbname, @rows );
} else {
print STDERR "$dbname has extra rows that are not in $file, skipping\n";
print STDERR "$dbname has extra rows "
. "that are not in $file, skipping\n";
}
......@@ -132,34 +148,61 @@ print STDERR "Updates complete\n";
sub load_database {
my ($db, $dbname, @rows) = @_;
$db->do("use $dbname");
my $sth = $db->prepare('DELETE FROM external_db');
$db->do("USE $dbname");
# Save all existing release information from the table.
my $sth = $db->prepare(
qq( SELECT external_db_id, db_release
FROM external_db) );
$sth->execute();
my %saved_release;
while ( my ( $id, $release ) = $sth->fetchrow_array() ) {
if ( defined($release) && $release ne '1' ) {
$saved_release{$id} = $release;
}
}
$sth->finish();
# Delete the existing table
$sth = $db->prepare('DELETE FROM external_db');
$sth->execute();
$sth->finish();
$sth = $db->prepare('INSERT INTO external_db (external_db_id, db_name,
db_release, status, dbprimary_acc_linkable,
display_label_linkable, priority,
db_display_name, type)
VALUES (?,?,?,?,?,?,?,?,?)');
# Populate the table with data from the file (using the saved release
# information)
$sth = $db->prepare(
qq( INSERT INTO external_db (
external_db_id,
db_name,
db_release,
status,
dbprimary_acc_linkable,
display_label_linkable,
priority,
db_display_name,
type) VALUES (?,?,?,?,?,?,?,?,?)) );
foreach my $row (@rows) {
$sth->execute($row->{'external_db_id'},
$row->{'db_name'},
$row->{'release'},
$row->{'status'},
$row->{'dbprimary_acc_linkable'},
$row->{'display_label_linkable'},
$row->{'priority'},
$row->{'db_display_name'},
$row->{'type'});
my $id = $row->{'external_db_id'};
$sth->execute( $id,
$row->{'db_name'}, (
exists( $saved_release{$id} )
? $saved_release{$id}
: $row->{'release'}
),
$row->{'status'},
$row->{'dbprimary_acc_linkable'},
$row->{'display_label_linkable'},
$row->{'priority'},
$row->{'db_display_name'},
$row->{'type'} );
}
$sth->finish();
}
......@@ -182,7 +225,6 @@ sub compare_external_db {
$sth->execute();
while (my ($id, $external_db_name) = $sth->fetchrow_array) {
print "$dbname has external_db entry for $external_db_name (ID $id) which is not present in $master\n";
$same = undef;
......@@ -196,40 +238,49 @@ sub compare_external_db {
sub usage {
my $error = shift;
print STDERR <<EOF
print STDERR <<EOF;
$error
Usage: update_external_db options
Where options are: -host hostname
-user username
-pass password
-port port_of_server optional
-master the name of the master database to load the file into
-force force update, even if there are rows in the database
that are not in the file
-release the release of the database to update used to
match database names. e.g. 13
-file the path of the file containing the insert statements
of the entries of the external_db table. Default is
external_dbs.txt
-dbnames db1
the names of the database to update. if not provided
all of the core databases matching the release arg
will be updated. Either -dbnames or -release must
be specified, but not both. Multiple dbnames can
be provided.
E.g.:
# update 2 databases
perl update_external_dbs.pl -host ecs1c -file external_dbs.txt -user ensadmin -pass secret -dbnames homo_sapiens_core_14_33 -dbnames mus_musculus_core_14_30
# update all core databases for release 14
perl update_external_dbs.pl -host ens-staging -file external_dbs.txt -user ensadmin -pass secret -release 42 -master master_schema_42
If the databases to be updated contain rows that are not in the file, a warning will
be given and the database in question skipped, unless -force is used.
Usage: $0 options
-host hostname
-user username
-pass password
-port port_of_server optional
-master the name of the master database to load the file into
-force force update, even if there are rows in the database
that are not in the file
-release the release of the database to update used to match
database names, e.g. 13
-file the path of the file containing the insert statements
of the entries of the external_db table. Default is
'external_dbs.txt'
-dbnames the names of the database to update. If not provided
all of the core databases matching the release arg
will be updated. Either -dbnames or -release must
be specified, but not both. Multiple dbnames can be
provided.
Examples:
# Update two databases
./update_external_dbs.pl -host ecs1c -file external_dbs.txt \\
-user ensadmin -pass secret -master master_schema_14 \\
-dbnames homo_sapiens_core_14_33 -dbnames mus_musculus_core_14_30
# Update all Core databases for release 14
./update_external_dbs.pl -host ens-staging -file external_dbs.txt \\
-user ensadmin -pass secret -release 42 -master master_schema_42
If the databases to be updated contain rows that are not in the file,
a warning will be given and the database in question skipped, unless
-force is used.
This program will not overwrite the db_release column of any table.
EOF
;
exit;
}
exit;
} ## end sub usage
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