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;
    }



( run in 2.862 seconds using v1.01-cache-2.11-cpan-5837b0d9d2c )