File Coverage

blib/lib/App/RecordStream/Operation/fromkv.pm
Criterion Covered Total %
statement 49 53 92.4
branch 8 10 80.0
condition n/a
subroutine 9 10 90.0
pod 0 6 0.0
total 66 79 83.5


line stmt bran cond sub pod time code
1             package App::RecordStream::Operation::fromkv;
2              
3             our $VERSION = "4.0.24";
4              
5 2     2   762 use strict;
  2         2  
  2         52  
6              
7 2     2   9 use base qw(App::RecordStream::Operation);
  2         3  
  2         107  
8              
9 2     2   10 use strict;
  2         4  
  2         28  
10 2     2   6 use warnings;
  2         4  
  2         836  
11              
12             sub init {
13 3     3 0 4 my $this = shift;
14 3         6 my $args = shift;
15              
16 3         4 my $kv_delim = " ";
17 3         5 my $entry_delim = "\n";
18 3         6 my $record_delim = "END\n";
19              
20 3         8 my $spec = {
21             "kv-delim|f=s" => \$kv_delim,
22             "entry-delim|e=s" => \$entry_delim,
23             "record-delim|r=s" => \$record_delim,
24             };
25              
26 3         11 $this->parse_options($args, $spec);
27              
28 3         9 $this->{'KV_DELIM'} = $kv_delim;
29 3         5 $this->{'ENTRY_DELIM'} = $entry_delim;
30 3         7 $this->{'RECORD_DELIM'} = $record_delim;
31 3         18 $this->{'ACC'} = undef;
32             }
33              
34              
35             sub wants_input {
36 6     6 0 25 return 1;
37             }
38              
39             sub stream_done {
40 3     3 0 4 my $this = shift;
41              
42 3         7 my $acc = $this->{'ACC'};
43 3 50       6 if(defined($acc)) {
44 3         7 $this->process_record($acc);
45             }
46             }
47              
48             sub accept_line {
49 12     12 0 19 my $this = shift;
50 12         15 my $line = shift;
51              
52 12 100       20 if(!defined($this->{'ACC'})) {
53 3         7 $this->{'ACC'} = '';
54             }
55 12         24 $this->{'ACC'} .= "$line\n";
56              
57 12         16 my $record_delim = $this->{'RECORD_DELIM'};
58              
59 12 100       79 if($this->{'ACC'} =~ s/^(.*?)\Q$record_delim\E//s) {
60 5         13 $this->process_record($1);
61             }
62              
63 12         38 return 1;
64             }
65              
66             sub process_record {
67 8     8 0 12 my $this = shift;
68 8         14 my $line = shift;
69              
70 8         14 my $kv_delim = $this->{'KV_DELIM'};
71 8         10 my $entry_delim = $this->{'ENTRY_DELIM'};
72              
73             # trim trailing and leading whitespace from record
74 8         27 $line =~ s/^\s+|\s+$//g;
75              
76 8         35 my @entries = split(/\Q$entry_delim\E/, $line);
77              
78 8 100       22 if (scalar(@entries) > 0) {
79 6         9 my $current_record = {};
80              
81 6         11 for my $entry (@entries) {
82 18         97 my @pair = split($kv_delim, $entry);
83              
84 18 50       57 $current_record->{$pair[0]} = $pair[1] if scalar(@pair) == 2;
85             }
86              
87 6         26 $this->push_record(App::RecordStream::Record->new($current_record));
88             }
89             }
90              
91             sub usage
92             {
93 0     0 0   my $this = shift;
94              
95 0           my $options = [
96             [ 'record-delim|r ', 'Delimiter to for separating records (defaults to "END\\n").'],
97             [ 'entry-delim|e ', 'Delimiter to for separating entries within records (defaults to "\\n").'],
98             [ 'kv-delim|f ', 'Delimiter to for separating key/value pairs within an entry (defaults to " ").'],
99             ];
100              
101 0           my $args_string = $this->options_string($options);
102              
103 0           return <
104             Usage : recs-fromkv []
105             __FORMAT_TEXT__
106             Records are generated from character input with the form "...".
107             Records have the form "...". Entries are pairs of the form
108             "".
109             __FORMAT_TEXT__
110              
111             Arguments:
112             $args_string
113              
114             Examples:
115             Parse memcached stat metrics into records
116             echo -ne 'stats\\r\\n' | nc -i1 localhost 11211 | tr -d "\\r" | awk '{if (! /END/) {print \$2" "\$3} else {print \$0}}' | recs-fromkv
117              
118             Parse records separated by "E\\n" with entries separated by '\|' and pairs separated by '='
119             recs-fromkv --kv-delim '=' --entry-delim '\|' --record-delim \$(echo -ne "E\\n")
120              
121             Parse records separated by "%\\n" with entries separated by "\\n" and pairs separated by '='
122             recs-fromkv --kv-delim '=' --record-delim \$(echo -ne "%\\n")
123              
124             Parse records separated by '%' with entries separated by '\|' and pairs separated by '='
125             recs-fromkv --kv-delim '=' --entry-delim '\|' --record-delim '%'
126             USAGE
127             }
128              
129             1;