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   64 use strict;
  10         28  
  10         646  
3 10     10   60 use warnings;
  10         21  
  10         363  
4 10     10   59 use base qw( Rose::Object );
  10         20  
  10         1053  
5 10     10   58 use Carp;
  10         22  
  10         743  
6 10     10   53 use Data::Dump qw( dump );
  10         22  
  10         2759  
7 10     10   59 use Net::LDAP::Class::MethodMaker ( 'scalar' => [qw( iterators )], );
  10         21  
  10         115  
8              
9             our $VERSION = '0.26';
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 190 my $self = shift;
42 6         43 $self->SUPER::init(@_);
43 6 50 33     316 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         39 $self->{_count} = 0;
51              
52 6         17 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 71 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 74940 my $self = shift;
74              
75             # find the first un-exhausted child iterator's next() value.
76 94         269 my $i = 0;
77 94         165 for my $iter ( @{ $self->{iterators} } ) {
  94         361  
78 140 100       741 next if $iter->is_exhausted;
79 95         351 my $ret = $iter->next;
80 95 100       501 if ( !defined $ret ) {
81 5 50       30 if ( !$iter->is_exhausted ) {
82 0         0 warn "non-exhausted iterator $iter returned undef";
83             }
84 5         21 next;
85             }
86 90         209 $self->{_count}++;
87 90         575 return $ret;
88             }
89              
90             # if we get here, completely exhausted.
91 4         22 $self->{_is_exhausted} = 1;
92 4         22 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 6 my $self = shift;
114              
115 2         6 my $i = 0;
116 2         4 my $finished = 0;
117 2         4 for my $iter ( @{ $self->{iterators} } ) {
  2         37  
118 4 100       20 next if $iter->is_exhausted;
119 2         46 $finished += $iter->finish();
120             }
121              
122 2         15 return $finished;
123             }
124              
125             1;
126              
127             __END__