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   2254 use 5.010001;
  6         18  
4 6     6   27 use strict;
  6         8  
  6         91  
5 6     6   25 use warnings;
  6         8  
  6         134  
6              
7 6     6   24 use Role::Tiny;
  6         16  
  6         27  
8              
9             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
10             our $DATE = '2022-02-20'; # DATE
11             our $DIST = 'TableDataRoles-Standard'; # DIST
12             our $VERSION = '0.014'; # VERSION
13              
14             with 'TableDataRole::Spec::Basic';
15              
16             sub new {
17 8     8 1 5476 require Text::CSV_XS;
18              
19 8         95755 my ($class, %args) = @_;
20              
21 8         17 my $fh;
22 8 100       49 if (defined(my $filename = delete $args{filename})) {
    50          
23 3 50       203 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       45 die "Unknown argument(s): ". join(", ", sort keys %args)
30             if keys %args;
31              
32 8         55 my $csv_parser = Text::CSV_XS->new({binary=>1});
33              
34 8         971 my $fhpos_data_begin = tell $fh;
35 8 50       297 my $columns = $csv_parser->getline($fh)
36             or die "Can't read columns from first row of CSV file";
37 8         316 my $fhpos_datarow_begin = tell $fh;
38              
39 8         109 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 10 my $self = shift;
51              
52 2         9 my $fh = $self->{fh};
53 2         4 my $oldpos = tell $fh;
54 2         23 seek $fh, $self->{fhpos_data_begin}, 0;
55 2         6 $self->{pos} = 0;
56 2         7 local $/;
57 2         50 scalar <$fh>;
58             }
59              
60             sub get_column_count {
61 3     3 0 9 my $self = shift;
62              
63 3         4 scalar @{ $self->{columns} };
  3         20  
64             }
65              
66             sub get_column_names {
67 10     10 0 19 my $self = shift;
68 10 100       38 wantarray ? @{ $self->{columns} } : $self->{columns};
  4         40  
69             }
70              
71             sub has_next_item {
72 327     327 0 412 my $self = shift;
73 327         357 my $fh = $self->{fh};
74 327         1049 !eof($fh);
75             }
76              
77             sub get_next_item {
78 312     312 0 547 my $self = shift;
79 312         333 my $fh = $self->{fh};
80 312 50       480 die "StopIteration" if eof($fh);
81 312         4457 my $row = $self->{csv_parser}->getline($fh);
82 312         5508 $self->{pos}++;
83 312         518 $row;
84             }
85              
86             sub get_next_row_hashref {
87 4     4 0 7 my $self = shift;
88 4         8 my $fh = $self->{fh};
89 4 50       25 die "StopIteration" if eof($fh);
90 4         90 my $row = $self->{csv_parser}->getline($fh);
91 4         82 $self->{pos}++;
92 4         8 +{ map {($self->{columns}[$_] => $row->[$_])} 0..$#{$self->{columns}} };
  12         76  
  4         10  
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 56 my $self = shift;
102 19         34 my $fh = $self->{fh};
103 19         204 seek $fh, $self->{fhpos_datarow_begin}, 0;
104 19         69 $self->{pos} = 0;
105             }
106              
107             sub DESTROY {
108 8     8   7387 my $self = shift;
109 8         66 my $fh = $self->{fh};
110 8         751 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__