File Coverage

blib/lib/Text/CSV/Slurp.pm
Criterion Covered Total %
statement 56 75 74.6
branch 10 18 55.5
condition 4 12 33.3
subroutine 9 9 100.0
pod 3 3 100.0
total 82 117 70.0


line stmt bran cond sub pod time code
1             package Text::CSV::Slurp;
2              
3 3     3   130463 use strict;
  3         4  
  3         95  
4 3     3   10 use warnings;
  3         3  
  3         63  
5              
6 3     3   1725 use Text::CSV;
  3         37132  
  3         15  
7 3     3   1590 use IO::File;
  3         23021  
  3         315  
8              
9 3     3   18 use vars qw/$VERSION/;
  3         3  
  3         1817  
10              
11             $VERSION = 1.02;
12              
13             sub new {
14 1     1 1 11 my $class = shift;
15 1         4 return bless {}, $class;
16             }
17              
18             sub load {
19 4     4 1 16816 my $class = shift;
20 4         12 my %opt = @_;
21              
22 4         9 my %default = ( binary => 1 );
23 4         17 %opt = (%default, %opt);
24              
25 4 0 33     16 unless (defined $opt{file} || defined $opt{filehandle} || defined $opt{string}) {
      33        
26 0         0 die "Need either a file, filehandle or string to work with";
27             }
28              
29 4 50       15 if (defined $opt{filehandle}) {
    50          
30 0         0 my $io = $opt{filehandle};
31 0         0 delete $opt{filehandle};
32 0         0 return _from_handle($io,\%opt);
33             }
34             elsif (defined $opt{file}) {
35 4         22 my $io = new IO::File;
36 4 100       258 open($io, "<$opt{file}") || die "Could not open $opt{file} $!";
37 3         7 delete $opt{file};
38 3         11 return _from_handle($io,\%opt);
39             }
40             else {
41 0         0 my @data = split /\n/, $opt{string};
42 0         0 delete $opt{string};
43              
44 0         0 my $csv = Text::CSV->new(\%opt);
45 0         0 $csv->parse(shift @data);
46              
47 0         0 my @names = $csv->fields();
48              
49 0         0 my @results;
50              
51 0         0 for my $line (@data) {
52 0         0 $csv->parse($line);
53 0         0 my %hash;
54 0         0 @hash{@names} = $csv->fields();
55 0         0 push @results, \%hash;
56             }
57              
58 0         0 return \@results;
59             }
60             }
61              
62             sub create {
63 1     1 1 40 my ( undef, %arg ) = @_;
64              
65 1         6 die "Need an an array of hashes input to create CSV from"
66             unless exists $arg{input} &&
67             ref( $arg{input} ) eq 'ARRAY' &&
68 1 50 33     9 ref( @{ $arg{input} }[0] ) eq 'HASH';
      33        
69              
70 1         2 my $list = $arg{input};
71 1         2 delete $arg{input};
72              
73             # get the field names
74 1         3 my @names = defined $arg{field_order}
75 0         0 ? @{ $arg{field_order} }
76 1 50       4 : sort keys %{ $list->[0] };
77              
78 1         2 delete $arg{field_order};
79              
80 1         4 %arg = ( binary => 1, %arg );
81              
82 1         7 my $csv = Text::CSV->new( \%arg );
83              
84 1 50       95 unless ( $csv->combine( @names ) ) {
85 0         0 die "Failed to create the header row because of this invalid input: " . $csv->error_input;
86             }
87              
88 1         222 my @string = $csv->string;
89              
90 1         8 for my $row ( @$list ) {
91 2         5 my @data;
92 2         3 for my $name ( @names ) {
93 24         25 push @data, $row->{$name};
94             }
95              
96 2 50       5 unless ( $csv->combine( @data ) ) {
97 0         0 die "Failed to create a data row because of this invalid input: " . $csv->error_input;
98             }
99              
100 2         257 push @string, $csv->string;
101             }
102              
103 1         22 return join "\n", @string;
104             }
105              
106             sub _from_handle {
107 3     3   3 my $io = shift;
108 3         5 my $opt = shift;
109              
110 3         16 my $csv = Text::CSV->new($opt);
111              
112 3 100       232 if ( my $head = $csv->getline($io) ) {
113 2         1303 $csv->column_names( $head );
114             }
115             else {
116 1         340 die $csv->error_diag();
117             }
118              
119 2         62 my @results;
120 2         7 while (my $ref = $csv->getline_hr($io)) {
121 2         825 push @results, $ref;
122             }
123              
124 2         396 return \@results;
125             }
126              
127             return qw/Open hearts and empty minds/;
128              
129             =pod
130              
131             =encoding UTF-8
132              
133             =head1 NAME
134              
135             Text::CSV::Slurp - Text::CSV::Slurp - convert CSV into an array of hashes, or an array of hashes into CSV
136              
137             =head1 VERSION
138              
139             version 1.02
140              
141             =head1 SUMMARY
142              
143             I often need to take a CSV file that has a header row and turn it into
144             a perl data structure for further manipulation. This package does that
145             in as few steps as possible.
146              
147             I added a C method in version 0.8 because sometimes you just
148             want to create some bog standard CSV from an array of hashes.
149              
150             =head1 USAGE
151              
152             use Text::CSV::Slurp;
153             use strict;
154              
155             # load data from CSV input
156              
157             my $data = Text::CSV::Slurp->load(file => $filename [,%options]);
158             my $data = Text::CSV::Slurp->load(filehandle => $filehandle [,%options]);
159             my $data = Text::CSV::Slurp->load(string => $string [,%options]);
160              
161             # create a string of CSV from an array of hashes
162             my $csv = Text::CSV::Slurp->create( input => \@array_of_hashes [,%options]);
163              
164             =head1 METHODS
165              
166             =head2 new
167              
168             my $slurp = Text::CSV::Slurp->new();
169              
170             Instantiate an object.
171              
172             =head2 load
173              
174             my $data = Text::CSV::Slurp->load(file => $filename);
175             my $data = $slurp->load(file => $filename);
176              
177             Returns an arrayref of hashrefs. Any extra arguments are passed to L.
178             The first line of the CSV is assumed to be a header row. Its fields are
179             used as the keys for each of the hashes.
180              
181             =head2 create
182              
183             my $csv = Text::CSV::Slurp->create( input => \@array_of_hashes [,%options]);
184             my $csv = $slurp->create( input => \@array_of_hashes [,%options]);
185              
186             my $file = "/path/to/output/file.csv";
187              
188             open( FH, ">$file" ) || die "Couldn't open $file $!";
189             print FH $csv;
190             close FH;
191              
192             Creates CSV from an arrayref of hashrefs and returns it as a string. All optional
193             arguments are passed to L except for C.
194              
195             =head3 field_order
196              
197             C which is used to determine the fields and order in which they
198             appear in the CSV. For example:
199              
200             my $csv = Text::CSV::Slurp->create( input => \@array_of_hashes,
201             field_order => ['one','three','two'] );
202              
203             If field_order is not supplied then the sorted keys of the first hash in the
204             input are used instead.
205              
206             =head1 DEPENDENCIES
207              
208             L
209              
210             L
211              
212             L - for tests only
213              
214             =head1 LICENCE
215              
216             GNU General Public License v3
217              
218             =head1 SOURCE
219              
220             Available at L
221              
222             =head1 SEE ALSO
223              
224             L
225              
226             L
227              
228             =head1 THANKS
229              
230             To Kyle Albritton for suggesting and testing the L method
231              
232             =head1 AUTHOR
233              
234             BABF
235              
236             =head1 COPYRIGHT AND LICENSE
237              
238             This software is copyright (c) 2014 by BABF.
239              
240             This is free software; you can redistribute it and/or modify it under
241             the same terms as the Perl 5 programming language system itself.
242              
243             =cut
244              
245             __END__