13 This
object represents the handle
for a Hive system enabled database
17 Copyright [1999-2015] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute
18 Copyright [2016-2022] EMBL-European Bioinformatics Institute
20 Licensed under the Apache License, Version 2.0 (the
"License"); you may not use
this file except in compliance with the License.
21 You may obtain a copy of the License at
25 Unless required by applicable law or agreed to in writing, software distributed under the License
26 is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
27 See the License
for the specific language governing permissions and limitations under the License.
31 Please subscribe to the
Hive mailing list: http:
36 package Bio::EnsEMBL::Hive::DBSQL::DBAdaptor;
41 use Scalar::Util qw(weaken);
64 my ($dbc, $url, $reg_conf, $reg_type, $reg_alias, $species, $no_sql_schema_version_check)
65 =
delete @flags{qw(-dbconn -url -reg_conf -reg_type -reg_alias -species -no_sql_schema_version_check)};
67 if ($url && $no_sql_schema_version_check) {
68 #check to see if the url has been quoted. If so, move the quote 69 #after the no_sql_schema_version_check 70 $url =~ s/([\
'\"]?)$/;no_sql_schema_version_check=1$1/; 73 if($reg_conf or $reg_alias) { # need to initialize Registry even if $reg_conf is not really given 74 require Bio::EnsEMBL::Registry; 75 Bio::EnsEMBL::Registry->load_all($reg_conf); # if undefined, default reg_conf will be used 81 $dbc = Bio::EnsEMBL::Hive::DBSQL::DBConnection->new(-url => $url, %flags) 82 or die "Unable to create a DBC using url='$url
'"; 86 if($reg_alias=~/^(\w+):(\w+)$/) { 87 ($reg_type, $reg_alias) = ($1, $2); 90 unless($reg_type) { # if no $reg_type explicitly given, try to guess: 91 my $dbas = Bio::EnsEMBL::Registry->get_all_DBAdaptors(-species => $reg_alias); 93 if( scalar(@$dbas) == 1 ) { 96 warn "The registry contains multiple entries for '$reg_alias
', please prepend the reg_alias with the desired type\n"; 100 unless($self) { # otherwise (or if not found) try a specific $reg_type 101 $reg_type ||= 'hive
'; 102 $self = Bio::EnsEMBL::Registry->get_DBAdaptor($reg_alias, $reg_type) 103 or die "Unable to connect to DBA using reg_conf='$reg_conf
', reg_type='$reg_type
', reg_alias='$reg_alias
'\n"; 106 if( $self and !$self->isa($class) ) { # if we found a non-Hive Registry entry, detach the $dbc and build a Hive dba around it: 113 $self = bless {}, $class; 117 unless($no_sql_schema_version_check) { 119 my $dbc = $self->dbc(); 121 # Make a safe URL without affecting EHIVE_PASS, which could have been set by the user 122 my $safe_url = $dbc->url('EHIVE_TMP_PASSWORD
'); 123 $safe_url =~ s/EHIVE_TMP_PASSWORD/EHIVE_PASS/; 125 my $code_sql_schema_version = Bio::EnsEMBL::Hive::DBSQL::SqlSchemaAdaptor->get_code_sql_schema_version() 126 || die "DB($safe_url) Could not establish code_sql_schema_version, please check that 'EHIVE_ROOT_DIR
' environment variable is set correctly"; 128 my $db_sql_schema_version = eval { $self->get_MetaAdaptor->fetch_by_meta_key( 'hive_sql_schema_version
' )->{'meta_value
'}; }; 131 if($@ =~ /hive_meta.*doesn't exist/) {
133 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";
137 die
"DB($safe_url) $@";
140 } elsif(!$db_sql_schema_version) {
142 die
"\nDB($safe_url) The 'hive_meta' table does not contain 'hive_sql_schema_version' entry.\nPlease investigate.\n";
144 } elsif($db_sql_schema_version < $code_sql_schema_version) {
146 my $new_patches = Bio::EnsEMBL::Hive::DBSQL::SqlSchemaAdaptor->get_sql_schema_patches( $db_sql_schema_version, $dbc->driver )
147 || 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" 148 .
"Unfortunately we cannot patch the database; you may have to create a new database or agree to run older code\n";
150 my $sql_patcher_command =
"$ENV{'EHIVE_ROOT_DIR'}/scripts/db_cmd.pl -url $safe_url";
152 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" 153 .
"Please upgrade the database by applying the following patches:\n\n" 154 .join(
"\n", map { ($_=~/\.\w*sql\w*$/) ?
"\t$sql_patcher_command < $_" :
"$_ -url $safe_url" } @$new_patches)
155 .
"\n\nand try again.\n";
157 } elsif($code_sql_schema_version < $db_sql_schema_version) {
159 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" 160 .
"Please update the code and try again.\n";
164 if($species) { # [compatibility with core code] store the
DBAdaptor in Registry:
165 require Bio::EnsEMBL::Registry;
166 Bio::EnsEMBL::Registry->add_DBAdaptor( $species,
'hive', $self );
173 sub species { # a stub to please Registry code
177 sub group { # a stub to please Registry code
185 $self->{
'_dbc'} = bless shift,
'Bio::EnsEMBL::Hive::DBSQL::DBConnection' if(@_);
187 return $self->{
'_dbc'};
194 $self->{
'_hive_pipeline'} = shift @_;
196 unless ($self->{
'_hive_pipeline'}) {
199 return $self->{
'_hive_pipeline'};
203 our %adaptor_type_2_package_name = (
204 'Accumulator' =>
'Bio::EnsEMBL::Hive::DBSQL::AccumulatorAdaptor',
205 'Analysis' =>
'Bio::EnsEMBL::Hive::DBSQL::AnalysisAdaptor',
206 'AnalysisCtrlRule' =>
'Bio::EnsEMBL::Hive::DBSQL::AnalysisCtrlRuleAdaptor',
207 'AnalysisData' =>
'Bio::EnsEMBL::Hive::DBSQL::AnalysisDataAdaptor',
208 'AnalysisJob' =>
'Bio::EnsEMBL::Hive::DBSQL::AnalysisJobAdaptor',
209 'AnalysisStats' =>
'Bio::EnsEMBL::Hive::DBSQL::AnalysisStatsAdaptor',
210 'Beekeeper' =>
'Bio::EnsEMBL::Hive::DBSQL::BeekeeperAdaptor',
211 'DataflowRule' =>
'Bio::EnsEMBL::Hive::DBSQL::DataflowRuleAdaptor',
212 'DataflowTarget' =>
'Bio::EnsEMBL::Hive::DBSQL::DataflowTargetAdaptor',
213 'LogMessage' =>
'Bio::EnsEMBL::Hive::DBSQL::LogMessageAdaptor',
214 'Meta' =>
'Bio::EnsEMBL::Hive::DBSQL::MetaAdaptor',
215 'PipelineWideParameters'=>
'Bio::EnsEMBL::Hive::DBSQL::PipelineWideParametersAdaptor',
216 'NakedTable' =>
'Bio::EnsEMBL::Hive::DBSQL::NakedTableAdaptor',
217 'ResourceClass' =>
'Bio::EnsEMBL::Hive::DBSQL::ResourceClassAdaptor',
218 'ResourceDescription' =>
'Bio::EnsEMBL::Hive::DBSQL::ResourceDescriptionAdaptor',
219 'Role' =>
'Bio::EnsEMBL::Hive::DBSQL::RoleAdaptor',
220 'Semaphore' =>
'Bio::EnsEMBL::Hive::DBSQL::SemaphoreAdaptor',
221 'Queen' =>
'Bio::EnsEMBL::Hive::Queen',
224 'Job' =>
'Bio::EnsEMBL::Hive::DBSQL::AnalysisJobAdaptor',
225 'Worker' =>
'Bio::EnsEMBL::Hive::Queen',
226 'MetaParameters' =>
'Bio::EnsEMBL::Hive::DBSQL::MetaAdaptor',
230 sub get_available_adaptors {
232 return \%adaptor_type_2_package_name;
236 sub parse_underscored_id_name {
237 my ($self, $underscored_id_name) = @_;
239 my ($is_an_id, $foo_id_method_name, $foo_obj_method_name);
241 my @syll = split(/_/, $underscored_id_name);
242 if($syll[scalar(@syll)-1] eq
'id') {
244 ($is_an_id, $foo_id_method_name, $foo_obj_method_name) = ( 1, $underscored_id_name, join(
'_', @syll) );
246 ($is_an_id, $foo_id_method_name, $foo_obj_method_name) = ( 0, $underscored_id_name .
'_id' , $underscored_id_name );
249 my $AdaptorType =
''; # will be growing from right to left
251 $AdaptorType = ucfirst(pop @syll) . $AdaptorType;
252 if(exists( $self->get_available_adaptors->{ $AdaptorType })) {
253 return ($AdaptorType, $is_an_id, $foo_id_method_name, $foo_obj_method_name);
256 return; # could not parse
262 my $AdaptorType = shift;
264 my $adaptor_package_name = $self->get_available_adaptors()->{$AdaptorType}
265 or
throw(
"Could not find a module corresponding to '$AdaptorType'");
267 my $signature = join(
':', $adaptor_package_name, @_);
269 unless( $self->{
'_cached_adaptor'}{$signature} ) {
271 eval
"require $adaptor_package_name" 272 or
throw(
"Could not load or compile module '$adaptor_package_name' because $@");
274 $self->{
'_cached_adaptor'}{$signature} = $adaptor_package_name->new( $self, @_ );
277 return $self->{
'_cached_adaptor'}{$signature};
281 sub DESTROY { } # to simplify AUTOLOAD
287 if ( $AUTOLOAD =~ /^.*::get_(\w+)Adaptor$/ ) {
289 } elsif ( $AUTOLOAD =~ /^.*::get_(\w+)$/ ) {
292 throw(
"DBAdaptor::AUTOLOAD: Could not interpret the method: $AUTOLOAD" );
297 return $self->get_adaptor($type, @_);