File Coverage

blib/lib/Ace/Iterator.pm
Criterion Covered Total %
statement 12 52 23.0
branch 0 26 0.0
condition 0 10 0.0
subroutine 4 11 36.3
pod 2 5 40.0
total 18 104 17.3


line stmt bran cond sub pod time code
1             package Ace::Iterator;
2 4     4   21 use strict;
  4         9  
  4         165  
3 4     4   20 use vars '$VERSION';
  4         7  
  4         186  
4 4     4   19 use Carp;
  4         7  
  4         310  
5 4     4   19 use Ace 1.50 qw(rearrange);
  4         124  
  4         2245  
6              
7             $VERSION = '1.51';
8              
9             sub new {
10 0     0 1   my $pack = shift;
11 0           my ($db,$query,$filled,$chunksize) = rearrange([qw/DB QUERY FILLED CHUNKSIZE/],@_);
12 0   0       my $self = {
      0        
13             'db' => $db,
14             'query' => $query,
15             'valid' => undef,
16             'cached_answers' => [],
17             'filled' => ($filled || 0),
18             'chunksize' => ($chunksize || 40),
19             'current' => 0
20             };
21 0           bless $self,$pack;
22 0 0 0       $db->_register_iterator($self) if $db && ref($db);
23 0           $self;
24             }
25              
26             sub next {
27 0     0 1   my $self = shift;
28 0 0         croak "Attempt to use an expired iterator" unless $self->{db};
29 0 0         $self->_fill_cache() unless @{$self->{'cached_answers'}};
  0            
30 0           my $cache = $self->{cached_answers};
31 0           my $result = shift @{$cache};
  0            
32 0           $self->{'current'}++;
33 0 0         unless ($result) {
34 0           $self->{db}->_unregister_iterator;
35 0           delete $self->{db};
36             }
37 0           return $result;
38             }
39              
40             sub invalidate {
41 0     0 0   my $self = shift;
42 0 0         return unless $self->_active;
43 0           $self->save_context;
44 0           $self->_active(0);
45             }
46              
47             sub save_context {
48 0     0 0   my $self = shift;
49 0 0         return unless my $db = $self->{db};
50 0 0         return unless $self->_active;
51 0           $self->{saved_ok} = $db->_save_iterator($self);
52             }
53              
54             # Fill up cache for iterator
55             sub _fill_cache {
56 0     0     my $self = shift;
57 0 0         return unless my $db = $self->{db};
58 0 0         $self->restore_context() if !$self->{active};
59 0 0         my @objects = $self->{filled} ? $db->_fetch($self->{'chunksize'},$self->{'current'}) :
60             $db->_list($self->{'chunksize'},$self->{'current'});
61 0           $self->{cached_answers} = \@objects;
62 0           $self->_active(1);
63             }
64              
65             # prevent reentry
66             sub _active {
67 0     0     my $self = shift;
68 0           my $val = $self->{active};
69 0 0         $self->{active} = shift if @_;
70 0           return $val;
71             }
72              
73             sub restore_context {
74 0     0 0   my $self = shift;
75 0 0         return unless my $db = $self->{db};
76 0 0 0       $db->raw_query($self->{query})
77             unless $self->{saved_ok} and $db->_restore_iterator($self);
78 0           undef $self->{saved_ok}; # no longer there!
79             }
80              
81             1;
82              
83             __END__