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.24";
4              
5 2     2   813 use strict;
  2         4  
  2         53  
6              
7 2     2   10 use base qw(App::RecordStream::Operation);
  2         3  
  2         158  
8              
9 2     2   13 use App::RecordStream::Record;
  2         4  
  2         35  
10 2     2   467 use Text::CSV;
  2         15949  
  2         908  
11              
12             sub init {
13 5     5 0 14 my $this = shift;
14 5         14 my $args = shift;
15              
16 5         10 my $header = 1;
17 5         43 my $key_groups = App::RecordStream::KeyGroups->new();
18 5         12 my $delim = ',';
19             my $spec = {
20 3     3   2082 "key|k=s" => sub { $key_groups->add_groups($_[1]); },
21 1     1   1454 "noheader|nh" => sub { $header = 0 },
22 5         60 "delim|d=s" => \$delim,
23             };
24              
25 5         33 $this->parse_options($args, $spec);
26 5         16 $this->{'KEY_GROUPS'} = $key_groups;
27              
28 5 50       21 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         60 $this->{'CSV'} = Text::CSV->new({
33             binary => 1,
34             sep_char => $delim,
35             });
36              
37 5         854 $this->{'FIRST'} = 1;
38 5         72 $this->{'HEADERS'} = $header;
39             };
40              
41             sub accept_record {
42 25     25 0 43 my $this = shift;
43 25         37 my $record = shift;
44              
45 25 100       58 if ( $this->{'FIRST'} ) {
46 5         18 $this->{'FIRST'} = 0;
47              
48 5 100       25 if ( $this->{'KEY_GROUPS'}->has_any_group() ) {
49 3         14 $this->{'KEYS'} = $this->{'KEY_GROUPS'}->get_keyspecs($record);
50             }
51             else {
52 2         24 $this->{'KEYS'} = [sort keys %$record];
53             }
54              
55 5 100       23 if ( $this->{'HEADERS'} ) {
56 4         14 $this->output_values($this->{'KEYS'});
57             }
58             }
59              
60 25         38 my @values;
61 25         40 foreach my $key (@{$this->{'KEYS'}}) {
  25         63  
62 45         69 push @values, ${$record->guess_key_from_spec($key)};
  45         120  
63             }
64              
65 25         86 $this->output_values(\@values);
66              
67 25         139 return 1;
68             }
69              
70             sub output_values {
71 29     29 0 48 my $this = shift;
72 29         42 my $values = shift;
73              
74 29         59 my $csv = $this->{'CSV'};
75 29         95 $csv->combine(@$values);
76 29         529 $this->push_line($csv->string());
77             }
78              
79             sub add_help_types {
80 5     5 0 14 my $this = shift;
81 5         31 $this->use_help_type('keyspecs');
82 5         23 $this->use_help_type('keygroups');
83 5         18 $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;