File Coverage

blib/lib/TableDataRole/Source/CSVInFile.pm
Criterion Covered Total %
statement 59 62 95.1
branch 10 16 62.5
condition n/a
subroutine 13 14 92.8
pod 2 9 22.2
total 84 101 83.1


line stmt bran cond sub pod time code
1             package TableDataRole::Source::CSVInFile;
2              
3 6     6   2871 use 5.010001;
  6         22  
4 6     6   31 use strict;
  6         11  
  6         115  
5 6     6   26 use warnings;
  6         12  
  6         148  
6              
7 6     6   30 use Role::Tiny;
  6         11  
  6         29  
8              
9             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
10             our $DATE = '2023-06-14'; # DATE
11             our $DIST = 'TableDataRoles-Standard'; # DIST
12             our $VERSION = '0.016'; # VERSION
13              
14             with 'TableDataRole::Spec::Basic';
15              
16             sub new {
17 8     8 1 6560 require Text::CSV_XS;
18              
19 8         120866 my ($class, %args) = @_;
20              
21 8         18 my $fh;
22 8 100       50 if (defined(my $filename = delete $args{filename})) {
    50          
23 3 50       163 open $fh, "<", $filename
24             or die "Can't open file '$filename': $!";
25             } elsif (defined($fh = delete $args{filehandle})) {
26             } else {
27 0         0 die "Please specify 'filename' or 'filehandle'";
28             }
29 8 50       39 die "Unknown argument(s): ". join(", ", sort keys %args)
30             if keys %args;
31              
32 8         63 my $csv_parser = Text::CSV_XS->new({binary=>1, auto_diag=>9, diag_verbose=>1});
33              
34 8         1327 my $fhpos_data_begin = tell $fh;
35 8 50       337 my $columns = $csv_parser->getline($fh)
36             or die "Can't read columns from first row of CSV file";
37 8         389 my $fhpos_datarow_begin = tell $fh;
38              
39 8         92 bless {
40             fh => $fh,
41             fhpos_data_begin => $fhpos_data_begin,
42             fhpos_datarow_begin => $fhpos_datarow_begin,
43             csv_parser => $csv_parser,
44             columns => $columns,
45             pos => 0, # iterator
46             }, $class;
47             }
48              
49             sub as_csv {
50 2     2 1 14 my $self = shift;
51              
52 2         12 my $fh = $self->{fh};
53 2         7 my $oldpos = tell $fh;
54 2         29 seek $fh, $self->{fhpos_data_begin}, 0;
55 2         9 $self->{pos} = 0;
56 2         11 local $/;
57 2         68 scalar <$fh>;
58             }
59              
60             sub get_column_count {
61 3     3 0 8 my $self = shift;
62              
63 3         7 scalar @{ $self->{columns} };
  3         22  
64             }
65              
66             sub get_column_names {
67 10     10 0 21 my $self = shift;
68 10 100       52 wantarray ? @{ $self->{columns} } : $self->{columns};
  4         41  
69             }
70              
71             sub has_next_item {
72 327     327 0 568 my $self = shift;
73 327         501 my $fh = $self->{fh};
74 327         1162 !eof($fh);
75             }
76              
77             sub get_next_item {
78 312     312 0 755 my $self = shift;
79 312         489 my $fh = $self->{fh};
80 312 50       674 die "StopIteration" if eof($fh);
81 312         6178 my $row = $self->{csv_parser}->getline($fh);
82 312         7902 $self->{pos}++;
83 312         728 $row;
84             }
85              
86             sub get_next_row_hashref {
87 4     4 0 11 my $self = shift;
88 4         10 my $fh = $self->{fh};
89 4 50       34 die "StopIteration" if eof($fh);
90 4         121 my $row = $self->{csv_parser}->getline($fh);
91 4         117 $self->{pos}++;
92 4         13 +{ map {($self->{columns}[$_] => $row->[$_])} 0..$#{$self->{columns}} };
  12         77  
  4         18  
93             }
94              
95             sub get_iterator_pos {
96 0     0 0 0 my $self = shift;
97 0         0 $self->{pos};
98             }
99              
100             sub reset_iterator {
101 19     19 0 72 my $self = shift;
102 19         39 my $fh = $self->{fh};
103 19         241 seek $fh, $self->{fhpos_datarow_begin}, 0;
104 19         87 $self->{pos} = 0;
105             }
106              
107             sub DESTROY {
108 8     8   9018 my $self = shift;
109 8         33 my $fh = $self->{fh};
110 8         858 seek $fh, $self->{fhpos_data_begin}, 0;
111             }
112              
113             1;
114             # ABSTRACT: Role to access table data from CSV in a file/filehandle
115              
116             __END__