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 3     3   469276 use 5.010001;
  3         12  
4 3     3   15 use strict;
  3         6  
  3         100  
5 3     3   12 use warnings;
  3         8  
  3         136  
6 3     3   5504 use Log::ger;
  3         139  
  3         13  
7              
8 3     3   1060 use Role::Tiny;
  3         4537  
  3         16  
9              
10             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
11             our $DATE = '2024-05-14'; # DATE
12             our $DIST = 'TableDataRoles-Standard'; # DIST
13             our $VERSION = '0.025'; # VERSION
14              
15             with 'TableDataRole::Spec::Basic';
16              
17             sub new {
18 2     2 1 538765 require Module::Load::Util;
19              
20 2         3075 my ($class, %args) = @_;
21              
22             my $tabledata = delete $args{tabledata}
23 2 50       15 or die "Please supply 'tabledata' argument";
24 2         6 my $filter = delete $args{filter};
25 2         15 my $filter_hashref = delete $args{filter_hashref};
26 2 50 66     14 ($filter || $filter_hashref) or die "Please supply 'filter' or 'filter_hashref' argument";
27 2         7 for ($filter, $filter_hashref) {
28 4 100       14 next unless defined;
29 2 50       17 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     15 my $load = delete($args{load}) // 1;
37 2 50       7 die "Unknown argument(s): ". join(", ", sort keys %args)
38             if keys %args;
39              
40 2         14 $tabledata = Module::Load::Util::instantiate_class_with_optional_args({load=>$load, ns_prefix=>"TableData"}, $tabledata);
41 2         31 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         43  
  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 12 my $self = shift;
56              
57 2         4 scalar @{ $self->{column_names} };
  2         18  
58             }
59              
60             sub get_column_names {
61 2     2 0 7 my $self = shift;
62 2 50       7 wantarray ? @{ $self->{column_names} } : $self->{column_names};
  2         21  
63             }
64              
65             sub _fill_buffer {
66 52     52   85 my $self = shift;
67 52 100       153 return if $self->{buffer};
68 30         43 while (1) {
69 215 100       1667 return unless $self->{tabledata}->has_next_item;
70 213 100       522 if ($self->{filter}) {
71 102         238 my $row = $self->{tabledata}->get_next_row_arrayref;
72 102 100       268 if ($self->{filter}->($row)) {
73 15         114 $self->{buffer} = $row;
74 15         30 return;
75             }
76             } else {
77 111         297 my $row = $self->{tabledata}->get_next_item;
78 111         192 my $row_hashref = { map {$self->{column_names}[$_] => $row->[$_]} 0..$#{$row} };
  333         1029  
  111         269  
79 111 100       384 if ($self->{filter_hashref}->($row_hashref)) {
80 13         86 $self->{buffer} = $row;
81 13         41 return;
82             }
83             }
84             }
85             }
86              
87             sub has_next_item {
88 24     24 0 96 my $self = shift;
89 24 50       64 return 1 if $self->{buffer};
90 24         59 $self->_fill_buffer;
91 24 100       82 return $self->{buffer} ? 1:0;
92             }
93              
94             sub get_next_item {
95 28     28 0 135 my $self = shift;
96 28         71 $self->_fill_buffer;
97 28 50       74 die "StopIteration" unless $self->{buffer};
98 28         45 $self->{pos}++;
99 28         84 return delete $self->{buffer};
100             }
101              
102             sub get_next_row_hashref {
103 4     4 0 11 my $self = shift;
104 4         18 my $row = $self->get_next_item;
105 4         12 +{ map {($self->{column_names}->[$_] => $row->[$_])} 0..$#{$row} };
  12         69  
  4         12  
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 56 my $self = shift;
115 6         36 $self->{tabledata}->reset_iterator;
116 6         17 $self->{pos} = 0;
117             }
118              
119             1;
120             # ABSTRACT: Role to filter rows from another tabledata
121              
122             __END__