AcePerl

 view release on metacpan or  search on metacpan

Ace/Iterator.pm  view on Meta::CPAN

package Ace::Iterator;
use strict;
use vars '$VERSION';
use Carp;
use Ace 1.50 qw(rearrange);

$VERSION = '1.51';

sub new {
  my $pack = shift; 
  my ($db,$query,$filled,$chunksize) = rearrange([qw/DB QUERY FILLED CHUNKSIZE/],@_);
  my $self = {
	      'db'    => $db,
	      'query' => $query,
	      'valid' => undef,
	      'cached_answers' => [],
	      'filled' => ($filled || 0),
	      'chunksize' => ($chunksize || 40),
	      'current' => 0
	     };
  bless $self,$pack;
  $db->_register_iterator($self) if $db && ref($db);
  $self;
}

sub next {
  my $self = shift;
  croak "Attempt to use an expired iterator" unless $self->{db};
  $self->_fill_cache() unless @{$self->{'cached_answers'}};
  my $cache = $self->{cached_answers};
  my $result = shift @{$cache};
  $self->{'current'}++;
  unless ($result) {
    $self->{db}->_unregister_iterator;
    delete $self->{db};
  }
  return $result;
}

sub invalidate {
  my $self = shift;
  return unless $self->_active;
  $self->save_context;
  $self->_active(0);
}

sub save_context {
  my $self = shift;
  return unless my $db = $self->{db};
  return unless $self->_active;
  $self->{saved_ok} = $db->_save_iterator($self);
}

# Fill up cache for iterator
sub _fill_cache {
  my $self = shift;
  return unless my $db = $self->{db};
  $self->restore_context() if !$self->{active};
  my @objects = $self->{filled} ? $db->_fetch($self->{'chunksize'},$self->{'current'}) :
                                  $db->_list($self->{'chunksize'},$self->{'current'});
  $self->{cached_answers} = \@objects;
  $self->_active(1);
}

# prevent reentry
sub _active {
  my $self = shift;
  my $val = $self->{active};
  $self->{active} = shift if @_;
  return $val;
}

sub restore_context {
  my $self = shift;
  return unless my $db = $self->{db};
  $db->raw_query($self->{query}) 
    unless $self->{saved_ok} and $db->_restore_iterator($self);
  undef $self->{saved_ok};   # no longer there!
}

1;

__END__


=head1 NAME

Ace::Iterator - Iterate Across an ACEDB Query

=head1 SYNOPSIS

    use Ace;
    $db = Ace->connect(-host => 'beta.crbm.cnrs-mop.fr',
                       -port => 20000100);

    $i  = $db->fetch_many(Sequence=>'*');  # fetch a cursor
    while ($obj = $i->next) {
       print $obj->asTable;
    }


=head1 DESCRIPTION

The Ace::Iterator class implements a persistent query on an Ace
database.  You can create multiple simultaneous queries and retrieve
objects from each one independently of the others.  This is useful
when a query is expected to return more objects than can easily fit
into memory.  The iterator is essentially a database "cursor."

=head2 new() Method

  $iterator = Ace::Iterator->new(-db        => $db,
                                 -query     => $query,
                                 -filled    => $filled,
                                 -chunksize => $chunksize);

An Ace::Iterator is returned by the Ace accessor's object's
fetch_many() method. You usually will not have cause to call the new()
method directly.  If you do so, the parameters are as follows:

=over 4

=item -db

The Ace database accessor object to use.

=item -query

A query, written in Ace query language, to pass to the database.  This
query should return a list of objects.

=item -filled



( run in 2.619 seconds using v1.01-cache-2.11-cpan-f56aa216473 )