Raw content of Bio::EnsEMBL::DBSQL::AttributeAdaptor
=head1 LICENSE
Copyright (c) 1999-2009 The European Bioinformatics Institute and
Genome Research Limited. All rights reserved.
This software is distributed under a modified Apache license.
For license details, please see
/info/about/code_licence.html
=head1 CONTACT
Please email comments or questions to the public Ensembl
developers list at .
Questions may also be sent to the Ensembl help desk at
.
=cut
=head1 NAME
Bio::EnsEMBL::DBSQL::AttributeAdaptor - Provides database interaction for
Bio::EnsEMBL::Attribute objects.
=head1 SYNOPSIS
# $db is a Bio::EnsEMBL::DBSQL::DBAdaptor object:
$attribute_adaptor = $db->get_AttributeAdaptor();
$attributes = $attribute_adaptor->fetch_all_by_MiscFeature($feature);
$attributes = $attribute_adaptor->fetch_all_by_Slice($slice);
$attribute_adaptor->store_on_Slice( $slice, \@attributes );
$attribute_adaptor->store_on_MiscFeature( $misc_feature,
\@attributes )
=head1 DESCRIPTION
=head1 METHODS
=cut
package Bio::EnsEMBL::DBSQL::AttributeAdaptor;
use strict;
use warnings;
use Bio::EnsEMBL::DBSQL::BaseAdaptor;
use Bio::EnsEMBL::Attribute;
use Bio::EnsEMBL::Utils::Exception qw(throw warning);
use vars qw(@ISA);
@ISA = qw(Bio::EnsEMBL::DBSQL::BaseAdaptor);
=head2 new
Arg [...] : Superclass args. See Bio::EnsEMBL::DBSQL::BaseAdaptor
Description: Instantiates a Bio::EnsEMBL::DBSQL::AttributeAdaptor
Returntype : Bio::EnsEMBL::AttributeAdaptor
Exceptions : none
Caller : DBAdaptor
Status : Stable
=cut
sub new {
my $class = shift;
my $self = $class->SUPER::new(@_);
# cache creation could go here
return $self;
}
use vars '$AUTOLOAD';
sub AUTOLOAD {
my ($self,@args) = @_;
my @array_return=();
my $ref_return = undef;
$AUTOLOAD =~ /^.*::(\w+_)+(\w+)$/ ;
my $sub = $1;
my $type = $2;
# print STDERR "AUTO".$AUTOLOAD."\n";
# print STDERR "AUTOLOAD reached with call to $sub of type $type\n";
if($self->can($sub)){
return $self->$sub($type,@args);
}
else{
warn("In AttribAdaptor cannot call sub $sub$type\n");
}
return undef;
}
sub store_on_ {
my $self = shift;
my $type = shift;
my $object = shift;
my $attributes = shift;
my $table;
my $object_id;
if($type =~ /[GT][er][na][en]/){
if (!ref($object)){
$object_id = $object;
}
else {
$object_id = $object->dbID;
}
$table = lc($type);
# $type = lc($type);
}
else{
if(!ref($object) || !$object->isa('Bio::EnsEMBL::'.$type)) {
throw("$type argument is required. but you passed $object");
}
if($type eq "Slice"){
$object_id = $object->get_seq_region_id();
$table = "seq_region";
$type = "seq_region";
}
else{
if($type eq "MiscFeature"){
$type = "misc_feature";
$table = "misc";
}
else{
$table = lc($type);
}
$object_id = $object->dbID();
my $db = $self->db();
if(!$object->is_stored($db)) {
throw("$type is not stored in this database.");
}
}
}
my $sth = $self->prepare( "INSERT into ".$table."_attrib ".
"SET ".$type."_id = ?, attrib_type_id = ?, ".
"value = ? " );
for my $attrib ( @$attributes ) {
if(!ref($attrib) && $attrib->isa('Bio::EnsEMBL::Attribute')) {
throw("Reference to list of Bio::EnsEMBL::Attribute objects " .
"argument expected.");
}
my $atid = $self->_store_type( $attrib );
$sth->bind_param(1,$object_id,SQL_INTEGER);
$sth->bind_param(2,$atid,SQL_INTEGER);
$sth->bind_param(3,$attrib->value,SQL_VARCHAR);
$sth->execute();
}
return;
}
sub remove_from_{
my $self = shift;
my $type = shift;
my $object = shift;
my $code = shift;
my $table;
if(!ref($object) || !$object->isa('Bio::EnsEMBL::'.$type)) {
throw("$type argument is required or a attrib code. but you passed $object");
}
my $object_id;
if($type eq "Slice"){
$object_id = $object->get_seq_region_id();
$table = "seq_region";
$type = "seq_region";
}
else{
if($type eq "MiscFeature"){
$type = "misc_feature";
$table = "misc";
}
else{
$table = lc($type);
}
$object_id = $object->dbID();
my $db = $self->db();
if(!$object->is_stored($db)) {
throw("$type is not stored in this database.");
}
}
if(!defined($object_id)) {
throw("$type must have dbID.");
}
my $sth;
if(defined($code)){
$sth = $self->prepare("DELETE a FROM ".$table."_attrib a ,attrib_type at " .
"WHERE a.attrib_type_id = at.attrib_type_id AND ".
"a.".$type."_id = ? AND ".
"at.code like ?");
$sth->bind_param(1,$object_id,SQL_INTEGER);
$sth->bind_param(2,$code,SQL_VARCHAR);
}
else{
$sth = $self->prepare("DELETE FROM ".$table."_attrib " .
"WHERE ".$type."_id = ?");
$sth->bind_param(1,$object_id,SQL_INTEGER);
}
$sth->execute();
$sth->finish();
return;
}
sub fetch_all_by_{
my $self = shift;
my $type = shift;
my $object = shift;
my $code = shift;
my $table =undef;
if(!ref($object) || !$object->isa('Bio::EnsEMBL::'.$type)) {
throw("$type argument is required. but you passed $object");
}
my $object_id;
if($type eq "Slice"){
$object_id = $object->get_seq_region_id();
$table = "seq_region";
$type = "seq_region";
}
else{
if($type eq "MiscFeature"){
$type = "misc_feature";
$table = "misc";
}
else{
$table = lc($type);
}
$object_id = $object->dbID();
}
if(!defined($object_id)) {
throw("$type must have dbID.");
}
my $sql = "SELECT at.code, at.name, at.description, t.value " .
"FROM ".($table||$type)."_attrib t, attrib_type at ".
"WHERE t.".$type."_id = ? " .
"AND at.attrib_type_id = t.attrib_type_id ";
if(defined($code)){
$sql .= 'AND at.code like "'.$code.'" ';
}
my $sth = $self->prepare($sql);
$sth->bind_param(1,$object_id,SQL_INTEGER);
$sth->execute();
my $results = $self->_obj_from_sth($sth);
$sth->finish();
return $results;
}
sub DESTROY{
}
#
# _id_check
#
# backwards compatibility check:
# check if $ensID is an object; if so, return $obj->dbID
#
sub _id_check {
my $self = shift;
my $ensID = shift;
if ($ensID =~ /^\d+$/) {
return $ensID;
} elsif (ref($ensID) eq 'Bio::EnsEMBL::Gene' or
ref($ensID) eq 'Bio::EnsEMBL::Transcript' or
ref($ensID) eq 'Bio::EnsEMBL::Translation') {
warning("You should pass a dbID rather than an ensembl object to store the attribute on");
if ($ensID->dbID) {
return $ensID->dbID;
} else {
throw("Ensembl object ".$ensID->display_id." doesn't have a dbID, can't store attribute");
}
} else {
throw("Invalid dbID");
}
}
# _store_type
sub _store_type {
my $self = shift;
my $attrib = shift;
my $sth1 = $self->prepare
("INSERT IGNORE INTO attrib_type set code = ?, name = ?, ".
"description = ?" );
$sth1->bind_param(1,$attrib->code,SQL_VARCHAR);
$sth1->bind_param(2,$attrib->name,SQL_VARCHAR);
$sth1->bind_param(3,$attrib->description,SQL_LONGVARCHAR);
my $rows_inserted = $sth1->execute();
my $atid = $sth1->{'mysql_insertid'};
if($rows_inserted == 0) {
# the insert failed because the code is already stored
my $sth2 = $self->prepare
("SELECT attrib_type_id FROM attrib_type " .
"WHERE code = ?");
$sth2->bind_param(1,$attrib->code,SQL_VARCHAR);
$sth2->execute();
($atid) = $sth2->fetchrow_array();
$sth2->finish();
if(!$atid) {
throw("Could not store or fetch attrib_type code [".$attrib->code."]\n" .
"Wrong database user/permissions?");
}
}
$sth1->finish();
return $atid;
}
sub _obj_from_sth {
my $self = shift;
my $sth = shift;
my ($code, $name, $desc, $value);
$sth->bind_columns(\$code, \$name, \$desc, \$value);
my @results;
while($sth->fetch()) {
push @results, Bio::EnsEMBL::Attribute->new_fast
( {'code' => $code,
'name' => $name,
'description' => $desc,
'value' => $value} );
}
return \@results;
}
1;