File Coverage

blib/lib/App/RecordStream/Operation/decollate.pm
Criterion Covered Total %
statement 57 75 76.0
branch 4 8 50.0
condition 0 3 0.0
subroutine 13 20 65.0
pod 0 7 0.0
total 74 113 65.4


line stmt bran cond sub pod time code
1             package App::RecordStream::Operation::decollate;
2              
3 2     2   969 use strict;
  2         4  
  2         49  
4 2     2   9 use warnings;
  2         5  
  2         41  
5              
6 2     2   613 use App::RecordStream::Deaggregator;
  2         6  
  2         37  
7 2     2   380 use App::RecordStream::DomainLanguage::Library;
  2         5  
  2         63  
8 2     2   16 use App::RecordStream::DomainLanguage;
  2         4  
  2         49  
9 2     2   10 use App::RecordStream::Operation;
  2         4  
  2         31  
10 2     2   8 use App::RecordStream::Record;
  2         4  
  2         47  
11              
12 2     2   10 use base 'App::RecordStream::Operation';
  2         5  
  2         1299  
13              
14             sub init
15             {
16 6     6 0 11 my $this = shift;
17 6         11 my $args = shift;
18              
19 6         44 App::RecordStream::Deaggregator->load_implementations();
20              
21 6         45960 my @deaggregators;
22             my @dldeaggregators;
23 6         14 my $list_deaggregators = 0;
24 6         10 my $deaggregator = 0;
25              
26             my $spec =
27             {
28 7     7   4309 "deaggregator|d=s" => sub { push @deaggregators, split(/:/, $_[1]); },
29 0     0   0 "dldeaggregator=s" => sub { push @dldeaggregators, build_dldeaggregator($_[1]); },
30 6         46 "list-deaggregators" => \$list_deaggregators,
31             "show-deaggregator=s" => \$deaggregator,
32             };
33              
34 6         33 $this->parse_options($args, $spec);
35              
36 6 50       18 if($list_deaggregators)
37             {
38 0     0   0 die sub { print App::RecordStream::Deaggregator->list_implementations(); };
  0         0  
39             }
40              
41 6 50       14 if($deaggregator)
42             {
43 0     0   0 die sub { App::RecordStream::Deaggregator->show_implementation($deaggregator) };
  0         0  
44             }
45              
46 6         11 my @deaggregator_objects;
47 6         11 for my $spec (@deaggregators)
48             {
49 7         35 push @deaggregator_objects, App::RecordStream::Deaggregator->make_deaggregator($spec);
50             }
51              
52 6         17 @deaggregator_objects = (@deaggregator_objects, @dldeaggregators);
53              
54 6         64 $this->{'DEAGGREGATORS'} = \@deaggregator_objects;
55             }
56              
57             sub build_dldeaggregator
58             {
59 0     0 0 0 my $string = shift;
60              
61 0         0 return App::RecordStream::DomainLanguage::Snippet->new($string)->evaluate_as('DEAGGREGATOR');
62             }
63              
64             sub accept_record
65             {
66 11     11 0 18 my $this = shift;
67 11         17 my $record = shift;
68              
69 11         34 $this->accept_record_aux(0, $record);
70              
71 11         73 return 1;
72             }
73              
74             sub accept_record_aux
75             {
76 50     50 0 77 my $this = shift;
77 50         80 my $depth = shift;
78 50         73 my $record = shift;
79              
80 50 100       81 if($depth < @{$this->{'DEAGGREGATORS'}})
  50         117  
81             {
82 17         33 my $deaggregator = $this->{'DEAGGREGATORS'}->[$depth];
83              
84 17         26 for my $deaggregated_record (@{$deaggregator->deaggregate($record)})
  17         58  
85             {
86 39         207 $this->accept_record_aux($depth + 1, App::RecordStream::Record->new({%$record, %$deaggregated_record}));
87             }
88             }
89             else
90             {
91 33         91 $this->push_record($record);
92             }
93             }
94              
95             sub print_usage
96             {
97 0     0 0 0 my $this = shift;
98 0         0 my $message = shift;
99              
100 0 0 0     0 if($message && UNIVERSAL::isa($message, 'CODE')) {
101 0         0 $message->();
102 0         0 exit(1);
103             }
104              
105 0         0 $this->SUPER::print_usage($message);
106             }
107              
108             sub add_help_types
109             {
110 6     6 0 11 my $this = shift;
111 6         25 $this->use_help_type('domainlanguage');
112             $this->add_help_type(
113             'deaggregators',
114 0     0     sub { print App::RecordStream::Deaggregator->list_implementations(); },
115 6         30 'List the deaggregators'
116             );
117             }
118              
119             sub usage {
120 0     0 0   my $this = shift;
121              
122 0           my $options = [
123             [ 'dldeaggregator ...', 'Specify a domain language aggregate. See "Domain Language Integration" below.'],
124             [ 'deaggregator|-d ', 'Colon separated list of aggregate field specifiers. See "Deaggregates" section below.'],
125             [ 'list-deaggregators', 'Bail and output a list of deaggregators.'],
126             [ 'show-deaggregator ', 'Bail and output this deaggregator\'s detailed usage.'],
127             ];
128              
129 0           my $args_string = $this->options_string($options);
130             return <
131             Usage: recs-decollate []
132             __FORMAT_TEXT__
133             Decollate records of input (or records from ) into output records.
134             __FORMAT_TEXT__
135              
136             Arguments:
137             $args_string
138              
139             Deaggregates:
140             __FORMAT_TEXT__
141             Deaggregates are specified as [,]. See
142             --list-deaggregators for a list of available deaggregators.
143              
144             In general, key name arguments to deaggregators may be key specs, but not
145             key groups
146             __FORMAT_TEXT__
147              
148             Domain Lanuage Integration:
149             USAGE
150 0           . App::RecordStream::DomainLanguage::short_usage()
151             . <
152              
153             __FORMAT_TEXT__
154             Deaggregates may be specified using the recs domain language.
155             --dldeaggregator requires the code evaluate as a deaggregator.
156              
157             See --help-domainlanguage for a more complete description of its workings
158             and a list of available functions.
159              
160             See the examples below for a more gentle introduction.
161             __FORMAT_TEXT__
162              
163             Examples:
164             Split the "hosts" field into individual "host" fields
165             recs-decollate --dldeaggregator '_split(hosts,qr/, */,host)'
166             USAGE
167             ;
168             }
169              
170             1;