Archive Ensembl HomeArchive Ensembl Home
DnaFragChunkAdaptor.pm
Go to the documentation of this file.
00001 =head1 LICENSE
00002 
00003   Copyright (c) 1999-2012 The European Bioinformatics Institute and
00004   Genome Research Limited.  All rights reserved.
00005 
00006   This software is distributed under a modified Apache license.
00007   For license details, please see
00008 
00009     http://www.ensembl.org/info/about/code_licence.html
00010 
00011 =head1 CONTACT
00012 
00013   Please email comments or questions to the public Ensembl
00014   developers list at <dev@ensembl.org>.
00015 
00016   Questions may also be sent to the Ensembl help desk at
00017   <helpdesk@ensembl.org>.
00018 
00019 =head1 NAME
00020 
00021 Bio::EnsEMBL::Compara::Production::DBSQL::DnaFragChunkAdaptor
00022 
00023 =head1 SYNOPSIS
00024 
00025 =head1 APPENDIX
00026 
00027 =cut
00028 
00029 package Bio::EnsEMBL::Compara::Production::DBSQL::DnaFragChunkAdaptor;
00030 
00031 use Bio::EnsEMBL::Compara::Production::DnaFragChunk;
00032 
00033 use Bio::EnsEMBL::Hive::DBSQL::AnalysisDataAdaptor;
00034 use Bio::EnsEMBL::Compara::DBSQL::DnaFragAdaptor;
00035 use Bio::EnsEMBL::Compara::DBSQL::SequenceAdaptor;
00036 
00037 use Bio::EnsEMBL::DBSQL::BaseAdaptor;
00038 our @ISA = qw(Bio::EnsEMBL::DBSQL::BaseAdaptor);
00039 
00040 
00041 #############################
00042 #
00043 # store methods
00044 #
00045 #############################
00046 
00047 =head2 store
00048 
00049   Arg[1]     : one or many DnaFragChunk objects
00050   Example    : $adaptor->store($chunk);
00051   Description: stores DnaFragChunk objects into compara database
00052   Returntype : none
00053   Exceptions : none
00054   Caller     : general
00055 
00056 =cut
00057 
00058 sub store {
00059   my ($self, $dfc)  = @_;
00060 
00061   return unless($dfc);
00062   return unless($dfc->isa('Bio::EnsEMBL::Compara::Production::DnaFragChunk'));
00063 
00064   my $query = "INSERT ignore INTO dnafrag_chunk".
00065               "(dnafrag_id,sequence_id,seq_start,seq_end,method_link_species_set_id, masking_tag_name) ".
00066               "VALUES (?,?,?,?,?,?)";
00067 
00068   $dfc->sequence_id($self->db->get_SequenceAdaptor->store($dfc->sequence));
00069 
00070   #print("$query\n");
00071   my $sth = $self->prepare($query);
00072   my $insertCount =
00073      $sth->execute($dfc->dnafrag_id, $dfc->sequence_id,
00074                    $dfc->seq_start, $dfc->seq_end,
00075                    $dfc->method_link_species_set_id,
00076           $dfc->masking_tag_name);
00077   if($insertCount>0) {
00078     #sucessful insert
00079     $dfc->dbID( $sth->{'mysql_insertid'} );
00080     $sth->finish;
00081   } else {
00082     $sth->finish;
00083     #UNIQUE(dnafrag_id,seq_start,seq_end,masking_analysis_data_id) prevented insert
00084     #since dnafrag_chunk was already inserted so get dnafrag_chunk_id with select
00085     my $sth2 = $self->prepare("SELECT dnafrag_chunk_id FROM dnafrag_chunk ".
00086            " WHERE dnafrag_id=? and seq_start=? and seq_end=? and method_link_species_set_id=? and masking_tag_name=?");
00087     $sth2->execute($dfc->dnafrag_id, $dfc->seq_start, $dfc->seq_end,
00088                    $dfc->method_link_species_set_id,
00089           $dfc->masking_tag_name);
00090     my($id) = $sth2->fetchrow_array();
00091     warn("DnaFragChunkAdaptor: insert failed, but dnafrag_chunk_id select failed too") unless($id);
00092     $dfc->dbID($id);
00093     $sth2->finish;
00094   }
00095 
00096   $dfc->adaptor($self);
00097   
00098   return $dfc;
00099 }
00100 
00101 
00102 sub update_sequence
00103 {
00104   my $self = shift;
00105   my $dfc  = shift;
00106 
00107   return 0 unless($dfc);
00108   return 0 unless($dfc->isa('Bio::EnsEMBL::Compara::Production::DnaFragChunk'));
00109   return 0 unless($dfc->dbID);
00110   return 0 unless(defined($dfc->sequence));
00111   return 0 unless(length($dfc->sequence) <= 11500000);  #limited by myslwd max_allowed_packet=12M 
00112 
00113   my $seqDBA = $self->db->get_SequenceAdaptor;
00114   my $newSeqID = $seqDBA->store($dfc->sequence);
00115 
00116   return if($dfc->sequence_id == $newSeqID); #sequence unchanged
00117 
00118   my $sth = $self->prepare("UPDATE dnafrag_chunk SET sequence_id=? where dnafrag_chunk_id=?");
00119   $sth->execute($newSeqID, $dfc->dbID);
00120   $sth->finish();
00121   $dfc->sequence_id($newSeqID);
00122   return $newSeqID;
00123 }
00124 
00125 
00126 ###############################################################################
00127 #
00128 # fetch methods
00129 #
00130 ###############################################################################
00131 
00132 =head2 fetch_by_dbID
00133 
00134   Arg [1]    : int $id
00135                the unique database identifier for the feature to be obtained
00136   Example    : $dfc = $adaptor->fetch_by_dbID(1234);
00137   Description: Returns the DnaFragChunk created from the database defined by the
00138                the id $id.
00139   Returntype : Bio::EnsEMBL::Compara::Production::DnaFragChunk
00140   Exceptions : thrown if $id is not defined
00141   Caller     : general
00142 
00143 =cut
00144 
00145 sub fetch_by_dbID{
00146   my ($self,$id) = @_;
00147 
00148   unless(defined $id) {
00149     $self->throw("fetch_by_dbID must have an id");
00150   }
00151 
00152   my @tabs = $self->_tables;
00153 
00154   my ($name, $syn) = @{$tabs[0]};
00155 
00156   #construct a constraint like 't1.table1_id = 1'
00157   my $constraint = "${syn}.${name}_id = $id";
00158 
00159   #return first element of _generic_fetch list
00160   my ($obj) = @{$self->_generic_fetch($constraint)};
00161   return $obj;
00162 }
00163 
00164 =head2 fetch_by_dbIDs
00165 
00166   Arg [1...] : int $id (multiple)
00167                the unique database identifier for the feature to be obtained
00168   Example    : $dfc = $adaptor->fetch_by_dbID(1234);
00169   Description: Returns an array of DnaFragChunk created from the database defined by the
00170                the id $id.
00171   Returntype : listref of Bio::EnsEMBL::Compara::Production::DnaFragChunk objects
00172   Exceptions : thrown if $id is not defined
00173   Caller     : general
00174 
00175 =cut
00176 
00177 sub fetch_by_dbIDs{
00178   my $self = shift;
00179   my @ids = @_;
00180 
00181   return undef unless(scalar(@ids));
00182 
00183   my $id_string = join(",", @ids);
00184   my $constraint = "dfc.dnafrag_chunk_id in ($id_string)";
00185   #printf("fetch_by_dbIDs has contraint\n$constraint\n");
00186 
00187   #return first element of _generic_fetch list
00188   return $self->_generic_fetch($constraint);
00189 }
00190 
00191 
00192 =head2 fetch_all
00193 
00194   Arg        : None
00195   Example    :
00196   Description:
00197   Returntype :
00198   Exceptions :
00199   Caller     :
00200 
00201 =cut
00202 
00203 sub fetch_all {
00204   my $self = shift;
00205 
00206   return $self->_generic_fetch();
00207 }
00208 
00209 =head2 fetch_all_for_genome_db_id
00210 
00211   Arg [1]    : int $genome_db_id
00212   Example    : $chunks = $adaptor->fetch_all_for_genome_db_id(1);
00213   Description: Returns an array with all the DnaFragChunk objects for a given genome_db_id
00214   Returntype : listref of Bio::EnsEMBL::Compara::Production::DnaFragChunk objects
00215   Exceptions : thrown if $id is not defined
00216   Caller     : general
00217 
00218 =cut
00219 
00220 sub fetch_all_for_genome_db_id{
00221   my $self = shift;
00222   my $genome_db_id = shift;
00223 
00224   $self->throw() unless (defined $genome_db_id);
00225   
00226   my $constraint = "df.genome_db_id='$genome_db_id'";
00227 
00228   my $join = [[['dnafrag', 'df'], 'dfc.dnafrag_id=df.dnafrag_id']];
00229   
00230   return $self->_generic_fetch($constraint, $join);
00231 }
00232 
00233 ############################
00234 #
00235 # INTERNAL METHODS
00236 # (pseudo subclass methods)
00237 #
00238 ############################
00239 
00240 #internal method used in multiple calls above to build objects from table data
00241 
00242 sub _tables {
00243   my $self = shift;
00244 
00245   return (['dnafrag_chunk', 'dfc'] );
00246 }
00247 
00248 sub _columns {
00249   my $self = shift;
00250 
00251   return qw (dfc.dnafrag_chunk_id
00252              dfc.dnafrag_id
00253              dfc.seq_start
00254              dfc.seq_end
00255              dfc.method_link_species_set_id
00256          dfc.masking_tag_name
00257              dfc.sequence_id
00258             );
00259 }
00260 
00261 sub _default_where_clause {
00262   my $self = shift;
00263   return '';
00264 }
00265 
00266 sub _final_clause {
00267   my $self = shift;
00268   $self->{'_final_clause'} = shift if(@_);
00269   return $self->{'_final_clause'};
00270 }
00271 
00272 
00273 sub _objs_from_sth {
00274   my ($self, $sth) = @_;
00275 
00276   my %column;
00277   $sth->bind_columns( \( @column{ @{$sth->{NAME_lc} } } ));
00278 
00279   my @chunks = ();
00280 
00281   while ($sth->fetch()) {
00282     my $dfc;
00283 
00284     $dfc = Bio::EnsEMBL::Compara::Production::DnaFragChunk->new();
00285 
00286     $dfc->adaptor($self);
00287     $dfc->dbID($column{'dnafrag_chunk_id'});
00288     $dfc->seq_start($column{'seq_start'});
00289     $dfc->seq_end($column{'seq_end'});
00290     $dfc->sequence_id($column{'sequence_id'});
00291     $dfc->dnafrag_id($column{'dnafrag_id'});
00292     $dfc->method_link_species_set_id($column{'method_link_species_set_id'});
00293     $dfc->masking_tag_name($column{'masking_tag_name'});
00294 
00295     if($column{'method_link_species_set_id'} && $column{'masking_tag_name'}) {
00296       $dfc->masking_options($self->fetch_MaskingOptions_by_mlss_tag($column{'method_link_species_set_id'},$column{'masking_tag_name'}));
00297 
00298       #reset method_link_species_set_id and masking_tag_name because setting masking_options clears these fields
00299       $dfc->method_link_species_set_id($column{'method_link_species_set_id'});
00300       $dfc->masking_tag_name($column{'masking_tag_name'});
00301 
00302     }
00303 
00304     #$dfc->display_short();
00305     
00306     push @chunks, $dfc;
00307 
00308   }
00309   $sth->finish;
00310   return \@chunks
00311 }
00312 
00313 
00314 =head2 _generic_fetch
00315 
00316   Arg [1]    : (optional) string $constraint
00317                An SQL query constraint (i.e. part of the WHERE clause)
00318   Arg [2]    : (optional) string $logic_name
00319                the logic_name of the analysis of the features to obtain
00320   Example    : $fts = $a->_generic_fetch('contig_id in (1234, 1235)', 'Swall');
00321   Description: Performs a database fetch and returns feature objects in
00322                contig coordinates.
00323   Returntype : listref of Bio::EnsEMBL::Production::DnaFragChunk in contig coordinates
00324   Exceptions : none
00325   Caller     : internal
00326 
00327 =cut
00328 
00329 sub _generic_fetch {
00330   my ($self, $constraint, $join) = @_;
00331 
00332   my @tables = $self->_tables;
00333   my $columns = join(', ', $self->_columns());
00334 
00335   if ($join) {
00336     foreach my $single_join (@{$join}) {
00337       my ($tablename, $condition, $extra_columns) = @{$single_join};
00338       if ($tablename && $condition) {
00339         push @tables, $tablename;
00340 
00341         if($constraint) {
00342           $constraint .= " AND $condition";
00343         } else {
00344           $constraint = " $condition";
00345         }
00346       }
00347       if ($extra_columns) {
00348         $columns .= ", " . join(', ', @{$extra_columns});
00349       }
00350     }
00351   }
00352 
00353   #construct a nice table string like 'table1 t1, table2 t2'
00354   my $tablenames = join(', ', map({ join(' ', @$_) } @tables));
00355 
00356   my $sql = "SELECT $columns FROM $tablenames";
00357 
00358   my $default_where = $self->_default_where_clause;
00359   my $final_clause = $self->_final_clause;
00360 
00361   #append a where clause if it was defined
00362   if($constraint) {
00363     $sql .= " WHERE $constraint ";
00364     if($default_where) {
00365       $sql .= " AND $default_where ";
00366     }
00367   } elsif($default_where) {
00368     $sql .= " WHERE $default_where ";
00369   }
00370 
00371   #append additional clauses which may have been defined
00372   $sql .= " $final_clause" if($final_clause);
00373 
00374   #print STDERR $sql,"\n";
00375   my $sth = $self->prepare($sql);
00376   $sth->execute;
00377 
00378   # print STDERR $sql,"\n";
00379   # print STDERR "sql execute finished. about to build objects\n";
00380 
00381   return $self->_objs_from_sth($sth);
00382 }
00383 
00384 
00385 sub _fetch_DnaFrag_by_dbID
00386 {
00387   my $self       = shift;
00388   my $dnafrag_id = shift;
00389 
00390   return $self->db->get_DnaFragAdaptor->fetch_by_dbID($dnafrag_id);  
00391 }
00392 
00393 sub fetch_MaskingOptions_by_mlss_tag
00394 {
00395   my $self    = shift;
00396   my $mlss_id = shift;
00397   my $tag_name= shift;
00398 
00399   my $cache_key = $mlss_id.':'.$tag_name;
00400 
00401   $self->{'_masking_cache'} ||= {};
00402 
00403   unless($self->{'_masking_cache'}->{$cache_key}) {
00404     my $mlss = $self->db->get_MethodLinkSpeciesSetAdaptor->fetch_by_dbID($mlss_id) or die "No MLSS object with id=$mlss_id";    
00405     $self->{'_masking_cache'}->{$cache_key} = $mlss->get_value_for_tag($tag_name);
00406   }
00407   
00408   return $self->{'_masking_cache'}->{$cache_key};
00409 }
00410 
00411 
00412 1;