File Coverage

blib/lib/Net/LDAP/Class/MultiIterator.pm
Criterion Covered Total %
statement 45 48 93.7
branch 8 10 80.0
condition 2 6 33.3
subroutine 10 11 90.9
pod 5 5 100.0
total 70 80 87.5


line stmt bran cond sub pod time code
1             package Net::LDAP::Class::MultiIterator;
2 10     10   33 use strict;
  10         12  
  10         252  
3 10     10   36 use warnings;
  10         12  
  10         229  
4 10     10   31 use base qw( Rose::Object );
  10         10  
  10         631  
5 10     10   36 use Carp;
  10         19  
  10         474  
6 10     10   34 use Data::Dump qw( dump );
  10         11  
  10         400  
7 10     10   40 use Net::LDAP::Class::MethodMaker ( 'scalar' => [qw( iterators )], );
  10         10  
  10         58  
8              
9             our $VERSION = '0.27';
10              
11             =head1 NAME
12              
13             Net::LDAP::Class::MultiIterator - a set of Net::LDAP::Class::Iterator objects
14              
15             =head1 SYNOPSIS
16              
17             my $iterator = $user->groups_iterator;
18             while ( my $group = $iterator->next ) {
19             # $group isa Net::LDAP::Class::Group
20             }
21             printf("%d groups found\n", $iterator->count);
22              
23             =head1 DESCRIPTION
24              
25             Net::LDAP::Class::MultiIterator handles multiple iterators under a single
26             call to next(). Used by users_iterator() and groups_iterator() methods.
27              
28             =head1 METHODS
29              
30             =head2 iterators
31              
32             The array ref of iterators. Required to be set in new().
33              
34             =head2 init
35              
36             Set up the object.
37              
38             =cut
39              
40             sub init {
41 6     6 1 132 my $self = shift;
42 6         27 $self->SUPER::init(@_);
43 6 50 33     129 if ( !$self->iterators
      33        
44             or !ref( $self->iterators )
45             or ref( $self->iterators ) ne 'ARRAY' )
46             {
47 0         0 croak "iterators ARRAY ref required";
48             }
49              
50 6         18 $self->{_count} = 0;
51              
52 6         10 return $self;
53             }
54              
55             =head2 count
56              
57             Returns the total number of iterations.
58              
59             =cut
60              
61             sub count {
62 6     6 1 40 return shift->{_count};
63             }
64              
65             =head2 next
66              
67             Return the next result. If one iterator on the stack is exhausted,
68             automatically moves to the next one.
69              
70             =cut
71              
72             sub next {
73 94     94 1 27176 my $self = shift;
74              
75             # find the first un-exhausted child iterator's next() value.
76 94         122 my $i = 0;
77 94         101 for my $iter ( @{ $self->{iterators} } ) {
  94         234  
78 140 100       340 next if $iter->is_exhausted;
79 95         193 my $ret = $iter->next;
80 95 100       290 if ( !defined $ret ) {
81 5 50       12 if ( !$iter->is_exhausted ) {
82 0         0 warn "non-exhausted iterator $iter returned undef";
83             }
84 5         11 next;
85             }
86 90         98 $self->{_count}++;
87 90         203 return $ret;
88             }
89              
90             # if we get here, completely exhausted.
91 4         15 $self->{_is_exhausted} = 1;
92 4         10 return undef;
93             }
94              
95             =head2 is_exhausted
96              
97             Returns true (1) if all the internal iterators return is_exhausted,
98             false (undef) otherwise.
99              
100             =cut
101              
102             sub is_exhausted {
103 0     0 1 0 return shift->{_is_exhausted};
104             }
105              
106             =head2 finish
107              
108             Calls finish() on all un-exhausted iterators.
109              
110             =cut
111              
112             sub finish {
113 2     2 1 4 my $self = shift;
114              
115 2         3 my $i = 0;
116 2         2 my $finished = 0;
117 2         5 for my $iter ( @{ $self->{iterators} } ) {
  2         81  
118 4 100       14 next if $iter->is_exhausted;
119 2         8 $finished += $iter->finish();
120             }
121              
122 2         8 return $finished;
123             }
124              
125             1;
126              
127             __END__