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 <ensembl-dev@ebi.ac.uk>. Questions may also be sent to the Ensembl help desk at <helpdesk@ensembl.org>. =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;