File Coverage

blib/lib/Parse/CSV/Colnames.pm
Criterion Covered Total %
statement 33 34 97.0
branch 4 6 66.6
condition n/a
subroutine 12 13 92.3
pod 7 7 100.0
total 56 60 93.3


line stmt bran cond sub pod time code
1             package Parse::CSV::Colnames;
2              
3             =pod
4              
5             =head1 NAME
6              
7             Parse::CSV::Colnames - Highly flexible CSV parser including column names (field names) manipulation
8              
9             =head1 NOTE
10              
11             This Module derives from L by Adam Kennedy inheriting its methods.
12             The main extensions are methods for column names manipulation and some simple method-fixes.
13              
14             =head1 SYNOPSIS
15              
16             Column names manipulation makes only sense if the fields-parameter is auto, i.e. column names are in the first line.
17              
18             # Parse a colon-separated variables file from a handle as a hash
19             # based on headers from the first line.
20             my $objects = Parse::CSV::Colnames->new(
21             handle => $io_handle,
22             sep_char => ';',
23             fields => 'auto',
24             # select only rows where column name fieldname is "value"
25             filter => sub { if($_->{fieldname} eq "value")
26             {$_} else
27             {undef}
28             }
29             );
30              
31             # get column names
32             my @fn=$objects->colnames
33             # you want lower case field names
34             @fn=map {lc} @fn;
35             # you want field names without blanks
36             @fn=map { s/\s+//g} @fn;
37             # set column names
38             $objects->colnames(@fn);
39              
40             while ( my $object = $objects->fetch ) {
41             $object->do_something;
42             }
43              
44             =head1 DESCRIPTION
45              
46             This module is only an extension of L
47              
48             For a detailed description of all methods see L
49              
50             For a detailed description of the underlying csv-parser see L
51              
52              
53             =cut
54              
55 2     2   75686 use 5.005;
  2         8  
  2         84  
56 2     2   11 use strict;
  2         3  
  2         64  
57 2     2   22 use Carp ();
  2         4  
  2         33  
58             #use IO::File ();
59             #use Text::CSV_XS ();
60             #use Params::Util qw{ _STRING _ARRAY _HASH0 _CODELIKE _HANDLE };
61              
62 2     2   1086 use Parse::CSV;
  2         31772  
  2         91  
63             our @ISA=("Parse::CSV");
64              
65 2     2   12 use vars qw{$VERSION};
  2         4  
  2         87  
66             BEGIN {
67 2     2   677 $VERSION = '0.05';
68             }
69              
70              
71              
72              
73              
74              
75              
76             =pod
77              
78             =head1 Fixed METHODS
79              
80             These methods have not work in the parent module L yet, because Adam Kennedy is very busy.
81              
82             =head2 combine
83              
84             $status = $csv->combine(@columns);
85              
86             The C method is passed through
87             to the underlying L object. See example 3.
88              
89             It sets the fields and constructs the corresponding csv string from the arguments. You can read this array with the C method.
90              
91             =cut
92              
93             sub combine {
94 1     1 1 13 shift->{csv_xs}->combine(@_);
95             }
96              
97             =pod
98              
99             =head2 string
100              
101             $line = $csv->string;
102              
103             The C method is passed through
104             to the underlying L object. See example 3 and example 4.
105              
106             It returns the parsed string or the corresponding combine-setting.
107              
108             =cut
109              
110             sub string {
111 1     1 1 2660 shift->{csv_xs}->string(@_);
112             }
113              
114             =pod
115              
116             =head2 print
117              
118             $status = $csv->print($io, $colref);
119              
120             The C method is passed through
121             to the underlying L object. See example 1.
122              
123             It prints the string of the corresponding @$colref directly to an IO handle.
124              
125              
126             =cut
127              
128             sub print {
129 0     0 1 0 shift->{csv_xs}->print(@_);
130             }
131              
132             =pod
133              
134             =head1 Added METHODS
135              
136             =head2 fields
137              
138             @fields = $csv->fields;
139              
140             The C method is passed through
141             to the underlying L object.
142              
143             It returns the input to C-method or the actual row as an array.
144              
145             =cut
146              
147             sub fields {
148 4     4 1 12228 shift->{csv_xs}->fields;
149             }
150              
151             =pod
152              
153             =head2 colnames
154              
155             @colnames = $csv->colnames("fn1","fn2") # sets colnames
156             or
157             @colnames = $csv->colnames; # gets colnames
158              
159             The C method sets or gets colnames (=C-param).
160             So you can rename the colnames (hash-keys in L object).
161              
162             =cut
163              
164             sub colnames {
165 3     3 1 641 my $self=shift;
166 3 50       14 $self->{fields}=$self->{names} if(exists($self->{names})); # quick and dirty
167 3 100       11 @{$self->{fields}}=@_ if(@_);
  1         6  
168 3         4 return @{$self->{fields}};
  3         25  
169             }
170              
171             =pod
172              
173             =head2 pushcolnames
174              
175             @colnames = $csv->pushcolnames("fn1","fn2")
176              
177             The C method adds colnames at the end of $csv->colnames (=C-param).
178             You can do that if the C-method adds some new fields at the end of fields-array in L object .
179             Please consider that these colnames or fields are not
180             in the underlying L object. See example 1 and example 4.
181              
182             =cut
183              
184             sub pushcolnames {
185 1     1 1 2 my $self=shift;
186 1 50       8 $self->{fields}=$self->{names} if(exists($self->{names})); # quick and dirty
187 1         2 push @{$self->{fields}},@_;
  1         3  
188 1         2 return @{$self->{fields}};
  1         7  
189             }
190              
191             =pod
192              
193             =head2 pushcombine
194              
195             @colnames = $csv->pushcombine("fn1","fn2")
196              
197             The C method adds fields at the end of the actual row (=C-method) and constructs the corresponding csv string.
198             You can read the result with the C-method.
199             The pushcombine and pushcolnames belong together. See example 4.
200              
201             =cut
202              
203             sub pushcombine {
204 1     1 1 2525 my $self=shift;
205 1         4 $self->combine($self->fields,@_);
206             }
207              
208             1;
209              
210             =pod
211              
212             =head1 EXAMPLES
213              
214             You can test these examples with copy and paste
215              
216             =cut
217              
218             =pod
219              
220             =head2 Example 1
221              
222             Using C<< csv->print >>, C<< csv->pushcolnames >>
223              
224              
225             #!/usr/bin/perl
226              
227             use strict;
228             use warnings;
229             use Parse::CSV::Colnames;
230             my $fh=\*DATA;
231             my $fhout=\*STDOUT; # only for demo
232             my $csv = Parse::CSV::Colnames->new(
233             #file => "testnamen.csv",
234             handle => $fh,
235             sep_char => ';',
236             fields => 'auto',
237             binary => 1, # for german umlauts and utf
238             filter => sub { $_->{country}="Germany";
239             $_->{product}=$_->{factor1}*$_->{factor2};
240             # select only rows where column name product>0
241             if($_->{product}>0) {
242             $_;
243             } else {
244             undef
245             }
246             }
247             );
248              
249             # add colnames at the end
250             $csv->pushcolnames(qw(product country));
251             # get column names
252             my @fn=$csv->colnames;
253             # you want lower case field names
254             @fn=map {lc} @fn;
255             # you want field names without blanks
256             map { s/\s+//g} @fn;
257             # set column names
258             $csv->colnames(@fn);
259              
260             # headerline for direct output
261             $csv->print($fhout,[$csv->colnames]); # print header-line
262             print "\n";
263              
264              
265             while(my $line=$csv->fetch) {
266             # csv direct output
267             $csv->print($fhout,[$csv->fields,$line->{product},$line->{country}]); # only input-fields are printed with method fields
268             print "\n";
269             }
270              
271             __DATA__
272             Name;Given Name;factor1;factor2
273             Hurtig;Hugo;5.4;4.6
274             Schnallnichts;Carlo;6.4;4.6
275             Weissnich;Carola;7.4;4.6
276             Leer;Hinnerk;0;4.6
277             Keine Ahnung;Maximilian;8.4;4.6
278            
279             =cut
280              
281             =pod
282              
283             =head2 Example 2
284              
285             Building new fields by hand with map
286              
287              
288              
289             #!/usr/bin/perl
290              
291             use strict;
292             use warnings;
293             use Parse::CSV::Colnames;
294             my $fh=\*DATA;
295             my $csv = Parse::CSV::Colnames->new(
296             #file => "testnamen.csv",
297             handle => $fh,
298             sep_char => ';',
299             fields => 'auto',
300             binary => 1, # for german umlauts
301             filter => sub { $_->{country}="Germany";
302             $_->{product}=$_->{factor1}*$_->{factor2};
303             # select only rows where column name product>0
304             if($_->{product}>0) {
305             $_;
306             } else {
307             undef
308             }
309             }
310             );
311             #add new fieldname at the end
312             $csv->pushcolnames(qw(product));
313             # get column names
314             my @fn=$csv->colnames;
315             # you want lower case field names
316             @fn=map {lc} @fn;
317             # you want field names without blanks
318             map { s/\s+//g} @fn;
319             # set column names
320             $csv->colnames(@fn);
321              
322             # headerline with only 2 fields
323             my @outcolnames1=(qw(givenname product));
324             print join(";",@outcolnames1) . "\n";
325              
326              
327             while(my $line=$csv->fetch) {
328             print join(";",map {$line->{$_}} @outcolnames1) . "\n";
329              
330             }
331              
332             __DATA__
333             Name;Given Name;factor1;factor2
334             Hurtig;Hugo;5.4;4.6
335             Schnallnichts;Carlo;6.4;4.6
336             Weissnich;Carola;7.4;4.6
337             Leer;Hinnerk;0;4.6
338             Keine Ahnung;Maximilian;8.4;4.6
339              
340             =cut
341              
342              
343             =pod
344              
345             =head2 Example 3
346              
347             Using C<< csv->combine >> and C<< csv->string >>
348              
349              
350             #!/usr/bin/perl
351              
352             use strict;
353             use warnings;
354             use Parse::CSV::Colnames;
355             my $fh=\*DATA;
356             my $csv = Parse::CSV::Colnames->new(
357             #file => "testnamen.csv",
358             handle => $fh,
359             sep_char => ';',
360             fields => 'auto',
361             binary => 1, # for german umlauts
362             filter => sub { $_->{country}="Germany";
363             $_->{product}=$_->{factor1}*$_->{factor2};
364             # select only rows where column name product>0
365             if($_->{product}>0) {
366             $_;
367             } else {
368             undef
369             }
370             }
371             );
372             $csv->pushcolnames(qw(product country));
373             # get column names
374             my @fn=$csv->colnames;
375             # you want lower case field names
376             @fn=map {lc} @fn;
377             # you want field names without blanks
378             map { s/\s+//g} @fn;
379             # set column names
380             $csv->colnames(@fn);
381              
382             # headerline
383             my @outcolnames2=(qw(givenname product country));
384             $csv->combine(@outcolnames2);
385             print $csv->string . "\n";
386              
387              
388             while(my $line=$csv->fetch) {
389             # csv output
390             $csv->combine(map {$line->{$_}} @outcolnames2);
391             print $csv->string . "\n";
392              
393              
394             }
395              
396              
397             __DATA__
398             Name;Given Name;factor1;factor2
399             Hurtig;Hugo;5.4;4.6
400             Schnallnichts;Carlo;6.4;4.6
401             Weissnich;Carola;7.4;4.6
402             Leer;Hinnerk;0;4.6
403             Keine Ahnung;Maximilian;8.4;4.6
404              
405             =cut
406              
407              
408             =pod
409              
410             =head2 Example 4
411              
412             Using C<< csv->pushcombine >> , C<< csv->pushcolnames >> and C<< csv->string >>
413              
414              
415             #!/usr/bin/perl
416              
417             use strict;
418             use warnings;
419             use Parse::CSV::Colnames;
420             my $fh=\*DATA;
421             my $csv = Parse::CSV::Colnames->new(
422             #file => "testnamen.csv",
423             handle => $fh,
424             sep_char => ';',
425             fields => 'auto',
426             binary => 1, # for german umlauts
427             filter => sub { $_->{country}="Germany";
428             $_->{product}=$_->{factor1}*$_->{factor2};
429             # select only rows where column name product>0
430             if($_->{product}>0) {
431             $_;
432             } else {
433             undef
434             }
435             }
436             );
437             $csv->pushcolnames(qw(product country));
438             # get column names
439             my @fn=$csv->colnames;
440             # you want lower case field names
441             @fn=map {lc} @fn;
442             # you want field names without blanks
443             map { s/\s+//g} @fn;
444             # set column names
445             $csv->colnames(@fn);
446              
447             # headerline
448             $csv->combine($csv->colnames);
449             print $csv->string . "\n";
450              
451              
452             while(my $line=$csv->fetch) {
453             # csv output
454             $csv->pushcombine(map {$line->{$_}} qw(product country));
455             # is like
456             $csv->pushcombine($line->{product},$line->{country});
457            
458             print $csv->string . "\n";
459              
460              
461             }
462              
463              
464             __DATA__
465             Name;Given Name;factor1;factor2
466             Hurtig;Hugo;5.4;4.6
467             Schnallnichts;Carlo;6.4;4.6
468             Weissnich;Carola;7.4;4.6
469             Leer;Hinnerk;0;4.6
470             Keine Ahnung;Maximilian;8.4;4.6
471              
472             =cut
473              
474             =pod
475              
476             =head1 TODO
477              
478             Creating Methods C and C. These methods delete the last fieldnames (column names) or fields. (I will add these methods if anybody wants this)
479              
480             Creating Methods C<(un)shiftcolnames> and C<(un)shiftcombine>. These methods add/delete the first fieldnames (column names) or fields. (I will add these methods if anybody wants this)
481              
482             Integrating methods C and C of the underlying object L.
483              
484             =head1 SUPPORT
485              
486             Bugs should always be reported via the CPAN bug tracker at
487              
488             L
489              
490              
491             =head1 AUTHORS
492              
493             Uwe Sarnowski Euwes at cpan.orgE
494              
495             Author of the parent modul L : Adam Kennedy
496              
497              
498             =head1 SEE ALSO
499              
500             L, L
501              
502             =head1 COPYRIGHT
503              
504             Copyright 2011 Uwe Sarnowski
505              
506             This program is free software; you can redistribute
507             it and/or modify it under the same terms as Perl itself.
508              
509             The full text of the license can be found in the
510             LICENSE file included with this module.
511              
512             =cut