Registry.pm 70.5 KB
Newer Older
Ian Longden's avatar
Ian Longden committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
#
# 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

16 17
Bio::EnsEMBL::Registry->load_all("configuration_file");

18 19
$gene_adaptor =
  Bio::EnsEMBL::Registry->get_adaptor( "human", "core", "gene" );
Ian Longden's avatar
Ian Longden committed
20 21 22 23


=head1 DESCRIPTION

24 25
All Adaptors are stored/registered using this module. This module should
then be used to get the adaptors needed.
Ian Longden's avatar
Ian Longden committed
26

27 28
The registry can be loaded from a configuration file using the load_all
method.
Ian Longden's avatar
Ian Longden committed
29

30 31 32 33
If a filename is passed to load_all then this is used.  Else if the
enviroment variable ENSEMBL_REGISTRY is set to the name on an existing
configuration file, then this is used.  Else if the file .ensembl_init
in your home directory exist, it is used.
Ian Longden's avatar
Ian Longden committed
34

35 36
For the Web server ENSEMBL_REGISTRY should be set in SiteDefs.pm.  This
will then be passed on to load_all.
37 38


39 40 41 42 43
The registry can also be loaded via the method load_registry_from_db
which given a database host will load the latest versions of the Ensembl
databases from it.

The four types of registries are for db adaptors, dba adaptors, dna adaptors
Ian Longden's avatar
Ian Longden committed
44 45 46 47
and the standard type.

=head2 db

48
These are registries for backwards compatibility and enable the subroutines
49
to add other adaptors to connections. 
Ian Longden's avatar
Ian Longden committed
50 51 52 53 54

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
55 56

    my $sfa = $self->adaptor()->db()->get_db_adaptor('blast');
Ian Longden's avatar
Ian Longden committed
57 58

We now want to change this to
59 60 61

    my $sfa =
      Bio::EnsEMBL::Registry->get_adaptor( "human", "core", "blast" );
Ian Longden's avatar
Ian Longden committed
62 63 64 65 66 67 68 69 70


=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

71 72
    my $db           = Bio::EnsEMBL::DBSQL::DBAdaptor->new(...);
    my $exon_adaptor = $db->get_ExonAdaptor;
Ian Longden's avatar
Ian Longden committed
73 74 75

we should now have just

76 77
    my $exon_adaptor =
      Bio::EnsEMBL::Registry->get_adaptor( "human", "core", "exon" );
Ian Longden's avatar
Ian Longden committed
78 79 80 81 82


=head2 DNA

This is an internal Registry and allows the configuration of a dnadb. 
Steve Trevanion's avatar
Steve Trevanion committed
83
An example here is to set the est database to get its dna data from the core database.
Ian Longden's avatar
Ian Longden committed
84

85 86 87
    ## set the est db to use the core for getting dna data.
    # Bio::EnsEMBL::Utils::ConfigRegistry->dnadb_add(
    #         "Homo Sapiens", "core", "Homo Sapiens", "est" );
Ian Longden's avatar
Ian Longden committed
88 89 90 91 92 93 94 95 96


=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.

97 98
    my $exon_adaptor =
      Bio::EnsEMBL::Registry->get_adaptor( "human", "core", "exon" );
Ian Longden's avatar
Ian Longden committed
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113

=head1 CONTACT

Post questions to the Ensembl developer list: <ensembl-dev@ebi.ac.uk>


=head1 METHODS

=cut


package Bio::EnsEMBL::Registry;

use strict;

114
use Bio::EnsEMBL::DBSQL::DBAdaptor;
Ian Longden's avatar
Ian Longden committed
115 116
use Bio::EnsEMBL::Utils::Exception qw( deprecate throw warning );
use Bio::EnsEMBL::Utils::Argument qw(rearrange);
117
use Bio::EnsEMBL::Utils::ConfigRegistry;
118
use DBI;
Ian Longden's avatar
Ian Longden committed
119 120 121

use vars qw(%registry_register);

Glenn Proctor's avatar
Glenn Proctor committed
122
my $API_VERSION = 54;
Ian Longden's avatar
Ian Longden committed
123

124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
# This is a map from group names to Ensembl DB adaptors.
#Used by load_all and reset_DBAdaptor
my %group2adaptor = 
  (
   'blast'         => 'Bio::EnsEMBL::External::BlastAdaptor',
   'compara'       => 'Bio::EnsEMBL::Compara::DBSQL::DBAdaptor',
   'core'          => 'Bio::EnsEMBL::DBSQL::DBAdaptor',
   'estgene'       => 'Bio::EnsEMBL::DBSQL::DBAdaptor',
   'funcgen'       => 'Bio::EnsEMBL::Funcgen::DBSQL::DBAdaptor',
   'haplotype'     => 'Bio::EnsEMBL::ExternalData::Haplotype::DBAdaptor',
   'hive'          => 'Bio::EnsEMBL::Hive::DBSQL::DBAdaptor',
   'lite'          => 'Bio::EnsEMBL::Lite::DBAdaptor',
   'otherfeatures' => 'Bio::EnsEMBL::DBSQL::DBAdaptor',
   'pipeline'      => 'Bio::EnsEMBL::Pipeline::DBSQL::DBAdaptor',
   'snp'           => 'Bio::EnsEMBL::ExternalData::SNPSQL::DBAdaptor',
   'variation'     => 'Bio::EnsEMBL::Variation::DBSQL::DBAdaptor',
   'vega'          => 'Bio::EnsEMBL::DBSQL::DBAdaptor',
  );



Ian Longden's avatar
Ian Longden committed
145
=head2 load_all
146

147 148
 Will load the registry with the configuration file which is
 obtained from the first in the following and in that order.
149

150 151
  1) If an argument is passed to this method, this is used as the
     name of the configuration file to read.
152

153 154
  2) If the enviroment variable ENSEMBL_REGISTRY is set, this is
     used as the name of the configuration file to read.
Ian Longden's avatar
Ian Longden committed
155

156 157
  3) If the file .ensembl_init exist in the home directory, it is
     used as the configuration file.
Ian Longden's avatar
Ian Longden committed
158

159 160
  Arg [1]    : (optional) string
               Name of file to load the registry from.
161

162 163
  Arg [2]    : (optional) integer
               If not 0, will print out all information.
164

165
  Arg [3]    : (optional) integer
166 167 168 169 170 171 172 173 174 175 176 177 178 179
               If not 0, the database connection will not be
               cleared, if 0 or if not set the database connections
               will be cleared (this is the default).

  Arg [4]:     (optional) boolean
               This option will turn off caching for slice features,
               so, every time a set of features is retrieved,
               they will come from the database instead of the
               cache.  This option is only recommended for advanced
               users, specially if you need to store and retrieve
               features.  It might reduce performance when querying
               the database if not used properly.  If in doubt, do
               not use it or ask in ensembl-dev.

Ian Longden's avatar
Ian Longden committed
180 181 182
  Example    : Bio::EnsEMBL::Registry->load_all();
  Returntype : none
  Exceptions : none
183
  Status     : Stable
Ian Longden's avatar
Ian Longden committed
184 185

=cut
186

187 188
sub load_all {
    my $class = shift;
189
    my ( $config_file, $verbose, $no_clear, $no_cache ) = @_;
190 191 192 193 194 195

    $config_file ||= $ENV{ENSEMBL_REGISTRY}
      || $ENV{HOME} . "/.ensembl_init";

    $verbose  ||= 0;
    $no_clear ||= 0;
196
    $no_cache ||= 0;
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226

    if ( !defined($config_file) ) {
        if ($verbose) {
            print( STDERR
                   "No default registry configuration to load.\n" );
        }
    } elsif ( !-e $config_file ) {
        if ($verbose) {
            printf( STDERR "Configuration file '%s' does not exist. "
                      . "Registry configuration not loaded.\n",
                    $config_file );
        }
    } else {
        if ( defined( $registry_register{'seen'} ) ) {
            if ( !$no_clear ) {
                if ($verbose) {
                    print( STDERR "Clearing previously loaded "
                           . "registry configuration\n" );
                }
                $class->clear();
            }
        }
        $registry_register{'seen'} = 1;

        if ($verbose) {
            printf( STDERR
                      "Loading registry configuration from '%s'.\n",
                    $config_file );
        }

227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
        my $cfg;

        eval { require Config::IniFiles };
        if ($@) {
          # The user does not have the 'Config::IniFiles' module.
          if ($verbose) {
            print( STDERR "No Config::IniFiles module found, "
                   . "assuming this is not an ini-file\n" );
          }
          # If the configuration file *is* an ini-file, we can expect a
          # load of compilation errors from the next eval...
        } else {
          # The user has the 'Config::IniFiles' module installed.  See
          # if this is an ini-file or not...
          $cfg = Config::IniFiles->new( -file => $config_file );
        }
243

244
        if ( defined $cfg ) {
245
		  my %default_adaptor_args = ();
246 247 248 249

            if ( $cfg->SectionExists('default') ) {
                # The 'default' section is special.  It contain default
                # values that should be implicit to all other section in
250 251 252 253 254 255 256 257 258 259 260 261 262
                # this configuration file.  Aliases are added if there
                # is also a 'species' setting.

                my $alias = $cfg->val( 'default', 'alias' );
                $cfg->delval( 'default', 'alias' );

                my $species = $cfg->val( 'default', 'species' );

                if ( defined($alias) && defined($species) ) {
                    Bio::EnsEMBL::Utils::ConfigRegistry->add_alias(
                                     -species => $species,
                                     -alias => [ split( /\n/, $alias ) ]
                    );
263
                }
264

265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
                %default_adaptor_args =
                  map { '-' . $_ => $cfg->val( 'default', $_ ) }
                  $cfg->Parameters('default');
            }

            foreach my $section ( $cfg->Sections() ) {
                if ( $section eq 'default' )
                {    # We have already done the 'default' section.
                    next;
                }

                my $group = $cfg->val( $section, 'group' )
                  || $cfg->val( 'default', 'group' );

                if ( !defined($group) ) {
                    printf( STDERR "Key 'group' is undefined "
                              . "for configuration section '%s', "
                              . "skipping this section.\n",
                            $section );
                    next;
                }

                my $adaptor = $group2adaptor{ lc($group) };
                if ( !defined($adaptor) ) {
                    printf( STDERR "Unknown group '%s' "
                              . "for configuration section '%s', "
                              . "skipping this section.\n",
                            $group, $section );
                    next;
                }

296 297 298 299 300
                # Handle aliases.  A section must have both an 'alias'
                # setting and a 'species' setting for aliases to be
                # added.  The 'species' setting might be inherited from
                # the 'default' section.

301 302 303
                my $alias = $cfg->val( $section, 'alias' );
                $cfg->delval( $section, 'alias' );

304 305 306 307 308 309 310 311 312 313 314
                my $species = $cfg->val( $section, 'species' )
                  || $cfg->val( 'default', 'species' );

                if ( defined($alias) && defined($species) ) {
                    Bio::EnsEMBL::Utils::ConfigRegistry->add_alias(
                                     -species => $species,
                                     -alias => [ split( /\n/, $alias ) ]
                    );
                }

                # Fill in the adaptor initialization arguments.
315 316 317
                # We trust the user to provide sensible key-value pairs.
                my %adaptor_args = %default_adaptor_args;
                foreach my $parameter ( $cfg->Parameters($section) ) {
318 319 320 321 322 323 324 325
                  $adaptor_args{ '-' . $parameter } =
                    $cfg->val( $section, $parameter );

                  # when set, do not use the feature cache in the
                  # different adaptors
                  if ($no_cache) {
                    $adaptor_args{'-no_cache'} = 1;
                  }
326 327 328 329 330 331 332 333
                }

                if ($verbose) {
                    printf( "Configuring adaptor '%s' "
                              . "for configuration section '%s'...\n",
                            $adaptor, $section );
                }

334 335 336
                eval "require $adaptor";
                if ($@) { die($@) }

337 338 339 340 341 342 343 344 345 346 347 348 349 350 351
                $adaptor->new(%adaptor_args);

            } ## end foreach my $section ( $cfg->Sections...
        } else {
            # This is probably no ini-file but an old style piece
            # of configuration written in Perl.  We need to try to
            # require() it.

            eval { require($config_file) };
            if ($@) { die($@) }

            # To make the web code avoid doing this again:
            delete $INC{$config_file};
        }
    } ## end else [ if ( !defined($config_file...
352
} ## end sub load_all
353 354

=head2 clear
355

356 357 358 359 360
 Will clear the registry and disconnect from all databases.

  Example    : Bio::EnsEMBL::Registry->clear();
  Returntype : none
  Exceptions : none
361
  Status     : Stable
362 363 364 365 366 367 368 369 370 371 372

=cut

sub clear{
  my ($self);
  
  foreach my $dba (@{$registry_register{'_DBA'}}){
    if($dba->dbc->connected){
      $dba->dbc->db_handle->disconnect();
    }
  }
Ian Longden's avatar
Ian Longden committed
373
  %registry_register = ();
Ian Longden's avatar
Ian Longden committed
374 375 376
}

#
377
# db adaptors. (for backwards compatibility)
Ian Longden's avatar
Ian Longden committed
378 379 380 381
#

=head2 add_db

382
  Arg [1]    : db (DBAdaptor) to add adaptor to.
Ian Longden's avatar
Ian Longden committed
383 384 385 386 387
  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
388
  Status     : At Risk.
389 390 391 392
             : This is here for backwards compatibility only and may
             : be removed eventually.  Solution is to make sure the
             : db and the adaptor have the same species and the call
             : is then no longer needed.
Ian Longden's avatar
Ian Longden committed
393

394
=cut
Ian Longden's avatar
Ian Longden committed
395

396 397
sub add_db {
  my ( $class, $db, $name, $adap ) = @_;
Ian Longden's avatar
Ian Longden committed
398

399 400 401
  if ( lc( $db->species() ) ne lc( $adap->species ) ) {
    $registry_register{ lc( $db->species() ) }{ lc( $db->group() ) }
      {'_special'}{ lc($name) } = $adap;
402
  }
Ian Longden's avatar
Ian Longden committed
403 404 405 406
}

=head2 remove_db

407
  Arg [1]    : db (DBAdaptor) to remove adaptor from.
Ian Longden's avatar
Ian Longden committed
408 409 410 411
  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
412
  Status     : At Risk.
413 414 415 416
             : This is here for backwards compatibility only and may
             : be removed eventually.  Solution is to make sure the
             : db and the adaptor have the same species and the call
             : is then no longer needed.
Ian Longden's avatar
Ian Longden committed
417 418 419

=cut

420 421 422 423 424 425
sub remove_db {
  my ( $class, $db, $name ) = @_;

  my $ret =
    $registry_register{ lc( $db->species() ) }{ lc( $db->group() ) }
    {'_special'}{ lc($name) };
Ian Longden's avatar
Ian Longden committed
426

427 428
  $registry_register{ lc( $db->species() ) }{ lc( $db->group() ) }
    {'_special'}{ lc($name) } = undef;
Ian Longden's avatar
Ian Longden committed
429 430 431 432 433 434

  return $ret;
}

=head2 get_db

435
  Arg [1]    : db (DBAdaptor) to get adaptor from.
Ian Longden's avatar
Ian Longden committed
436 437 438 439
  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
440
  Status     : At Risk.
441 442 443 444
             : This is here for backwards compatibility only and may
             : be removed eventually.  Solution is to make sure the
             : db and the adaptor have the same species then call
             : get_DBAdaptor instead.
Ian Longden's avatar
Ian Longden committed
445 446 447

=cut

448 449
sub get_db {
  my ( $class, $db, $name ) = @_;
Ian Longden's avatar
Ian Longden committed
450

451 452
  my $ret = Bio::EnsEMBL::Registry->get_DBAdaptor( lc( $db->species ),
    lc($name) );
453

454 455 456 457
  if ( defined($ret) ) { return $ret }

  return $registry_register{ lc( $db->species() ) }
    { lc( $db->group() ) }{'_special'}{ lc($name) };
Ian Longden's avatar
Ian Longden committed
458 459 460 461
}

=head2 get_all_db_adaptors

462
  Arg [1]    : db (DBAdaptor) to get all the adaptors from.
Ian Longden's avatar
Ian Longden committed
463 464 465
  Example    : my $db = Bio::EnsEMBL::Registry->get_all_db_adaptors($db);
  Returntype : adaptor
  Exceptions : none
466
  Status     : At Risk.
467 468 469 470
             : This is here for backwards compatibility only and
             : may be removed eventually.  Solution is to make
             : sure the dbs all have the same species then call
             : get_all_DBAdaptors(-species => "human");
471

Ian Longden's avatar
Ian Longden committed
472 473 474

=cut

475 476 477
sub get_all_db_adaptors {
  my ( $class, $db ) = @_;
  my %ret = ();
Ian Longden's avatar
Ian Longden committed
478

479 480
  # we now also want to add all the DBAdaptors for the same species.
  # as add_db_adaptor does not add if it is from the same species.
Ian Longden's avatar
Ian Longden committed
481

482 483 484 485
  foreach my $dba ( @{ $registry_register{'_DBA'} } ) {
    if ( lc( $dba->species() ) eq lc( $db->species() ) ) {
      $ret{ $dba->group() } = $dba;
    }
Ian Longden's avatar
Ian Longden committed
486 487
  }

488
  foreach my $key (
489 490 491
    keys %{
      $registry_register{ $class->get_alias( $db->species() ) }
        { lc( $db->group() ) }{'_special'} } )
492 493 494 495 496
  {
    $ret{$key} =
      $registry_register{ $class->get_alias( $db->species() ) }
      { lc( $db->group() ) }{'_special'}{$key};
  }
Ian Longden's avatar
Ian Longden committed
497 498

  return \%ret;
499
} ## end sub get_all_db_adaptors
Ian Longden's avatar
Ian Longden committed
500 501 502 503 504 505 506 507 508 509 510 511 512 513


#
# 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
514 515
  caller     : internal
  Status     : Stable
Ian Longden's avatar
Ian Longden committed
516 517 518

=cut

519 520
sub add_DBAdaptor {
  my ( $class, $species, $group, $adap ) = @_;
Ian Longden's avatar
Ian Longden committed
521

522 523
  if ( !( $class->alias_exists($species) ) ) {
    $class->add_alias( $species, $species );
524 525
  }

Ian Longden's avatar
Ian Longden committed
526 527
  $species = $class->get_alias($species);

528
  $registry_register{$species}{ lc($group) }{'_DB'} = $adap;
Ian Longden's avatar
Ian Longden committed
529

530 531 532 533 534 535
  if ( !defined( $registry_register{'_DBA'} ) ) {
    my @list = ();
    push( @list, $adap );
    $registry_register{'_DBA'} = \@list;
  } else {
    push( @{ $registry_register{'_DBA'} }, $adap );
Ian Longden's avatar
Ian Longden committed
536 537 538 539 540 541 542 543 544 545 546 547 548
  }

}



=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
549
  Status     : Stable
Ian Longden's avatar
Ian Longden committed
550 551 552

=cut

553 554
sub get_DBAdaptor {
  my ( $class, $species, $group ) = @_;
Ian Longden's avatar
Ian Longden committed
555 556 557

  $species = $class->get_alias($species);

558
  return $registry_register{$species}{ lc($group) }{'_DB'};
Ian Longden's avatar
Ian Longden committed
559 560 561 562
}

=head2 get_all_DBAdaptors

563 564 565 566
  Arg [SPECIES]: (optional) string 
                  species name to get adaptors for
  Arg [GROUP]  : (optional) string 
                  group name to get adaptors for
567 568 569 570 571 572 573 574 575
  Example      : 
                @dba =
                  @{ Bio::EnsEMBL::Registry->get_all_DBAdaptors() };

                @human_dbas =
                  @{ Bio::EnsEMBL::Registry->get_all_DBAdaptors(
                    -species => 'human'
                  ) };

576 577
  Returntype   : list of DBAdaptors
  Exceptions   : none
578
  Status       : Stable
Ian Longden's avatar
Ian Longden committed
579 580 581

=cut

582 583 584 585
sub get_all_DBAdaptors {
  my ( $class, @args ) = @_;

  my ( $species, $group ) = rearrange( [qw(SPECIES GROUP)], @args );
Ian Longden's avatar
Ian Longden committed
586

587
  if ( defined($species) ) { $species = $class->get_alias($species) }
588

589
  my @ret;
590
  foreach my $dba ( @{ $registry_register{'_DBA'} } ) {
591 592 593 594
    if ( ( !defined($species) || lc($species) eq lc( $dba->species() ) )
      && ( !defined($group) || lc($group) eq lc( $dba->group() ) ) )
    {
      push( @ret, $dba );
595 596 597 598
    }
  }

  return \@ret;
Ian Longden's avatar
Ian Longden committed
599 600
}

601 602
=head2 get_all_DBAdaptors_by_connection

603
  Arg [1]    : DBConnection used to find DBAdaptors
604
  Returntype : reference to list of DBAdaptors
605 606 607
  Exceptions : none
  Example    : @dba = @{ Bio::EnsEMBL::Registry
                  ->get_all_DBAdaptors_by_connection($dbc) };
608
  Status     : Stable
609 610 611

=cut

612 613 614
sub get_all_DBAdaptors_by_connection {
  my ( $self, $dbc_orig ) = @_;

615 616
  my @return;

617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651
  foreach my $dba ( @{ $registry_register{'_DBA'} } ) {
    my $dbc = $dba->dbc();

    if (    defined($dbc)
         && $dbc->can('equals')
         && $dbc->equals($dbc_orig) )
    {
      push( @return, $dba );
    }
  }

  return \@return;
}

=head2 get_all_DBAdaptors_by_dbname

  Arg [1]    : string, name of database
  Returntype : reference to list of DBAdaptors
  Exceptions : none
  Example    : @dba = @{ Bio::EnsEMBL::Registry
                  ->get_all_DBAdaptors_by_dbname($dbname) };
  Status     : Stable

=cut

sub get_all_DBAdaptors_by_dbname {
  my ( $self, $dbname ) = @_;

  my @return;

  foreach my $dba ( @{ $registry_register{'_DBA'} } ) {
    my $dbc = $dba->dbc();

    if ( defined($dbc) && $dbc->dbname() eq $dbname ) {
      push( @return, $dba );
652 653
    }
  }
654

655 656 657
  return \@return;
}

658 659 660 661 662 663 664 665 666 667 668 669 670 671 672
=head2 remove_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->remove_DBAdaptor("Human", "core");
  Returntype : none
  Exceptions : none
  Status     : At risk

=cut

sub remove_DBAdaptor{
  my ($class, $species, $group) = @_;

  $species = $class->get_alias($species);
Nathan Johnson's avatar
Nathan Johnson committed
673 674
  
 
675
  delete $registry_register{$species}{$group};
676
  # This will remove the DBAdaptor and all the other adaptors
677

678
  # Now remove if from the _DBA array
679 680
  my $index;

Nathan Johnson's avatar
Nathan Johnson committed
681

682 683
  foreach my $i(0..$#{$registry_register{'_DBA'}}){
    my $dba = $registry_register{'_DBA'}->[$i];
Nathan Johnson's avatar
Nathan Johnson committed
684

685 686 687
    if(($dba->species eq $species) &&
       $dba->group eq $group){
      $index = $i;
Nathan Johnson's avatar
Nathan Johnson committed
688

689 690 691 692
      last;
    }
  }
  
693
  
694
  # Now remove from _DBA cache
695
  splice(@{$registry_register{'_DBA'}}, $index, 1) if defined $index;
Nathan Johnson's avatar
Nathan Johnson committed
696

697 698 699
  return;
}

700

Nathan Johnson's avatar
Nathan Johnson committed
701 702 703 704 705 706 707

=head2 reset_DBAdaptor

  Arg [1]:     string - species e.g. homo_sapiens
  Arg [2]:     string - DB group e.g. core
  Arg [3]:     string - new dbname
  Args [4-7]:  string - optional DB parameters, defaults to current db params if omitted
708
  Arg [8]:     hashref - Hash ref of additional parameters e.g. eFG dnadb params for auto selecting dnadb
709 710
  Usage :      $reg->reset_registry_db( 'homo_sapiens', 'core',
                  'homo_sapiens_core_37_35j' );
Nathan Johnson's avatar
Nathan Johnson committed
711 712 713 714 715 716 717 718
  Description: Resets a DB within the registry.
  Exceptions:  Throws if mandatory params not supplied
               Throws if species name is not already seen by the registry
               Throws if no current DB for species/group available
  Status :     At risk

=cut

719 720 721 722 723
sub reset_DBAdaptor {
  my (
    $self, $species, $group, $dbname, $host,
    $port, $user,    $pass,  $params
  ) = @_;
Nathan Johnson's avatar
Nathan Johnson committed
724

725
  # Check mandatory params
726 727 728 729
  if ( !( defined $species && defined $group && defined $dbname ) ) {
    throw(
      'Must provide at least a species, group, and dbname parameter '
        . 'to redefine a DB in the registry' );
Nathan Johnson's avatar
Nathan Johnson committed
730
  }
731

732
  # Validate species here
Nathan Johnson's avatar
Nathan Johnson committed
733
  my $alias = $self->get_alias($species);
734 735 736
  throw("Could not find registry alias for species:\t$species")
    if ( !defined $alias );

737
  # Get all current defaults if not defined
Nathan Johnson's avatar
Nathan Johnson committed
738

739
  my $db = $self->get_DBAdaptor( $alias, $group );
740
  my $class;
Nathan Johnson's avatar
Nathan Johnson committed
741

742 743 744 745 746 747 748 749 750
  if ($db) {
    $class = ref($db);
    $host ||= $db->dbc->host;
    $port ||= $db->dbc->port;
    $user ||= $db->dbc->username;
    $pass ||= $db->dbc->password;
  } else {
    #Now we need to test mandatory params
    $class = $group2adaptor{ lc($group) };
751

752 753 754 755
    if ( !( $host && $user ) ) {
      throw("No comparable $alias $group DB present in Registry. "
          . "You must pass at least a dbhost and dbuser" );
    }
756
  }
Nathan Johnson's avatar
Nathan Johnson committed
757

758
  $self->remove_DBAdaptor( $alias, $group );
Nathan Johnson's avatar
Nathan Johnson committed
759

760 761 762 763
  #my @adaptors = @{$self->get_all_adaptors};
  #This is causing a loop as it was constantly trying to reset the db
  #and never getting there.
  #I think this was left over from testing
Nathan Johnson's avatar
Nathan Johnson committed
764

765
  # ConfigRegistry should automatically add this to the Registry
766 767

  $db = $class->new(
768 769 770 771 772 773 774 775
    -user    => $user,
    -host    => $host,
    -port    => $port,
    -pass    => $pass,
    -dbname  => $dbname,
    -species => $alias,
    -group   => $group,
    %{$params} );
Nathan Johnson's avatar
Nathan Johnson committed
776 777

  return $db;
778
} ## end sub reset_DBAdaptor
Nathan Johnson's avatar
Nathan Johnson committed
779 780


Ian Longden's avatar
Ian Longden committed
781 782 783 784 785 786 787 788
#
# 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.
789 790 791
  Arg [3]    : name of the species to get the dna from
  Arg [4]    : name of the group to get the dna from
  Example    : Bio::EnsEMBL::Registry->add_DNAAdaptor("Human", "estgene", "Human", "core");
Ian Longden's avatar
Ian Longden committed
792 793
  Returntype : none
  Exceptions : none
794
  Status     : Stable
Ian Longden's avatar
Ian Longden committed
795 796 797

=cut

798 799
sub add_DNAAdaptor {
  my ( $class, $species, $group, $dnadb_species, $dnadb_group ) = @_;
Ian Longden's avatar
Ian Longden committed
800

801
  $species       = $class->get_alias($species);
802
  $dnadb_species = $class->get_alias($dnadb_species);
803
  if ( $dnadb_group->isa('Bio::EnsEMBL::DBSQL::DBAdaptor') ) {
Ian Longden's avatar
Ian Longden committed
804
    deprecated("");
805 806 807 808
  } else {
    $registry_register{$species}{ lc($group) }{'_DNA'} = $dnadb_group;
    $registry_register{$species}{ lc($group) }{'_DNA2'} =
      $dnadb_species;
809
  }
Ian Longden's avatar
Ian Longden committed
810 811 812 813 814 815 816 817 818
}

=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
819
  Status     : Stable
Ian Longden's avatar
Ian Longden committed
820 821 822

=cut

823 824
sub get_DNAAdaptor {
  my ( $class, $species, $group ) = @_;
Ian Longden's avatar
Ian Longden committed
825 826

  $species = $class->get_alias($species);
827 828 829 830 831
  my $new_group   = $registry_register{$species}{ lc($group) }{'_DNA'};
  my $new_species = $registry_register{$species}{ lc($group) }{'_DNA2'};

  if ( defined $new_group ) {
    return $class->get_DBAdaptor( $new_species, $new_group );
832
  }
833 834

  return undef;
Ian Longden's avatar
Ian Longden committed
835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850
}

#
# 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
851 852
  Caller     : internal
  Status     : Stable
Ian Longden's avatar
Ian Longden committed
853 854 855

=cut

856 857
sub add_adaptor {
  my ( $class, $species, $group, $type, $adap, $reset ) = @_;
Ian Longden's avatar
Ian Longden committed
858 859 860

  $species = $class->get_alias($species);

861 862 863 864 865
  # Since the adaptors are not stored initially, only their 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
Ian Longden's avatar
Ian Longden committed
866

867 868 869
  if ( defined($reset) )
  {    # JUST REST THE HASH VALUE NO MORE PROCESSING NEEDED
    $registry_register{$species}{ lc($group) }{ lc($type) } = $adap;
Ian Longden's avatar
Ian Longden committed
870 871
    return;
  }
872 873 874 875 876 877 878
  if (
    defined( $registry_register{$species}{ lc($group) }{ lc($type) } ) )
  {
  # print STDERR (
  #      "Overwriting Adaptor in Registry for $species $group $type\n");
    $registry_register{$species}{ lc($group) }{ lc($type) } = $adap;
    return;
Ian Longden's avatar
Ian Longden committed
879
  }
880
  $registry_register{$species}{ lc($group) }{ lc($type) } = $adap;
Ian Longden's avatar
Ian Longden committed
881

882 883 884 885
  if ( !defined( $registry_register{$species}{'list'} ) ) {
    $registry_register{$species}{'list'} = [$type];
  } else {
    push( @{ $registry_register{$species}{'list'} }, $type );
Ian Longden's avatar
Ian Longden committed
886 887
  }

888 889 890 891
  if ( !defined( $registry_register{ lc($type) }{$species} ) ) {
    $registry_register{ lc($type) }{$species} = [$type];
  } else {
    push( @{ $registry_register{ lc($type) }{$species} }, $adap );
Ian Longden's avatar
Ian Longden committed
892 893
  }

894
} ## end sub add_adaptor
Ian Longden's avatar
Ian Longden committed
895 896 897 898 899 900 901 902 903 904


=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
905
  Status     : Stable
Ian Longden's avatar
Ian Longden committed
906 907 908

=cut

909 910
sub get_adaptor {
  my ( $class, $species, $group, $type ) = @_;
Glenn Proctor's avatar
Typos.  
Glenn Proctor committed
911

912
  $species = $class->get_alias($species);
Glenn Proctor's avatar
Typos.  
Glenn Proctor committed
913

914 915 916 917 918 919 920 921
  my %dnadb_adaptors = (
    'sequence'                 => 1,
    'assemblymapper'           => 1,
    'karyotypeband'            => 1,
    'repeatfeature'            => 1,
    'coordsystem'              => 1,
    'assemblyexceptionfeature' => 1
  );
922

923
  ## warn "$species, $group, $type";
924 925 926

  $type = lc($type);

927
  my $dnadb_group = $registry_register{$species}{ lc($group) }{'_DNA'};
928

929 930 931 932 933
  if ( defined($dnadb_group)
    && defined( $dnadb_adaptors{ lc($type) } ) )
  {
    $species = $registry_register{$species}{ lc($group) }{'_DNA2'};
    $group   = $dnadb_group;
Ian Longden's avatar
Ian Longden committed
934 935
  }

936
  my $ret = $registry_register{$species}{ lc($group) }{ lc($type) };
937 938
  if ( !defined($ret) ) { return undef }
  if ( ref($ret) )      { return $ret }
939

940
  # Not instantiated yet
Ian Longden's avatar
Ian Longden committed
941

942 943 944 945 946 947 948
  my $dba    = $registry_register{$species}{ lc($group) }{'_DB'};
  my $module = $ret;

  eval "require $module";
  if ($@) {
    warning("'$module' cannot be found.\nException $@\n");
    return undef;
Ian Longden's avatar
Ian Longden committed
949 950
  }

951 952 953 954 955 956 957 958 959 960 961 962
  if (
    !defined( $registry_register{$species}{ lc($group) }{'CHECKED'} ) )
  {
    $registry_register{$species}{ lc($group) }{'CHECKED'} = 1;
    $class->version_check($dba);
  }

  my $adap = "$module"->new($dba);
  Bio::EnsEMBL::Registry->add_adaptor( $species, $group, $type, $adap,
    'reset' );
  $ret = $adap;

Ian Longden's avatar
Ian Longden committed
963
  return $ret;
964
} ## end sub get_adaptor
Ian Longden's avatar
Ian Longden committed
965 966 967

=head2 get_all_adaptors

968 969 970 971 972 973
  Arg [SPECIES] : (optional) string 
                  species name to get adaptors for
  Arg [GROUP] : (optional) string 
                  group name to get adaptors for
  Arg [TYPE] : (optional) string 
                  type to get adaptors for
Ian Longden's avatar
Ian Longden committed
974
  Example    : @adaps = @{Bio::EnsEMBL::Registry->get_all_adaptors()};
975
  Returntype : ref to list of adaptors
Ian Longden's avatar
Ian Longden committed
976
  Exceptions : none
977
  Status     : Stable
Ian Longden's avatar
Ian Longden committed
978 979 980 981

=cut

sub get_all_adaptors{
982 983 984 985
  my ($class,@args)= @_;
  my ($species, $group, $type);
  my @ret=();
  my (%species_hash, %group_hash, %type_hash);
Ian Longden's avatar
Ian Longden committed
986

987

988
  if(@args == 1){ # Old species only one parameter
989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019
    warn("-SPECIES argument should now be used to get species adaptors");
    $species = $args[0];
  }
  else{
    # new style -SPECIES, -GROUP, -TYPE
    ($species, $group, $type) =
      rearrange([qw(SPECIES GROUP TYPE)], @args);
  }

  if(defined($species)){
    $species_hash{$species} = 1;
  }
  else{
    # get list of species
    foreach my $dba (@{$registry_register{'_DBA'}}){
      $species_hash{lc($dba->species())} = 1;
    }
  }
  if(defined($group)){
    $group_hash{$group} = 1;
  }
  else{
    foreach my $dba (@{$registry_register{'_DBA'}}){
      $group_hash{lc($dba->group())} = 1;
    }
  }
  if(defined($type)){
    $type_hash{$type} =1;
  }
  else{
    foreach my $dba (@{$registry_register{'_DBA'}}){ 
1020
	foreach my $ty (@{$registry_register{lc($dba->species)}{'list'}}){
1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037
	  $type_hash{lc($ty)} = 1;
	}
      }
  }
  
  ### NOW NEED TO INSTANTIATE BY CALLING get_adaptor
  foreach my $sp (keys %species_hash){
    foreach my $gr (keys %group_hash){
      foreach my $ty (keys %type_hash){
	my $temp = $class->get_adaptor($sp,$gr,$ty);
	if(defined($temp)){
	  push @ret, $temp;
	}
      }
    }
  }
  return (\@ret);
Ian Longden's avatar
Ian Longden committed
1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048
}


=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
1049
  Status     : Stable
Ian Longden's avatar
Ian Longden committed
1050 1051 1052 1053 1054 1055

=cut

sub add_alias{
  my ($class, $species,$key) = @_;

1056
  $registry_register{'_ALIAS'}{lc($key)} = lc($species);
Ian Longden's avatar
Ian Longden committed
1057 1058 1059 1060 1061 1062 1063 1064
}

=head2 get_alias

  Arg [1]    : name of the possible alias to get species for
  Example    : Bio::EnsEMBL::Registry->get_alias("Human");
  Description: get proper species name.
  Returntype : species name
1065
  Exceptions : none
1066
  Status     : Stable
Ian Longden's avatar
Ian Longden committed
1067 1068 1069 1070

=cut

sub get_alias{
1071
  my ($class, $key) = @_;
Ian Longden's avatar
Ian Longden committed
1072

1073
  if(!defined($registry_register{'_ALIAS'}{lc($key)})){
1074
    return $key;
Ian Longden's avatar
Ian Longden committed
1075
  }
1076
  return $registry_register{'_ALIAS'}{lc($key)};
Ian Longden's avatar
Ian Longden committed
1077
}
1078 1079 1080 1081

=head2 alias_exists

  Arg [1]    : name of the possible alias to get species for
Ian Longden's avatar
Ian Longden committed
1082
  Example    : Bio::EnsEMBL::Registry->alias_exists("Human");
1083