File Coverage

blib/lib/App/dategrep/Iterator.pm
Criterion Covered Total %
statement 56 58 96.5
branch 19 20 95.0
condition 11 12 91.6
subroutine 10 10 100.0
pod 0 4 0.0
total 96 104 92.3


line stmt bran cond sub pod time code
1             package App::dategrep::Iterator;
2 9     9   3628 use strict;
  9         12  
  9         212  
3 9     9   29 use warnings;
  9         9  
  9         162  
4 9     9   28 use Moo;
  9         9  
  9         36  
5 9     9   1630 use Fcntl ':seek';
  9         12  
  9         781  
6 9     9   35 use File::stat;
  9         13  
  9         74  
7 9     9   366 use App::dategrep::Date qw(date_to_epoch);
  9         16  
  9         3555  
8              
9             has multiline => ( is => 'ro', default => sub { 0 } );
10             has start => ( is => 'rw', required => 1 );
11             has end => ( is => 'rw', required => 1 );
12             has format => ( is => 'rw', required => 1 );
13             has fh => ( is => 'lazy' );
14             has next_line => ( is => 'rw', clearer => 1, );
15             has next_date => ( is => 'rw' );
16              
17             has skip_unparsable => ( is => 'ro', default => sub { 0 } );
18              
19             has eof => ( is => 'rw', default => 0 );
20              
21             sub print_all {
22 3     3 0 4 my $self = shift;
23 3         78 my $pos = $self->fh->tell;
24              
25 3         77 my $max = $self->search( $self->end, $self->fh->tell );
26 3 100       10 if ( not defined $max ) {
27 2         33 $max = stat( $self->fh )->size;
28             }
29              
30 3         228 $self->fh->seek( $pos, SEEK_SET );
31 3         63 while ( $self->fh->tell < $max ) {
32 6         312 print $self->fh->getline;
33             }
34 3         129 $self->eof(1);
35 3         3 return;
36             }
37              
38             sub print {
39 34     34 0 45 my ( $self, $until ) = @_;
40              
41 34   66     170 $until ||= $self->end;
42 34   100     170 my $ignore = $self->multiline || $self->skip_unparsable;
43              
44 34 100       81 if ( $self->next_line ) {
45 31         1115 print $self->next_line;
46             }
47              
48 34 100 100     243 if ( $until >= $self->end && $self->multiline && $self->can_seek ) {
      100        
49 3         15 $self->print_all;
50 3         23 return;
51             }
52              
53 31         35 while (1) {
54 82         1695 my $line = $self->fh->getline;
55 82 100       3064 if ( !$line ) {
56 17         52 $self->eof(1);
57 17         80 return;
58             }
59 65         116 my ( $date, $error ) = $self->to_epoch($line);
60 65 100       10922 if ($date) {
    100          
    100          
61              
62 59         180 $self->next_line($line);
63 59         79 $self->next_date($date);
64              
65 59 100       220 if ( $date >= $self->end ) {
    100          
    50          
66 10         56 $self->eof(1);
67 10         62 return;
68             }
69             elsif ( $date >= $until ) {
70 3         9 return;
71             }
72             elsif ( $date < $self->start ) {
73 0         0 next;
74             }
75             else {
76 46         558 print $line;
77             }
78             }
79             elsif ( $self->multiline ) {
80 4         52 print $line;
81             }
82             elsif ( $self->skip_unparsable ) {
83 1         2 next;
84             }
85             else {
86 1         9 die "No date found in line $line";
87             }
88             }
89 0         0 return;
90             }
91              
92             sub BUILD {
93 35     35 0 18400 shift->seek;
94             }
95              
96             sub to_epoch {
97 180     180 0 229 my ( $self, $line ) = @_;
98 180         618 return date_to_epoch( $line, $self->format );
99             }
100              
101             1;