File Coverage

blib/lib/TableDataRole/Munge/Filter.pm
Criterion Covered Total %
statement 69 75 92.0
branch 21 30 70.0
condition 3 5 60.0
subroutine 13 14 92.8
pod 1 8 12.5
total 107 132 81.0


line stmt bran cond sub pod time code
1             package TableDataRole::Munge::Filter;
2              
3 1     1   469 use 5.010001;
  1         4  
4 1     1   5 use strict;
  1         2  
  1         18  
5 1     1   5 use warnings;
  1         2  
  1         22  
6 1     1   1713 use Log::ger;
  1         51  
  1         5  
7              
8 1     1   263 use Role::Tiny;
  1         2  
  1         6  
9              
10             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
11             our $DATE = '2023-06-14'; # DATE
12             our $DIST = 'TableDataRoles-Standard'; # DIST
13             our $VERSION = '0.016'; # VERSION
14              
15             with 'TableDataRole::Spec::Basic';
16              
17             sub new {
18 2     2 1 664 require Module::Load::Util;
19              
20 2         1557 my ($class, %args) = @_;
21              
22             my $tabledata = delete $args{tabledata}
23 2 50       11 or die "Please supply 'tabledata' argument";
24 2         5 my $filter = delete $args{filter};
25 2         5 my $filter_hashref = delete $args{filter_hashref};
26 2 50 66     11 ($filter || $filter_hashref) or die "Please supply 'filter' or 'filter_hashref' argument";
27 2         10 for ($filter, $filter_hashref) {
28 4 100       13 next unless defined;
29 2 50       6 unless (ref $_ eq 'CODE') {
30 0         0 my $code = "package main; sub { no strict; no warnings; $_ }";
31 0         0 log_trace "Eval-ing: $code";
32 0         0 $_ = eval $code; ## no critic: BuiltinFunctions::ProhibitStringyEval
33 0 0       0 die if $@;
34             }
35             }
36 2   50     11 my $load = delete($args{load}) // 1;
37 2 50       8 die "Unknown argument(s): ". join(", ", sort keys %args)
38             if keys %args;
39              
40 2         9 $tabledata = Module::Load::Util::instantiate_class_with_optional_args({load=>$load, ns_prefix=>"TableData"}, $tabledata);
41 2         17 my $column_names = $tabledata->get_column_names;
42              
43             bless {
44             tabledata => $tabledata,
45             column_names => $column_names,
46 2         6 column_idxs => {map {$column_names->[$_] => $_} 0..$#{$column_names}},
  6         31  
  2         7  
47             filter => $filter,
48             filter_hashref => $filter_hashref,
49             pos => 0, # iterator
50             # buffer => undef,
51             }, $class;
52             }
53              
54             sub get_column_count {
55 2     2 0 14 my $self = shift;
56              
57 2         3 scalar @{ $self->{column_names} };
  2         12  
58             }
59              
60             sub get_column_names {
61 2     2 0 5 my $self = shift;
62 2 50       6 wantarray ? @{ $self->{column_names} } : $self->{column_names};
  2         27  
63             }
64              
65             sub _fill_buffer {
66 50     50   66 my $self = shift;
67 50 100       106 return if $self->{buffer};
68 29         43 while (1) {
69 191 100       1153 return unless $self->{tabledata}->has_next_item;
70 189 100       419 if ($self->{filter}) {
71 90         198 my $row = $self->{tabledata}->get_next_row_arrayref;
72 90 100       198 if ($self->{filter}->($row)) {
73 15         90 $self->{buffer} = $row;
74 15         28 return;
75             }
76             } else {
77 99         216 my $row = $self->{tabledata}->get_next_item;
78 99         159 my $row_hashref = { map {$self->{column_names}[$_] => $row->[$_]} 0..$#{$row} };
  297         732  
  99         207  
79 99 100       272 if ($self->{filter_hashref}->($row_hashref)) {
80 12         64 $self->{buffer} = $row;
81 12         31 return;
82             }
83             }
84             }
85             }
86              
87             sub has_next_item {
88 23     23 0 77 my $self = shift;
89 23 50       50 return 1 if $self->{buffer};
90 23         56 $self->_fill_buffer;
91 23 100       69 return $self->{buffer} ? 1:0;
92             }
93              
94             sub get_next_item {
95 27     27 0 86 my $self = shift;
96 27         60 $self->_fill_buffer;
97 27 50       57 die "StopIteration" unless $self->{buffer};
98 27         44 $self->{pos}++;
99 27         69 return delete $self->{buffer};
100             }
101              
102             sub get_next_row_hashref {
103 4     4 0 9 my $self = shift;
104 4         9 my $row = $self->get_next_item;
105 4         8 +{ map {($self->{column_names}->[$_] => $row->[$_])} 0..$#{$row} };
  12         64  
  4         9  
106             }
107              
108             sub get_iterator_pos {
109 0     0 0 0 my $self = shift;
110 0         0 $self->{pos};
111             }
112              
113             sub reset_iterator {
114 6     6 0 34 my $self = shift;
115 6         22 $self->{tabledata}->reset_iterator;
116 6         15 $self->{pos} = 0;
117             }
118              
119             1;
120             # ABSTRACT: Role to filter rows from another tabledata
121              
122             __END__