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