Commit 1c3e10a3 authored by Matthieu Muffato's avatar Matthieu Muffato
Browse files

New script to automatically create fenced SQL patches

parent 4de8f76e
#!/usr/bin/env perl
# Copyright [1999-2015] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
use strict;
use warnings;
# Finding out own path in order to reference own components (including own modules):
use Cwd ();
use File::Basename ();
BEGIN {
$ENV{'EHIVE_ROOT_DIR'} ||= File::Basename::dirname( File::Basename::dirname( Cwd::realpath($0) ) );
unshift @INC, $ENV{'EHIVE_ROOT_DIR'}.'/modules';
}
use DateTime;
use File::Basename;
use File::Copy;
use Getopt::Long;
use Bio::EnsEMBL::Hive::DBSQL::SqlSchemaAdaptor;
my $opts = {
driver => [],
date => undef, # this means today
help => 0,
};
my @args = ('driver=s@', 'date=s', 'help|h');
my $parse = GetOptions($opts, @args);
if(!$parse) {
print STDERR "Could not parse the given arguments. Please consult the help\n";
usage();
exit 1;
}
# Print usage on '-h' command line option
if ($opts->{help}) {
usage();
exit;
}
$opts->{driver} = [qw(mysql sqlite pgsql)] unless scalar(@{$opts->{driver}});
$opts->{date} = DateTime->now->ymd('-') unless $opts->{date};
my $code_sql_schema_version = Bio::EnsEMBL::Hive::DBSQL::SqlSchemaAdaptor->get_code_sql_schema_version()
|| die "Could not establish code_sql_schema_version, please check that 'EHIVE_ROOT_DIR' environment variable is set correctly\n";
foreach my $driver (@{$opts->{driver}}) {
-s "$ENV{'EHIVE_ROOT_DIR'}/sql/patch_$opts->{date}.$driver" && die "$ENV{'EHIVE_ROOT_DIR'}/sql/patch_$opts->{date}.$driver already exists ! Remove this file or change the patch date\n";
system("sed 's/___EXPECTED_SCHEMA_VERSION___/$code_sql_schema_version/' '$ENV{'EHIVE_ROOT_DIR'}/sql/template_patch.$driver' > '$ENV{'EHIVE_ROOT_DIR'}/sql/patch_$opts->{date}.$driver'");
-s "$ENV{'EHIVE_ROOT_DIR'}/sql/patch_$opts->{date}.$driver" || die "Could not copy $ENV{'EHIVE_ROOT_DIR'}/sql/template_patch.$driver to $ENV{'EHIVE_ROOT_DIR'}/sql/patch_$opts->{date}.$driver\n";
}
sub usage {
print <<EOT;
Usage:
\t$0 [-date <day_of_the_patch>] [-driver <name_of_first_driver>] [-driver <name_of_second_driver>] ...
\t$0 -h
\t-date\n\t\tdate in ISO format, e.g. 2015-02-14. Defaults to the current date
\t-driver (can be repeated)\n\t\tdriver for which create a patch. Defaults to MySQL, SQLite, and Postgre
\t-h|--help\n\t\tdisplay this help text
EOT
}
-- ---------------------------------------------------------------------------------------------------
SET @expected_version = ___EXPECTED_SCHEMA_VERSION___;
-- make MySQL stop immediately after it encounters division by zero:
SET SESSION sql_mode='TRADITIONAL';
-- warn that we detected the schema version mismatch:
SELECT CONCAT( 'The patch only applies to schema version ',
@expected_version,
', but the current schema version is ',
meta_value,
', so skipping the rest.') AS ''
FROM hive_meta WHERE meta_key='hive_sql_schema_version' AND meta_value<>@expected_version;
-- cause division by zero only if current version differs from the expected one:
INSERT INTO hive_meta (meta_key, meta_value)
SELECT 'this_should_never_be_inserted', 1 FROM hive_meta WHERE NOT 1/(meta_key<>'hive_sql_schema_version' OR meta_value=@expected_version);
SELECT CONCAT( 'The patch seems to be compatible with schema version ',
@expected_version,
', applying the patch...') AS '';
-- Now undo the change so that we could patch potentially non-TRADITIONAL schema:
SET SESSION sql_mode='';
-- ----------------------------------<actual_patch> -------------------------------------------------
-- ----------------------------------</actual_patch> -------------------------------------------------
-- increase the schema version by one:
UPDATE hive_meta SET meta_value=meta_value+1 WHERE meta_key='hive_sql_schema_version';
-- ---------------------------------------------------------------------------------------------------
\set expected_version ___EXPECTED_SCHEMA_VERSION___
\set ON_ERROR_STOP on
-- warn that we detected the schema version mismatch:
SELECT ('The patch only applies to schema version '
|| CAST(:expected_version AS VARCHAR)
|| ', but the current schema version is '
|| meta_value
|| ', so skipping the rest.') as incompatible_msg
FROM hive_meta WHERE meta_key='hive_sql_schema_version' AND meta_value!=CAST(:expected_version AS VARCHAR);
-- cause division by zero only if current version differs from the expected one:
INSERT INTO hive_meta (meta_key, meta_value)
SELECT 'this_should_never_be_inserted', 1 FROM hive_meta WHERE 1 != 1/CAST( (meta_key!='hive_sql_schema_version' OR meta_value=CAST(:expected_version AS VARCHAR)) AS INTEGER );
SELECT ('The patch seems to be compatible with schema version '
|| CAST(:expected_version AS VARCHAR)
|| ', applying the patch...') AS compatible_msg;
-- ----------------------------------<actual_patch> -------------------------------------------------
-- ----------------------------------</actual_patch> -------------------------------------------------
-- increase the schema version by one:
UPDATE hive_meta SET meta_value= (CAST(meta_value AS INTEGER) + 1) WHERE meta_key='hive_sql_schema_version';
-- ---------------------------------------------------------------------------------------------------
CREATE TEMPORARY VIEW exp_ver AS SELECT "___EXPECTED_SCHEMA_VERSION___" AS expected_version;
.bail ON
SELECT ('The patch only applies to schema version '
|| expected_version
|| ', but the current schema version is '
|| meta_value
|| ', skipping the rest.') AS ''
FROM hive_meta JOIN exp_ver WHERE meta_key='hive_sql_schema_version' AND meta_value<>expected_version;
INSERT INTO hive_meta (meta_key, meta_value)
SELECT hm.* FROM hive_meta AS hm JOIN exp_ver WHERE meta_key='hive_sql_schema_version' AND meta_value<>expected_version;
SELECT ('The patch seems to be compatible with schema version '
|| expected_version
|| ', applying the patch...') AS '' FROM exp_ver;
-- ----------------------------------<actual_patch> -------------------------------------------------
-- ----------------------------------</actual_patch> -------------------------------------------------
-- increase the schema version by one:
UPDATE hive_meta SET meta_value=meta_value+1 WHERE meta_key='hive_sql_schema_version';
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