From ff0713ae154909e33d0659ab75d3afcdc21a442e Mon Sep 17 00:00:00 2001 From: Ian Longden <ianl@sanger.ac.uk> Date: Thu, 29 Jul 2004 08:21:31 +0000 Subject: [PATCH] Registry modifications --- modules/Bio/EnsEMBL/DBSQL/BaseAdaptor.pm | 31 +- .../Bio/EnsEMBL/DBSQL/BaseFeatureAdaptor.pm | 2 +- modules/Bio/EnsEMBL/DBSQL/DBAdaptor.pm | 1261 ++++++----------- modules/Bio/EnsEMBL/DBSQL/DBConnection.pm | 388 ++--- modules/Bio/EnsEMBL/DBSQL/ProxyAdaptor.pm | 37 +- modules/Bio/EnsEMBL/DBSQL/ProxySNPAdaptor.pm | 32 +- modules/Bio/EnsEMBL/DBSQL/SliceAdaptor.pm | 2 +- modules/Bio/EnsEMBL/External/BlastAdaptor.pm | 18 +- modules/Bio/EnsEMBL/Lite/DBAdaptor.pm | 8 +- modules/Bio/EnsEMBL/Registry.pm | 766 ++++++++++ modules/Bio/EnsEMBL/Slice.pm | 18 +- modules/Bio/EnsEMBL/Storable.pm | 5 +- modules/Bio/EnsEMBL/Utils/ConfigRegistry.pm | 2 +- 13 files changed, 1464 insertions(+), 1106 deletions(-) create mode 100644 modules/Bio/EnsEMBL/Registry.pm diff --git a/modules/Bio/EnsEMBL/DBSQL/BaseAdaptor.pm b/modules/Bio/EnsEMBL/DBSQL/BaseAdaptor.pm index 4d912e9995..bead6dfa63 100755 --- a/modules/Bio/EnsEMBL/DBSQL/BaseAdaptor.pm +++ b/modules/Bio/EnsEMBL/DBSQL/BaseAdaptor.pm @@ -124,12 +124,13 @@ sub new { throw("Don't have a db [$dbobj] for new adaptor"); } - if($dbobj->isa('Bio::EnsEMBL::Container')) { - #avoid a circular reference loop! - $self->db($dbobj->_obj); - } else { - $self->db($dbobj); - } + if( ref($dbobj) =~ /DBAdaptor$/){ + $self->db($dbobj); + $self->dbc($dbobj->db); + } + else{ + throw("Don't have a DBAdaptor [$dbobj] for new adaptor"); + } return $self; } @@ -152,7 +153,7 @@ sub new { sub prepare{ my ($self,$string) = @_; - return $self->db->prepare($string); + return $self->dbc->prepare($string); } @@ -170,15 +171,19 @@ sub prepare{ =cut sub db{ - my $obj = shift; - if( @_ ) { - my $value = shift; - $obj->{'db'} = $value; - } - return $obj->{'db'}; + my $self = shift; + $self->{'db'} = shift if(@_); + + return $self->{'db'}; } +sub dbc{ + my $self = shift; + $self->{'dbc'} = shift if(@_); + + return $self->{'dbc'}; +} =head2 deleteObj diff --git a/modules/Bio/EnsEMBL/DBSQL/BaseFeatureAdaptor.pm b/modules/Bio/EnsEMBL/DBSQL/BaseFeatureAdaptor.pm index ad58cb3b5b..01065b9133 100644 --- a/modules/Bio/EnsEMBL/DBSQL/BaseFeatureAdaptor.pm +++ b/modules/Bio/EnsEMBL/DBSQL/BaseFeatureAdaptor.pm @@ -170,7 +170,7 @@ sub generic_fetch { #append additional clauses which may have been defined $sql .= "\n$final_clause"; - my $sth = $db->prepare($sql); + my $sth = $db->db->prepare($sql); $sth->execute; my $res = $self->_objs_from_sth($sth, $mapper, $slice); diff --git a/modules/Bio/EnsEMBL/DBSQL/DBAdaptor.pm b/modules/Bio/EnsEMBL/DBSQL/DBAdaptor.pm index 4da0879a92..a4d542b03f 100755 --- a/modules/Bio/EnsEMBL/DBSQL/DBAdaptor.pm +++ b/modules/Bio/EnsEMBL/DBSQL/DBAdaptor.pm @@ -37,25 +37,21 @@ methods are usually preceded with a _ =cut - package Bio::EnsEMBL::DBSQL::DBAdaptor; + use vars qw(@ISA); use strict; use Bio::EnsEMBL::DBSQL::DBConnection; use Bio::EnsEMBL::DBSQL::BaseFeatureAdaptor; use Bio::EnsEMBL::Utils::SeqRegionCache; - use Bio::EnsEMBL::Utils::Exception qw(throw warning deprecate); +#use Bio::EnsEMBL::Utils::Exception qw(warning throw deprecate stack_trace_dump); use Bio::EnsEMBL::Utils::Argument qw(rearrange); - -@ISA = qw(Bio::EnsEMBL::DBSQL::DBConnection); - - - -#Override constructor inherited by Bio::EnsEMBL::DBSQL::DBConnection - +use Bio::EnsEMBL::Registry; +use Bio::EnsEMBL::Utils::ConfigRegistry; +my $reg = "Bio::EnsEMBL::Registry"; =head2 new @@ -69,6 +65,9 @@ use Bio::EnsEMBL::Utils::Argument qw(rearrange); -dbname => 'pog', -host => 'caldy', -driver => 'mysql' ); + Exmaple2 : $db = new Bio::EnsEMBL::DBSQL::DBAdaptor( + -species => 'Homo_sapiens', + -group => 'core'); Description: Constructor for DBAdaptor. Returntype : Bio::EnsEMBL::DBSQL::DBAdaptor Exceptions : none @@ -80,861 +79,341 @@ sub new { my($class, @args) = @_; #call superclass constructor - my $self = $class->SUPER::new(@args); - - my ( $dnadb ) = rearrange([qw(DNADB)],@args); - - if(defined $dnadb) { - $self->dnadb($dnadb); - } - - # $self here is actually a Container object - # so need to call _obj to get the DBAdaptor - $self->_obj->{'default_module'} = - { 'Analysis' => 'Bio::EnsEMBL::DBSQL::AnalysisAdaptor', - 'ArchiveStableId' => 'Bio::EnsEMBL::DBSQL::ArchiveStableIdAdaptor', - 'Attribute' => 'Bio::EnsEMBL::DBSQL::AttributeAdaptor', - 'AssemblyExceptionFeature' => 'Bio::EnsEMBL::DBSQL::AssemblyExceptionFeatureAdaptor', - 'AssemblyMapper' => 'Bio::EnsEMBL::DBSQL::AssemblyMapperAdaptor', - 'Blast' => 'Bio::EnsEMBL::External::BlastAdaptor', - 'Chromosome' => 'Bio::EnsEMBL::DBSQL::ChromosomeAdaptor', - 'Clone' => 'Bio::EnsEMBL::DBSQL::CloneAdaptor', - 'CoordSystem' => 'Bio::EnsEMBL::DBSQL::CoordSystemAdaptor', - 'CompressedSequence' => 'Bio::EnsEMBL::DBSQL::CompressedSequenceAdaptor', - 'DBEntry' => 'Bio::EnsEMBL::DBSQL::DBEntryAdaptor', - 'DnaAlignFeature' => 'Bio::EnsEMBL::DBSQL::DnaAlignFeatureAdaptor', - 'DensityFeature' => 'Bio::EnsEMBL::DBSQL::DensityFeatureAdaptor', - 'DensityType' => 'Bio::EnsEMBL::DBSQL::DensityTypeAdaptor', - 'Exon' => 'Bio::EnsEMBL::DBSQL::ExonAdaptor', - 'Gene' => 'Bio::EnsEMBL::DBSQL::GeneAdaptor', - 'KaryotypeBand' => 'Bio::EnsEMBL::DBSQL::KaryotypeBandAdaptor', - 'MapFrag' => 'Bio::EnsEMBL::DBSQL::MapFragAdaptor', - 'Marker' => 'Bio::EnsEMBL::Map::DBSQL::MarkerAdaptor', - 'MarkerFeature' => - 'Bio::EnsEMBL::Map::DBSQL::MarkerFeatureAdaptor', - 'MetaContainer' => 'Bio::EnsEMBL::DBSQL::MetaContainer', - 'MetaCoordContainer' => 'Bio::EnsEMBL::DBSQL::MetaCoordContainer', - 'MiscSet' => 'Bio::EnsEMBL::DBSQL::MiscSetAdaptor', - 'MiscFeature' => 'Bio::EnsEMBL::DBSQL::MiscFeatureAdaptor', - 'PredictionTranscript' => - 'Bio::EnsEMBL::DBSQL::PredictionTranscriptAdaptor', - 'PredictionExon' => 'Bio::EnsEMBL::DBSQL::PredictionExonAdaptor', - 'ProteinFeature' => 'Bio::EnsEMBL::DBSQL::ProteinFeatureAdaptor', - 'Protein' => 'Bio::EnsEMBL::DBSQL::ProteinAdaptor', - 'ProteinAlignFeature' => - 'Bio::EnsEMBL::DBSQL::ProteinAlignFeatureAdaptor', - 'ProxySNP' => 'Bio::EnsEMBL::DBSQL::ProxySNPAdaptor', - 'QtlFeature' => 'Bio::EnsEMBL::Map::DBSQL::QtlFeatureAdaptor', - 'Qtl' => 'Bio::EnsEMBL::Map::DBSQL::QtlAdaptor', - 'RawContig' => 'Bio::EnsEMBL::DBSQL::RawContigAdaptor', - 'RepeatConsensus' => 'Bio::EnsEMBL::DBSQL::RepeatConsensusAdaptor', - 'RepeatFeature' => 'Bio::EnsEMBL::DBSQL::RepeatFeatureAdaptor', - 'Sequence' => 'Bio::EnsEMBL::DBSQL::SequenceAdaptor', - 'SimpleFeature' => 'Bio::EnsEMBL::DBSQL::SimpleFeatureAdaptor', - 'Slice' => 'Bio::EnsEMBL::DBSQL::SliceAdaptor', - 'SupportingFeature' => - 'Bio::EnsEMBL::DBSQL::SupportingFeatureAdaptor', - 'Transcript' => 'Bio::EnsEMBL::DBSQL::TranscriptAdaptor', - 'Translation' => 'Bio::EnsEMBL::DBSQL::TranslationAdaptor', - - }; - - - # initialise storage for hash of names of current modules - %{$self->_obj->{'current_module'}} = %{$self->_obj->{'default_module'}}; - - # keep a hash of objects representing objects of each adaptor type - # instantiated as required in get adaptor - $self->_obj->{'current_objects'} = {}; - - # initialise generic feature adaptor storage - $self->_obj->{'generic_feature_adaptors'} = {}; - - - - return $self; -} - - - -=head2 get_ArchiveStableIdAdaptor - - Args : none - Example : none - Description: ... - Returntype : Bio::EnsEMBL::DBSQL::ArchiveStableIdAdaptor - Exceptions : none - Caller : general - -=cut - -sub get_ArchiveStableIdAdaptor { - my( $self ) = @_; - - return - $self->get_adaptor("ArchiveStableId"); -} - - -=head2 get_QtlFeatureAdaptor - - Args : none - Example : none - Description: ... - Returntype : Bio::EnsEMBL::Map::DBSQL::QtlFeatureAdaptor - Exceptions : none - Caller : general - -=cut - -sub get_QtlFeatureAdaptor { - my $self = shift; - return $self->get_adaptor("QtlFeature"); -} - -=head2 get_QtlAdaptor - - Args : none - Example : none - Description: ... - Returntype : Bio::EnsEMBL::Map::DBSQL::QtlAdaptor - Exceptions : none - Caller : general - -=cut - -sub get_QtlAdaptor { - my $self = shift; - return $self->get_adaptor("Qtl"); -} - -=head2 get_MetaContainer - - Args : none - Example : $meta_container = $db_adaptor->get_MetaContainer(); - Description: Gets a MetaContainer object for this database - Returntype : Bio::EnsEMBL::DBSQL::MetaContainer - Exceptions : none - Caller : general - -=cut - -sub get_MetaContainer { - my $self = shift; - return $self->get_adaptor('MetaContainer'); -} - - - -=head2 get_MetaCoordContainer - - Arg [1] : none - Example : $meta_coord_container = $db_adaptor->get_MetaCoordContainer(); - Description: Gets a MetaCoordContainer object for this database. - Returntype : Bio::EnsEMBL::DBSQL::MetaCoordContainer - Exceptions : none - Caller : general - -=cut - -sub get_MetaCoordContainer { - my $self = shift; - return $self->get_adaptor('MetaCoordContainer'); -} - -=head2 get_ProteinFeatureAdaptor - - Args : none - Example : $pfa = $database_adaptor->get_ProteinFeatureAdaptor(); - Description: Gets a ProteinFeatureAdaptor for this database. - Formerly named get_Protfeat_Adaptor() - Returntype : Bio::EnsEMBL::DBSQL::ProteinFeatureAdaptor - Exceptions : none - Caller : general - -=cut - -sub get_ProteinFeatureAdaptor { - my $self = shift; - return $self->get_adaptor("ProteinFeature"); -} - - -=head2 get_SNPAdaptor - - Args : none - Example : $snp_adaptor = $db_adaptor->get_SNPAdaptor(); - Description: Gets a SNPAdaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::SNPAdaptor - Exceptions : none - Caller : general - -=cut - -sub get_SNPAdaptor { - my ($self) = @_; - - my $lite = $self->get_db_adaptor('lite'); - my $primary_adaptor; - - if($lite) { - $primary_adaptor = $lite->get_SNPAdaptor(); - } else { - my $snp = $self->get_db_adaptor('SNP'); - - unless($snp) { - warning("No lite or SNP database, cannot get snp adaptor\n"); - return undef; - } - - $primary_adaptor = $snp->get_SNPAdaptor(); - $primary_adaptor->ensembl_db( $self ); - } - - #return a proxy adaptor which can use the lite or the core database - return $self->get_adaptor("ProxySNP", - $primary_adaptor); -} - - -=head2 get_BlastAdaptor - - Args : none - Example : $blast_adaptor = $db_adaptor->get_BlastAdaptor(); - Description: Gets a BlastAdaptor for retrieving stored blast hits - Returntype : Bio::EnsEMBL::External::BlastAdaptor - Exceptions : none - Caller : general - -=cut - -sub get_BlastAdaptor { - my ($self) = @_; - - my $db_apt = $self->get_db_adaptor('blast'); - - return $self->get_adaptor("Blast", - $db_apt); -} - - -=head2 get_PredictionTranscriptAdaptor - - Args : none - Example : $pta = $db_adaptor->get_PredictionTranscriptAdaptor(); - Description: Gets a PredictionTranscriptAdaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::PredictionTranscriptAdaptor - Exceptions : none - Caller : general - -=cut - -sub get_PredictionTranscriptAdaptor { - my ($self) = @_; - - return $self->get_adaptor("PredictionTranscript"); -} - - -=head2 get_PredictionExonAdaptor - - Args : none - Example : $pea = $db_adaptor->get_PredictionExonAdaptor(); - Description: Gets a PredictionExonAdaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::PredictionExonAdaptor - Exceptions : none - Caller : general - -=cut - -sub get_PredictionExonAdaptor { - my ($self) = @_; - - return $self->get_adaptor("PredictionExon"); -} - - -=head2 get_SequenceAdaptor - - Args : none - Example : $sequence_adaptor = $db_adaptor->get_SequenceAdaptor(); - Description: Gets a SequenceAdaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::SequenceAdaptor - Exceptions : none - Caller : general - -=cut - -sub get_SequenceAdaptor { - my $self = shift; - - my $mc = $self->dnadb->get_MetaContainer(); - - my ($use_compressed) = @{$mc->list_value_by_key('sequence.compression')}; - - if($use_compressed) { - return $self->dnadb->get_adaptor("CompressedSequence"); - } else { - #return the sequence adaptor for the dnadb (which may be this db) - return $self->dnadb->get_adaptor("Sequence"); - } -} - - -=head2 get_CompressedSequenceAdaptor - - Args : none - Example : $seq_adaptor = $db_adaptor->get_CompressedSequenceAdaptor(); - Description: Gets a CompressedSequenceAdaptor for this database. - A compressed sequence adaptor behaves like a normal - SequenceAdaptor except that it stores and retrieves compressed - sequence from the dnac table (rather than the dna table). - Normally if you want to use compressed sequence you should - convert your database to a compressed database with a script - and then set the 'sequence.compression' meta_key to a value - of '1' in the meta table. This way the compressed sequence - adaptor will be used instead of the normal sequence adaptor. - Returntype : Bio::EnsEMBL::DBSQL::SequenceAdaptor - Exceptions : none - Caller : general - -=cut - -sub get_CompressedSequenceAdaptor { - my $self = shift; - - #return the sequence adaptor for the dnadb (which may be this db) - return $self->dnadb->get_adaptor("CompressedSequence"); -} - - - -=head2 get_GeneAdaptor - - Args : none - Example : $gene_adaptor = $db_adaptor->get_GeneAdaptor(); - Description: Gets a GeneAdaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::GeneAdaptor - Exceptions : none - Caller : general - -=cut - -sub get_GeneAdaptor { - my( $self ) = @_; - #get a core db adaptor - return $self->get_adaptor("Gene"); -} - - -=head2 get_ExonAdaptor - - Args : none - Example : $exon_adaptor = $db_adaptor->get_ExonAdaptor(); - Description: Gets an ExonAdaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::ExonAdaptor - Exceptions : none - Caller : general - -=cut - -sub get_ExonAdaptor { - my( $self ) = @_; - - return $self->get_adaptor("Exon"); -} - - -=head2 get_TranscriptAdaptor - - Args : none - Example : $transcript_adaptor = $db_adaptor->get_TranscriptAdaptor(); - Description: Gets a TranscriptAdaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::TranscriptAdaptor - Exceptions : none - Caller : general - -=cut - -sub get_TranscriptAdaptor { - my( $self ) = @_; - - return $self->get_adaptor("Transcript"); -} - - -=head2 get_TranslationAdaptor - - Args : none - Example : $translation_adaptor = $db_adaptor->get_TranslationAdaptor(); - Description: Gets a TranslationAdaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::TranslationAdaptor - Exceptions : none - Caller : general - -=cut - -sub get_TranslationAdaptor { - my( $self ) = @_; - - return $self->get_adaptor("Translation"); -} - - - -=head2 get_SliceAdaptor - - Args : none - Example : $slice_adaptor = $db_adaptor->get_SliceAdaptor(); - Description: Gets a SliceAdaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::SliceAdaptor - Exceptions : none - Caller : general - -=cut - -sub get_SliceAdaptor { - my( $self ) = @_; - - return $self->get_adaptor("Slice"); -} - - -=head2 get_AnalysisAdaptor - - Args : none - Example : $analysis_adaptor = $db_adaptor->get_AnalysisAdaptor(); - Description: Gets an AnalysisAdaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::AnalysisAdaptor - Exceptions : none - Caller : general - -=cut - -sub get_AnalysisAdaptor { - my( $self ) = @_; - - return $self->get_adaptor("Analysis"); -} - - -=head2 get_SimpleFeatureAdaptor - - Args : none - Example : $sfa = $db_adaptor->get_SimpleFeatureAdaptor(); - Description: Gets a SimpleFeatureAdaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::SimpleFeatureAdaptor - Exceptions : none - Caller : general - -=cut - -sub get_SimpleFeatureAdaptor { - my( $self ) = @_; - - return $self->get_adaptor("SimpleFeature"); -} - - -=head2 get_RepeatConsensusAdaptor - - Args : none - Example : $rca = $db_adaptor->get_RepeatConsensusAdaptor(); - Description: Gets a RepeatConsensusAdaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::RepeatConsensusAdaptor - Exceptions : none - Caller : general - -=cut - -sub get_RepeatConsensusAdaptor { - my( $self ) = @_; - - return $self->get_adaptor("RepeatConsensus"); -} - - -=head2 get_RepeatFeatureAdaptor - - Args : none - Example : $rfa = $db_adaptor->get_RepeatFeatureAdaptor(); - Description: Gets a RepeatFeatureAdaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::RepeatFeatureAdaptor - Exceptions : none - Caller : general - -=cut - -sub get_RepeatFeatureAdaptor { - my( $self ) = @_; - - return $self->dnadb->get_adaptor("RepeatFeature"); -} - - -=head2 get_ProteinAlignFeatureAdaptor - - Args : none - Example : $pafa = $db_adaptor->get_ProteinAlignFeatureAdaptor(); - Description: Gets a ProteinAlignFeatureAdaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::ProteinAlignFeatureAdaptor - Exceptions : none - Caller : general - -=cut - -sub get_ProteinAlignFeatureAdaptor { - my( $self ) = @_; - - return $self->get_adaptor("ProteinAlignFeature"); -} - - -=head2 get_DnaAlignFeatureAdaptor - - Args : none - Example : $dafa = $db_adaptor->get_DnaAlignFeatureAdaptor(); - Description: Gets a DnaAlignFeatureAdaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::DnaAlignFeatureAdaptor - Exceptions : none - Caller : general - -=cut - -sub get_DnaAlignFeatureAdaptor { - my $self = shift; - - return $self->get_adaptor("DnaAlignFeature"); -} - - -=head2 get_AssemblyMapperAdaptor - - Args : none - Example : $asma = $db_adaptor->get_AssemblyMapperAdaptor(); - Description: Gets an AsemblyMapperAdaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::AssemblyMapperAdaptor - Exceptions : none - Caller : general - -=cut - -sub get_AssemblyMapperAdaptor { - my( $self ) = @_; - - return - $self->dnadb->get_adaptor("AssemblyMapper"); -} - - -=head2 get_DBEntryAdaptor - - Args : none - Example : $dbentry_adaptor = $db_adaptor->get_DBEntryAdaptor(); - Description: Gets a DBEntryAdaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::DBEntryAdaptor - Exceptions : none - Caller : general - -=cut - -sub get_DBEntryAdaptor { - my( $self ) = @_; - - return $self->get_adaptor("DBEntry"); -} - - - - -=head2 get_DensityFeatureAdaptor - - Arg [1] : none - Example : $density_feature_adaptor = $db_adaptor->get_DBEntryAdaptor(); - Description: Gets a DensityFeatureAdaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::DensityFeatureAdaptor - Exceptions : none - Caller : general - -=cut - -sub get_DensityFeatureAdaptor { - my $self = shift; - return $self->get_adaptor('DensityFeature'); -} - -=head2 get_DensityTypeAdaptor - - Arg [1] : none - Example : $density_feature_adaptor = $db_adaptor->get_DBEntryAdaptor(); - Description: Gets a DensityTypeAdaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::DensityTypeAdaptor - Exceptions : none - Caller : general - -=cut - -sub get_DensityTypeAdaptor { - my $self = shift; - return $self->get_adaptor('DensityType'); -} - + my $self ={}; + bless $self,$class; + my ($species, $group, $dbname) = + rearrange([qw(SPECIES GROUP DBNAME)], @args); -=head2 get_KaryotypeBandAdaptor - Args : none - Example : $kba = $db_adaptor->get_KaryotypeBandAdaptor(); - Description: Gets a KaryotypeBandAdaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::KaryotypeBandAdaptor - Exceptions : none - Caller : general + my ($spec,$gro) = $reg->check_if_already_there(@args); + if($spec){ + $self = $reg->get_DBAdaptor($spec,$gro); + $self->species($species); + $self->group($group); + return $self; + } + my $config_sub; + if(defined($species)and defined($group)){ # NEW style usage of registry + $self = $reg->get_DBAdaptor($species,$group); + $self->species($species); + $self->group($group); + } + else{ # OLD style, so mimic by adding to registry + my $free=0; + if(!defined($species)){ + $species= "DEFAULT"; + } + if($class->isa('Bio::EnsEMBL::Compara::DBSQL::DBAdaptor')){ + $group = "compara"; + $config_sub = \&Bio::EnsEMBL::Utils::ConfigRegistry::load_compara; + } + elsif($class->isa('Bio::EnsEMBL::Lite::DBAdaptor')){ + $group = 'lite'; + $config_sub = \&Bio::EnsEMBL::Utils::ConfigRegistry::load_lite; + } + elsif($class->isa('Bio::EnsEMBL::External::BlastAdaptor')){ + $group = 'blast'; + $config_sub = \&Bio::EnsEMBL::Utils::ConfigRegistry::load_blast; + } + elsif($class->isa('Bio::EnsEMBL::ExternalData::SNPSQL::DBAdaptor')){ + $group = "SNP"; + $config_sub = \&Bio::EnsEMBL::Utils::ConfigRegistry::load_SNP; + } + elsif($class->isa('Bio::EnsEMBL::Pipeline::DBSQL::DBAdaptor')){ + $group = "pipeline"; + $config_sub = \&Bio::EnsEMBL::Utils::ConfigRegistry::load_pipeline; + } + elsif($class->isa('Bio::EnsEMBL::Hive::DBSQL::DBAdaptor')){ + $group = "hive"; + $config_sub = \&Bio::EnsEMBL::Utils::ConfigRegistry::load_hive; + } + elsif($class->isa('Bio::EnsEMBL::DBSQL::DBAdaptor')){ + $group = "core"; + $config_sub = \&Bio::EnsEMBL::Utils::ConfigRegistry::load_core; + } + else{ + throw("Unknown DBAdaptor type $class\n"); + } -=cut + $reg->add_alias($species,$species); -sub get_KaryotypeBandAdaptor { - my( $self ) = @_; + my $i = 0; + while(!$free){ + if($i == 0){ + if(!defined($reg->get_DBAdaptor($species, $group))){ + $free =1; + $i =""; + } + else{ + $i = 1; + } + } + else{ + $reg->add_alias($species.$i,$species.$i); #set needed self alias + if(!defined($reg->get_DBAdaptor($species.$i, $group))){ + $free =1; + } + else{ + $i++; + } + } + } - return - $self->dnadb->get_adaptor("KaryotypeBand"); -} + $species .= $i; + push (@args, '-species'); + push (@args, $species); -=head2 get_SupportingFeatureAdaptor + &{$config_sub}($class,@args); - Arg [1] : none - Example : $sfa = $db_adaptor->get_SupportingFeatureAdaptor(); - Description: Gets a SupportingFeatreAdaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::SupportingFeatureAdaptor - Exceptions : none - Caller : Bio::EnsEMBL::Exon + $self = $reg->get_DBAdaptor($species,$group); -=cut + } -sub get_SupportingFeatureAdaptor { - my $self = shift; + my ( $dnadb ) = rearrange([qw(DNADB)],@args); - return $self->get_adaptor("SupportingFeature"); + if(defined $dnadb) { + $self->dnadb($dnadb); + } + return $self; } +=head2 new_fast + Arg [-CON]: Bio::EnsEMBL::DBSQL::DBConnection -=head2 get_MarkerFeatureAdaptor - - Arg [1] : none - Example : $mfa = $db_adaptor->get_MarkerFeatureAdaptor; - Description: Gets a MarkerFeatureAdaptor for this database - Returntype : Bio::EnsEMBL::Map::DBSQL::MarkerFeatureAdaptor + Exmaple : $db = new Bio::EnsEMBL::DBSQL::DBAdaptor( -con => $dbc); + Description: Constructor for DBAdaptor. + Returntype : Bio::EnsEMBL::DBSQL::DBAdaptor Exceptions : none Caller : general =cut -sub get_MarkerFeatureAdaptor { - my $self = shift; +sub new_fast{ + my($class, @args) = @_; + my ( $con ) = rearrange([qw(CON)],@args); - return $self->get_adaptor('MarkerFeature'); -} + #call superclass constructor + my $self ={}; + bless $self,$class; + unless($con && ref $con && + $con->isa('Bio::EnsEMBL::DBSQL::DBConnection')) { + throw("$con passed is not of type Bio::EnsEMBL::DBSQL::DBConnection"); + } + $self->db($con); + $self->species($con->species()); + $self->group($con->group()); + return $self; +} -=head2 get_MarkerAdaptor - Arg [1] : none - Example : $ma = $db_adaptor->get_MarkerAdaptor; - Description: Gets a MarkerAdaptor for this database - Returntype : Bio::EnsEMBL::Map::DBSQL::MarkerAdaptor - Exceptions : none - Caller : general +sub new_merged{ + my($class, $species, @args) = @_; -=cut + my $self ={}; + bless $self,$class; -sub get_MarkerAdaptor { - my $self = shift; + $self->species($species); + $self->group("_MERGED_"); - return $self->get_adaptor('Marker'); + return $self; } -=head2 get_CoordSystemAdaptor +=head2 db - Arg [1] : none - Example : $csa = $db_adaptor->get_CoordSystemAdaptor(); - Description: Gets a CoordSystemAdaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::CoordSystemAdaptor + Arg[1] : (optional) Bio::EnsEMBL::DBSQL::DBConnection + + Exmaple : $dbc = $dba->db(); + Description: Getter/Setter for DBConnection. + Returntype : Bio::EnsEMBL::DBSQL::DBConnection Exceptions : none Caller : general =cut -sub get_CoordSystemAdaptor { - my $self = shift; - - return $self->dnadb()->get_adaptor('CoordSystem'); +sub db{ + my ($self, $arg ) = @_; + ( defined $arg ) && + ( $self->{_db} = $arg ); + $self->{_db}; } +sub DESTROY{ + my ($self)= @_; + $self->{'_db'} = undef; +} -=head2 get_MiscSetAdaptor +=head2 deleteObj Arg [1] : none - Example : $msa = $db_adaptor->get_MiscSetAdaptor(); - Description: Gets a MiscSet adaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::MiscSetAdaptor + Example : none + Description: Cleans up circular reference loops so proper garbage collection + can occur. + Returntype : none Exceptions : none - Caller : general + Caller : DBAdaptorContainer::DESTROY =cut -sub get_MiscSetAdaptor { +sub deleteObj { my $self = shift; + #print "called deleteObj on DBAdaptor\n"; - return $self->get_adaptor('MiscSet'); -} - - - -=head2 get_MiscFeatureAdaptor + #clean up external feature adaptor references + if(exists $self->{'_xf_adaptors'}) { + foreach my $key (keys %{$self->{'_xf_adaptors'}}) { + delete $self->{'_xf_adaptors'}->{$key}; + } + } - Arg [1] : none - Example : $mfa = $db_adaptor->get_MiscFeatureAdaptor(); - Description: Gets a MiscFeature adaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::MiscFeatureAdaptor - Exceptions : none - Caller : general + if(exists $self->{'generic_feature_adaptors'}) { + foreach my $name (keys %{$self->{'generic_feature_adaptors'}}) { + my $adaptor = $self->{'generic_feature_adaptors'}->{$name}; + if(ref($adaptor) && $adaptor->can('deleteObj')) { + $adaptor->deleteObj(); + } -=cut + delete $self->{'generic_feature_adaptors'}->{$name}; + } -sub get_MiscFeatureAdaptor { - my $self = shift; + delete $self->{'generic_feature_adaptors'}; + } - return $self->get_adaptor('MiscFeature'); } -=head2 get_AssemblyExceptionFeatureAdaptor +=head2 add_db_adaptor - Arg [1] : none - Example : $aefa = $db_adaptor->get_AssemblyExceptionFeatureAdaptor(); - Description: Gets a AssemblyExceptionFeature adaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::AssemblyExceptionFeatureAdaptor + Arg [1] : string $name + the name of the database to attach to this database + Arg [2] : Bio::EnsEMBL::DBSQL::DBConnection + the db adaptor to attach to this database + Example : $db->add_db_adaptor('lite', $lite_db_adaptor); + Description: Attaches another database instance to this database so + that it can be used in instances where it is required. + Returntype : none Exceptions : none - Caller : general + Caller : EnsWeb =cut -sub get_AssemblyExceptionFeatureAdaptor { - my $self = shift; +sub add_db_adaptor { + my ($self, $name, $adaptor) = @_; - return $self->dnadb->get_adaptor('AssemblyExceptionFeature'); -} + unless($name && $adaptor && ref $adaptor) { + throw('adaptor and name arguments are required'); + } + + Bio::EnsEMBL::Registry->add_db($self, $name, $adaptor); +} -=head2 get_AttributeAdaptor +=head2 remove_db_adaptor - Arg [1] : none - Example : $aa = $db_adaptor->get_AttributeAdaptor() - Description: Gets an AttributeAdaptor for this database - Returntype : Bio::EnsEMBL::DBSQL::AttributeAdaptor + Arg [1] : string $name + the name of the database to detach from this database. + Example : $lite_db = $db->remove_db_adaptor('lite'); + Description: Detaches a database instance from this database and returns + it. + Returntype : none Exceptions : none - Caller : general + Caller : ? =cut -sub get_AttributeAdaptor { - my $self = shift; - return $self->get_adaptor('Attribute'); +sub remove_db_adaptor { + my ($self, $name) = @_; + + return Bio::EnsEMBL::Registry->remove_db($self, $name); } -=head2 dnadb +=head2 get_all_db_adaptors - Title : dnadb - Usage : my $dnadb = $db->dnadb; - Function: returns the database adaptor where the dna lives - Useful if you only want to keep one copy of the dna - on disk but have other databases with genes and features in - Returns : dna database adaptor - Args : Bio::EnsEMBL::DBSQL::DBAdaptor + Arg [1] : none + Example : @attached_dbs = values %{$db->get_all_db_adaptors()}; + Description: returns all of the attached databases as + a hash reference of key/value pairs where the keys are + database names and the values are the attached databases + Returntype : hash reference with Bio::EnsEMBL::DBSQL::DBConnection values + Exceptions : none + Caller : Bio::EnsEMBL::DBSQL::ProxyAdaptor =cut -sub dnadb { - my $self = shift; +sub get_all_db_adaptors { + my ($self) = @_; - if(@_) { - my $arg = shift; - if(ref($arg) && (($arg->isa('Bio::EnsEMBL::Container') && - $arg->_obj == $self) || $arg == $self)) { - #we don't want to store a circular reference to our self - return; - } + my %ret = %{Bio::EnsEMBL::Registry->get_all_db_adaptors($self)}; - $self->{'dnadb'} = $arg; - } +# foreach my $key (%ret){ +# print $key."\n"; +# } +# print %ret."\n"; + return \%ret; +# unless(defined $self->{'_db_adaptors'}) { +# return {}; +# } - return $self->{'dnadb'} || $self; +# return $self->{'_db_adaptors'}; } -=head2 deleteObj +=head2 get_db_adaptor - Arg [1] : none - Example : none - Description: Cleans up circular reference loops so proper garbage collection - can occur. - Returntype : none + Arg [1] : string $name + the name of the attached database to retrieve + Example : $lite_db = $db->get_db_adaptor('lite'); + Description: returns an attached db adaptor of name $name or undef if + no such attached database exists + Returntype : Bio::EnsEMBL::DBSQL::DBConnection Exceptions : none - Caller : DBAdaptorContainer::DESTROY + Caller : ? =cut -sub deleteObj { - my $self = shift; - #print "called deleteObj on DBAdaptor\n"; - - #clean up external feature adaptor references - if(exists $self->{'_xf_adaptors'}) { - foreach my $key (keys %{$self->{'_xf_adaptors'}}) { - delete $self->{'_xf_adaptors'}->{$key}; - } - } - - if(exists $self->{'current_objects'}) { - foreach my $adaptor_name (keys %{$self->{'current_objects'}}) { - my $adaptor = $self->{'current_objects'}->{$adaptor_name}; +sub get_db_adaptor { + my ($self, $name) = @_; - if(ref($adaptor) && $adaptor->can('deleteObj')) { - $adaptor->deleteObj(); - } + return Bio::EnsEMBL::Registry->get_db($self, $name); +} - delete $self->{'current_objects'}->{$adaptor_name}; - } - } +sub get_SNPAdaptor { + my ($self) = @_; + + my $lite = $self->get_db_adaptor('lite'); #### use register directly here - if(exists $self->{'generic_feature_adaptors'}) { - foreach my $name (keys %{$self->{'generic_feature_adaptors'}}) { - my $adaptor = $self->{'generic_feature_adaptors'}->{$name}; - if(ref($adaptor) && $adaptor->can('deleteObj')) { - $adaptor->deleteObj(); - } + my $primary_adaptor; - delete $self->{'generic_feature_adaptors'}->{$name}; + if($lite) { + $primary_adaptor = $lite->get_SNPAdaptor(); + } else { + my $snp = $self->get_db_adaptor('SNP'); + + unless($snp) { + warn("No lite or SNP database, cannot get snp adaptor"); + return undef; } - delete $self->{'generic_feature_adaptors'}; + $primary_adaptor = $snp->get_SNPAdaptor(); + $primary_adaptor->ensembl_db( $self ); } - - delete $self->{'_meta_container'}; - delete $self->{'dnadb'}; - - #call the superclass deleteObj method - $self->SUPER::deleteObj; + #return a proxy adaptor which can use the lite or the core database + my $ret = $self->get_adaptor("ProxySNP"); + $ret->set_primary($primary_adaptor); + return $ret; +# return $self->get_adaptor("ProxySNP", $primary_adaptor); } @@ -1115,36 +594,79 @@ sub add_ExternalFeatureFactory{ Arg [1] : Canonical data type for which an adaptor is required. Example : $db_adaptor->get_adaptor("Protein") Description: Gets an adaptor object for a standard data type. - Returntype : Adaptor Object of arbitrary type - Exceptions : thrown if there is no associated module + Returntype : Adaptor Object of arbitrary type or undef + Exceptions : none Caller : external =cut sub get_adaptor { - my ($self, $canonical_name, @other_args) = @_; + my ($self, $canonical_name, @other_args) = @_; - if ($self->isa('Bio::EnsEMBL::Container')) { - $self = $self->_obj; - } + return $reg->get_adaptor($self->db->species(),$self->db->group(),$canonical_name); +} - # throw if module for $canonical_name does not exist - throw("No such data type $canonical_name") - if (!exists($self->{'current_module'}->{$canonical_name})); - # get module name for $canonical_name - my $module_name = $self->{'default_module'}->{$canonical_name}; - # create and store a new one if necessary - if (!exists($self->{'current_objects'}->{$canonical_name})) { - $self->{'current_objects'}->{$canonical_name} = - $self->_get_adaptor($module_name, @other_args); - } +sub prepare{ + my ($self, @args) = @_; + + deprecate("prepare Should no longer be called from the DBAdaptor. DBConnection should now be used OR preferably the object adaptor itself\n"); + $self->db->prepare(@args); +} + +sub dbname{ + my ($self, @args) = @_; + + deprecate("dbname Should no longer be called from the DBAdaptor. DBConnection should now be used OR preferably the object adaptor itself\n"); + $self->db->dbname(@args); +} - return $self->{'current_objects'}->{$canonical_name}; +sub disconnect_when_inactive{ + my ($self, @args) = @_; + deprecate("disconnect_when_inactive Should no longer be called from the DBAdaptor. DBConnection should now be used OR preferably the object adaptor itself\n"); + $self->db->disconnect_when_inactive(@args); } +sub host{ + my ($self, @args) = @_; + + deprecate("host Should no longer be called from the DBAdaptor. DBConnection should now be used OR preferably the object adaptor itself\n"); + $self->db->host(@args); +} +sub username{ + my ($self, @args) = @_; + + deprecate("username Should no longer be called from the DBAdaptor. DBConnection should now be used OR preferably the object adaptor itself\n"); + $self->db->username(@args); +} +sub password{ + my ($self, @args) = @_; + + deprecate("password Should no longer be called from the DBAdaptor. DBConnection should now be used OR preferably the object adaptor itself\n"); + $self->db->password(@args); +} +sub driver{ + my ($self, @args) = @_; + + deprecate("driver Should no longer be called from the DBAdaptor. DBConnection should now be used OR preferably the object adaptor itself\n"); + $self->db->driver(@args); +} +sub port{ + my ($self, @args) = @_; + + deprecate("port Should no longer be called from the DBAdaptor. DBConnection should now be used OR preferably the object adaptor itself\n"); + $self->db->port(@args); +} + +sub db_handle{ + my ($self, @args) = @_; + + + deprecate("db_handle Should no longer be called from the DBAdaptor. DBConnection should now be used OR preferably the object adaptor itself\n"); + $self->db->db_handle(@args); +} =head2 set_adaptor @@ -1155,34 +677,61 @@ sub get_adaptor { Description: Stores the object which represents the adaptor for the arg1 data type. Returntype : none - Exceptions : If arg2 is not a subclass of the default module for this - data type. + Exceptions : none Caller : external =cut sub set_adaptor { - my ($self, $canonical_name, $new_object) = @_; + my ($self, $canonical_name, $module) = @_; - if ($self->isa('Bio::EnsEMBL::Container')) { - $self = $self->_obj; - } + my $adaptor = $self->_get_adaptor($module); - # throw if an unrecognised canonical_name is used - throw("No such data type $canonical_name") - if(!exists($self->{'default_module'}->{$canonical_name})); + $reg->add_adaptor($self->species(), $self->group(), $canonical_name, $adaptor); - my $default_module = $self->{'default_module'}->{$canonical_name}; + return $adaptor; +} + +=head2 _get_adaptor + + Arg [1] : string $module + the fully qualified of the adaptor module to be retrieved + Arg [2..n] : (optional) arbitrary list @args + list of arguments to be passed to adaptors constructor + Example : $adaptor = $self->_get_adaptor("full::adaptor::name"); + Description: PROTECTED Used by subclasses to obtain adaptor objects + for this database connection using the fully qualified + module name of the adaptor. If the adaptor has not been + retrieved before it is created, otherwise it is retreived + from the adaptor cache. + Returntype : Adaptor Object of arbitrary type + Exceptions : thrown if $module can not be instantiated + Caller : Bio::EnsEMBL::DBAdaptor + +=cut + +sub _get_adaptor { + my( $self, $module) = @_; + + my( $adaptor); + + eval "require $module"; - # Check that $new_module is a subclass of $default_module - if (!$new_object->isa($default_module)) { # polymorphism should work - throw("ref($new_object) is not a subclass of $default_module"); + if($@) { + warning("$module cannot be found.\nException $@\n"); + return undef; } - # set the value in current_module - $self->{'current_objects'}->{$canonical_name} = $new_object; + $adaptor = "$module"->new($self); + + return $adaptor; } + + + + + # # GENERIC FEATURE ADAPTORS # @@ -1214,6 +763,8 @@ sub get_GenericFeatureAdaptors { if (!exists($self->{'generic_feature_adaptors'}->{$name})) { throw("No generic feature adaptor has been defined for $name" ); } + + $adaptors{$name} = $self->{'generic_feature_adaptors'}->{$name}; } } @@ -1248,8 +799,50 @@ sub add_GenericFeatureAdaptor { $self->{'generic_feature_adaptors'}->{$name} = $adaptor_obj; } +=head2 species + Arg [1] : (optional) string $arg + The new value of the species used by this DBAdaptor. + Example : $species = $dba->species() + Description: Getter/Setter for the species of to use for + this connection. There is currently no point in setting + this value after the connection has already been established + by the constructor. + Returntype : string + Exceptions : none + Caller : new + +=cut + +sub species { + my ($self, $arg ) = @_; + ( defined $arg ) && + ( $self->{_species} = $arg ); + $self->{_species}; +} + + +=head2 group + + Arg [1] : (optional) string $arg + The new value of the group used by this DBAdaptor. + Example : $group = $dba->group() + Description: Getter/Setter for the group of to use for + this connection. There is currently no point in setting + this value after the connection has already been established + by the constructor. + Returntype : string + Exceptions : none + Caller : new + +=cut +sub group { + my ($self, $arg ) = @_; + ( defined $arg ) && + ( $self->{_group} = $arg ); + $self->{_group}; +} =head2 get_SeqRegionCache @@ -1278,6 +871,64 @@ sub get_SeqRegionCache { } +=head2 dnadb + + Title : dnadb + Usage : my $dnadb = $db->dnadb(); + Function: returns the database adaptor where the dna lives + Useful if you only want to keep one copy of the dna + on disk but have other databases with genes and features in + Returns : dna database adaptor + Args : Bio::EnsEMBL::DBSQL::BaseAdaptor + +=cut + +sub dnadb { + my $self = shift; + + if(@_) { + my $arg = shift; + $reg->add_DNAAdaptor($self->species(),$self->group(),$arg); + } + +# return $self->{'dnadb'} || $self; + return $reg->get_DNAAdaptor($self->species(),$self->group()) || $self; +} + + +use vars '$AUTOLOAD'; + +sub AUTOLOAD { + my ($self,@args) = @_; + + my $type; + if($AUTOLOAD =~ /^.*::get_(\w+)Adaptor$/){ + $type = $1; + } + elsif($AUTOLOAD =~ /^.*::get_(\w+)$/){ + $type = $1; + } + else{ + throw("Could not work out type for $AUTOLOAD \n"); + } + + my $ret = undef; + if($self->group() eq "_MERGED_"){ + $ret = $reg->get_MergedAdaptor($self->species(),$type); + } + else{ + $ret = $reg->get_adaptor($self->species(),$self->group(),$type); + } + if($ret){ + return $ret; + } + else{ + warning("Could not find $type adaptor in the registry for ".$self->species." ".$self->group."\n"); + return $ret; + } + die("No such method: $AUTOLOAD\n"); +} + ######################### # sub DEPRECATED METHODS ######################### @@ -1356,20 +1007,22 @@ sub source { =head2 assembly_type - Description: DEPRECATED - Use CoordSystemAdaptor to obtain coordinate - systems instead. + Description: DEPRECATED - Use CoordSystemAdaptor to obtain default coordinate + system instead. =cut sub assembly_type{ my $self = shift; - deprecate("Use version of coordinate system you are interested in instead.\n" - . "Example:\n". - ' ($cs) = @{$coord_system_adaptor->fetch_all()};'."\n" . - ' $assembly = $cs->version();'); + + deprecate('Use CoordSystemAdaptor::fetch_top_level instead'); + my $csa = $self->get_CoordSystemAdaptor(); - my $cs = @{$csa->fetch_all()}; - return $cs->version(); + + #get the default top-level coord system + my ($dbID,$name,$version) = $csa->fetch_top_level(); + + return $version; } diff --git a/modules/Bio/EnsEMBL/DBSQL/DBConnection.pm b/modules/Bio/EnsEMBL/DBSQL/DBConnection.pm index 0edc89d5fc..e1e1ff2ee7 100644 --- a/modules/Bio/EnsEMBL/DBSQL/DBConnection.pm +++ b/modules/Bio/EnsEMBL/DBSQL/DBConnection.pm @@ -3,10 +3,12 @@ =head1 SYNOPSIS $db = Bio::EnsEMBL::DBSQL::DBConnection->new( - -user => 'anonymous', - -dbname => 'homo_sapiens_core_20_34c', - -host => 'ensembldb.ensembl.org', - -driver => 'mysql', + -user => 'anonymous', + -dbname => 'homo_sapiens_core_20_34c', + -host => 'ensembldb.ensembl.org', + -driver => 'mysql', + -species => 'Homo Sapiens', + -group => 'core' ); @@ -40,7 +42,9 @@ package Bio::EnsEMBL::DBSQL::DBConnection; use vars qw(@ISA); use strict; -use Bio::EnsEMBL::Container; +#use Bio::EnsEMBL::Container; ## Container no longer needed here +use Bio::EnsEMBL::Registry; +my $reg = "Bio::EnsEMBL::Registry"; use Bio::EnsEMBL::Root; use DBI; @@ -80,33 +84,65 @@ use Bio::EnsEMBL::Utils::Argument qw(rearrange); which would otherwise keep open a lot of connections to the database. Database connections are automatically reopened when required. + Arg [DNADB] : (optional) Bio::EnsEMBL::DBSQL::DBConnection + The dbconnection to get the dna from. + Arg [SPECIES]: (optional) string + Name of the species to be labelled as. + Arg [GROUP]: (optional) string + Name of the group to be labelled as. (e.g. core, estgene, vega etc) Example : $dbc = Bio::EnsEMBL::DBSQL::DBConnection->new (-user => 'anonymous', -dbname => 'homo_sapiens_core_20_34c', -host => 'ensembldb.ensembl.org', - -driver => 'mysql'); + -driver => 'mysql' + -species => 'Homo Sapiens', + -group => 'core'); Description: Constructor for a DatabaseConenction. Any adaptors that require database connectivity should inherit from this class. Returntype : Bio::EnsEMBL::DBSQL::DBConnection Exceptions : thrown if USER or DBNAME are not specified, or if the database cannot be connected to. - Caller : Bio::EnsEMBL::DBSQL::DBAdaptor + Caller : Bio::EnsEMBL::::Utils::ConfigRegistry ( for newer code using the registry) + Bio::EnsEMBL::DBSQL::DBAdaptor ( for old style code) =cut sub new { my $class = shift; - my ($db,$host,$driver,$user,$password,$port, $inactive_disconnect, $dbconn) = + my ($db,$host,$driver,$user,$password,$port, $inactive_disconnect, $dbconn, $species, $group, $dnadb) = rearrange([qw(DBNAME HOST DRIVER USER PASS PORT - DISCONNECT_WHEN_INACTIVE DBCONN)], @_); + DISCONNECT_WHEN_INACTIVE DBCONN SPECIES GROUP DNADB)], @_); my $self = {}; bless $self, $class; + # make sure the register can find the species name in the alias list as itself. + + if(!defined($species)){ + $species= "DEFAULT"; + $group = "core"; + + Bio::EnsEMBL::Registry->add_alias($species,$species); #set needed self alias + + my $free=0; + my $i = 1; + while(!$free){ + Bio::EnsEMBL::Registry->add_alias($species.$i,$species.$i); #set needed self alias + if(!defined(Bio::EnsEMBL::Registry->get_DBAdaptor($species.$i, $group))){ + $free =1; + } + else{ + $i++; + } + } + $species .= $i; + } + if($dbconn) { - if($db || $host || $driver || $password || $port || $inactive_disconnect) { + if($db || $host || $driver || $password || $port || $inactive_disconnect + || $dnadb) { throw("Cannot specify other arguments when -DBCONN argument used."); } @@ -116,14 +152,20 @@ sub new { $self->password($dbconn->password()); $self->port($dbconn->port()); $self->driver($dbconn->driver()); + $self->species($dbconn->species()); + $self->group($dbconn->group()); - $self->connect(); +# $self->connect(); if($dbconn->disconnect_when_inactive()) { $self->disconnect_when_inactive(1); } + else{ + $self->connect(); + } } else { + $db || throw("-DBNAME argument is required."); $user || throw("-USER argument is required."); @@ -140,18 +182,37 @@ sub new { $self->port($port); $self->driver($driver); - $self->connect(); + +# $self->connect(); + + + if($species){ +# print "setting species to $species\n"; + Bio::EnsEMBL::Registry->add_alias($species,$species); + $self->species($species); +# print "setting species to $species\n"; + } + else{ + throw("No species specified\n"); + } + if($group){ + $self->group($group); + } + if($inactive_disconnect) { $self->disconnect_when_inactive($inactive_disconnect); } + else{ + $self->connect(); + } - # be very sneaky and actually return a container object which is outside - # of the circular reference loops and will perform cleanup when all - # references to the container are gone. } - return new Bio::EnsEMBL::Container($self); + if(defined $dnadb) { + $self->dnadb($dnadb); + } + return $self; } @@ -183,6 +244,9 @@ sub connect { }; if(!$dbh || $@) { + warn("Could not connect to database " . $self->dbname() . + " as user " . $self->username() . + " using [$dsn] as a locator:\n" . $DBI::errstr); throw("Could not connect to database " . $self->dbname() . " as user " . $self->username() . " using [$dsn] as a locator:\n" . $DBI::errstr); @@ -332,6 +396,53 @@ sub password { $self->{_password}; } +=head2 species + + Arg [1] : (optional) string $arg + The new value of the species used by this connection. + Example : $host = $db_connection->species() + Description: Getter/Setter for the species of to use for + this connection. There is currently no point in setting + this value after the connection has already been established + by the constructor. + Returntype : string + Exceptions : none + Caller : new + +=cut + +sub species { + my ($self, $arg ) = @_; + ( defined $arg ) && + ( $self->{_species} = $arg ); + return $self->{_species}; +} + + +=head2 group + + Arg [1] : (optional) string $arg + The new value of the group used by this connection. + Example : $host = $db_connection->group() + Description: Getter/Setter for the group of to use for + this connection. There is currently no point in setting + this value after the connection has already been established + by the constructor. + Returntype : string + Exceptions : none + Caller : new + +=cut + +sub group { + my ($self, $arg ) = @_; + ( defined $arg ) && + ( $self->{_group} = $arg ); + return $self->{_group}; +} + + + =head2 disconnect_when_inactive @@ -356,7 +467,10 @@ sub disconnect_when_inactive { $self->{'disconnect_when_inactive'} = $val; if($val) { $self->disconnect_if_idle(); - } elsif(!$self->db_handle->ping()) { + } + elsif(!defined($self->db_handle)){ + $self->connect(); + }elsif(!$self->db_handle->ping()) { # reconnect if the connect went away $self->connect(); } @@ -433,8 +547,11 @@ sub prepare { if( ! $string ) { throw("Attempting to prepare an empty SQL query."); } - if( ! defined($self->db_handle) ) { - throw("Database object has lost its database handle."); + if( ! defined($self->db_handle) ) { # No connection to star with now so need to try again. + $self->connect(); + if( ! defined($self->db_handle) ) { + throw("Database object has lost its database handle."); + } } if($self->disconnect_when_inactive() && !$self->db_handle->ping()) { @@ -476,7 +593,10 @@ sub do { throw("Attempting to do an empty SQL query."); } if( ! defined($self->db_handle) ) { - throw("Database object has lost its database handle."); + $self->connect(); + if( ! defined($self->db_handle) ) { + throw("Database object has lost its database handle."); + } } if($self->disconnect_when_inactive() && !$self->db_handle->ping()) { @@ -519,233 +639,13 @@ sub do { sub disconnect_if_idle { my $self = shift; - if($self->db_handle()->{'Kids'} == 0 && - !$self->db_handle()->{'InactiveDestroy'}) { - $self->db_handle->disconnect(); - } -} - - -=head2 _get_adaptor - - Arg [1] : string $module - the fully qualified of the adaptor module to be retrieved - Arg [2..n] : (optional) arbitrary list @args - list of arguments to be passed to adaptors constructor - Example : $adaptor = $self->_get_adaptor("full::adaptor::name"); - Description: PROTECTED Used by subclasses to obtain adaptor objects - for this database connection using the fully qualified - module name of the adaptor. If the adaptor has not been - retrieved before it is created, otherwise it is retreived - from the adaptor cache. - Returntype : Adaptor Object of arbitrary type - Exceptions : thrown if $module can not be instantiated - Caller : Bio::EnsEMBL::DBAdaptor - -=cut - -sub _get_adaptor { - my( $self, $module, @args) = @_; - - my( $adaptor, $internal_name ); - - #Create a private member variable name for the adaptor by replacing - #:: with _ - - $internal_name = $module; - - $internal_name =~ s/::/_/g; - - unless (defined $self->{'_adaptors'}->{$internal_name}) { - eval "require $module"; - - if($@) { - warning("$module cannot be found.\nException $@\n"); - return undef; + if(defined($self->db_handle())){ + if($self->db_handle()->{'Kids'} == 0 && + !$self->db_handle()->{'InactiveDestroy'}) { + $self->db_handle->disconnect(); } - - $adaptor = "$module"->new($self, @args); - - $self->{'_adaptors'}->{$internal_name} = $adaptor; } - - return $self->{'_adaptors'}->{$internal_name}; } - -=head2 add_db_adaptor - - Arg [1] : string $name - the name of the database to attach to this database - Arg [2] : Bio::EnsEMBL::DBSQL::DBConnection - the db adaptor to attach to this database - Example : $db->add_db_adaptor('lite', $lite_db_adaptor); - Description: Attaches another database instance to this database so - that it can be used in instances where it is required. - Returntype : none - Exceptions : none - Caller : EnsWeb - -=cut - -sub add_db_adaptor { - my ($self, $name, $adaptor) = @_; - - unless($name && $adaptor && ref $adaptor) { - throw('adaptor and name arguments are required'); - } - - #avoid circular references and memory leaks - if($adaptor->isa('Bio::EnsEMBL::Container')) { - $adaptor = $adaptor->_obj; - } - - $self->{'_db_adaptors'}->{$name} = $adaptor; -} - - -=head2 remove_db_adaptor - - Arg [1] : string $name - the name of the database to detach from this database. - Example : $lite_db = $db->remove_db_adaptor('lite'); - Description: Detaches a database instance from this database and returns - it. - Returntype : none - Exceptions : none - Caller : ? - -=cut - -sub remove_db_adaptor { - my ($self, $name) = @_; - - my $adaptor = $self->{'_db_adaptors'}->{$name}; - delete $self->{'_db_adaptors'}->{$name}; - - unless($adaptor) { - return undef; - } - - return $adaptor; -} - - -=head2 get_all_db_adaptors - - Arg [1] : none - Example : @attached_dbs = values %{$db->get_all_db_adaptors()}; - Description: returns all of the attached databases as - a hash reference of key/value pairs where the keys are - database names and the values are the attached databases - Returntype : hash reference with Bio::EnsEMBL::DBSQL::DBConnection values - Exceptions : none - Caller : Bio::EnsEMBL::DBSQL::ProxyAdaptor - -=cut - -sub get_all_db_adaptors { - my ($self) = @_; - - unless(defined $self->{'_db_adaptors'}) { - return {}; - } - - return $self->{'_db_adaptors'}; -} - - - -=head2 get_db_adaptor - - Arg [1] : string $name - the name of the attached database to retrieve - Example : $lite_db = $db->get_db_adaptor('lite'); - Description: returns an attached db adaptor of name $name or undef if - no such attached database exists - Returntype : Bio::EnsEMBL::DBSQL::DBConnection - Exceptions : none - Caller : ? - -=cut - -sub get_db_adaptor { - my ($self, $name) = @_; - - unless($self->{'_db_adaptors'}->{$name}) { - return undef; - } - - return $self->{'_db_adaptors'}->{$name}; -} - - -# -# This method is automatically called by the Container DESTROY method to -# break circular references. Do not call it directly. -# -sub deleteObj { - my $self = shift; - - #print STDERR "DBConnection::deleteObj : Breaking circular references:\n"; - - if(exists($self->{'_adaptors'})) { - foreach my $adaptor_name (keys %{$self->{'_adaptors'}}) { - my $adaptor = $self->{'_adaptors'}->{$adaptor_name}; - - #call each of the adaptor deleteObj methods - if($adaptor && $adaptor->can('deleteObj')) { - #print STDERR "\t\tdeleting adaptor\n"; - $adaptor->deleteObj(); - } - - #break dbadaptor -> object adaptor references - delete $self->{'_adaptors'}->{$adaptor_name}; - } - } - - #print STDERR "Cleaning up attached databases\n"; - - #break dbadaptor -> dbadaptor references - foreach my $db_name (keys %{$self->get_all_db_adaptors()}) { - #print STDERR "\tbreaking reference to $db_name database\n"; - $self->remove_db_adaptor($db_name); - } -} - - -=head2 DESTROY - - Arg [1] : none - Example : none - Description: Called automatically by garbage collector. Should - never be explicitly called. The purpose of this destructor - is to disconnect any active database connections. - Returntype : none - Exceptions : none - Caller : Garbage Collector - -=cut - -sub DESTROY { - my ($obj) = @_; - - #print STDERR "DESTROYING DBConnection\n"; - - my $dbh = $obj->db_handle(); - - if($dbh) { - # don't disconnect if InactiveDestroy flag is set, this can really - # screw up forked processes - if(!$dbh->{'InactiveDestroy'}) { - $dbh->disconnect(); - } - } - - $obj->db_handle(undef); -} - - - 1; diff --git a/modules/Bio/EnsEMBL/DBSQL/ProxyAdaptor.pm b/modules/Bio/EnsEMBL/DBSQL/ProxyAdaptor.pm index 40b227736d..60bcd4e00b 100644 --- a/modules/Bio/EnsEMBL/DBSQL/ProxyAdaptor.pm +++ b/modules/Bio/EnsEMBL/DBSQL/ProxyAdaptor.pm @@ -74,18 +74,6 @@ sub new { #invoke superclass constructor my $self = $class->SUPER::new($db); - unless($primary_adaptor) { - throw("The primary_adaptor argument is required\n"); - return undef; - } - - #determine the type of adaptor the proxy is filling in for - $self->{'_proxy_type'} = ref($primary_adaptor); - - #strip out fully qualified package name - $self->{'_proxy_type'} =~ s/.*:://; - - $self->{'_primary_adaptor'} = $primary_adaptor; return $self; } @@ -112,7 +100,7 @@ sub new { sub AUTOLOAD { my ($self, @args) = @_; - + #determine the method which was called my $method = $AUTOLOAD; @@ -128,30 +116,29 @@ sub AUTOLOAD { return $adaptor->$method(@args); } - + # # The request could not be filled by the primary adaptor # try the same request using all of the attached databases # my @databases = values %{$self->db()->get_all_db_adaptors()}; - foreach my $database (@databases) { - + foreach my $adaptor (@databases) { + #Try to get the appropriate adaptor from the database - my $get_adaptor = "get_" . $self->{'_proxy_type'}; - if($database->can($get_adaptor)) { - - #Try to invoke the request on the database's adaptor - my $adaptor = eval "\$database->$get_adaptor"; - if($adaptor->can($method)) { - return $adaptor->$method(@args); - } + # my $get_adaptor = "get_" . $self->{'_proxy_type'}; + # if($database->can($get_adaptor)) { + + #Try to invoke the request on the database's adaptor + # my $adaptor = eval "\$database->$get_adaptor"; + if($adaptor->can($method)) { + return $adaptor->$method(@args); } } #none of the attached adaptors could fulfill the request either throw("The requested method $method could not be found in the " . $self->{'_proxy_type'} . " of the attached databases:" . - @databases); + @databases); return undef; } diff --git a/modules/Bio/EnsEMBL/DBSQL/ProxySNPAdaptor.pm b/modules/Bio/EnsEMBL/DBSQL/ProxySNPAdaptor.pm index 9956afa9d8..f0d8794c6a 100644 --- a/modules/Bio/EnsEMBL/DBSQL/ProxySNPAdaptor.pm +++ b/modules/Bio/EnsEMBL/DBSQL/ProxySNPAdaptor.pm @@ -39,6 +39,26 @@ use vars '@ISA'; @ISA = qw(Bio::EnsEMBL::DBSQL::ProxyAdaptor); +sub set_primary{ + my ($self, $primary_adaptor) = @_; + +# +# For old style code i will have to add primary db later when get is called +# + unless($primary_adaptor) { + throw("The primary_adaptor argument is required\n"); + return undef; + } +# +# #determine the type of adaptor the proxy is filling in for + $self->{'_proxy_type'} = ref($primary_adaptor); +# + #strip out fully qualified package name + $self->{'_proxy_type'} =~ s/.*:://; + + $self->{'_primary_adaptor'} = $primary_adaptor; +# +} =head2 fetch_by_Slice @@ -56,15 +76,19 @@ use vars '@ISA'; sub fetch_all_by_Slice { my ($self, @args) = @_; - my $lite_db = $self->db()->get_db_adaptor('lite'); - my $snp_db = $self->db()->get_db_adaptor('SNP'); + my $lite_db = Bio::EnsEMBL::Registry->get_db($self->db(),'lite');#$self->db()->get_db_adaptor('lite'); + my $snp_db = Bio::EnsEMBL::Registry->get_db($self->db(),'SNP'); #$self->db()->get_db_adaptor('SNP'); if(defined $lite_db) { #use the Lite database if it is available - return $lite_db->get_SNPAdaptor()->fetch_all_by_Slice(@args); + my $lite_adaptor = Bio::EnsEMBL::Registry->get_adaptor( + $lite_db->species, $lite_db->group ,"lite"); + return $lite_adaptor->fetch_all_by_Slice(@args); } elsif(defined $snp_db) { #use the snp database if it is available - return $snp_db->get_SNPAdaptor()->fetch_all_by_Slice(@args); + my $snp_adaptor = Bio::EnsEMBL::Registry->get_adaptor( + $snp_db->species, $snp_db->group ,"SNP"); + return $snp_adaptor->fetch_all_by_Slice(@args); } #There is no core SNPAdaptor so throw an exception if lite and SNP diff --git a/modules/Bio/EnsEMBL/DBSQL/SliceAdaptor.pm b/modules/Bio/EnsEMBL/DBSQL/SliceAdaptor.pm index 12a87941d3..4c75fedd6c 100644 --- a/modules/Bio/EnsEMBL/DBSQL/SliceAdaptor.pm +++ b/modules/Bio/EnsEMBL/DBSQL/SliceAdaptor.pm @@ -1267,7 +1267,7 @@ sub prepare { my $self = shift; my $sql = shift; - return $self->db()->dnadb()->prepare( $sql ); + return $self->db()->dnadb()->db->prepare( $sql ); } sub _build_exception_cache { diff --git a/modules/Bio/EnsEMBL/External/BlastAdaptor.pm b/modules/Bio/EnsEMBL/External/BlastAdaptor.pm index 7d803c9b76..670de48c82 100644 --- a/modules/Bio/EnsEMBL/External/BlastAdaptor.pm +++ b/modules/Bio/EnsEMBL/External/BlastAdaptor.pm @@ -182,6 +182,13 @@ SET chr_name = NULL, WHERE hsp_id = ?"; + +sub new_fast{ + my ($caller,$connection) = @_; + my $self = $caller->SUPER::new($connection); + return $self; +} + #---------------------------------------------------------------------- =head2 new @@ -197,7 +204,16 @@ WHERE hsp_id = ?"; sub new { my $caller = shift; - my $connection = Bio::EnsEMBL::DBSQL::DBConnection->new(@_); + my @tmp = @_; + my $con = shift; + my $connection; + + if(ref($con) and $con->isa("Bio::EnsEMBL::DBSQL::DBConnection")){ + $connection = new_fast Bio::EnsEMBL::DBSQL::DBAdaptor('-con' => $con); + } + else{ + $connection = Bio::EnsEMBL::DBSQL::DBAdaptor->new(@tmp); + } my $self = $caller->SUPER::new($connection); return $self; } diff --git a/modules/Bio/EnsEMBL/Lite/DBAdaptor.pm b/modules/Bio/EnsEMBL/Lite/DBAdaptor.pm index 725bab413e..fdd4f366bc 100755 --- a/modules/Bio/EnsEMBL/Lite/DBAdaptor.pm +++ b/modules/Bio/EnsEMBL/Lite/DBAdaptor.pm @@ -35,11 +35,14 @@ package Bio::EnsEMBL::Lite::DBAdaptor; use vars qw(@ISA); use strict; +use Bio::EnsEMBL::Registry; +my $reg = "Bio::EnsEMBL::Registry"; use Bio::EnsEMBL::DBSQL::DBConnection; use Bio::EnsEMBL::Utils::Exception qw(deprecate); +use Bio::EnsEMBL::Utils::Argument qw(rearrange); -@ISA = qw(Bio::EnsEMBL::DBSQL::DBConnection); +@ISA = qw(Bio::EnsEMBL::DBSQL::DBAdaptor); @@ -58,7 +61,8 @@ use Bio::EnsEMBL::Utils::Exception qw(deprecate); sub get_SNPAdaptor { my $self = shift; - return $self->_get_adaptor("Bio::EnsEMBL::Lite::SNPAdaptor"); +# return $self->_get_adaptor("Bio::EnsEMBL::Lite::SNPAdaptor"); + return Bio::EnsEMBL::Registry->get_adaptor($self->db->species(), "lite", "ProxySNP"); } diff --git a/modules/Bio/EnsEMBL/Registry.pm b/modules/Bio/EnsEMBL/Registry.pm new file mode 100644 index 0000000000..dcb224195f --- /dev/null +++ b/modules/Bio/EnsEMBL/Registry.pm @@ -0,0 +1,766 @@ +# +# Ensembl module for Registry +# +# Copyright EMBL/EBI +## +# You may distribute this module under the same terms as perl itself + +# POD documentation - main docs before the code + +=head1 NAME + +Bio::EnsEMBL::Registry + +=head1 SYNOPSIS + +$gene_adaptor = Bio::EnsEMBL::Registry->get_adaptor("Homo Sapiens","core","Gene")) + + +=head1 DESCRIPTION + +All Adaptors are stored/registered using this module. This module should then +be used to get the adaptors needed. + +The registry can be loaded from a configuration file. If the enviroment +variable ENSEMBL_REGISTRY is set then the file pointed to by it is executed. +If not set then if the file ~/.ensembl_init exists then this will be executed. +For the Web server ENSEMBL_REGISTRY should be set in SiteDefs.pm. + +The four types of registrys are for db adaptors, dba adaptors, dna adaptors +and the standard type. + +=head2 db + +These are registrys for backwards compatibillity and enable the subroutines +to add other adaptors to connections. + +e.g. get_all_db_adaptors, get_db_adaptor, add_db_adaptor, remove_db_adaptor +are the old DBAdaptor subroutines which are now redirected to the Registry. + +So if before we had + my $sfa = $self->adaptor()->db()->get_db_adaptor('blast'); + +We now want to change this to + my $sfa = Bio::EnsEMBL::Registry->get_db($self->adaptor->db,'blast'); + +OR preferably if the blast adaptor was set up in configure + my $sfa = Bio::EnsEMBL::Registry->get_adaptor("Human","core","blast"); + + +=head2 DBA + +These are the stores for the DBAdaptors + +The Registry will create all the DBConnections needed now if you set up the +configuration correctly. So instead of the old commands like + +my $db = Bio::EnsEMBL::DBSQL::DBAdaptor->new(....) +my $exon_adaptor = $db->get_ExonAdaptor; + +we should now have just + +my $exon_adaptor = Bio::EnsEMBL::Registry->get_adaptor("Human","core","Exon"); + + +=head2 DNA + +This is an internal Registry and allows the configuration of a dnadb. +An example here is to set the est database to get it's dna data from the core database. + +## set the est db to use the core for getting dna data. +#Bio::EnsEMBL::Utils::ConfigRegistry-> +# dnadb_add("Homo Sapiens","core","Homo Sapiens","est"); + + +=head2 adaptors + +This is the registry for all the general types of adaptors like GeneAdaptor, ExonAdaptor, +Slice Adaptor etc. + +These are accessed by the get_adaptor subroutine i.e. + +my $exon_adaptor = Bio::EnsEMBL::Registry->get_adaptor("Human","core","Exon"); + +=head1 CONTACT + +Post questions to the Ensembl developer list: <ensembl-dev@ebi.ac.uk> + + +=head1 METHODS + +=cut + + +package Bio::EnsEMBL::Registry; + +use strict; + +use Bio::EnsEMBL::DBSQL::MergedAdaptor; +use Bio::EnsEMBL::Utils::Exception qw( deprecate throw warning ); +use Bio::EnsEMBL::Utils::Argument qw(rearrange); + +use vars qw(%registry_register); + +$registry_register{'_WARN'} = 0; + + + +=head2 load_all + Will load the registry with the configuration file which is obtained from + the first in the following and in that order. + + 1) if an argument is passed to this method this is used as the conf file. + 2) If the enviroment variable ENSEMBL_REGISTRY is set this is used. + 3) If the file .ensembl_init exist in the home directory it is used + + Arg [1] : (optional) string $arg file to load the registry from + Example : Bio::EnsEMBL::Registry->load_all(); + Returntype : none + Exceptions : none + + +=cut + +sub load_all{ + my $class = shift; + my $web_reg = shift; + + #$registry_register{'_WARN'} = 0; # default report overwriting + if(!defined($registry_register{'seen'})){ + $registry_register{'seen'}=1; + if(defined($web_reg)){ +# print STDERR "Loading conf from site defs file ".$web_reg."\n"; + unless (my $return = do $web_reg ){ + throw "Error in Configuration\n $!\n"; + } + # other wise it gets done again by the web initialisation stuff + delete $INC{$web_reg}; + } + elsif(defined($ENV{ENSEMBL_REGISTRY}) and -e $ENV{ENSEMBL_REGISTRY}){ +# print STDERR "Loading conf from ".$ENV{ENSEMBL_REGISTRY}."\n"; + unless (my $return = do $ENV{ENSEMBL_REGISTRY}){ + throw "Error in Configuration\n $!\n"; + } + } + elsif(-e $ENV{HOME}."/.ensembl_init"){ + do($ENV{HOME}."/.ensembl_init"); + } +# else{ +# print STDERR "NO default configuration to load\n"; +# } + } +# else{ +# print STDERR "Already configured???\n"; +# } +} + +=head2 check_if_already_there + + Arg [DBNAME] : string + The name of the database to check for. + Arg [HOST] : (optional) string + The domain name of the database host to check for + Arg [PORT] : int + The port to check for when connecting to the database + Arg [DRIVER] : (optional) string + The type of database driver to check for + + Description: Check to see if the database is already stored. + Returntype : 0 if not found else the species and group. + Exceptions : none + + +=cut + + +sub check_if_already_there{ + my ($class) = shift; + + my ($dbname,$host,$driver,$port ) = + rearrange([qw(DBNAME HOST DRIVER PORT )], @_); + + if(defined($registry_register{'_DBA'})){ + foreach my $db (@{$registry_register{'_DBA'}}){ + my $dbc= $db->db(); + if($dbc->host() eq $host and $dbc->dbname() eq $dbname + and $dbc->driver() eq $driver and $dbc->port() eq $port){ + return ($db->species(),$db->group()); + } + } + } + return 0; +} + + +# +# add ons. +# + +=head2 add_db + + Arg [1] : db to add adaptor to. + Arg [2] : name of the name to add the adaptor to in the registry. + Arg [3] : The adaptor to be added to the registry. + Example : Bio::EnsEMBL::Registry->add_db($db, "lite", $dba); + Returntype : none + Exceptions : none + +=cut + +sub add_db{ + my ($class, $db, $name, $adap) = @_; + + $registry_register{$db->species()}{$db->group()}{'_special'}{$name} = $adap; + +} + +=head2 remove_db + + Arg [1] : db to remove adaptor from. + Arg [2] : name to remove the adaptor from in the registry. + Example : my $db = Bio::EnsEMBL::Registry->remove_db($db, "lite"); + Returntype : adaptor + Exceptions : none + +=cut + +sub remove_db{ + my ($class, $db, $name) = @_; + + my $ret = $registry_register{$db->species()}{$db->group()}{'_special'}{$name}; + $registry_register{$db->species()}{$db->group()}{'_special'}{$name} = undef; + + return $ret; +} + +=head2 get_db + + Arg [1] : db to get adaptor from. + Arg [2] : name to get the adaptor for in the registry. + Example : my $db = Bio::EnsEMBL::Registry->get_db("Human", "core", "lite"); + Returntype : adaptor + Exceptions : none + +=cut + +sub get_db{ + my ($class, $db, $name) = @_; + + return $registry_register{$db->species()}{$db->group()}{'_special'}{$name}; +} + +=head2 get_all_db_adaptors + + Arg [1] : db to get all the adaptor from. + Example : my $db = Bio::EnsEMBL::Registry->get_all_db_adaptors($db); + Returntype : adaptor + Exceptions : none + +=cut + +sub get_all_db_adaptors{ + my ($class,$db) = @_; + my %ret=(); + + foreach my $key (keys %{$registry_register{$db->species()}{$db->group()}{'_special'}}){ + $ret{$key} = $registry_register{$db->species()}{$db->group()}{'_special'}{$key}; + } + + return \%ret; +} + + +# +# DBAdaptors +# + +=head2 add_DBAdaptor + + Arg [1] : name of the species to add the adaptor to in the registry. + Arg [2] : name of the group to add the adaptor to in the registry. + Arg [3] : The DBAaptor to be added to the registry. + Example : Bio::EnsEMBL::Registry->add_DBAdaptor("Human", "core", $dba); + Returntype : none + Exceptions : none + +=cut + +sub add_DBAdaptor{ + my ($class, $species, $group, $adap) = @_; + + $species = $class->get_alias($species); +# if(defined($registry_register{$species}{$group}{'_DB'}) && warn_on_duplicates()){ +# warning("Overwriting DBAdaptor in Registry for $species $group $adap\n"); +# } + + $registry_register{$species}{$group}{'_DB'} = $adap; + + if(!defined($registry_register{'_DBA'})){ + my @list =(); + push(@list,$adap); + $registry_register{'_DBA'}= \@list; + } + else{ + push(@{$registry_register{'_DBA'}},$adap); + } + +} + + + +=head2 get_DBAdaptor + + Arg [1] : name of the species to get the adaptor for in the registry. + Arg [2] : name of the group to get the adaptor for in the registry. + Example : $dba = Bio::EnsEMBL::Registry->get_DBAdaptor("Human", "core"); + Returntype : DBAdaptor + Exceptions : none + +=cut + +sub get_DBAdaptor{ + my ($class, $species, $group) = @_; + + $species = $class->get_alias($species); + + if(defined($group)){ # group defined so return standard DB Adaptor + return $registry_register{$species}{$group}{'_DB'}; + } + else{ #return a merged db adaptor + return new_merged Bio::EnsEMBL::DBSQL::DBAdaptor($species); + } +} + +=head2 get_all_DBAdaptors + + Example : @dba = @{Bio::EnsEMBL::Registry->get_all_DBAdaptors(); + Returntype : list of DBAdaptors + Exceptions : none + +=cut + +sub get_all_DBAdaptors{ + my ($class)=@_; + + return @{$registry_register{'_DBA'}}; +} + +# +# DNA Adaptors +# + +=head2 add_DNAAdaptor + + Arg [1] : name of the species to add the adaptor to in the registry. + Arg [2] : name of the group to add the adaptor to in the registry. + Arg [3] : The adaptor to be added to the registry as a DNA adaptor. + Example : Bio::EnsEMBL::Registry->add_DNAAdaptor("Human", "core", $dnaAdap); + Returntype : none + Exceptions : none + +=cut + +sub add_DNAAdaptor{ + my ($class, $species, $group, $adap) = @_; + + $species = $class->get_alias($species); +# if(defined($registry_register{$species}{$group}{'_DNA'}) && warn_on_duplicates()){ +# warning("Overwriting DNAAdaptor in Registry for $species $group $adap\n"); +# } + + $registry_register{$species}{$group}{'_DNA'} = $adap; + +} + +=head2 get_DNAAdaptor + + Arg [1] : name of the species to get the adaptor for in the registry. + Arg [2] : name of the group to get the adaptor for in the registry. + Example : $dnaAdap = Bio::EnsEMBL::Registry->get_DNAAdaptor("Human", "core"); + Returntype : adaptor + Exceptions : none + +=cut + +sub get_DNAAdaptor{ + my ($class, $species, $group) = @_; + + $species = $class->get_alias($species); + return $registry_register{$species}{$group}{'_DNA'}; +} + +# +# General Adaptors +# + +=head2 add_adaptor + + Arg [1] : name of the species to add the adaptor to in the registry. + Arg [2] : name of the group to add the adaptor to in the registry. + Arg [3] : name of the type to add the adaptor to in the registry. + Arg [4] : The DBAaptor to be added to the registry. + Arg [5] : (optional) if set okay to overwrite. + Example : Bio::EnsEMBL::Registry->add_adaptor("Human", "core", "Gene", $adap); + Returntype : none + Exceptions : none + + +=cut + +sub add_adaptor{ + my ($class,$species,$group,$type,$adap, $reset)= @_; + + $species = $class->get_alias($species); + +# +# Becouse the adaptors are not stored initially only there class paths when +# the adaptors are obtained we need to store these instead. +# It is not necessarily an error if the registry is overwritten without +# the reset set but it is an indication that we are overwriting a database +# which should be a warning for now +# + + if(defined($reset)){ # JUST REST THE HASH VLAUE NO MORE PROCESSING NEEDED + $registry_register{$species}{$group}{$type} = $adap; + return; + } + if(defined($registry_register{$species}{$group}{$type})){ + print STDERR ("Overwriting Adaptor in Registry for $species $group $type\n"); + $registry_register{$species}{$group}{$type} = $adap; + return; + } + $registry_register{$species}{$group}{$type} = $adap; + + + if(!defined ($registry_register{$species}{'list'})){ + my @list =(); + push(@list,$adap); + $registry_register{$species}{'list'}= \@list; + } + else{ + push(@{$registry_register{$species}{'list'}},$adap); + } + +# print STDERR "REGADD $species \t $group \t $type\t to the registry\n"; + + if(!defined ($registry_register{$type}{$species})){ + my @list =(); + push(@list,$adap); + $registry_register{$type}{$species}= \@list; + } + else{ + push(@{$registry_register{$type}{$species}},$adap); + } + +} + + +=head2 set_get_via_dnadb_if_set + + set the flag so that for this type of adaptor the data is obtained + from the dna source and not centrally i.e. estgenes where the sequence + data is held in the core. + + Arg [1] : name of the species to set flag for. + Arg [2] : name of the type to set flag for. (i.e. Sequence) + Example : Bio::EnsEMBL::Registry->set_get_via_dnadb_if_set("Human","Sequence"); + Returntype : none + Exceptions : none + + + +=cut + +sub set_get_via_dnadb_if_set{ + my ($class,$species,$type) = @_; + + $registry_register{$species}{$type}{'DNADB'} = 1; +} + +=head2 get_adaptor + + Arg [1] : name of the species to add the adaptor to in the registry. + Arg [2] : name of the group to add the adaptor to in the registry. + Arg [3] : name of the type to add the adaptor to in the registry. + Example : $adap = Bio::EnsEMBL::Registry->get_adaptor("Human", "core", "Gene"); + Returntype : adaptor + Exceptions : none + +=cut + +sub get_adaptor{ + my ($class,$species,$group,$type)= @_; + + $species = $class->get_alias($species); + + #throw in a check to see if we should get the dnadb one and not the normal + if(defined($registry_register{$species}{$type}{'DNADB'}) && $class->get_DNAAdaptor($species,$group)){ + my $dna = $class->get_DNAAdaptor($species,$group); + $species = $dna->species(); + $group = $dna->group(); + } + + my $ret = $registry_register{$species}{$group}{$type}; + if(!defined($ret)){ + throw("COULD NOT FIND ADAPTOR species=$species\tgroup=$group\ttype=$type\n"); + } + if(!ref($ret)){ # not instantiated yet + my $dba = $registry_register{$species}{$group}{'_DB'}; + my $module = $ret; + eval "require $module"; + + if($@) { + warning("$module cannot be found.\nException $@\n"); + return undef; + } + my $adap = "$module"->new($dba); + Bio::EnsEMBL::Registry->add_adaptor($species, $group, $type, $adap, "reset"); + $ret = $adap; + } + + return $ret; +} + +=head2 get_all_adaptors + + Arg [1] : name of the species to get the adaptors for. + Example : @adaps = @{Bio::EnsEMBL::Registry->get_all_adaptors()}; + Returntype : list of adaptors + Exceptions : none + +=cut + +sub get_all_adaptors{ + my ($class,$species)= @_; + + $species = get_alias($species); + return $registry_register{$species}{'list'}; +} + + +=head2 get_MergedAdaptor + + Arg [1] : name of the species to get the adaptors for in the registry. + Arg [2] : name of the type to get the adaptors for in the registry. + Example : $merged = Bio::EnsEMBL::Registry->get_MergedAdaptor("Mouse","Gene"); + Returntype : Bio::EnsEMBL::DBSQL::MergedAdaptor + Exceptions : none + +=cut + +sub get_MergedAdaptor{ + my ($class,$species,$type)=@_; + + $species = $class->get_alias($species); + my $ret = new Bio::EnsEMBL::DBSQL::MergedAdaptor(); + $ret->add_list(@{$registry_register{$type}{$species}}); + + return $ret; +} + +=head2 add_alias + + Arg [1] : name of the species to add alias for + Arg [2] : name of the alias + Example : Bio::EnsEMBL::Registry->add_alias("Homo Sapiens","Human"); + Description: add alternative name for the species. + Returntype : none + Exceptions : none + +=cut + +sub add_alias{ + my ($class, $species,$key) = @_; + + $registry_register{'_ALIAS'}{$key} = $species; +} + +=head2 get_alias + + Arg [1] : name of the possible alias to get species for + Arg [2] : if set will not throw if not found. + Example : Bio::EnsEMBL::Registry->get_alias("Human"); + Description: get proper species name. + Returntype : species name + Exceptions : if not found and second argument + +=cut + +sub get_alias{ + my ($class, $key, $no_throw) = @_; + + if(!defined($registry_register{'_ALIAS'}{$key})){ + if(defined($no_throw)){ + return undef; + } + else{ + throw("Unknown species $key has it been mistyped??\n"); + } + } + return $registry_register{'_ALIAS'}{$key}; +} + +# +# Web specific routines +# + + +=head2 load_registry_with_web_adaptors + Will load the registry with all the Adaptors used in the Web server. + Providing Sitedefs and SpeciesDefs can be found on PERL5LIB path. + + Example : Bio::EnsEMBL::Registry->load_registry_with_web_adaptors(); + Returntype : none + Exceptions : Will die if Sitedefs or SpeciesDefs is not found on the + PERL5LIB path. + +=cut + +sub load_registy_with_web_adaptors{ + my $class = shift; + + + eval{ require SiteDefs }; + if ($@){ die "Can't use SiteDefs.pm - $@\n"; } + SiteDefs->import(qw(:ALL)); + + eval{ require SpeciesDefs }; + if ($@){ die "Can't use SpeciesDefs.pm - $@\n"; } + my $conf = new SpeciesDefs(); + +} + +=head2 set_default_track + Sets a flag to say that that this species/group are a default track and do not + need to be added as another web track. + + Arg [1] : name of the species to get the adaptors for in the registry. + Arg [2] : name of the type to get the adaptors for in the registry. + Example : $merged = Bio::EnsEMBL::Registry->set_default_track("Human","core"); + Returntype : none + Exceptions : none + +=cut + +sub set_default_track{ + my ($class, $species, $group) = @_; + + $registry_register{'def_track'}{$species}{$group} = 1; +} + +=head2 default_track + Check flag to see if this is a default track + + Arg [1] : name of the species to get the adaptors for in the registry. + Arg [2] : name of the type to get the adaptors for in the registry. + Example : $merged = Bio::EnsEMBL::Registry->set_default_track("Human","core"); + Returntype : int + Exceptions : none + +=cut + +sub default_track{ + my ($class, $species, $group) = @_; + + if(defined($registry_register{'def_track'}{$species}{$group})){ + return 1; + } + + return 0; +} + + +=head2 add_new_tracks + Will add new gene tracks to the configuration of the WEB server if they are + not of the type default and the configuration already has genes in the display. + + Arg [1] : hash of the default configuration of the web page + Returntype : none + Exceptions : none + Called by : UserConfig.pm + +=cut + +sub add_new_tracks{ + my($class, $conf) = @_; + + my $start = 0; + my $reg = $class; + my $species_reg = $reg->get_alias($conf->{'species'},"nothrow"); + my $view = $conf->{'type'}; + if(defined($species_reg)){ + my $config = $conf->{'general'}->{$view}; + foreach my $dba ($reg->get_all_DBAdaptors()){ + # if($dba->species eq $species_reg and !$reg->default_track($dba->species,$dba->group)){ + if(!$reg->default_track($dba->species,$dba->group)){ + if($start == 0){ + if(exists($config->{'vega_transcript_lite'}) and defined($config->{'vega_transcript_lite'}->{'pos'})){ + $start = $config->{'vega_transcript_lite'}->{'pos'}; + } + elsif(exists($config->{'transcript_lite'}) and defined($config->{'transcript_lite'}->{'pos'})){ + $start = $config->{'transcript_lite'}->{'pos'}; + } + else{ # no transcripts on this view so do not add track here + # print STDERR "no transcript options on this display \n"; + next; + } + $start ++; + } + else{ + if(exists($config->{'vega_transcript_lite'}) and defined($config->{'vega_transcript_lite'}->{'pos'})){ + $start++; + } + elsif(exists($config->{'transcript_lite'}) and defined($config->{'transcript_lite'}->{'pos'})){ + $start++; + } + else{ # no transcripts on this view so do not add track here + # print STDERR "no transcript options on this display \n"; + next; + } + } + $reg->_add_new_track( $conf->{'general'}->{$view}, $dba, $start); + } + } + } +} + + +=head2 _add_new_track + + Arg [1] : hash of the configuration + Arg [2] : dbadaptor to use to get track info from + Arg [3] : start index to place track in the right place + Returntype : none + Exceptions : none + Called by : add_new_tracks + +=cut + +sub _add_new_track{ + my ($class, $config, $dba, $start ) = @_; + + + my $KEY = $dba->group(); + + $config->{$KEY} ={ + 'on' => "on", + 'compact' => 'yes', + 'pos' => $start, + 'str' => 'b', + 'src' => 'all', # 'ens' or 'all' + 'available'=> 'species '.$dba->species(), + 'dba' => $dba, +# 'colours' => {$config->{'_colourmap'}->colourSet( 'vega_gene' )}, + 'glyphset' => 'generic_transcript', + 'dep' => 6, + }; + + push @{ $config->{'_artefacts'} }, $KEY; + push @{ $config->{'_settings'}->{'features'}}, [$KEY => $KEY] ; + +# [ 'transcript_lite' => "Ensembl Trans." ], + return; +} + + +1; diff --git a/modules/Bio/EnsEMBL/Slice.pm b/modules/Bio/EnsEMBL/Slice.pm index b884541a46..8f8458264c 100644 --- a/modules/Bio/EnsEMBL/Slice.pm +++ b/modules/Bio/EnsEMBL/Slice.pm @@ -73,6 +73,8 @@ use Bio::EnsEMBL::RepeatMaskedSlice; use Bio::EnsEMBL::Utils::Sequence qw(reverse_comp); use Bio::EnsEMBL::ProjectionSegment; +use Bio::EnsEMBL::Registry; +my $reg = "Bio::EnsEMBL::Registry"; # inheritance to Bio::EnsEMBL::Root will eventually be removed @ISA = qw(Bio::EnsEMBL::Root Bio::PrimarySeqI); @@ -1307,20 +1309,18 @@ sub get_all_Genes{ return []; } - my $db; + my $ga; if($dbtype) { - $db = $self->adaptor->db->get_db_adaptor($dbtype); - if(!$db) { - warning("Don't have db $dbtype returning empty list\n"); + $ga = $reg->get_adaptor( $self->adaptor()->db()->species(), $dbtype, "Gene" ); + if(!defined $ga) { + warning( "$dbtype genes not available" ); return []; } - } else { - $db = $self->adaptor->db; + } else { + $ga = $self->adaptor->db->get_GeneAdaptor(); } - my $ga = $db->get_GeneAdaptor(); - - return $ga->fetch_all_by_Slice( $self, $logic_name, $load_transcripts); + return $ga->fetch_all_by_Slice( $self, $logic_name, $load_transcripts); } =head2 get_all_Genes_by_type diff --git a/modules/Bio/EnsEMBL/Storable.pm b/modules/Bio/EnsEMBL/Storable.pm index 17f4b62ad9..d1709be997 100644 --- a/modules/Bio/EnsEMBL/Storable.pm +++ b/modules/Bio/EnsEMBL/Storable.pm @@ -129,6 +129,9 @@ sub is_stored { my $self = shift; my $db = shift; + if($db and $db->isa('Bio::EnsEMBL::DBSQL::DBAdaptor')) { + $db = $db->db(); + } if(!$db || !ref($db) || !$db->isa('Bio::EnsEMBL::DBSQL::DBConnection')) { throw('db argument must be a Bio::EnsEMBL::DBSQL::DBConnection'); } @@ -148,7 +151,7 @@ sub is_stored { return 0 if (!$adaptor && !$dbID); - my $cur_db = $adaptor->db(); + my $cur_db = $adaptor->dbc(); # # Databases are the same if they share the same port, host and username diff --git a/modules/Bio/EnsEMBL/Utils/ConfigRegistry.pm b/modules/Bio/EnsEMBL/Utils/ConfigRegistry.pm index e40de04da1..82664e603d 100644 --- a/modules/Bio/EnsEMBL/Utils/ConfigRegistry.pm +++ b/modules/Bio/EnsEMBL/Utils/ConfigRegistry.pm @@ -726,6 +726,6 @@ sub get_alias{ # eval{ require Bio::EnsEMBL::Utils::User_defined_load }; -if ($@){ print STDERR "No user defined loads\n"; } +#if ($@){ print STDERR "No user defined loads\n"; } 1; -- GitLab