File Coverage

blib/lib/TablesRole/Source/Iterator.pm
Criterion Covered Total %
statement 65 68 95.5
branch 18 30 60.0
condition 4 10 40.0
subroutine 12 12 100.0
pod 0 6 0.0
total 99 126 78.5


line stmt bran cond sub pod time code
1             package TablesRole::Source::Iterator;
2              
3             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
4             our $DATE = '2020-11-10'; # DATE
5             our $DIST = 'TablesRoles-Standard'; # DIST
6             our $VERSION = '0.006'; # VERSION
7              
8 1     1   537 use 5.010001;
  1         4  
9 1     1   5 use Role::Tiny;
  1         2  
  1         6  
10 1     1   159 use Role::Tiny::With;
  1         2  
  1         754  
11             with 'TablesRole::Spec::Basic';
12             with 'TablesRole::Util::CSV';
13              
14             sub _new {
15 1     1   5 my ($class, %args) = @_;
16              
17 1 50       6 my $gen_iterator = delete $args{gen_iterator} or die "Please specify 'gen_iterator' argument";
18 1   50     6 my $gen_iterator_params = delete $args{gen_iterator_params} // {};
19              
20 1 50       4 die "Unknown argument(s): ". join(", ", sort keys %args)
21             if keys %args;
22              
23 1         7 bless {
24             gen_iterator => $gen_iterator,
25             gen_iterator_params => $gen_iterator_params,
26             iterator => undef,
27             # buffer => undef,
28             # column_names => undef,
29             # column_idxs => undef,
30             }, $class;
31             }
32              
33             # as_csv from TablesRole::Util::CSV
34              
35             sub _get_row {
36             # get a row from iterator or buffer, and empty the buffer
37 12     12   18 my $self = shift;
38 12 100       27 if ($self->{buffer}) {
39 1         3 my $row = delete $self->{buffer};
40 1 50 33     5 if (!ref($row) && $row == -1) {
41 0         0 return undef;
42             } else {
43 1         3 return $row;
44             }
45             } else {
46 11 50       26 $self->reset_iterator unless $self->{iterator};
47 11         22 return $self->{iterator}->();
48             }
49             }
50              
51             sub _peek_row {
52             # get a row from iterator, put it in buffer. will return the existing buffer
53             # content if it exists.
54 1     1   3 my $self = shift;
55 1 50       3 unless ($self->{buffer}) {
56 1 50       4 $self->reset_iterator unless $self->{iterator};
57 1   50     4 $self->{buffer} = $self->{iterator}->() // -1;
58             }
59 1 50 33     6 if (!ref($self->{buffer}) && $self->{buffer} == -1) {
60 0         0 return undef;
61             } else {
62 1         3 return $self->{buffer};
63             }
64             }
65              
66             sub get_column_count {
67 1     1 0 3 my $self = shift;
68 1         4 $self->get_column_names;
69 1         2 scalar(@{ $self->{column_names} });
  1         4  
70             }
71              
72             sub get_column_names {
73 9     9 0 14 my $self = shift;
74 9 100       26 unless ($self->{column_names}) {
75 1         4 my $row = $self->_peek_row;
76 1 50       4 unless ($row) {
77 0 0       0 return wantarray ? () : [];
78             }
79 1         2 my $i = -1;
80 1         3 $self->{column_names} = [];
81 1         2 $self->{column_idxs} = {};
82 1         6 for (sort keys %$row) {
83 1         2 push @{ $self->{column_names} }, $_;
  1         3  
84 1         5 $self->{column_idxs}{$_} = ++$i;
85             }
86             }
87 9 100       21 wantarray ? @{ $self->{column_names} } : $self->{column_names};
  2         11  
88             }
89              
90             sub get_row_arrayref {
91 6     6 0 27 my $self = shift;
92 6         16 $self->get_column_names;
93 6         13 my $row_hashref = $self->_get_row;
94 6 100       15 return undef unless $row_hashref;
95 5         11 my $row_aryref = [];
96 5         15 for (keys %$row_hashref) {
97 5         12 my $idx = $self->{column_idxs}{$_};
98 5 50       11 next unless defined $idx;
99 5         13 $row_aryref->[$idx] = $row_hashref->{$_};
100             }
101 5         21 $row_aryref;
102             }
103              
104             sub get_row_count {
105 1     1 0 4 my $self = shift;
106 1         3 $self->reset_iterator;
107 1 50       4 unless (defined $self->{row_count}) {
108 1         3 my $i = 0;
109 1         3 $i++ while $self->_get_row;
110 1         3 $self->{row_count} = $i;
111             }
112 1         5 $self->{row_count};
113             }
114              
115             sub get_row_hashref {
116 2     2 0 4 my $self = shift;
117 2         6 $self->_get_row;
118             }
119              
120             sub reset_iterator {
121 4     4 0 9 my $self = shift;
122 4         9 $self->{iterator} = $self->{gen_iterator}->(%{ $self->{gen_iterator_params} });
  4         16  
123             }
124              
125             1;
126             # ABSTRACT: Get table data from an iterator
127              
128             __END__