sub new {
my $class = shift @_;
my %flags = @_;
my ($dbc, $url, $reg_conf, $reg_type, $reg_alias, $species, $no_sql_schema_version_check)
=
delete @flags{qw(-dbconn -url -reg_conf -reg_type -reg_alias -
species -no_sql_schema_version_check)};
if ($url && $no_sql_schema_version_check) {
#check to see if the url has been quoted. If so, move the quote
#after the no_sql_schema_version_check
$url =~ s/([\'\"]?)$/;no_sql_schema_version_check=1$1/;
}
if($reg_conf or $reg_alias) { # need to initialize Registry even if $reg_conf is not really given
require Bio::EnsEMBL::Registry;
Bio::EnsEMBL::Registry->load_all($reg_conf); # if undefined, default reg_conf will be used
}
my $self;
if($url) {
$dbc = Bio::EnsEMBL::Hive::DBSQL::DBConnection->new(-url => $url, %flags)
or die "Unable to create a DBC using url='$url'";
} elsif($reg_alias) {
if($reg_alias=~/^(\w+):(\w+)$/) {
($reg_type, $reg_alias) = ($1, $2);
}
unless($reg_type) { # if no $reg_type explicitly given, try to guess:
my $dbas = Bio::EnsEMBL::Registry->get_all_DBAdaptors(-species => $reg_alias);
if( scalar(@$dbas) == 1 ) {
$self = $dbas->[0];
} elsif( @$dbas ) {
warn "The registry contains multiple entries for '$reg_alias', please prepend the reg_alias with the desired type\n";
}
}
unless($self) { # otherwise (or if not found) try a specific $reg_type
$reg_type ||= 'hive';
$self = Bio::EnsEMBL::Registry->get_DBAdaptor($reg_alias, $reg_type)
or die "Unable to connect to DBA using reg_conf='$reg_conf', reg_type='$reg_type', reg_alias='$reg_alias'\n";
}
if( $self and !$self->isa($class) ) { # if we found a non-Hive Registry entry, detach the $dbc and build a Hive dba around it:
$dbc = $self->dbc;
$self = undef;
}
}
if($dbc && !$self) {
$self = bless {}, $class;
$self->dbc( $dbc );
}
unless($no_sql_schema_version_check) {
my $dbc = $self->dbc();
# Make a safe URL without affecting EHIVE_PASS, which could have been set by the user
my $safe_url = $dbc->url('EHIVE_TMP_PASSWORD');
$safe_url =~ s/EHIVE_TMP_PASSWORD/EHIVE_PASS/;
my $code_sql_schema_version = Bio::EnsEMBL::Hive::DBSQL::SqlSchemaAdaptor->get_code_sql_schema_version()
|| die "DB($safe_url) Could not establish code_sql_schema_version, please check that 'EHIVE_ROOT_DIR' environment variable is set correctly";
my $db_sql_schema_version = eval { $self->get_MetaAdaptor->fetch_by_meta_key( 'hive_sql_schema_version' )->{'meta_value'}; };
if($@) {
if($@ =~ /hive_meta.*doesn't exist/) {
die "\nDB($safe_url) The 'hive_meta' table does not seem to exist in the database yet.\nPlease patch the database up to sql_schema_version '$code_sql_schema_version' and try again.\n";
} else {
die "DB($safe_url) $@";
}
} elsif(!$db_sql_schema_version) {
die "\nDB($safe_url) The 'hive_meta' table does not contain 'hive_sql_schema_version' entry.\nPlease investigate.\n";
} elsif($db_sql_schema_version < $code_sql_schema_version) {
|| die "DB($safe_url) sql_schema_version mismatch: the database's version is '$db_sql_schema_version' but the code is already '$code_sql_schema_version'.\n"
."Unfortunately we cannot patch the database; you may have to create a new database or agree to run older code\n";
my $sql_patcher_command = "$ENV{'EHIVE_ROOT_DIR'}/scripts/db_cmd.pl -url $safe_url";
die "DB($safe_url) sql_schema_version mismatch: the database's version is '$db_sql_schema_version' but the code is already '$code_sql_schema_version'.\n"
."Please upgrade the database by applying the following patches:\n\n"
.join("\n", map { ($_=~/\.\w*sql\w*$/) ? "\t$sql_patcher_command < $_" : "$_ -url $safe_url" } @$new_patches)
."\n\nand try again.\n";
} elsif($code_sql_schema_version < $db_sql_schema_version) {
die "DB($safe_url) sql_schema_version mismatch: the database's version is '$db_sql_schema_version', but your code is still '$code_sql_schema_version'.\n"
."Please update the code and try again.\n";
}
}
if($species) { # [compatibility with core code] store the DBAdaptor in Registry:
require Bio::EnsEMBL::Registry;
Bio::EnsEMBL::Registry->add_DBAdaptor( $species, 'hive', $self );
}
return $self;
}