diff --git a/modules/Bio/EnsEMBL/Map/DBSQL/DitagAdaptor.pm b/modules/Bio/EnsEMBL/Map/DBSQL/DitagAdaptor.pm new file mode 100644 index 0000000000000000000000000000000000000000..90db4302141625d1e3d169e6941edc95510e4db4 --- /dev/null +++ b/modules/Bio/EnsEMBL/Map/DBSQL/DitagAdaptor.pm @@ -0,0 +1,349 @@ +# EnsEMBL module for DitagAdaptor +# +# Copyright EMBL-EBI/Wellcome Trust Sanger Center 2006 +# +# You may distribute this module under the same terms as perl itself +# +# Cared for by EnsEMBL (ensembl-dev@ebi.ac.uk) + +# POD documentation - main docs before the code + +=head1 NAME + +Bio::EnsEMBL::Map::DBSQL::DitagAdaptor + +=head1 SYNOPSIS + +my $ditagadaptor = $db->get_DitagAdaptor(); +my @ditags = @{ $ditagadaptor->fetch_by_type("ZZ11") }; + +=head1 DESCRIPTION + +Provides database interaction for the Bio::EnsEMBL::Map::Ditag object + +=cut + +package Bio::EnsEMBL::Map::DBSQL::DitagAdaptor; + +use strict; +use vars ('@ISA'); + +use Bio::EnsEMBL::Map::Ditag; +use Bio::EnsEMBL::DBSQL::BaseAdaptor; +use Bio::EnsEMBL::Utils::Exception qw(throw warning); + +@ISA = qw(Bio::EnsEMBL::DBSQL::BaseAdaptor); + + +=head2 fetch_by_name + + Arg [1] : ditag name + Example : $tag = $ditag_adaptor->fetch_by_name("U3"); + Description: Retrieves ditags from the database using the name + Returntype : listref of Bio::EnsEMBL::Map::Ditag + Caller : general + +=cut + +sub fetch_by_name { + my ($self, $tagname) = @_; + + if(!$tagname){ + throw "must be called with a name of a ditag."; + } + my $sth = $self->prepare("SELECT d.ditag_id, d.name, d.type, d.tag_count, d.sequence + FROM ditag d + WHERE d.name = ?"); + $sth->execute($tagname); + my $result = $self->_fetch($sth); + + return $result; + +} + + +=head2 fetch_by_dbID + + Arg [1] : ditag type + Example : @all_tags = @{$ditag_adaptor->fetch_by_dbID(1003)}; + Description: Retrieve ditags with a certain id from the database + Returntype : listref of Bio::EnsEMBL::Map::Ditag + Caller : general + +=cut + +sub fetch_by_dbID { + my ($self, $tagid) = @_; + + if(!$tagid){ + throw "must be called with the type of a ditag."; + } + my $sth = $self->prepare("SELECT d.ditag_id, d.name, d.type, d.tag_count, d.sequence + FROM ditag d + WHERE d.ditag_id = ?"); + $sth->execute($tagid); + my $result = $self->_fetch($sth); + + return $result; +} + + +=head2 fetch_all_by_type + + Arg [1] : ditag type + Example : @all_tags = @{$ditag_adaptor->fetch_by_type("SME005")}; + Description: Retrieves all ditags of a certain type from the database + Returntype : listref of Bio::EnsEMBL::Map::Ditag + Caller : general + +=cut + +sub fetch_all_by_type { + my ($self, $tagtype) = @_; + + if(!$tagtype){ + throw "must be called with the type of a ditag."; + } + my $sth = $self->prepare("SELECT d.ditag_id, d.name, d.type, d.tag_count, d.sequence + FROM ditag d + WHERE d.type = ?"); + $sth->execute($tagtype); + my $result = $self->_fetch($sth); + + return $result; +} + + +=head2 fetch_all_by_name_and_type + + Arg [1] : ditag name + Arg [2] : ditag type + Example : $tag = $ditag_adaptor->fetch_by_name_and_type("U3", "SME005"); + Description: Retrieves ditags from the database using name/type combination + which should be non-ambiguous + Returntype : listref of Bio::EnsEMBL::Map::Ditag + Caller : general + +=cut + +sub fetch_all_by_name_and_type { + my ($self, $tagname, $tagtype) = @_; + + if(!$tagname or !$tagtype){ + throw "must be called with a name and type of a ditag."; + } + my $sth = $self->prepare("SELECT d.ditag_id, d.name, d.type, d.tag_count, d.sequence + FROM ditag d + WHERE d.name = ? and d.type = ?"); + $sth->execute($tagname, $tagtype); + my $result = $self->_fetch($sth); + + return $result; +} + + +=head2 fetch_all + + Args : none + Example : @all_tags = @{$ditag_adaptor->fetch_all}; + Description: Retrieves all ditags from the database + Returntype : listref of Bio::EnsEMBL::Map::Ditag + Caller : general + +=cut + +sub fetch_all { + my ($self) = @_; + + my $sth = $self->prepare("SELECT d.ditag_id, d.name, d.type, d.tag_count, d.sequence + FROM ditag d"); + $sth->execute; + my $result = $self->_fetch($sth); + + return $result; +} + + +=head2 fetch_with_limit + + Arg [1] : ditag type + Arg [2] : row limit + Arg [3] : row offset + Description: fetch_by_type with row limit and offset + Returntype : listref of Bio::EnsEMBL::Map::Ditag + +=cut + +sub fetch_with_limit { + my ($self, $tagtype, $limit, $offset) = @_; + + my @ditags = (); + print STDERR "> $tagtype, $limit, $offset\n"; + my $sql = "SELECT d.ditag_id, d.name, d.type, d.tag_count, d.sequence ". + "FROM ditag d ". + "WHERE d.type = ? LIMIT ? OFFSET ?;"; + my $sth = $self->db->dbc->prepare($sql); + $sth->execute($tagtype, $limit, $offset); + my $result = $self->_fetch($sth); + + return $result; +} + + +=head2 _fetch + + Arg [1] : statement handler object + Description: generic sql-fetch function for the ditag fetch methods + Returntype : listref of Bio::EnsEMBL::Map::Ditag + Caller : private + +=cut + +sub _fetch { + my ($self, $sth) = @_; + + my($tag_id, $name, $type, $count, $sequence); + my @tags; + + $sth->bind_columns(\$tag_id, \$name, \$type, \$count, \$sequence); + while($sth->fetch) { + push @tags, Bio::EnsEMBL::Map::Ditag->new ( + -dbID => $tag_id, + -name => $name, + -type => $type, + -tag_count => $count, + -sequence => $sequence, + -adaptor => $self, + ); + } + + return \@tags; +} + + +=head2 store + + Arg [1] : Bio::EnsEMBL::Map::Ditag + Example : $ditag_adaptor->store(\@ditags); + Description: Stores a single ditag or + a list of ditags in this database. + Returntype : none + Caller : general + +=cut + +sub store { + my ($self, $ditags) = @_; + + if(ref $ditags eq 'ARRAY'){ + if(scalar(@$ditags) == 0){ + throw("Must call store with ditag or list ref of ditags"); + } + } + elsif($ditags){ + my @ditags; + push @ditags, $ditags; + $ditags = \@ditags; + } + else{ + throw("Must call store with ditag or list ref of ditags not ".$ditags); + } + + my $db = $self->db() or throw "Couldn t get database connection."; + + TAG: + foreach my $ditag (@$ditags) { + + if ( !ref $ditag || !$ditag->isa("Bio::EnsEMBL::Map::Ditag") ) { + throw( "Object must be an Ensembl Ditag, " . "not a [" . ref($ditag) . "]" ); + } + +# if ( $ditag->is_stored($db) ) { +# warning( "Ditag [" . $ditag->dbID . "] is already stored in this database." ); +# next TAG; +# } + + #check if tag with same name/type exists + my $sth = $self->prepare( "SELECT COUNT(*) FROM ditag + WHERE name = ? AND type = ?" ); + $sth->execute($ditag->name, $ditag->type); + if($sth->fetchrow() > 0){ + warning( "Ditag with name/type ".$ditag->name." / ".$ditag->type. + " is already stored in this database." ); + next TAG; + } + + if ( $ditag->dbID ) { + my $sth = $self->prepare( "INSERT INTO ditag( ditag_id , name, type, tag_count, sequence ) ". + "VALUES( ?,?,?,?,? )" ); + $sth->bind_param(1,$ditag->dbID,SQL_INTEGER); + $sth->bind_param(2,$ditag->name,SQL_VARCHAR); + $sth->bind_param(3,$ditag->type,SQL_VARCHAR); + $sth->bind_param(4,$ditag->tag_count,SQL_VARCHAR); + $sth->bind_param(5,$ditag->sequence,SQL_VARCHAR); + $sth->execute(); + } else { + my $sth = $self->prepare( "INSERT INTO ditag( name, type, tag_count, sequence ) ". + "VALUES( ?,?,?,? )" ); + $sth->bind_param(1,$ditag->name,SQL_VARCHAR); + $sth->bind_param(2,$ditag->type,SQL_VARCHAR); + $sth->bind_param(3,$ditag->tag_count,SQL_VARCHAR); + $sth->bind_param(4,$ditag->sequence,SQL_VARCHAR); + $sth->execute(); + my $dbID = $sth->{'mysql_insertid'}; + $ditag->dbID($dbID); + $ditag->adaptor($self); + } + } + + return 1; +} + + +=head2 print_creation + + Arg [1] : ditag probe name + Arg [2] : ditag type + Arg [3] : ditag count + Arg [4] : ditag sequence + Arg [5] : (optional) ditag dbID + Description: convenience method to produce SQL insert statements + to speed up the creation of new ditags + Returntype : string + +=cut + +sub print_creation { + my ($self, $probe_name, $type, $count, $sequence, $dbid) = @_; + my $string; + if($dbid){ + $string = "INSERT INTO ditag( ditag_id, name, type, tag_count, sequence ) ". + "VALUES($dbid, '".$probe_name."', '".$type."', ".$count."'".$sequence."');\n"; + } + else { + $string = "INSERT INTO ditag( name, type, tag_count, sequence ) ". + "VALUES('".$probe_name."', '".$type."', ".$count.", '".$sequence."');\n"; + } + + return $string; +} + + +=head2 list_dbIDs + + Args : None + Example : my @feature_ids = @{$da->list_dbIDs()}; + Description: Gets an array of internal IDs for all Ditag objects in + the current database. + Returntype : List of ints + Exceptions : None + +=cut + +sub list_dbIDs { + my $self = shift; + + return $self->_list_dbIDs('ditag'); +} + +1; diff --git a/modules/Bio/EnsEMBL/Map/DBSQL/DitagFeatureAdaptor.pm b/modules/Bio/EnsEMBL/Map/DBSQL/DitagFeatureAdaptor.pm new file mode 100644 index 0000000000000000000000000000000000000000..c0034743f97130bc9a45dc008fbe23bfa7d43a45 --- /dev/null +++ b/modules/Bio/EnsEMBL/Map/DBSQL/DitagFeatureAdaptor.pm @@ -0,0 +1,579 @@ +# EnsEMBL module for DitagFeatureAdaptor +# +# Copyright EMBL-EBI/Wellcome Trust Sanger Center 2006 +# +# You may distribute this module under the same terms as perl itself +# +# Cared for by EnsEMBL (ensembl-dev@ebi.ac.uk) + +# POD documentation - main docs before the code + +=head1 NAME + +Bio::EnsEMBL::Map::DBSQL::DitagFeatureAdaptor + +=head1 SYNOPSIS + +my $dfa = $db->get_DitagFeatureAdaptor; +my $ditagFeatures = $dfa->fetch_by_ditag_id(123); +foreach my $ditagFeature (@$ditagFeatures){ + print $ditagFeature->ditag_id . " " . + $ditagFeature->slice . " " . $ditagFeature->start . "-" . + $ditagFeature->end . " " . $ditagFeature->strand; +} + +=head1 DESCRIPTION + +Provides database interaction for the Bio::EnsEMBL::Map::DitagFeature object + +=cut + +package Bio::EnsEMBL::Map::DBSQL::DitagFeatureAdaptor; + +use strict; +use vars ('@ISA'); + +use Bio::EnsEMBL::Map::Ditag; +use Bio::EnsEMBL::Map::DitagFeature; +use Bio::EnsEMBL::DBSQL::BaseAdaptor; +use Bio::EnsEMBL::Utils::Exception qw(throw warning); + +@ISA = qw(Bio::EnsEMBL::DBSQL::BaseAdaptor); + + +=head2 fetch_all + + Arg [1] : none + Example : @all_tags = @{$ditagfeature_adaptor->fetch_all}; + Description: Retrieves all ditagFeatures from the database + Returntype : listref of Bio::EnsEMBL::Map::DitagFeature + Caller : general + +=cut + +sub fetch_all { + my $self = shift; + + my $sth = $self->prepare("SELECT ditag_feature_id, ditag_id, seq_region_id, seq_region_start, + seq_region_end, seq_region_strand, analysis_id, hit_start, hit_end, + hit_strand, cigar_line, ditag_side, ditag_pair_id + FROM ditag_feature" ); + $sth->execute; + + my $result = $self->_fetch($sth); + + return $result; +} + + +=head2 fetch_by_dbID + + Arg [1] : ditagFeature dbID + Example : @my_tags = @{$ditagfeature_adaptor->fetch_by_dbID($my_id)}; + Description: Retrieves a ditagFeature from the database. + Returntype : Bio::EnsEMBL::Map::DitagFeature + Caller : general + +=cut + +sub fetch_by_dbID { + my ($self, $dbid) = @_; + + my $sth = $self->prepare("SELECT ditag_feature_id, ditag_id, seq_region_id, seq_region_start, + seq_region_end, seq_region_strand, analysis_id, hit_start, hit_end, + hit_strand, cigar_line, ditag_side, ditag_pair_id + FROM ditag_feature + WHERE ditag_feature_id = ?" ); + $sth->execute($dbid); + + my $result = $self->_fetch($sth); + + return $result->[0]; +} + + +=head2 fetch_by_ditagID + + Arg [1] : ditag dbID + Example : @my_tags = @{$ditagfeature_adaptor->fetch_by_ditag_id($my_id)}; + Description: Retrieves all ditagFeatures from the database linking to a specific ditag-id + Returntype : listref of Bio::EnsEMBL::Map::DitagFeature + Caller : general + +=cut + +sub fetch_by_ditagID { + my ($self, $ditag_id) = @_; + +print "\nID=$ditag_id\n"; + + my $sth = $self->prepare("SELECT ditag_feature_id, ditag_id, seq_region_id, seq_region_start, + seq_region_end, seq_region_strand, analysis_id, hit_start, hit_end, + hit_strand, cigar_line, ditag_side, ditag_pair_id + FROM ditag_feature + WHERE ditag_id = ? + ORDER BY ditag_pair_id" ); + $sth->execute($ditag_id); + + my $result = $self->_fetch($sth); + + return $result; +} + + +=head2 fetch_all_by_type + + Arg [1] : ditag type + Example : @my_tags = @{$ditagfeature_adaptor->fetch_all_by_type($type)}; + Description: Retrieves all ditagFeatures from the database linking to a specific ditag-type + Returntype : listref of Bio::EnsEMBL::Map::DitagFeature + Caller : general + +=cut + +sub fetch_all_by_type { + my ($self, $ditag_type) = @_; + + my $sth = $self->prepare("SELECT df.ditag_feature_id, df.ditag_id, df.seq_region_id, + df.seq_region_start, df.seq_region_end, df.seq_region_strand, + df.analysis_id, df.hit_start, df.hit_end, df.hit_strand, + df.cigar_line, df.ditag_side, ditag_pair_id + FROM ditag_feature df, ditag d + WHERE df.ditag_id=d.ditag_id and d.type = ? + ORDER BY df.ditag_id, df.ditag_pair_id" ); + $sth->execute($ditag_type); + + my $result = $self->_fetch($sth); + + return $result; +} + + + +=head2 fetch_all_by_Slice + + Arg [1] : Bio::EnsEMBL::Slice + Arg [2] : (optional) ditag type + Example : $tag = $ditagfeature_adaptor->fetch_all_by_Slice($slice, "SME005"); + Description: Retrieves ditagFeatures from the database for a specific region + and (optional) ditag type. + Returntype : listref of Bio::EnsEMBL::Map::DitagFeatures + Caller : general + +=cut + +sub fetch_all_by_Slice { + my ($self, $slice, $tagtype) = @_; + + if(!ref($slice) || !$slice->isa("Bio::EnsEMBL::Slice")) { + throw("Bio::EnsEMBL::Slice argument expected."); + } + + my $sql = "SELECT df.ditag_feature_id, df.ditag_id, df.seq_region_id, + df.seq_region_start, df.seq_region_end, df.seq_region_strand, + df.analysis_id, df.hit_start, df.hit_end, df.hit_strand, + df.cigar_line, df.ditag_side, ditag_pair_id + FROM ditag_feature df, ditag d + WHERE df.ditag_id=d.ditag_id AND df.seq_region_id = ? + AND df.seq_region_start >= ? AND df.seq_region_end <= ? "; + if($tagtype){ + $sql .= " and d.type = ? "; + } + $sql .= "ORDER BY ditag_pair_id"; + my $sth = $self->prepare($sql); + if($tagtype){ + $sth->execute($slice->get_seq_region_id, $slice->start, $slice->end, $tagtype); + } + else{ + $sth->execute($slice->get_seq_region_id, $slice->start, $slice->end); + } + my $result = $self->_fetch($sth); + + return $result; +} + + +=head2 fetch_grouped + + Arg [1] : (optional) ditag id + Arg [2] : (optional) ditag type + Arg [3] : (optional) Bio::EnsEMBL::Slice + Example : $gouped_tags = $ditagfeature_adaptor->fetch_grouped(undef, "ZZ11", undef); + Description: Retrieves Features from the database in their start-end groups; + The start will be the lower seq_region_start, the end the higher seq_region_end. + In context this should refer to potential transcript start and end locations. + Returntype : listref of hashes similar to DitagFeatures: + %grouped_tag( -slice => $slice, + -start => $seqstart, + -end => $seqend, + -strand => $strand, + -tag_count => $tagcount, + -hit_strand => $hit_strand, + -ditag_id => $ditag_id, + -ditag_pair_id => $ditag_pair_id, + ); + Caller : general + +=cut + +sub fetch_grouped { + my ($self, $ditagid, $tagtype, $slice) = @_; + + my (@grouped_tags, @querywords); + my $sql = "SELECT df.seq_region_id, MIN(df.seq_region_start) AS minstart, + MAX(df.seq_region_end) AS maxend, df.seq_region_strand, + df.hit_strand, df.ditag_id, df.ditag_pair_id, d.tag_count + FROM ditag_feature df, ditag d + WHERE df.ditag_id=d.ditag_id "; + + if($tagtype){ + $sql .= " AND d.type = \"".$tagtype."\""; + } + if($ditagid){ + $sql .= " AND df.ditag_id = ".$ditagid; + } + if($slice){ + $sql .= " AND df.seq_region_id = ".$slice->get_seq_region_id. + " AND df.seq_region_start >= ".$slice->start. + " AND df.seq_region_end <= ".$slice->end; + } + $sql .= " GROUP BY df.ditag_id, df.ditag_pair_id". + " ORDER BY df.seq_region_id, minstart, maxend"; + + my $sth = $self->prepare($sql); + $sth->execute(); + + my ( $seqreg, $seqstart, $seqend, $strand, $hit_strand, $ditag_id, $ditag_pair_id, $tagcount ); + $sth->bind_columns( \$seqreg, \$seqstart, \$seqend, + \$strand, \$hit_strand, \$ditag_id, + \$ditag_pair_id, \$tagcount ); + + while ( $sth->fetch ) { + my $alt_slice = $self->db->get_SliceAdaptor->fetch_by_seq_region_id($seqreg); + + my %grouped_tag = ( slice => $alt_slice, + start => $seqstart, + end => $seqend, + strand => $strand, + tag_count => $tagcount, + hit_strand => $hit_strand, + ditag_id => $ditag_id, + ditag_pair_id => $ditag_pair_id, + ); + push @grouped_tags, \%grouped_tag; + } + + return \@grouped_tags; +} + + +=head2 _fetch + + Arg [1] : statement handler + Description: generic sql-fetch function for the DitagFeature fetch methods + Returntype : listref of Bio::EnsEMBL::Map::DitagFeatures + Caller : private + +=cut + +sub _fetch { + my ($self, $sth) = @_; + + my ( $tag_id, $mothertag_id, $seqreg, $seqstart, $seqend, $strand, $analysis_id, $hit_start, + $hit_end, $hit_strand, $cigar_line, $ditag_side, $ditag_pair_id ); + $sth->bind_columns( \$tag_id, \$mothertag_id, \$seqreg, + \$seqstart, \$seqend, \$strand, + \$analysis_id, \$hit_start, \$hit_end, + \$hit_strand, \$cigar_line, \$ditag_side, + \$ditag_pair_id ); + + my @ditags; + + while ( $sth->fetch ) { + my $analysis_obj = $self->db->get_AnalysisAdaptor->fetch_by_dbID($analysis_id); + my $slice = $self->db->get_SliceAdaptor->fetch_by_seq_region_id($seqreg); + + push @ditags, + Bio::EnsEMBL::Map::DitagFeature->new( -dbid => $tag_id, + -slice => $slice, + -start => $seqstart, + -end => $seqend, + -strand => $strand, + -analysis => $analysis_obj, + -hit_start => $hit_start, + -hit_end => $hit_end, + -hit_strand => $hit_strand, + -ditag_id => $mothertag_id, + -cigar_line => $cigar_line, + -ditag_side => $ditag_side, + -ditag_pair_id => $ditag_pair_id, + -adaptor => $self, + ); + } + + return \@ditags; +} + + +=head2 sequence + + Arg [1] : dbID of DitagFeature + Example : $ditagfeature_adaptor->get_sequence($ditagFeature->dbID) + Description: get the part of the sequence of a ditag, + that is actully aligned to the genome. + Returntype : string + Exceptions : thrown if not all data needed for storing is populated in the + ditag features + Caller : Bio::EnsEMBL::Map::DitagFeature + +=cut + +sub sequence { + my ($self, $dbID) = @_; + + my $sequence = undef; + my $db = $self->db() or throw "Couldn t get database connection."; + my $sql = "SELECT d.sequence, df.hit_start, df.hit_end, df.hit_strand ". + "FROM ditag d, ditag_feature df ". + "WHERE df.ditag_id=d.ditag_id and df.ditag_feature_id = ?"; + my $sth = $db->dbc->prepare($sql); + $sth->execute( $dbID ); + my ($seq, $start, $end, $strand) = $sth->fetchrow_array(); + if($seq and $start and $end and $strand){ + $sequence = substr($seq, ($start-1), ($end-$strand)); + if($strand == -1) { + $sequence =~ tr/acgtrymkswhbvdnxACGTRYMKSWHBVDNX/tgcayrkmswdvbhnxTGCAYRKMSWDVBHNX/; + } + } + + return $sequence; +} + + +=head2 store + + Arg [1] : (Array ref of) Bio::EnsEMBL::Map::DitagFeature + Example : $ditagfeature_adaptor->store(@ditag_features); + Description: Stores a single ditagFeature or + a list of ditagFeatures in this database. + Returntype : none + Exceptions : thrown if not all data needed for storing is populated in the + ditag features + Caller : general + +=cut + +sub store { + my ( $self, $ditags ) = @_; + + if ( ref $ditags eq 'ARRAY' ) { + if ( scalar(@$ditags) == 0 ) { + throw( "Must call store with ditagFeature or list ref of ditagsFeature" ); + } + } elsif ($ditags) { + my @ditags; + push @ditags, $ditags; + $ditags = \@ditags; + } else { + throw( "Must call store with ditagFeature or list ref of ditagsFeature." ); + } + + my $db = $self->db() or throw "Couldn t get database connection."; + + my $sth1 = $self->prepare( "INSERT INTO ditag_feature( ditag_id, seq_region_id, seq_region_start, + seq_region_end, seq_region_strand, analysis_id, hit_start, hit_end, + hit_strand, cigar_line, ditag_side, ditag_pair_id ) + VALUES( ?,?,?,?,?,?,?,?,?,?,?,? )" ); + my $sth2 = $self->prepare( "INSERT INTO ditag_feature( ditag_feature_ID, ditag_id, seq_region_id, + seq_region_start, seq_region_end, seq_region_strand, analysis_id, hit_start, + hit_end, hit_strand, cigar_line, ditag_side, ditag_pair_id ) + VALUES( ?,?,?,?,?,?,?,?,?,?,?,?,? )" ); + my $sth3 = $self->prepare( "SELECT COUNT(*) FROM ditag_feature + WHERE ditag_id = ?" ); + +TAG: + foreach my $ditag (@$ditags) { + + if ( !ref $ditag || !$ditag->isa("Bio::EnsEMBL::Map::DitagFeature") ) { + throw( "Object must be an Ensembl DitagFeature, " + . "not a " . ref($ditag) ); + } + +# if ( $ditag->is_stored($db) ) { +# warning( "DitagFeature " . $ditag->dbID +# . " is already stored in this database." ); +# #-->update ?! +# next TAG; +# } + +# #check if more than 1 tag with this ditag id exist +# $sth3->execute( $ditag->ditag_id ); +# my ($num) = $sth3->fetchrow_array(); +# if ( ($num) and ($num > 1) ) { +# warning( "There are already at least 2 DitagFeatures relating to Ditag ". +# $ditag->ditag_id." stored in this database." ); +# if ( $num > 4 ) { +# warning( "not storing" ); +# next TAG; +# } +# } + + if ( $ditag->dbID ) { + $sth2->bind_param( 1, $ditag->dbID, SQL_INTEGER ); + $sth2->bind_param( 2, $ditag->ditag_id, SQL_INTEGER ); + $sth2->bind_param( 3, ($ditag->slice->get_seq_region_id), SQL_INTEGER ); + $sth2->bind_param( 4, $ditag->start, SQL_INTEGER ); + $sth2->bind_param( 5, $ditag->end, SQL_INTEGER ); + $sth2->bind_param( 6, $ditag->strand, SQL_VARCHAR ); + $sth2->bind_param( 7, $ditag->analysis->dbID, SQL_INTEGER ); + $sth2->bind_param( 8, $ditag->hit_start, SQL_INTEGER ); + $sth2->bind_param( 9, $ditag->hit_end, SQL_INTEGER ); + $sth2->bind_param( 10, $ditag->hit_strand, SQL_VARCHAR ); + $sth2->bind_param( 11, $ditag->cigar_line, SQL_VARCHAR ); + $sth2->bind_param( 12, $ditag->ditag_side, SQL_VARCHAR ); + $sth2->bind_param( 13, $ditag->ditag_pair_id, SQL_VARCHAR ); + $sth2->execute(); + } + else{ + $sth1->bind_param( 1, $ditag->ditag_id, SQL_INTEGER ); + $sth1->bind_param( 2, ($ditag->slice->get_seq_region_id), SQL_INTEGER ); + $sth1->bind_param( 3, $ditag->start, SQL_INTEGER ); + $sth1->bind_param( 4, $ditag->end, SQL_INTEGER ); + $sth1->bind_param( 5, $ditag->strand, SQL_VARCHAR ); + $sth1->bind_param( 6, $ditag->analysis->dbID, SQL_INTEGER ); + $sth1->bind_param( 7, $ditag->hit_start, SQL_INTEGER ); + $sth1->bind_param( 8, $ditag->hit_end, SQL_INTEGER ); + $sth1->bind_param( 9, $ditag->hit_strand, SQL_VARCHAR ); + $sth1->bind_param( 10, $ditag->cigar_line, SQL_VARCHAR ); + $sth1->bind_param( 11, $ditag->ditag_side, SQL_VARCHAR ); + $sth1->bind_param( 12, $ditag->ditag_pair_id, SQL_VARCHAR ); + $sth1->execute(); + my $dbID = $sth1->{'mysql_insertid'}; + $ditag->dbID($dbID); + $ditag->adaptor($self); + } + + } +} + + +=head2 batch_store + + Arg [1] : (Array ref of) Bio::EnsEMBL::Map::DitagFeature + Example : $ditagfeature_adaptor->batch_store(\@ditag_features); + Description: Stores a list of ditagFeatures in this database. + DitagFeatures are expected to have no dbID yet. + They are inserted in one combined INSERT for better performance. + Returntype : none + Exceptions : thrown if not all data needed for storing is given for the + ditag features + Caller : general + +=cut + +sub batch_store { + my ( $self, $ditags ) = @_; + + my %tag_ids = (); + my @good_ditags; + my ($sql, $sqladd); + my $inserts = 0; + + if ( ref $ditags eq 'ARRAY' ) { + if ( scalar(@$ditags) == 0 ) { + throw( "Must call store with ditagFeature or list ref of ditagsFeature" ); + } + } elsif ($ditags) { + my @ditags; + push @ditags, $ditags; + $ditags = \@ditags; + } else { + throw( "Must call store with ditagFeature or list ref of ditagsFeature." ); + } + + my $db = $self->db() or throw "Couldn t get database connection."; + + #check whether it s a DitagFeature object and is not stored already + foreach my $ditag (@$ditags) { + + if ( !ref $ditag || !$ditag->isa("Bio::EnsEMBL::Map::DitagFeature") ) { + throw( "Object must be an Ensembl DitagFeature, " + . "not a " . ref($ditag) ); + } + if ( $ditag->is_stored($db) ) { + warning( "DitagFeature " . $ditag->dbID + . " is already stored in this database." ); + next; + } + $tag_ids{$ditag->ditag_id} = $ditag; + push(@good_ditags, $ditag); + } + $ditags = undef; + +# #check if more than 1 tag with this ditag id exists +# $sql = "SELECT COUNT(*), ditag_id FROM ditag_feature ". +# "WHERE ditag_id IN (".(join(", ", keys %tag_ids)).") group by ditag_id"; +# my $sth2 = $db->prepare($sql); +# $sth2->execute(); +# while (my ($num, $ditag_id) = $sth2->fetchrow_array()){ +# if ( ($num) and ($num > 1) ) { +# warning( "There are already at least 2 DitagFeatures relating to Ditag ". +# $ditag_id." stored in this database." ); +# if ( $num > 4 ) { +# warning( "not storing" ); +# next; +# } +# } +# $ditag->ditag_id +# push(@good_ditags, $tag_ids{$ditag_id}); +# } + + #create batch INSERT + $sql = "INSERT INTO ditag_feature ( ditag_id, seq_region_id, seq_region_start, ". + "seq_region_end, seq_region_strand, analysis_id, hit_start, hit_end, ". + "hit_strand, cigar_line, ditag_side, ditag_pair_id ) VALUES "; + foreach my $ditag (@good_ditags) { + $sqladd = ""; + if($inserts){ $sqladd = ", " } + $sqladd .= "(". $ditag->ditag_id.", ".($ditag->slice->get_seq_region_id).", ". $ditag->start.", ". + $ditag->end.", '".$ditag->strand."', ".$ditag->analysis->dbID.", ".$ditag->hit_start. + ", ".$ditag->hit_end.", '".$ditag->hit_strand."', '".$ditag->cigar_line."', '". + $ditag->ditag_side."', ".$ditag->ditag_pair_id.")"; + $sql .= $sqladd; + $inserts++; + } + + #STORE + if($inserts){ + eval{ + $db->dbc->do($sql); + }; + if($@){ + warning("Problem inserting ditag batch!".$@); + } + } + else{ + warn "Nothing stored!"; + } + +} + + +=head2 list_dbIDs + + Args : None + Example : my @feature_ids = @{$dfa->list_dbIDs()}; + Description: Gets an array of internal IDs for all DitagFeature objects in + the current database. + Returntype : List of ints + Exceptions : None + +=cut + +sub list_dbIDs { + my $self = shift; + + return $self->_list_dbIDs('ditag_feature'); +} + +1;