BioPerl-DB

 view release on metacpan or  search on metacpan

lib/Bio/DB/BioSQL/AnnotationCollectionAdaptor.pm  view on Meta::CPAN

	    splice(@$objs, $i, 1); # remove the AnnotationCollection
	    last;
	}
	$i++;
    }
    # make sure we have an instantiated and persistent AnnotationCollectionI
    if(! (ref($ac) && $ac->isa("Bio::AnnotationCollectionI"))) {
	my $fact = $params{-obj_factory} || $params{-OBJ_FACTORY};
	$ac = $fact ?
	    $fact->create_object() : Bio::Annotation::Collection->new();
    }
    if(! $ac->isa("Bio::DB::PersistentObjectI")) {
	$ac = $self->create_persistent($ac);
    }
    delete $params{-OBJ_FACTORY};
    # prepare the factory for the individual annotation objects
    my $fact = Bio::Annotation::AnnotationFactory->new();
    $params{-obj_factory} = $fact;
    # obtain the map from annotation types to annotation keys
    my $annotmap = $self->_supported_annotation_map();
    # loop over all supported annotations and find the ones associated
    # with the "other" objects
    my $foundanything = 0;
    foreach my $anntype (keys %$annotmap) {
	# we only do this for association links
	next unless $annotmap->{$anntype}->{"link"} eq "association";
	# ok, this is linked by association
	my $annadp = $self->db()->get_object_adaptor($anntype);
	# temporarily add the type to the array of objects to be associated
	push(@$objs, $anntype);
	# set type for annotation object factory
	$fact->type($anntype);
	# determine type-specific arguments if there are any
	my @typeargs = $self->_anntype_assoc_args($annadp, $anntype);
	# get query result
	my $qres = $annadp->find_by_association(%params, @typeargs);
	# loop over all result objects and attach
	while(my $ann = $qres->next_object()) {
	    # tagname may come from the db - otherwise set it from the map
	    $ann->tagname($annotmap->{$anntype}->{"key"}) if ! $ann->tagname();
	    $ac->add_Annotation($ann);
	    $foundanything = 1;
	}
	# restore object array
	pop(@$objs);
    }
    # add children if there are any (those annotations linked by
    # foreign key instead of association)
    $self->attach_children($ac,$objs);
    # return a prebuilt query result to be compatible with the expected
    # return type
    return $foundanything ?
	Bio::DB::Query::PrebuiltResult->new(-objs => [$ac]) :
	Bio::DB::Query::PrebuiltResult->new(-objs => []);
}

=head2 remove_children

 Title   : remove_children
 Usage   :
 Function: This method is to cascade deletes in maintained objects.

           We need to undefine the primary keys of all contained
           children objects here.

 Example :
 Returns : TRUE on success and FALSE otherwise
 Args    : The persistent object that was just removed from the database.
           Additional (named) parameter, as passed to remove().


=cut

sub remove_children{
    my $self = shift;
    my $ac = shift;

    # get the annotation type map
    my $annotmap = $self->_supported_annotation_map();
    # check annotation for each key
    foreach my $annkey ($ac->get_all_annotation_keys()) {
	foreach my $ann ($ac->get_Annotations($annkey)) {
	    if($ann->isa("Bio::DB::PersistentObjectI")) {
		# undef the PK if this is a child relationship by FK
		my $key = $self->_annotation_map_key($annotmap,$ann);
		if($annotmap->{$key}->{"link"} eq "child") {
		    $ann->primary_key(undef);
		    # cascade through in case the object needs it
		    $ann->adaptor->remove_children($ann);
		}
	    }
	}
    }
    # done
    return 1;
}

=head1 Internal Methods

 These are mostly private or 'protected.' Methods which are in the
 latter class have this explicitly stated in their
 documentation. 'Protected' means you may call these from derived
 classes, but not from outside.

 Most of these methods cache certain adaptors or otherwise reduce call
 path and object creation overhead. There's no magic here.

=cut

=head2 _anntype_assoc_args

 Title   : _anntype_assoc_args
 Usage   :
 Function: Get the arguments to be passed to the annotation object
           adaptor''s add_association method, based on the type of
           annotation to be associated.

           This is an internal method.

 Example :
 Returns : an array of arguments in the format of named parameters
 Args    : the adaptor for the annotation object
           the type of the annotation object (a string)


=cut

sub _anntype_assoc_args{
    my ($self,$adp,$anntype) = @_;
    my @typeargs = ();

    if($anntype eq "Bio::Annotation::OntologyTerm") {
	# exclude the SimpleValue annotation
	my $ont = $self->{'_ontology_fk'};
	if (! defined($ont)) {
	    $ont = Bio::Ontology::Ontology->new(-name => "Annotation Tags");
	}
	if(! $ont->isa("Bio::DB::PersistentObjectI")) {
	    $ont = $self->db()->create_persistent($ont);
	    $self->{'_ontology_fk'} = $ont;
	}
	$ont = $ont->adaptor->find_by_unique_key($ont);
	if (ref($ont)) {
	    my $qc = Bio::DB::Query::QueryConstraint->new($anntype.
							  "::ontology != ?");
	    push(@typeargs,
		 -constraints => [$qc],
		 -values => { $qc => $ont->primary_key() });



( run in 1.081 second using v1.01-cache-2.11-cpan-98e64b0badf )