Raw content of Bio::EnsEMBL::Compara::DBSQL::DnaFragAdaptor
#
# Ensembl module for Bio::EnsEMBL::Compara::DBSQL::DnaFragAdaptor
#
# Cared for by Ewan Birney
#
# Copyright Ewan Birney
#
# You may distribute this module under the same terms as perl itself
# POD documentation - main docs before the code
=head1 NAME
Bio::EnsEMBL::Compara::DBSQL::DnaFragAdaptor
=head1 SYNOPSIS
use Bio::EnsEMBL::Registry;
my $reg = "Bio::EnsEMBL::Registry";
$reg->load_registry_from_db(-host=>"ensembldb.ensembl.org", -user=>"anonymous");
my $dnafrag_adaptor = $reg->get_adaptor("Multi", "compara", "DnaFrag");
$dnafrag_adaptor->store($dnafrag);
$dnafrag = $dnafrag_adaptor->fetch_by_dbID(905406);
$dnafrag = $dnafrag_adaptor->fetch_by_GenomeDB_and_name($human_genome_db, 'X');
$dnafrags = $dnafrag_adaptor->fetch_all_by_GenomeDB_region(
$human_genome_db, 'chromosome')
$dnafrag = $dnafrag_adaptor->fetch_by_Slice($slice);
$all_dnafrags = $dnafrag_adaptor->fetch_all();
=head1 DESCRIPTION
This module is intended to access data in the dnafrag table. The dnafrag table stores information on the toplevel sequences such as the name, coordinate system, length and species.
=head1 AUTHOR - Ewan Birney
This modules is part of the Ensembl project
Email birney@ebi.ac.uk
Describe contact details here
=head1 APPENDIX
The rest of the documentation details each of the object methods. Internal methods are usually preceded with a _
=cut
# Let the code begin...
package Bio::EnsEMBL::Compara::DBSQL::DnaFragAdaptor;
use vars qw(@ISA);
use strict;
use Bio::EnsEMBL::DBSQL::BaseAdaptor;
use Bio::EnsEMBL::Compara::DnaFrag;
use Bio::EnsEMBL::Utils::Exception qw( throw warning verbose );
@ISA = qw(Bio::EnsEMBL::DBSQL::BaseAdaptor);
=head2 fetch_by_dbID
Arg [1] : integer $db_id
Example : my $dnafrag = $dnafrag_adaptor->fetch_by_dbID(905406);
Description: Returns the Bio::EnsEMBL::Compara::DnaFrag object corresponding to the database internal identifier
Returntype : Bio::EnsEMBL::Compara::DnaFrag
Exceptions : throw if $dbid is not supplied.
Caller : general
Status : Stable
=cut
sub fetch_by_dbID {
my ($self,$dbid) = @_;
if( !defined $dbid) {
$self->throw("Must fetch by dbid");
}
$self->{'_dna_frag_id_cache'} ||= {};
if($self->{'_dna_frag_id_cache'}->{$dbid}) {
return $self->{'_dna_frag_id_cache'}->{$dbid};
}
my $sth = $self->prepare(qq{
SELECT
dnafrag_id,
length,
name,
genome_db_id,
coord_system_name
FROM
dnafrag
WHERE
dnafrag_id = ?
});
$sth->execute($dbid);
my $dna_frags = $self->_objs_from_sth($sth);
$self->throw("No dnafrag with this dbID $dbid") unless(@$dna_frags);
$self->{'_dna_frag_id_cache'}->{$dbid} = $dna_frags->[0];
return $dna_frags->[0];
}
=head2 fetch_by_GenomeDB_and_name
Arg [1] : integer $genome_db_id
- or -
Bio::EnsEMBL::Compara::DBSQL::GenomeDB
Arg [2] : string $name
Example : my $dnafrag = $dnafrag_adaptor->fetch_by_GenomeDB_and_name($human_genome_db, 'X');
Example : my $dnafrag = $dnafrag_adaptor->fetch_by_GenomeDB_and_name(1, 'X');
Description: Returns the Bio::EnsEMBL::Compara::DnaFrag object corresponding to the
Bio::EnsEMBL::Compara::GenomeDB and name given. $genome_db can
be a valid $genome_db_id instead.
Returntype : Bio::EnsEMBL::Compara::DnaFrag
Exceptions : throw when genome_db_id cannot be retrieved
Exceptions : warns and returns undef when no DnaFrag matches the query
Caller : $dnafrag_adaptor->fetch_by_GenomeDB_and_name
Status : Stable
=cut
sub fetch_by_GenomeDB_and_name {
my ($self, $genome_db, $name) = @_;
my $dnafrag; # Returned value
my $genome_db_id;
if ($genome_db =~ /^\d+$/) {
$genome_db_id = $genome_db;
} elsif ($genome_db && ref $genome_db &&
$genome_db->isa('Bio::EnsEMBL::Compara::GenomeDB')) {
$genome_db_id = $genome_db->dbID;
if (!$genome_db_id) {
throw("[$genome_db] does not have a dbID");
}
} else {
throw("[$genome_db] must be Bio::EnsEMBL::Compara::GenomeDB\n");
}
my $sql = qq{
SELECT
dnafrag_id,
length,
name,
genome_db_id,
coord_system_name
FROM
dnafrag
WHERE
genome_db_id = ?
AND name = ?
};
my $sth = $self->prepare($sql);
$sth->execute($genome_db_id, $name);
$dnafrag = $self->_objs_from_sth($sth)->[0];
if (!$dnafrag) {
warning("No Bio::EnsEMBL::Compara::DnaFrag found for ".$genome_db->name."(".$genome_db->assembly."),".
" chromosome $name");
}
return $dnafrag;
}
=head2 fetch_all_by_GenomeDB_region
Arg [1] : Bio::EnsEMBL::Compara::DBSQL::GenomeDB
Arg [2] : (optional) string $coord_system_name
Arg [3] : (optional) string $name
Example : my $human_chr_dnafrags = $dnafrag_adaptor->
fetch_all_by_GenomeDB_region(
$human_genome_db, 'chromosome')
Description: Returns the Bio::EnsEMBL::Compara::DnaFrag object corresponding to the
Bio::EnsEMBL::Compara::GenomeDB and region given.
Returntype : listref of Bio::EnsEMBL::Compara::DnaFrag objects
Exceptions : throw unless $genome_db is a Bio::EnsEMBL::Compara::GenomeDB
Caller :
Status : Stable
=cut
sub fetch_all_by_GenomeDB_region {
my ($self, $genome_db, $coord_system_name, $name) = @_;
unless($genome_db && ref $genome_db &&
$genome_db->isa('Bio::EnsEMBL::Compara::GenomeDB')) {
$self->throw("genome_db arg must be Bio::EnsEMBL::Compara::GenomeDB".
" not [$genome_db]\n")
}
my $gdb_id = $genome_db->dbID;
unless($gdb_id) {
$self->throw('GenomeDB does not have a dbID. Is it stored in the db?');
}
# unless($dnafrag_type) {
# $self->throw('dnafrag_type argument must be defined');
# }
my $sql = qq{
SELECT
dnafrag_id,
length,
name,
genome_db_id,
coord_system_name
FROM
dnafrag d
WHERE
genome_db_id = ?
};
my @bind_values = ($gdb_id);
if(defined $coord_system_name) {
$sql .= ' AND coord_system_name = ?';
push @bind_values, "$coord_system_name";
}
if(defined $name) {
$sql .= ' AND d.name = ?';
push @bind_values, "$name";
}
my $sth = $self->prepare($sql);
$sth->execute(@bind_values);
return $self->_objs_from_sth($sth);
}
=head2 fetch_by_Slice
Arg [1] : Bio::EnsEMBL::Slice $slice
Example : $dnafrag = $dnafrag_adaptor->fetch_by_Slice($slice);
Description: Retrieves the DnaFrag corresponding to this
Bio::EnsEMBL::Slice object
Returntype : Bio::EnsEMBL::Compara::DnaFrag
Exceptions : thrown if $slice is not a Bio::EnsEMBL::Slice
Caller : general
Status : Stable
=cut
sub fetch_by_Slice {
my ($self, $slice) = @_;
my $genome_db_adaptor = $self->db->get_GenomeDBAdaptor;
my $genome_db = $genome_db_adaptor->fetch_by_Slice($slice);
return $self->fetch_by_GenomeDB_and_name($genome_db, $slice->seq_region_name);
}
=head2 fetch_all
Arg : none
Example : my $all_dnafrags = $dnafrag_adaptor->fetch_all();
Description : fetches all Bio::EnsEMBL::Compara::DnaFrag objects for this
compara database
Returntype : listref of all Bio::EnsEMBL::Compara::DnaFrag objects
Exceptions : none
Caller : general
Status : Stable
=cut
sub fetch_all {
my ($self) = @_;
my $sth = $self->prepare(qq{
SELECT
dnafrag_id,
length,
name,
genome_db_id,
coord_system_name
FROM
dnafrag
});
$sth->execute;
return $self->_objs_from_sth( $sth );
}
=head2 _tables
Args : none
Example : $tables = $self->_tables()
Description: a list of [tablename, alias] pairs for use with generic_fetch
Returntype : list of [tablename, alias] pairs
Exceptions : none
Caller : BaseAdaptor::generic_fetch
Status : Stable
=cut
sub _tables {
return (
['dnafrag', 'df']
);
}
=head2 _columns
Args : none
Example : $columns = $self->_columns()
Description: a list of [tablename, alias] pairs for use with generic_fetch
Returntype : list of [tablename, alias] pairs
Exceptions : none
Caller : BaseAdaptor::generic_fetch
Status : Stable
=cut
sub _columns {
return ('df.dnafrag_id',
'df.length',
'df.name',
'df.genome_db_id',
'df.coord_system_name'
);
}
=head2 _objs_from_sth
Args[1] : DBI::row_hashref $hashref containing key-value pairs
Example : my $dna_frags = $self->_objs_from_sth($sth);
Description: convert DBI row hash reference into a
Bio::EnsEMBL::Compara::DnaFrag object
Returntype : listref of Bio::EnsEMBL::Compara::DnaFrag objects
Exceptions : throw if $sth is not supplied
Caller : general
Status : Stable
=cut
sub _objs_from_sth {
my ($self, $sth) = @_;
throw if (!$sth);
my $these_dnafrags = [];
my ($dbID, $length, $name, $genome_db_id, $coord_system_name);
$sth->bind_columns(
\$dbID,
\$length,
\$name,
\$genome_db_id,
\$coord_system_name
);
my $gda = $self->db->get_GenomeDBAdaptor();
while ($sth->fetch()) {
my $this_dnafrag = Bio::EnsEMBL::Compara::DnaFrag->new_fast(
{'dbID' => $dbID,
'adaptor' => $self,
'length' => $length,
'name' => $name,
'genome_db_id' => $genome_db_id,
'coord_system_name' => $coord_system_name}
);
push(@$these_dnafrags, $this_dnafrag);
}
return $these_dnafrags;
}
=head2 store
Arg [1] : Bio::EnsEMBL::Compara::DnaFrag $new_dnafrag
Example : $dnafrag_adaptor->store($new_dnafrag)
Description : Stores a Bio::EnsEMBL::Compara::DnaFrag object
in the DB-
ReturnType : integer new_dnafrag_id
Exceptions : throw if $new_dnafrag is not a
Bio::EnsEMBL::Compara::DnaFrag object
Exceptions : does not store anything if $new_dnafrag->adaptor is
already defined and is equal to this adaptor
Exceptions : throw if $new_dnafrag->genome_db is not defined or has
no dbID.
Exceptions : throw if $new_dnafrag has no name
Caller : $object->methodname
Status : Stable
=cut
sub store {
my ($self, $dnafrag) = @_;
if( !defined $dnafrag ) {
throw("Must store $dnafrag object");
}
if( !ref $dnafrag || !$dnafrag->isa('Bio::EnsEMBL::Compara::DnaFrag') ) {
throw("Must have dnafrag arg [$dnafrag]");
}
if (defined $dnafrag->adaptor() && $dnafrag->adaptor() == $self) {
return $dnafrag->dbID();
}
my $gdb = $dnafrag->genome_db();
if( !defined $gdb || !ref $gdb || !$gdb->isa('Bio::EnsEMBL::Compara::GenomeDB') ) {
$self->throw("Must have genomedb attached to the dnafrag to store the dnafrag [$gdb]");
}
if( !defined $gdb->dbID ) {
throw("genomedb must be stored (no dbID). Store genomedb first");
}
if( !defined $dnafrag->name ) {
throw("dnafrag must have a name");
}
my $name = $dnafrag->name;
my $gid = $gdb->dbID;
my $type = $dnafrag->coord_system_name;
my $stored_id;
# use INSERT IGNORE so that this method can be used
# in a multi-process environment
my $sth = $self->prepare("
INSERT IGNORE INTO dnafrag ( genome_db_id, coord_system_name,
name, length )
VALUES (?,?,?,?)");
my $rows_inserted = $sth->execute($gid, $type, $name, $dnafrag->length);
if ($rows_inserted > 0) {
$stored_id = $sth->{'mysql_insertid'};
} else {
# entry was already stored by another process
my $sth2 = $self->prepare("
SELECT dnafrag_id
FROM dnafrag
WHERE name= ?
AND genome_db_id= ?");
$sth2->execute($name, $gid);
($stored_id) = $sth2->fetchrow_array();
}
throw("DnaFrag apparently already stored, but could not be retrieved")
if not defined $stored_id;
$dnafrag->adaptor($self);
$dnafrag->dbID($stored_id);
return $dnafrag->dbID;
}
=head2 is_already_stored
Title : is_already_stored
Usage : $self->is_already_stored($dnafrag)
Function: checks if already stored by querying database
Example :
Returns : $dnafrag->dbID if stored and 0 if not stored
Args : Bio::EnsEMBL::Compara::DnaFrag object
Status : Stable
=cut
sub is_already_stored {
my ($self,$dnafrag) = @_;
if( !defined $dnafrag ) {
$self->throw("Must store $dnafrag object");
}
if( !defined $dnafrag || !ref $dnafrag || !$dnafrag->isa('Bio::EnsEMBL::Compara::DnaFrag') ) {
$self->throw("Must have dnafrag arg [$dnafrag]");
}
if (defined $dnafrag->adaptor() && $dnafrag->adaptor() == $self) {
return $dnafrag->dbID();
}
my $gdb = $dnafrag->genome_db();
if( !defined $gdb || !ref $gdb || !$gdb->isa('Bio::EnsEMBL::Compara::GenomeDB') ) {
$self->throw("Must have genomedb attached to the dnafrag to store the dnafrag [$gdb]");
}
if( !defined $gdb->dbID ) {
$self->throw("genomedb must be stored (no dbID). Store genomedb first");
}
if( !defined $dnafrag->name ) {
$self->throw("dna frag must have a name");
}
my $name = $dnafrag->name;
my $gid = $gdb->dbID;
my $sth = $self->prepare("
SELECT dnafrag_id
FROM dnafrag
WHERE name= ?
AND genome_db_id= ?
");
unless ($sth->execute( "$name", $gid )) {
$self->throw("Failed execution of a select query");
}
my ($dnafrag_id) = $sth->fetchrow_array();
if (defined $dnafrag_id) {
# $dnafrag already stored
$dnafrag->dbID($dnafrag_id);
$dnafrag->adaptor( $self );
return $dnafrag_id;
}
return 0;
}
=head2 store_if_needed
Title : store_if_needed
Usage : $self->store_if_needed($dnafrag)
Function: store instance in the defined database if NOT
already present.
Example :
Returns : $dnafrag->dbID
Args : Bio::EnsEMBL::Compara::DnaFrag object
Status : Stable
=cut
sub store_if_needed {
my ($self,$dnafrag) = @_;
$self->store($dnafrag) unless($self->is_already_stored($dnafrag));
return $dnafrag->dbID;
}
=head2 update
Title : update
Usage : $self->update($dnafrag)
Function: look for this dnafrag in the database, using the genome_db_id,
the coordinate_system_name and the name of the
Bio::EnsEMBL::Compara::DnaFrag object. If there is already an
entry in the database for this dnafrag, it does do anything. If
the length is different, it updates it. If there is not any entry
for this, it stores it.
Example :
Returns : int $dnafrag->dbID
Args : Bio::EnsEMBL::Compara::DnaFrag object
Status : Stable
=cut
sub update {
my ($self,$dnafrag) = @_;
my $current_verbose_level = verbose();
verbose(0);
my $existing_dnafrag = $self->fetch_by_GenomeDB_and_name($dnafrag->genome_db, $dnafrag->name);
verbose($current_verbose_level);
if (!$existing_dnafrag) {
return $self->store($dnafrag);
}
if ($existing_dnafrag->length != $dnafrag->length) {
my $sql = "UPDATE dnafrag SET length = ? WHERE dnafrag_id = ?";
my $sth = $self->prepare($sql);
$sth->execute($dnafrag->length, $existing_dnafrag->dbID);
}
$dnafrag->dbID($existing_dnafrag->dbID);
return $dnafrag->dbID;
}
1;