File Coverage

blib/lib/App/RecordStream/Operation/tocsv.pm
Criterion Covered Total %
statement 51 55 92.7
branch 7 8 87.5
condition n/a
subroutine 10 11 90.9
pod 0 5 0.0
total 68 79 86.0


line stmt bran cond sub pod time code
1             package App::RecordStream::Operation::tocsv;
2              
3             our $VERSION = "4.0.25";
4              
5 2     2   841 use strict;
  2         4  
  2         44  
6              
7 2     2   7 use base qw(App::RecordStream::Operation);
  2         2  
  2         128  
8              
9 2     2   9 use App::RecordStream::Record;
  2         3  
  2         24  
10 2     2   481 use Text::CSV;
  2         12668  
  2         707  
11              
12             sub init {
13 5     5 0 5 my $this = shift;
14 5         6 my $args = shift;
15              
16 5         5 my $header = 1;
17 5         17 my $key_groups = App::RecordStream::KeyGroups->new();
18 5         6 my $delim = ',';
19             my $spec = {
20 3     3   1510 "key|k=s" => sub { $key_groups->add_groups($_[1]); },
21 1     1   456 "noheader|nh" => sub { $header = 0 },
22 5         23 "delim|d=s" => \$delim,
23             };
24              
25 5         17 $this->parse_options($args, $spec);
26 5         9 $this->{'KEY_GROUPS'} = $key_groups;
27              
28 5 50       10 die "Delimiter must be a single character\n\n"
29             unless length $delim == 1;
30              
31             # binary => 1 is to handle new lines in field values
32 5         22 $this->{'CSV'} = Text::CSV->new({
33             binary => 1,
34             sep_char => $delim,
35             });
36              
37 5         487 $this->{'FIRST'} = 1;
38 5         40 $this->{'HEADERS'} = $header;
39             };
40              
41             sub accept_record {
42 25     25 0 28 my $this = shift;
43 25         26 my $record = shift;
44              
45 25 100       37 if ( $this->{'FIRST'} ) {
46 5         6 $this->{'FIRST'} = 0;
47              
48 5 100       11 if ( $this->{'KEY_GROUPS'}->has_any_group() ) {
49 3         6 $this->{'KEYS'} = $this->{'KEY_GROUPS'}->get_keyspecs($record);
50             }
51             else {
52 2         9 $this->{'KEYS'} = [sort keys %$record];
53             }
54              
55 5 100       9 if ( $this->{'HEADERS'} ) {
56 4         10 $this->output_values($this->{'KEYS'});
57             }
58             }
59              
60 25         26 my @values;
61 25         28 foreach my $key (@{$this->{'KEYS'}}) {
  25         38  
62 45         49 push @values, ${$record->guess_key_from_spec($key)};
  45         78  
63             }
64              
65 25         54 $this->output_values(\@values);
66              
67 25         90 return 1;
68             }
69              
70             sub output_values {
71 29     29 0 33 my $this = shift;
72 29         29 my $values = shift;
73              
74 29         31 my $csv = $this->{'CSV'};
75 29         75 $csv->combine(@$values);
76 29         339 $this->push_line($csv->string());
77             }
78              
79             sub add_help_types {
80 5     5 0 8 my $this = shift;
81 5         12 $this->use_help_type('keyspecs');
82 5         10 $this->use_help_type('keygroups');
83 5         6 $this->use_help_type('keys');
84             }
85              
86             sub usage {
87 0     0 0   my $this = shift;
88              
89 0           my $options = [
90             ['noheader|--nh', 'Do not output headers on the first line'],
91             ['key|-k ', 'Comma separated keys to output. Defaults to all fields in first record. May be a keyspec, may be a keyspec group'],
92             ['delim|-d ', "Field delimiter to use when outputting lines (default ',')."],
93             ];
94              
95 0           my $args_string = $this->options_string($options);
96              
97 0           return <
98             Usage: recs-tocsv [files]
99             __FORMAT_TEXT__
100             This script outputs csv formatted recs. With the --delim option, it can
101             output tsv or other line-based formats with character-separated fields.
102             __FORMAT_TEXT__
103              
104             Arguments:
105             $args_string
106              
107             Examples
108             # Print records to csv format with headers
109             recs-tocsv myrecords
110              
111             # Only print time and a nested value of stat/avg
112             ... | recs-tocsv --key time,stat/avg
113             USAGE
114             }
115              
116             1;