Commit ca440f91 authored by Graham McVicker's avatar Graham McVicker
Browse files

Moved meta_coord table information retrieval/storage out of CoordSystemAdaptor...

Moved meta_coord table information retrieval/storage out of CoordSystemAdaptor and into new MetaCoordContainer class.  This was causing problems because the meta coord information should be stored/retrieved in the feature database and the coord system information should be stored/retrieved in the dna database
parent 497c95bb
......@@ -430,8 +430,8 @@ sub fetch_all_by_Slice_constraint {
my ($tab_name, $tab_syn) = @{$tabs[0]};
#find out what coordinate systems the features are in
my $csa = $self->db->get_CoordSystemAdaptor();
my @feat_css = @{$csa->fetch_all_by_feature_table($tab_name)};
my $mcc = $self->db->get_MetaCoordContainer();
my @feat_css = @{$mcc->fetch_all_CoordSystems_by_feature_type($tab_name)};
my $asma = $self->db->get_AssemblyMapperAdaptor();
my @features;
......@@ -441,11 +441,11 @@ sub fetch_all_by_Slice_constraint {
my $mapper;
my @coords;
my @ids;
if($feat_cs->equals($slice_cs)) {
#no mapping is required if this is the same coord system
my $constraint = $original_constraint;
# obtain seq_region_id of this slice from db
my $seq_region_id =
$self->db->get_SliceAdaptor->get_seq_region_id($slice);
......@@ -463,7 +463,7 @@ sub fetch_all_by_Slice_constraint {
push @features, @$fs;
} else {
$mapper = $asma->fetch_by_CoordSystems($slice_cs, $feat_cs);
# Get a list of coordinates and corresponding internal ids for the
# regions we are interested in
@coords = $mapper->map($slice_seq_region, $slice_start, $slice_end,
......@@ -488,10 +488,10 @@ sub fetch_all_by_Slice_constraint {
my $id_str = join(',', @ids);
$constraint .= " AND " if($constraint);
$constraint .= "${tab_syn}.seq_region_id IN ($id_str)";
my $fs =
my $fs =
$self->generic_fetch($constraint, $mapper, $slice);
$fs = $self->_remap($fs, $mapper, $slice);
push @features, @$fs;
......@@ -509,13 +509,13 @@ sub fetch_all_by_Slice_constraint {
my $fs = $self->generic_fetch($constraint,$mapper,$slice);
$fs = $self->_remap($fs, $mapper, $slice);
push @features, @$fs;
}
}
}
} #COORD system loop
#if this was a symlinked slice offset the feature coordinates as needed
if($slice != $orig_slice) {
foreach my $f (@features) {
......@@ -530,7 +530,7 @@ sub fetch_all_by_Slice_constraint {
} else {
push @result_features, @features;
}
} #slice & symmlinked slice loop
$self->{'_slice_feature_cache'}->{$key} = \@result_features;
......@@ -595,27 +595,31 @@ sub _pre_store {
# Ensure that this type of feature is known to be stored in this coord
# system.
#
my $csa = $db->get_CoordSystemAdaptor();
my $cs = $slice->coord_system;
my ($tab) = $self->_tables();
my $tabname = $tab->[0];
$csa->add_feature_table($cs, $tabname);
my $mcc = $db->get_MetaCoordContainer();
$mcc->add_feature_type($cs, $tabname);
# we have to update the meta coord table in both the dna db and the feature
# db so that the feature db can be used independently later
if($db->dnadb() != $db) {
my $dnadb = $db->dnadb();
$db->dnadb(undef); # unset the dnadb temporarily
# Actually, the meta coord info should probably only go in the database
# where the features are actually stored, not the dnadb (which is often
# going to be read-only anyway)
# if($db->dnadb() != $db) {
# my $dnadb = $db->dnadb();
# $db->dnadb(undef); # unset the dnadb temporarily
#get a coord system adaptor from the feature database
$csa = $db->get_CoordSystemAdaptor();
$csa->add_feature_table($cs, $tabname);
# #get a coord system adaptor from the feature database
# $csa = $db->get_CoordSystemAdaptor();
# $csa->add_feature_table($cs, $tabname);
$db->dnadb($dnadb); # reinstate the dnadb
}
# $db->dnadb($dnadb); # reinstate the dnadb
# }
my $seq_region_id = $slice_adaptor->get_seq_region_id($slice);
......
......@@ -182,21 +182,7 @@ sub new {
}
$sth->finish();
#
# Retrieve the list of the coordinate systems that features are stored in
# and cache them
#
$sth = $self->prepare('SELECT table_name, coord_system_id FROM meta_coord');
$sth->execute();
while(my ($table_name, $dbID) = $sth->fetchrow_array()) {
$self->{'_feature_cache'}->{lc($table_name)} ||= [];
my $cs = $self->{'_dbID_cache'}->{$dbID};
if(!$cs) {
throw("meta_coord table refers to non-existant coord_system id=[$dbID]");
}
push @{$self->{'_feature_cache'}->{lc($table_name)}}, $cs;
}
$sth->finish();
#
# Retrieve a list of available mappings from the meta table.
......@@ -432,97 +418,6 @@ sub fetch_all_by_name {
=head2 fetch_all_by_feature_table
Arg [1] : string $table - the name of the table to retrieve coord systems
for
Example : my @coord_systems = $csa->fetch_by_feature_table('gene')
Description: This retrieves the list of coordinate systems that features
in a particular table are stored. It is used internally by
the API to perform queries to these tables and to ensure that
features are only stored in appropriate coordinate systems.
Returntype : listref of Bio::EnsEMBL::CoordSystem objects
Exceptions : none
Caller : BaseFeatureAdaptor
=cut
sub fetch_all_by_feature_table {
my $self = shift;
my $table = lc(shift); #case insensitive matching
throw('Name argument is required') unless $table;
return $self->{'_feature_cache'}->{$table} || [];
}
=head2 add_feature_table
Arg [1] : Bio::EnsEMBL::CoordSystem $cs
The coordinate system to associate with a feature table
Arg [2] : string $table - the name of the table in which features of
a given coordinate system will be stored in
Example : $csa->add_feature_table($chr_coord_system, 'gene');
Description: This function tells the coordinate system adaptor that
features from a specified table will be stored in a certain
coordinate system. If this information is not already stored
in the database it will be added.
Returntype : none
Exceptions : none
Caller : BaseFeatureAdaptor
=cut
sub add_feature_table {
my $self = shift;
my $cs = shift;
my $table = lc(shift);
if(!ref($cs) || !$cs->isa('Bio::EnsEMBL::CoordSystem')) {
throw('CoordSystem argument is required.');
}
if(!$table) {
throw('Table argument is required.');
}
my $coord_systems = $self->{'_feature_cache'}->{$table};
my ($exists) = grep {$_->equals($cs)} @$coord_systems;
#do not do anything if this feature table is already associated with the
#coord system
return if($exists);
#make sure to use a coord system stored in this database so that we
#do not use the wrong coord_system_id
if(!$cs->is_stored($self->db())) {
my ($name,$version) = ($cs->name(), $cs->version());
$cs = $self->fetch_by_name($name, $version);
if(!$cs) {
throw("CoordSystem $name $version not found in database.");
}
}
#store the new tablename -> coord system relationship in the db
#ignore failures b/c during the pipeline multiple processes may try
#to update this table and only the first will be successful
my $sth = $self->prepare('INSERT IGNORE INTO meta_coord ' .
'SET coord_system_id = ?, ' .
'table_name = ?');
$sth->execute($cs->dbID, $table);
#update the internal cache
$self->{'_feature_cache'}->{$table} ||= [];
push @{$self->{'_feature_cache'}->{$table}}, $cs;
return;
}
=head2 fetch_by_dbID
......
......@@ -112,6 +112,7 @@ sub new {
'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' =>
......@@ -209,7 +210,7 @@ sub get_QtlAdaptor {
=head2 get_MetaContainer
Args : none
Example : $meta_container = $db_adaptor->get_MetaContainer();
Example : $meta_container = $db_adaptor->get_MetaContainer();
Description: Gets a MetaContainer object for this database
Returntype : Bio::EnsEMBL::DBSQL::MetaContainer
Exceptions : none
......@@ -223,6 +224,23 @@ sub get_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
......
use strict;
use warnings;
package Bio::EnsEMBL::DBSQL::MetaCoordContainer;
use vars qw(@ISA);
use strict;
use Bio::EnsEMBL::DBSQL::BaseAdaptor;
use Bio::EnsEMBL::Utils::Exception;
@ISA = qw(Bio::EnsEMBL::DBSQL::BaseAdaptor);
sub new {
my $class = shift;
my $self = $class->SUPER::new(@_);
#
# Retrieve the list of the coordinate systems that features are stored in
# and cache them
#
my $sth = $self->prepare
('SELECT table_name, coord_system_id FROM meta_coord');
$sth->execute();
while(my ($table_name, $cs_id) = $sth->fetchrow_array()) {
$self->{'_feature_cache'}->{lc($table_name)} ||= [];
push @{$self->{'_feature_cache'}->{lc($table_name)}}, $cs_id;
}
$sth->finish();
return $self;
}
=head2 fetch_all_CoordSystems_by_feature_type
Arg [1] : string $table - the name of the table to retrieve coord systems
for. E.g. 'gene', 'exon', 'dna_align_feature'
Example : @css = @{$mcc->fetch_all_CoordSystems_by_feature_type('gene')};
Description: This retrieves the list of coordinate systems that features
in a particular table are stored. It is used internally by
the API to perform queries to these tables and to ensure that
features are only stored in appropriate coordinate systems.
Returntype : listref of Bio::EnsEMBL::CoordSystem objects
Exceptions : none
Caller : BaseFeatureAdaptor
=cut
sub fetch_all_CoordSystems_by_feature_type {
my $self = shift;
my $table = lc(shift); #case insensitive matching
throw('Name argument is required') unless $table;
if(!$self->{'_feature_cache'}->{$table}) {
return [];
}
my @cs_ids = @{$self->{'_feature_cache'}->{$table}};
my @coord_systems;
my $csa = $self->db->get_CoordSystemAdaptor();
foreach my $cs_id (@cs_ids) {
my $cs = $csa->fetch_by_dbID($cs_id);
if(!$cs) {
throw("meta_coord table refers to non-existant coord_system $cs_id");
}
push @coord_systems, $cs;
}
return \@coord_systems;
}
=head2 add_feature_type
Arg [1] : Bio::EnsEMBL::CoordSystem $cs
The coordinate system to associate with a feature table
Arg [2] : string $table - the name of the table in which features of
a given coordinate system will be stored in
Example : $csa->add_feature_table($chr_coord_system, 'gene');
Description: This function tells the coordinate system adaptor that
features from a specified table will be stored in a certain
coordinate system. If this information is not already stored
in the database it will be added.
Returntype : none
Exceptions : none
Caller : BaseFeatureAdaptor
=cut
sub add_feature_type {
my $self = shift;
my $cs = shift;
my $table = lc(shift);
if(!ref($cs) || !$cs->isa('Bio::EnsEMBL::CoordSystem')) {
throw('CoordSystem argument is required.');
}
if(!$table) {
throw('Table argument is required.');
}
my $cs_ids = $self->{'_feature_cache'}->{$table} || [];
my ($exists) = grep {$cs->dbID() == $_} @$cs_ids;
#do not do anything if this feature table is already associated with the
#coord system
return if($exists);
#store the new tablename -> coord system relationship in the db
#ignore failures b/c during the pipeline multiple processes may try
#to update this table and only the first will be successful
my $sth = $self->prepare('INSERT IGNORE INTO meta_coord ' .
'SET coord_system_id = ?, ' .
'table_name = ?');
$sth->execute($cs->dbID, $table);
#update the internal cache
$self->{'_feature_cache'}->{$table} ||= [];
push @{$self->{'_feature_cache'}->{$table}}, $cs->dbID();
return;
}
1;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment