AcePerl

 view release on metacpan or  search on metacpan

Ace.pm  view on Meta::CPAN

      %param = @param;                # convert into associative array
    }

    my(@return_array);

    local($^W) = 0;
    my($key)='';
    foreach $key (@$order) {
        my($value);
        if (ref($key) eq 'ARRAY') {
            foreach (@$key) {
                last if defined($value);
                $value = $param{$_};
                delete $param{$_};
            }
        } else {
            $value = $param{$key};
            delete $param{$key};
        }
        push(@return_array,$value);
    }
    push (@return_array,\%param) if %param;
    return @return_array;
}

# do a query, but don't return the result
sub _query {
  my ($self,@query) = @_;
  $self->_alert_iterators;
  $self->{'database'}->query("@query");
}

# return a portion of the active list
sub _list {
  my $self = shift;
  my ($count,$offset) = @_;
  my (@result);
  my $query = 'list -j';
  $query .= " -b $offset" if defined $offset;
  $query .= " -c $count"  if defined $count;
  my $result = $self->raw_query($query);
  $result =~ s/\0//g;  # get rid of &$#&@( nulls
  foreach (split("\n",$result)) {
    my ($class,$name) = Ace->split($_);
    next unless $class and $name;
    my $obj = $self->memory_cache_fetch($class,$name);
    $obj  ||= $self->file_cache_fetch($class,$name);
    unless ($obj) {
      $obj = $self->class_for($class,$name)->new($class,$name,$self,1);
      $self->memory_cache_store($obj);
      $self->file_cache_store($obj);
    }
    push @result,$obj;
  }
  return @result;
}

# return a portion of the active list
sub _fetch {
  my $self = shift;
  my ($count,$start,$tag) = @_;
  my (@result);
  $tag = '' unless defined $tag;
  my $query = "show -j $tag";
  $query .= ' -T' if $self->{timestamps};
  $query .= " -b $start"  if defined $start;
  $query .= " -c $count"  if defined $count;
  $self->{database}->query($query);
  while (my @objects = $self->_fetch_chunk) {
    push (@result,@objects);
  }
  # copy tag into a portion of the tree
  if ($tag) {
    for my $tree (@result) {
      my $obj = $self->class_for($tree->class,$tree->name)->new($tree->class,$tree->name,$self,1);
      $obj->_attach_subtree($tag=>$tree);
      $tree = $obj;
    }
  }
  # now recache 'em
  for (@result) {
    if (my $obj = $self->memory_cache_store($_)) {
      %$obj = %$_ unless $obj->filled;  # contents copy -- replace partial object with full object
      $_ = $obj;
    } else {
      $self->memory_cache_store($_);
    }
  }
  return wantarray ? @result : $result[0];
}

sub _fetch_chunk {
  my $self = shift;
  return unless $self->{database}->status == STATUS_PENDING();
  my $result = $self->{database}->read();
  $result =~ s/\0//g;  # get rid of &$#&@!! nulls
  my @chunks = split("\n\n",$result);
  my @result;
  foreach (@chunks) {
    next if m!^//!;
    next unless /\S/;  # occasional empty lines
    my ($class,$id) = Ace->split($_); # /^\?([^?]+)\?([^?]+)\?/m;
    push(@result,$self->class_for($class,$id)->newFromText($_,$self));
  }
  return @result;
}

sub _alert_iterators {
  my $self = shift;
  foreach (keys %{$self->{iterators}}) {
    $self->{iterators}{$_}->invalidate if $self->{iterators}{$_};
  }
  undef $self->{active_list};
}

sub asString {
  my $self = shift;
  return "tace://$self->{path}" if $self->{'path'};
  my $server = $self->db && $self->db->isa('Ace::SocketServer') ? 'sace' : 'rpcace';
  return "$server://$self->{host}:$self->{port}" if $self->{'host'};
  return ref $self;
}

sub cmp {
  my ($self,$arg,$reversed) = @_;
  my $cmp;

Ace.pm  view on Meta::CPAN


This method behaves differently depending on whether it is called in a
scalar or a list context, and whether it is asked to search for a name
pattern or a simple name.

When called with a class and a simple name, it returns the object
referenced by that time, or undef, if no such object exists.  In an
array context, it will return an empty list.

When called with a class and a name pattern in a list context, fetch()
returns the list of objects that match the name.  When called with a
pattern in a scalar context, fetch() returns the I<number> of objects
that match without actually retrieving them from the database.  Thus,
it is similar to count().

In the examples below, the first line of code will fetch the Sequence
object whose database ID is I<D12345>.  The second line will retrieve
all objects matching the pattern I<D1234*>.  The third line will
return the count of objects that match the same pattern.

   $object =  $db->fetch(Sequence => 'D12345');
   @objects = $db->fetch(Sequence => 'D1234*');
   $cnt =     $db->fetch(Sequence =>'D1234*');

A variety of communications and database errors may occur while
processing the request.  When this happens, undef or an empty list
will be returned, and a string describing the error can be retrieved
by calling Ace->error.

When retrieving database objects, it is possible to retrieve a
"filled" or an "unfilled" object.  A filled object contains the entire
contents of the object, including all tags and subtags.  In the case
of certain Sequence objects, this may be a significant amount of data.
Unfilled objects consist just of the object name.  They are filled in
from the database a little bit at a time as tags are requested.  By
default, fetch() returns the unfilled object.  This is usually a
performance win, but if you know in advance that you will be needing
the full contents of the retrieved object (for example, to display
them in a tree browser) it can be more efficient to fetch them in
filled mode. You do this by calling fetch() with the argument of
B<-fill> set to a true value.

The B<-filltag> argument, if provided, asks the database to fill in
the subtree anchored at the indicated tag.  This will improve
performance for frequently-accessed subtrees.  For example:

   @objects = $db->fetch(-name    => 'D123*',
                         -class   => 'Sequence',
                         -filltag => 'Visible');

This will fetch all Sequences named D123* and fill in their Visible
trees in a single operation.

Other arguments in the named parameter calling form are B<-count>, to
retrieve a certain maximum number of objects, and B<-offset>, to
retrieve objects beginning at the indicated offset into the list.  If
you want to limit the number of objects returned, but wish to learn
how many objects might have been retrieved, pass a reference to a
scalar variable in the B<-total> argument.  This will return the
object count.  This example shows how to fetch 100 Sequence
objects, starting at Sequence number 500:

  @some_sequences = $db->fetch('Sequence','*',100,500);

The next example uses the named argument form to fetch 100 Sequence
objects starting at Sequence number 500, and leave the total number of
Sequences in $total:

  @some_sequences = $db->fetch(-class  => 'Sequence',
	                       -count  => 100,
	                       -offset => 500,
	                       -total  => \$total);

Notice that if you leave out the B<-name> argument the "*" wildcard is 
assumed.

You may also pass an arbitrary Ace query string with the B<-query>
argument.  This will supersede any name and class you provide.
Example: 

  @ready_dnas= $db->fetch(-query=>
      'find Annotation Ready_for_submission ; follow gene ; 
       follow derived_sequence ; >DNA');

If your request is likely to retrieve very many objects, fetch() many
consume a lot of memory, even if B<-fill> is false.  Consider using
B<fetch_many()> instead (see below).  Also see the get() method, which
is equivalent to the simple two-argument form of fetch().

=item get() method

   $object = $db->get($class,$name [,$fill]);

The get() method will return one and only one AceDB object
identified by its class and name.  The optional $fill argument can be
used to control how much data is retrieved from the database. If $fill
is absent or undefined, then the method will return a lightweight
"stub" object that is filled with information as requested in a lazy
fashion. If $fill is the number "1" then the retrieved object contains
all the relevant information contained within the database.  Any other
true value of $fill will be treated as a tag name: the returned object
will be prefilled with the subtree to the right of that tag.

Examples:

   # return lightweight stub for Author object "Sulston JE."
   $author = $db->get(Author=>'Sulston JE');

   # return heavyweight object
   $author = $db->get(Author=>'Sulston JE',1);

   # return object containing the Address subtree
   $author = $db->get(Author=>'Sulston JE','Address');

The get() method is equivalent to this form of the fetch()
method:

   $object = $db->fetch($class=>$name);

=head2 aql() method

    $count   = $db->aql($aql_query);
    @objects = $db->aql($aql_query);

Ace::aql() will perform an AQL query on the database.  In a scalar
context it returns the number of rows returned.  In an array context



( run in 1.384 second using v1.01-cache-2.11-cpan-524268b4103 )