File Coverage

blib/lib/Tapper/Reports/Web/Controller/Tapper/Metareports.pm
Criterion Covered Total %
statement 83 665 12.4
branch 0 178 0.0
condition 0 78 0.0
subroutine 28 65 43.0
pod 0 23 0.0
total 111 1009 11.0


line stmt bran cond sub pod time code
1             package Tapper::Reports::Web::Controller::Tapper::Metareports;
2             our $AUTHORITY = 'cpan:TAPPER';
3             $Tapper::Reports::Web::Controller::Tapper::Metareports::VERSION = '5.0.14';
4             # ABSTRACT: Tapper - Catalyst Controller Metareports
5              
6 10     10   8529 use strict;
  10         43  
  10         371  
7 10     10   67 use warnings;
  10         31  
  10         357  
8 10     10   63 use parent 'Tapper::Reports::Web::Controller::Base';
  10         25  
  10         98  
9              
10 10     10   855 use Try::Tiny;
  10         31  
  10         765  
11 10     10   96 use List::MoreUtils qw( any );
  10         32  
  10         208  
12              
13 10     10   8264 use 5.010;
  10         42  
14              
15             sub index :Path :Args() {
16              
17 0     0   0 my ( $self, $c, @args ) = @_;
18              
19 0         0 $c->go('/tapper/metareports/chart_overview');
20              
21 10     10   96 }
  10         33  
  10         77  
22              
23             sub auto : Private {
24              
25 0     0 0 0 my ( $self, $or_c ) = @_;
26              
27             # set js, csss file
28 0         0 push @{$or_c->stash->{js_files}}, '/tapper/static/js/metareports.js';
  0         0  
29 0         0 push @{$or_c->stash->{css_files}}, '/tapper/static/css/metareports/default.css';
  0         0  
30              
31 0         0 $or_c->forward('/tapper/metareports/prepare_navi');
32 10     10   136154 }
  10         34  
  10         62  
33              
34             sub hr_get_search : Private {
35              
36 0     0 0 0 my ( $or_schema, $hr_params ) = @_;
37              
38 0         0 my ( $hr_search, $ar_join ) = ({},[]);
39 0 0       0 if ( $hr_params->{chart_tiny_url} ) {
    0          
40 0         0 $hr_search->{chart_tiny_url_id} = $hr_params->{chart_tiny_url};
41 0         0 push @{$ar_join}, { 'chart_lines' => 'chart_tiny_url_lines' };
  0         0  
42             }
43             elsif ( $hr_params->{chart_id} ) {
44 0 0       0 if (! $hr_params->{chart_version} ) {
45             $hr_params->{chart_version} = $or_schema->resultset('ChartVersions')
46             ->search({
47             chart_id => $hr_params->{chart_id}
48             })
49 0         0 ->get_column('chart_version')
50             ->max();
51             }
52 0         0 $hr_search->{'me.chart_id'} = $hr_params->{chart_id} ;
53 0         0 $hr_search->{'me.chart_version'} = $hr_params->{chart_version};
54             }
55             else {
56 0         0 return;
57             }
58              
59 0         0 return ( $hr_search, $ar_join );
60              
61 10     10   12335 }
  10         26  
  10         60  
62              
63             sub detail : Local {
64              
65 0     0 0 0 my ( $or_self, $or_c ) = @_;
66              
67 0         0 $or_c->stash->{head_overview} = 'Metareports - Detail';
68              
69             # set css file
70 0         0 push @{$or_c->stash->{css_files}},
  0         0  
71             '/tapper/static/css/metareports/detail.css',
72             , '/tapper/static/css/jquery-ui/jquery.ui.css'
73             , '/tapper/static/css/jquery-ui/jquery.ui.core.css'
74             , '/tapper/static/css/jquery-ui/jquery.ui.datepicker.css'
75             ;
76              
77             # set js file
78 0         0 push @{$or_c->stash->{js_files}},
  0         0  
79             '/tapper/static/js/jquery-ui/jquery.ui.core.js'
80             , '/tapper/static/js/jquery-ui/jquery.ui.effect.js'
81             , '/tapper/static/js/jquery-ui/jquery.ui.datepicker.js'
82             , '/tapper/static/js/jquery-ui/jquery.ui.effect-slide.js'
83             , '/tapper/static/js/metareports.js'
84             , '/tapper/static/js/jquery-plugins/jquery.json.js'
85             , '/tapper/static/js/jquery-plugins/jquery.flot.js'
86             , '/tapper/static/js/jquery-plugins/jquery.flot.time.js'
87             , '/tapper/static/js/jquery-plugins/jquery.flot.selection.js'
88             , '/tapper/static/js/jquery-plugins/jquery.timepicker.js'
89             ;
90              
91 0         0 my $hr_params = $or_c->req->params;
92 0         0 my $or_schema = $or_c->model('TestrunDB');
93              
94 0         0 my ( $hr_search, $ar_join ) = hr_get_search( $or_schema, $hr_params );
95 0 0       0 if ( $hr_search ) {
96              
97 0         0 $or_c->stash->{chart} = $or_schema
98             ->resultset('ChartVersions')
99             ->search(
100             $hr_search,
101             {
102             join => $ar_join,
103             prefetch => [
104             {
105             'chart_lines' => {
106             'chart_line_restrictions' => 'chart_line_restriction_values',
107             },
108             },{
109             'chart' => [
110             'chart_versions',
111             { 'chart_tag_relations' => 'chart_tag', },
112             ],
113             },
114             ],
115             }
116             )
117             ->first()
118             ;
119              
120             # check for template parameter
121 0         0 my %h_restriction_values;
122 0 0       0 for my $or_chart_line ( $or_c->stash->{chart} ? $or_c->stash->{chart}->chart_lines : () ) {
123 0         0 for my $or_restriction ( $or_chart_line->chart_line_restrictions ) {
124 0 0       0 if ( $or_restriction->is_template_restriction ) {
125 0         0 my $s_restricted_value =
126             ($or_restriction->chart_line_restriction_values)[0]->chart_line_restriction_value
127             ;
128 0 0       0 if ( $hr_params->{$s_restricted_value} ) {
129 0         0 $h_restriction_values{$s_restricted_value} = $hr_params->{$s_restricted_value};
130             }
131             else {
132 0         0 $or_c->stash->{error} = "Missing restricted value '$s_restricted_value'";
133             }
134             }
135             }
136             }
137 0 0       0 if ( %h_restriction_values ) {
138 0         0 $or_c->stash->{parameter_restriction_values} = \%h_restriction_values;
139             }
140              
141             }
142              
143 0         0 return 1;
144              
145 10     10   13623 }
  10         33  
  10         59  
146              
147             sub chart_overview : Local {
148              
149 0     0 0 0 my ( $or_self, $or_c ) = @_;
150              
151             # set css file
152 0         0 push @{$or_c->stash->{css_files}},
  0         0  
153             '/tapper/static/css/metareports/chart_overview.css'
154             ;
155              
156             # set js file
157 0         0 push @{$or_c->stash->{js_files}},
  0         0  
158             '/tapper/static/js/metareports.js'
159             , '/tapper/static/js/jquery-plugins/jquery.flot.js'
160             , '/tapper/static/js/jquery-plugins/jquery.flot.time.js'
161             ;
162              
163 0         0 my $hr_where = {
164             'me.active' => 1,
165             'chart_versions.chart_version' => \" = (
166             SELECT MAX(cv.chart_version)
167             FROM chart_versions cv
168             WHERE cv.chart_id = chart_versions.chart_id
169             )",
170             };
171 0         0 my $hr_options = {
172             order_by => {
173             -asc => 'chart_versions.chart_name'
174             },
175             join => [
176             {
177             'chart_versions' => {
178             'chart_lines' => {
179             'chart_line_restrictions' => 'chart_line_restriction_values',
180             },
181             },
182             },
183             ],
184             prefetch => {
185             'chart_versions' => {
186             'chart_lines' => {
187             'chart_line_restrictions' => 'chart_line_restriction_values',
188             },
189             },
190             },
191             };
192              
193 0         0 my $i_chart_tag = $or_c->req->params->{chart_tag};
194 0 0 0     0 if ( defined($i_chart_tag) && $i_chart_tag ne '0' ) {
195 0         0 $hr_where->{'chart_tag_relations.chart_tag_id'} = $i_chart_tag;
196 0         0 push @{$hr_options->{join}}, 'chart_tag_relations';
  0         0  
197             }
198              
199 0         0 $or_c->stash->{head_overview} = 'Metareports - Overview';
200             $or_c->stash->{charts} = [
201 0         0 $or_c->model('TestrunDB')->resultset('Charts')->search(
202             $hr_where, $hr_options,
203             )
204             ];
205              
206 0         0 return 1;
207              
208 10     10   12537 }
  10         41  
  10         60  
209              
210             sub get_chart_points : Local {
211              
212 0     0 0 0 my ( $or_self, $or_c ) = @_;
213              
214 0         0 my %h_params = %{$or_c->req->params};
  0         0  
215 0         0 my $or_schema = $or_c->model('TestrunDB');
216              
217             # get chart information
218 0         0 my ( $hr_search, $ar_join ) = hr_get_search( $or_schema, \%h_params );
219 0 0       0 if (! $hr_search ) {
220 0         0 $or_c->res->status( 500 );
221 0         0 $or_c->stash->{content} = { error => 'cannot create search condition' };
222             }
223              
224 0         0 my $or_chart = $or_schema->resultset('ChartVersions')->search(
225             $hr_search,
226             {
227             join => $ar_join,
228             prefetch => [
229             {
230             'chart_lines' => [
231             'chart_additionals',
232             {
233             'chart_line_restrictions' => 'chart_line_restriction_values',
234             },
235             {
236             'chart_axis_elements' => [
237             'axis_column',
238             'axis_separator',
239             ],
240             },
241             ],
242             },
243             'chart_markings',
244             'chart_axis_type_x',
245             'chart_axis_type_y',
246             'chart_type',
247             ],
248             }
249             )->first();
250              
251 0         0 my %h_axis = ( x => {}, y => {}, );
252 0         0 my ( @a_first, @a_last, @a_result, @a_markings, @a_chart_line_point_warnings );
253              
254             # update tiny url counter if exists
255 0         0 my $or_tiny_url;
256 0         0 my $NOW = DateTime->now();
257 0 0       0 if ( my $i_chart_tiny_url_id = $h_params{chart_tiny_url} ) {
258 0         0 $or_tiny_url = $or_schema
259             ->resultset('ChartTinyUrls')
260             ->search({
261             'me.chart_tiny_url_id' => $i_chart_tiny_url_id,
262             },{
263             rows => 1,
264             prefetch => {
265             chart_tiny_url_line => 'chart_tiny_url_relation'
266             },
267             })
268             ->first()
269             ;
270 0 0       0 if ($or_tiny_url) {
271 0         0 $or_tiny_url->visit_count( $or_tiny_url->visit_count() + 1 );
272 0         0 $or_tiny_url->last_visited($NOW);
273 0         0 $or_tiny_url->update();
274 0         0 $or_c->stash->{tiny_url_count} = $or_tiny_url->visit_count;
275             }
276             }
277              
278 0 0       0 if ( my @a_chart_lines = $or_chart->chart_lines ) {
279              
280 0         0 require JSON::XS;
281 0         0 require YAML::Syck;
282 0         0 require Tapper::Config;
283 0         0 require BenchmarkAnything::Storage::Frontend::Lib;
284              
285             my $balib = BenchmarkAnything::Storage::Frontend::Lib->new
286 0         0 (cfgfile => Tapper::Config->subconfig->{_last_used_tapper_config_file});
287              
288 0         0 require DateTime;
289 0         0 require DateTime::Format::Epoch;
290 0         0 require DateTime::Format::Strptime;
291 0         0 my $formatter = DateTime::Format::Epoch->new(
292             epoch => DateTime->new( year => 1970, month => 1, day => 1 ),
293             unit => 'milliseconds',
294             type => 'int', # or 'float', 'bigint'
295             skip_leap_seconds => 1,
296             start_at => 0,
297             local_epoch => undef,
298             );
299              
300 0         0 my %h_counter = (
301             x => 0 ,
302             y => 0,
303             );
304 0         0 my %h_axis_type = (
305             x => $or_chart->chart_axis_type_x->chart_axis_type_name,
306             y => $or_chart->chart_axis_type_y->chart_axis_type_name,
307             );
308             my %h_label_type = (
309             x => $h_axis_type{x} eq 'alphanumeric' || $or_chart->order_by_x_axis == 2 && $or_chart->order_by_y_axis == 1 ? 'list' : 'auto',
310 0 0 0     0 y => $h_axis_type{y} eq 'alphanumeric' || $or_chart->order_by_y_axis == 2 && $or_chart->order_by_x_axis == 1 ? 'list' : 'auto',
    0 0        
311             );
312              
313 0 0 0     0 $h_params{limit} ||= $h_params{graph_width} ? int( $h_params{graph_width} / 4 ) : 100;
314              
315 0 0       0 if ( $h_params{pager_direction} ) {
316 0 0       0 if ( $h_params{pager_direction} eq 'prev' ) {
317 0         0 $h_params{offset} = $h_params{offset};
318             }
319             else {
320 0         0 $h_params{offset} = $h_params{offset} - ( $h_params{limit} * 2 );
321             }
322             }
323             else {
324 0         0 $h_params{offset} = 0;
325             }
326              
327 0         0 CHART_LINE: for my $or_chart_line ( @a_chart_lines ) {
328              
329 0         0 my @a_additionals;
330 0         0 my $b_value_id_exists = 0;
331 0         0 for my $or_additional_column ( $or_chart_line->chart_additionals ) {
332 0 0       0 if ( $or_additional_column->chart_line_additional_column eq 'VALUE_ID' ) {
333 0         0 $b_value_id_exists = 1;
334             }
335 0         0 push @a_additionals, [
336             $or_additional_column->chart_line_additional_column,
337             $or_additional_column->chart_line_additional_url,
338             ];
339             }
340 0 0       0 if ( !$b_value_id_exists ) {
341 0         0 unshift @a_additionals, ['VALUE_ID'];
342             }
343              
344 0         0 my $hr_chart_search = {};
345 0         0 $hr_chart_search->{limit} = $h_params{limit};
346 0         0 $hr_chart_search->{offset} = $h_params{offset};
347              
348 0         0 for my $s_axis (qw/ x y /) {
349 0         0 for my $or_element ( sort { $a->chart_line_axis_element_number <=> $b->chart_line_axis_element_number } $or_chart_line->chart_axis_elements ) {
  0         0  
350 0 0 0     0 if ( $or_element->chart_line_axis eq $s_axis && $or_element->axis_column ) {
351 0         0 push @{$hr_chart_search->{order_by}}, [
352             $or_element->axis_column->chart_line_axis_column,
353             'DESC',
354 0         0 { numeric => $h_axis_type{$s_axis} eq 'numeric' },
355             ];
356             }
357             }
358             }
359              
360 0         0 my @a_chart_line_points;
361             LOADING_DATA: {
362              
363             # set where clause with bench_value_id for tiny url
364 0 0       0 if ( $or_tiny_url ) {
  0 0       0  
365 0         0 my $or_chart_tiny_url_line;
366 0         0 for my $or_act_line ( $or_tiny_url->chart_tiny_url_line ) {
367 0 0       0 if ( $or_act_line->chart_line_id == $or_chart_line->chart_line_id ) {
368 0         0 $or_chart_tiny_url_line = $or_act_line;
369             }
370             }
371 0         0 my @a_bench_value_ids = $or_chart_tiny_url_line
372             ->chart_tiny_url_relation
373             ->get_column('bench_value_id')
374             ->all
375             ;
376 0 0       0 if ( @a_bench_value_ids ) {
377             $hr_chart_search->{where} = [[
378 0         0 '=',
379             'VALUE_ID',
380             @a_bench_value_ids,
381             ]];
382             }
383             else {
384 0         0 last LOADING_DATA;
385             }
386             }
387             # set where clause
388             elsif ( $or_chart_line->chart_line_restrictions ) {
389 0   0     0 $hr_chart_search->{where} ||= [];
390 0         0 for my $or_chart_line_restriction ( $or_chart_line->chart_line_restrictions ) {
391 0         0 my @a_chart_line_restriction_value;
392 0 0       0 if ( $or_chart_line_restriction->is_template_restriction ) {
393 0         0 my ( $s_restriction_value_identifier )
394             = ($or_chart_line_restriction->chart_line_restriction_values)[0]->chart_line_restriction_value
395             ;
396 0 0       0 if ( defined $h_params{$s_restriction_value_identifier} ) {
397 0         0 @a_chart_line_restriction_value = @{toarrayref( $h_params{$s_restriction_value_identifier} )};
  0         0  
398             }
399             else {
400             $or_c->stash->{content} = {
401 0         0 error => "missing template parameter '$s_restriction_value_identifier'",
402             };
403 0         0 return 0;
404             }
405             }
406             else {
407             @a_chart_line_restriction_value = map {
408 0         0 $_->chart_line_restriction_value
  0         0  
409             } $or_chart_line_restriction->chart_line_restriction_values;
410             }
411 0         0 push @{$hr_chart_search->{where}}, [
  0         0  
412             $or_chart_line_restriction->chart_line_restriction_operator,
413             $or_chart_line_restriction->chart_line_restriction_column,
414             @a_chart_line_restriction_value,
415             ];
416             }
417             }
418             else {
419 0         0 last LOADING_DATA;
420             }
421              
422             # set select columns
423 0         0 my %h_chart_search_select = map { $_ => 1 }
424             (
425 0         0 map { $_->axis_column->chart_line_axis_column }
426 0         0 grep { $_->axis_column }
427             $or_chart_line->chart_axis_elements
428             ), (
429 0         0 map { $_->[0] } @a_additionals
  0         0  
430             );
431             $hr_chart_search->{select} = [
432 0         0 keys %h_chart_search_select
433             ];
434              
435 0         0 my $ar_chart_points = $balib->search( $hr_chart_search );
436              
437 0 0 0     0 if ( $ar_chart_points && @{$ar_chart_points} ) {
  0         0  
438              
439 0         0 for my $or_element ( sort { $a->chart_line_axis_element_number <=> $b->chart_line_axis_element_number } $or_chart_line->chart_axis_elements ) {
  0         0  
440 0 0       0 if ( $or_element->axis_column ) {
441 0         0 push @a_first, [ $or_element->axis_column->chart_line_axis_column, $ar_chart_points->[-1]{$or_element->axis_column->chart_line_axis_column} ];
442 0         0 push @a_last , [ $or_element->axis_column->chart_line_axis_column, $ar_chart_points->[ 0]{$or_element->axis_column->chart_line_axis_column} ];
443             }
444             }
445              
446 0         0 for my $hr_point ( @{$ar_chart_points} ) {
  0         0  
447              
448 0         0 eval {
449              
450 0         0 my $hr_chart_point = { x => q##, y => q##, additionals => {} };
451 0         0 for my $or_element ( sort { $a->chart_line_axis_element_number <=> $b->chart_line_axis_element_number } $or_chart_line->chart_axis_elements ) {
  0         0  
452 0 0       0 if ( $or_element->axis_column ) {
453 0 0       0 if ( defined $hr_point->{$or_element->axis_column->chart_line_axis_column} ) {
454 0         0 $hr_chart_point->{$or_element->chart_line_axis} .= $hr_point->{$or_element->axis_column->chart_line_axis_column};
455             }
456             else {
457 0         0 die 'missing value for ' . $or_element->chart_line_axis . "-axis\n";
458             }
459             }
460             else {
461 0         0 $hr_chart_point->{$or_element->chart_line_axis} .= $or_element->axis_separator->chart_line_axis_separator;
462             }
463             }
464              
465 0         0 my ( %h_strp );
466 0 0       0 if ( $or_chart->chart_axis_type_x->chart_axis_type_name eq 'date' ) {
467 0 0       0 if ( my $dt_format = $or_chart_line->chart_axis_x_column_format ) {
468 0         0 require DateTime::Format::Strptime;
469 0         0 $h_strp{x} = DateTime::Format::Strptime->new( pattern => $dt_format );
470             }
471             else {
472 0         0 $or_c->response->status( 500 );
473 0         0 $or_c->body('xaxis type is date but no date format is given for "' . $or_chart_line->chart_line_name . '"');
474 0         0 return 1;
475             }
476             }
477 0 0       0 if ( $or_chart->chart_axis_type_y->chart_axis_type_name eq 'date' ) {
478 0 0       0 if ( my $dt_format = $or_chart_line->chart_axis_y_column_format ) {
479 0         0 require DateTime::Format::Strptime;
480 0         0 $h_strp{y} = DateTime::Format::Strptime->new( pattern => $dt_format );
481             }
482             else {
483 0         0 $or_c->response->status( 500 );
484 0         0 $or_c->body('yaxis type is date but no date format is given for "' . $or_chart_line->chart_line_name . '"');
485 0         0 return 1;
486             }
487             }
488              
489 0         0 for my $s_axis (qw/ x y /) {
490 0         0 $hr_chart_point->{$s_axis.'o'} = $hr_chart_point->{$s_axis};
491 0 0       0 if ( $h_strp{$s_axis} ) {
492             $hr_chart_point->{$s_axis} = $formatter->format_datetime(
493 0         0 $h_strp{$s_axis}->parse_datetime( $hr_chart_point->{$s_axis.'o'} )
494             );
495             }
496             }
497              
498 0 0 0     0 if ( $or_chart->order_by_x_axis == 1 && $or_chart->order_by_y_axis == 2 ) {
    0 0        
499 0         0 $hr_chart_point->{'yh'} = $hr_chart_point->{'x'}.'|-|'.$hr_chart_point->{'y'};
500             }
501             elsif ( $or_chart->order_by_x_axis == 2 && $or_chart->order_by_y_axis == 1 ) {
502 0         0 $hr_chart_point->{'xh'} = $hr_chart_point->{'y'}.'|-|'.$hr_chart_point->{'x'};
503             }
504              
505 0         0 for my $s_axis (qw/ x y /) {
506 0 0       0 if ( $h_label_type{$s_axis} eq 'list' ) {
507 0   0     0 $hr_chart_point->{$s_axis.'h'} //= $hr_chart_point->{$s_axis.'o'};
508 0   0     0 $hr_chart_point->{$s_axis} = $h_axis{$s_axis}{$hr_chart_point->{$s_axis.'h'}} //= $h_counter{$s_axis}++;
509             }
510             }
511              
512 0         0 for my $ar_chart_line_addition ( @a_additionals ) {
513             $hr_chart_point->{additionals}{$ar_chart_line_addition->[0]} = [
514 0         0 $hr_point->{$ar_chart_line_addition->[0]},
515             ];
516 0 0       0 if ( $ar_chart_line_addition->[1] ) {
517 0         0 $hr_chart_point->{additionals}{$ar_chart_line_addition->[0]}[1] =
518             $ar_chart_line_addition->[1];
519             }
520             }
521              
522 0 0 0     0 if (( defined $hr_chart_point->{x} ) && ( defined $hr_chart_point->{y} )) {
523 0         0 push @a_chart_line_points, $hr_chart_point;
524             }
525              
526             };
527 0 0       0 if ( $@ ) {
528 0         0 push @a_chart_line_point_warnings, $@;
529             }
530              
531             }
532              
533             }
534              
535             } # LOADING_DATA
536              
537 0         0 push @a_result, {
538             data => \@a_chart_line_points,
539             label => $or_chart_line->chart_line_name,
540             chart_line_id => $or_chart_line->chart_line_id,
541             };
542              
543             }
544              
545             my %h_sort_function = (
546 0     0   0 date => sub { $_[0] <=> $_[1] },
547 0     0   0 numeric => sub { $_[0] <=> $_[1] },
548 0     0   0 alphanumeric => sub { $_[0] cmp $_[1] },
549 0         0 );
550              
551             $h_sort_function{x_first_array} = sub {
552             $h_sort_function{$h_axis_type{x}}->( $_[0]->[0], $_[1]->[0] )
553 0 0   0   0 || $h_sort_function{$h_axis_type{y}}->( $_[0]->[1], $_[1]->[1] )
554 0         0 };
555             $h_sort_function{y_first_array} = sub {
556             $h_sort_function{$h_axis_type{y}}->( $_[0]->[0], $_[1]->[0] )
557 0 0   0   0 || $h_sort_function{$h_axis_type{x}}->( $_[0]->[1], $_[1]->[1] )
558 0         0 };
559             $h_sort_function{x_first_hash} = sub {
560             $_[0]->{x} <=> $_[1]->{x}
561             || $_[0]->{y} <=> $_[1]->{y}
562 0 0   0   0 };
  0         0  
563             $h_sort_function{y_first_hash} = sub {
564             $_[0]->{y} <=> $_[1]->{y}
565             || $_[0]->{x} <=> $_[1]->{x}
566 0 0   0   0 };
  0         0  
567              
568             # sortiere die Labels
569 0 0       0 if ( $h_label_type{x} eq 'list' ) {
570 0         0 my $i_counter = 0;
571 0 0 0     0 if ( $or_chart->order_by_x_axis == 2 && $or_chart->order_by_y_axis == 1 ) {
572 0         0 for my $ar_key ( sort { $h_sort_function{'y_first_array'}->( $a, $b ) } map {[split /\|-\|/, $_]} keys %{$h_axis{x}} ) {
  0         0  
  0         0  
  0         0  
573 0         0 $h_axis{x}{join '|-|', @{$ar_key}} = $i_counter++;
  0         0  
574             }
575             }
576             else {
577 0         0 for my $s_key ( sort { $h_sort_function{$h_axis_type{x}}->( $a, $b ) } keys %{$h_axis{x}} ) {
  0         0  
  0         0  
578 0         0 $h_axis{x}{$s_key} = $i_counter++;
579             }
580             }
581             }
582 0 0       0 if ( $h_label_type{y} eq 'list' ) {
583 0         0 my $i_counter = 0;
584 0 0 0     0 if ( $or_chart->order_by_x_axis == 1 && $or_chart->order_by_y_axis == 2 ) {
585 0         0 for my $ar_key ( sort { $h_sort_function{'x_first_array'}->( $a, $b ) } map {[split /\|-\|/, $_]} keys %{$h_axis{y}} ) {
  0         0  
  0         0  
  0         0  
586 0         0 $h_axis{y}{join '|-|', @{$ar_key}} = $i_counter++;
  0         0  
587             }
588             }
589             else {
590 0         0 for my $s_key ( sort { $h_sort_function{$h_axis_type{y}}->( $a, $b ) } keys %{$h_axis{y}} ) {
  0         0  
  0         0  
591 0         0 $h_axis{y}{$s_key} = $i_counter++;
592             }
593             }
594             }
595             # setze die richtigen Label-Verknüpfungen nach der sortierung
596 0         0 for my $hr_line ( @a_result ) {
597 0         0 for my $hr_point ( @{$hr_line->{data}} ) {
  0         0  
598 0         0 for my $s_axis (qw/ x y /) {
599 0 0       0 if ( $h_label_type{$s_axis} eq 'list' ) {
600 0         0 $hr_point->{$s_axis} = $h_axis{$s_axis}{delete $hr_point->{$s_axis.'h'}};
601             }
602             }
603             }
604             }
605             # sortiere die Datenpunkte
606 0         0 AXIS: for my $s_axis (qw/ x y /) {
607 0 0       0 if ( $or_chart->get_column('order_by_'.$s_axis.'_axis') == 1 ) {
608 0         0 for my $hr_line ( @a_result ) {
609 0         0 @{$hr_line->{data}} = sort { $h_sort_function{$s_axis.'_first_hash'}->( $a, $b ) } @{$hr_line->{data}};
  0         0  
  0         0  
  0         0  
610             }
611 0         0 last AXIS;
612             }
613             } # AXIS
614              
615             # set chart markings
616 0         0 for my $or_marking ( $or_chart->chart_markings ) {
617 0         0 push @a_markings, {
618             chart_marking_name => $or_marking->chart_marking_name,
619             chart_marking_color => $or_marking->chart_marking_color,
620             chart_marking_x_from => $or_marking->chart_marking_x_from,
621             chart_marking_x_to => $or_marking->chart_marking_x_to,
622             chart_marking_y_from => $or_marking->chart_marking_y_from,
623             chart_marking_y_to => $or_marking->chart_marking_y_to,
624             };
625 0 0 0     0 if ( $a_markings[-1]{chart_marking_x_from} || $a_markings[-1]{chart_marking_x_to} ) {
626 0 0       0 if ( $or_chart->chart_axis_type_x->chart_axis_type_name eq 'date' ) {
627 0 0       0 if ( my $dt_format = $or_marking->chart_marking_x_format ) {
628 0         0 require DateTime::Format::Strptime;
629 0         0 my $or_format_x = DateTime::Format::Strptime->new( pattern => $dt_format );
630 0   0     0 $a_markings[-1]{chart_marking_x_from} &&= $formatter->format_datetime($or_format_x->parse_datetime($a_markings[-1]{chart_marking_x_from}));
631 0   0     0 $a_markings[-1]{chart_marking_x_to} &&= $formatter->format_datetime($or_format_x->parse_datetime($a_markings[-1]{chart_marking_x_to}));
632             }
633             else {
634 0         0 $or_c->response->status( 500 );
635 0         0 $or_c->body('xaxis type is date but no date format is given for marking "' . $or_marking->chart_marking_name . '"');
636 0         0 return 1;
637             }
638             }
639             }
640 0 0 0     0 if ( $a_markings[-1]{chart_marking_y_from} || $a_markings[-1]{chart_marking_y_to} ) {
641 0 0       0 if ( $or_chart->chart_axis_type_y->chart_axis_type_name eq 'date' ) {
642 0 0       0 if ( my $dt_format = $or_marking->chart_marking_y_format ) {
643 0         0 require DateTime::Format::Strptime;
644 0         0 my $or_format_y = DateTime::Format::Strptime->new( pattern => $dt_format );
645 0   0     0 $a_markings[-1]{chart_marking_y_from} &&= $formatter->format_datetime($or_format_y->parse_datetime($a_markings[-1]{chart_marking_y_from}));
646 0   0     0 $a_markings[-1]{chart_marking_y_to} &&= $formatter->format_datetime($or_format_y->parse_datetime($a_markings[-1]{chart_marking_y_to}));
647             }
648             else {
649 0         0 $or_c->response->status( 500 );
650 0         0 $or_c->body('yaxis type is date but no date format is given for marking "' . $or_marking->chart_marking_name . '"');
651 0         0 return 1;
652             }
653             }
654             }
655             }
656              
657             }
658              
659             $or_c->stash->{content} = {
660             chart_type => $or_chart->chart_type->chart_type_flot_name,
661 0         0 xaxis_alphas => [ map { [ $h_axis{x}{$_}, $_ ] } keys %{$h_axis{x}} ],
  0         0  
662 0         0 yaxis_alphas => [ map { [ $h_axis{y}{$_}, $_ ] } keys %{$h_axis{y}} ],
  0         0  
663             xaxis_type => $or_chart->chart_axis_type_x->chart_axis_type_name,
664             yaxis_type => $or_chart->chart_axis_type_y->chart_axis_type_name,
665             order_by_x_axis => $or_chart->order_by_x_axis,
666             order_by_y_axis => $or_chart->order_by_y_axis,
667 0   0     0 offset => ($h_params{offset} || 0) + ($h_params{limit} || 0),
      0        
668             warnings => \@a_chart_line_point_warnings,
669             markings => \@a_markings,
670             series => \@a_result,
671             };
672              
673 0         0 return 1;
674              
675 10     10   41910 }
  10         33  
  10         61  
676              
677             sub create_static_url : Local {
678              
679 0     0 0 0 my ( $or_self, $or_c ) = @_;
680              
681 0         0 my $i_chart_tiny_url_id;
682 0         0 my $or_schema = $or_c->model('TestrunDB');
683 0         0 my $hr_params = $or_c->req->params;
684              
685             try {
686             $or_schema->txn_do(sub {
687              
688 0 0       0 if ( $hr_params->{ids} ) {
689              
690 0         0 require JSON::XS;
691 0         0 my $ar_ids = JSON::XS::decode_json( $hr_params->{ids} );
692              
693 0         0 require DateTime;
694 0         0 my $or_chart_tiny_url = $or_schema->resultset('ChartTinyUrls')->new({
695             created_at => DateTime->now(),
696             });
697 0         0 $or_chart_tiny_url->insert();
698              
699 0 0       0 if ( $i_chart_tiny_url_id = $or_chart_tiny_url->chart_tiny_url_id ) {
700 0         0 for my $hr_chart_line ( @{$ar_ids} ) {
  0         0  
701 0 0       0 if ( $hr_chart_line->{chart_line_id} ) {
702              
703             my $or_chart_tiny_url_line = $or_schema->resultset('ChartTinyUrlLines')->new({
704             chart_tiny_url_id => $i_chart_tiny_url_id,
705             chart_line_id => $hr_chart_line->{chart_line_id},
706 0         0 });
707 0         0 $or_chart_tiny_url_line->insert();
708              
709 0 0       0 if ( my $i_chart_tiny_url_line_id = $or_chart_tiny_url_line->chart_tiny_url_line_id ) {
710              
711 0         0 my @a_relations;
712 0         0 for my $i_bench_value_id ( @{$hr_chart_line->{data}} ) {
  0         0  
713 0         0 push @a_relations, {
714             chart_tiny_url_line_id => $or_chart_tiny_url_line->chart_tiny_url_line_id,
715             bench_value_id => $i_bench_value_id,
716             };
717             }
718              
719 0         0 $or_schema->resultset('ChartTinyUrlRelations')->populate(
720             \@a_relations
721             );
722              
723             }
724             else {
725 0         0 die "error: cannot insert tiny url line";
726             }
727              
728             }
729             else {
730 0         0 die "error: cannot find chart line id";
731             }
732             }
733             }
734             else {
735 0         0 die "error: cannot insert tiny url";
736             }
737             }
738              
739             $or_c->stash->{content} = {
740 0         0 chart_tiny_url_id => $i_chart_tiny_url_id,
741             };
742              
743 0     0   0 });
744             }
745             catch {
746 0     0   0 $or_c->res->status( 500 );
747 0         0 $or_c->response->body( "Transaction failed: $_" );
748 0         0 };
749              
750 0         0 return 1;
751              
752 10     10   14990 }
  10         36  
  10         55  
753              
754             sub get_columns : Private {
755              
756 0     0 0 0 my ( $or_self, $or_c ) = @_;
757              
758 0         0 require Tapper::Config;
759 0         0 require BenchmarkAnything::Storage::Frontend::Lib;
760              
761             my $balib = BenchmarkAnything::Storage::Frontend::Lib->new
762 0         0 (cfgfile => Tapper::Config->subconfig->{_last_used_tapper_config_file});
763              
764 0         0 my @a_columnlist = @{$balib->listkeys};
  0         0  
765 0         0 push @a_columnlist, keys %{$balib->_default_additional_keys}; # TODO: too much unrequested data from this?
  0         0  
766              
767 0         0 return \@a_columnlist;
768              
769 10     10   11623 }
  10         32  
  10         75  
770              
771             sub is_column : Private {
772              
773 0     0 0 0 my ( $or_self, $or_c, $s_column ) = @_;
774              
775 0         0 require Tapper::Config;
776 0         0 require BenchmarkAnything::Storage::Frontend::Lib;
777              
778             my $balib = BenchmarkAnything::Storage::Frontend::Lib->new
779 0         0 (cfgfile => Tapper::Config->subconfig->{_last_used_tapper_config_file});
780              
781 0         0 my $hr_columns = $balib->_default_additional_keys;
782              
783 0 0       0 return 1 if $hr_columns->{$s_column};
784              
785 0         0 my @a_columnlist = $balib->_get_additional_key_id($s_column);
786              
787 0 0       0 return @a_columnlist ? 1 : 0;
788              
789 10     10   11232 }
  10         98  
  10         86  
790              
791             sub edit_chart : Local {
792              
793 0     0 0 0 my ( $or_self, $or_c ) = @_;
794              
795             # set css file
796 0         0 push @{$or_c->stash->{css_files}},
  0         0  
797             '/tapper/static/css/metareports/edit.css'
798             , '/tapper/static/css/jquery-ui/jquery.ui.css'
799             ;
800              
801             # set js file
802 0         0 push @{$or_c->stash->{js_files}}, '/tapper/static/js/jquery-ui/jquery-ui-autocomplete.js';
  0         0  
803              
804 0         0 my $or_schema = $or_c->model('TestrunDB');
805 0 0       0 if (! $or_c->stash->{chart} ) {
806 0 0       0 if ( $or_c->req->params->{chart_id} ) {
807 0         0 $or_c->stash->{chart} = get_edit_page_chart_hash_by_chart_id(
808             $or_c->req->params,
809             $or_schema,
810             );
811             }
812             else {
813 0         0 $or_c->stash->{chart} = {};
814             }
815             }
816              
817 0         0 $or_c->stash->{columns} = $or_self->get_columns( $or_c );
818 0 0       0 $or_c->stash->{head_overview} = 'Metareports - Edit' . ( $or_c->req->params->{asnew} ? ' as New' : q## );
819              
820 0         0 return 1;
821              
822 10     10   12212 }
  10         27  
  10         65  
823              
824             sub get_edit_page_chart_hash_by_chart_id {
825              
826 0     0 0   my ( $hr_params, $or_schema ) = @_;
827              
828 0           my ( $hr_search, $ar_join ) = hr_get_search( $or_schema, $hr_params );
829 0           my $or_chart = $or_schema->resultset('ChartVersions')->search(
830             $hr_search,
831             {
832             join => $ar_join,
833             prefetch => {
834             'chart' => {
835             'chart_tag_relations' => 'chart_tag',
836             },
837             'chart_lines' => 'chart_additionals',
838             'chart_lines' => {
839             'chart_axis_elements' => [
840             'axis_column',
841             'axis_separator',
842             ],
843             },
844             },
845             },
846             )->first();
847              
848             my $hr_chart = {
849             chart_id => $or_chart->chart_id,
850             chart_version => $or_chart->chart_version,
851             chart_version_id => $or_chart->chart_version_id,
852             chart_name => $or_chart->chart_name,
853             chart_type_id => $or_chart->chart_type_id,
854             chart_axis_type_x_id => $or_chart->chart_axis_type_x_id,
855             chart_axis_type_y_id => $or_chart->chart_axis_type_y_id,
856             order_by_x_axis => $or_chart->order_by_x_axis,
857             order_by_y_axis => $or_chart->order_by_y_axis,
858             chart_lines => [],
859             chart_tag_new => [
860             map {
861 0           $_->chart_tag->chart_tag
862             } $or_chart->chart->chart_tag_relations
863             ],
864             chart_markings => [
865 0           map {{
866 0           chart_marking_name => $_->chart_marking_name,
867             chart_marking_color => $_->chart_marking_color,
868             chart_marking_x_format => $_->chart_marking_x_format,
869             chart_marking_x_from => $_->chart_marking_x_from,
870             chart_marking_x_to => $_->chart_marking_x_to,
871             chart_marking_y_format => $_->chart_marking_y_format,
872             chart_marking_y_from => $_->chart_marking_y_from,
873             chart_marking_y_to => $_->chart_marking_y_to,
874             }} $or_chart->chart_markings
875             ],
876             };
877              
878 0           for my $or_line ( $or_chart->chart_lines ) {
879 0           my ( %h_chart_elements );
880 0           for my $or_element (
881             sort {
882 0           $a->chart_line_axis_element_number <=> $b->chart_line_axis_element_number
883             } $or_line->chart_axis_elements
884             ) {
885 0 0 0       push @{$h_chart_elements{$or_element->chart_line_axis} ||= []},
  0            
886             $or_element->axis_column
887             ? [ 'column' , $or_element->axis_column->chart_line_axis_column , ]
888             : [ 'separator', $or_element->axis_separator->chart_line_axis_separator, ]
889             ;
890             }
891 0           push @{$hr_chart->{chart_lines}}, {
892             chart_line_name => $or_line->chart_line_name,
893             chart_line_restrictions => [map {{
894             is_template_restriction => $_->is_template_restriction,
895             is_numeric_restriction => $_->is_numeric_restriction,
896             chart_line_restriction_column => $_->chart_line_restriction_column,
897             chart_line_restriction_operator => $_->chart_line_restriction_operator,
898             chart_line_restriction_values => [map {
899 0           $_->chart_line_restriction_value
  0            
900             } $_->chart_line_restriction_values],
901             }} $or_line->chart_line_restrictions],
902             chart_line_x_column => $h_chart_elements{x},
903             chart_line_x_format => $or_line->chart_axis_x_column_format(),
904             chart_line_y_column => $h_chart_elements{y},
905 0           chart_line_y_format => $or_line->chart_axis_y_column_format(),
906             chart_additionals => [],
907             };
908 0           for my $or_add ( $or_line->chart_additionals ) {
909 0           push @{$hr_chart->{chart_lines}[-1]{chart_additionals}}, {
  0            
910             chart_line_additional_column => $or_add->chart_line_additional_column,
911             chart_line_additional_url => $or_add->chart_line_additional_url,
912             };
913             }
914             }
915              
916 0           return $hr_chart;
917              
918             }
919              
920             sub get_undef_on_empty_string {
921 0 0 0 0 0   return defined $_[0] && $_[0] eq q## ? undef : $_[0];
922             }
923              
924             sub get_edit_page_chart_hash_by_params : Private {
925              
926 0     0 0 0 my ( $or_self, $or_c, $hr_params, $or_schema ) = @_;
927              
928 0         0 my @a_chart_marking_name = @{toarrayref($hr_params->{chart_marking_name})};
  0         0  
929 0         0 my @a_chart_marking_color = @{toarrayref($hr_params->{chart_marking_color})};
  0         0  
930 0         0 my @a_chart_marking_x_from = @{toarrayref($hr_params->{chart_marking_x_from})};
  0         0  
931 0         0 my @a_chart_marking_x_to = @{toarrayref($hr_params->{chart_marking_x_to})};
  0         0  
932 0         0 my @a_chart_marking_x_format = @{toarrayref($hr_params->{chart_marking_x_format})};
  0         0  
933 0         0 my @a_chart_marking_y_from = @{toarrayref($hr_params->{chart_marking_y_from})};
  0         0  
934 0         0 my @a_chart_marking_y_to = @{toarrayref($hr_params->{chart_marking_y_to})};
  0         0  
935 0         0 my @a_chart_marking_y_format = @{toarrayref($hr_params->{chart_marking_y_format})};
  0         0  
936              
937             my $hr_chart = {
938             chart_id => $hr_params->{chart_id},
939             chart_version => $hr_params->{chart_version},
940             chart_version_id => $hr_params->{chart_version_id},
941             chart_name => $hr_params->{chart_name},
942             chart_type_id => $hr_params->{chart_type},
943             chart_axis_type_x_id => $hr_params->{chart_axis_type_x},
944             chart_axis_type_y_id => $hr_params->{chart_axis_type_y},
945             order_by_x_axis => $hr_params->{order_by_x_axis},
946             order_by_y_axis => $hr_params->{order_by_y_axis},
947             chart_lines => [],
948             chart_tag_new => [
949 0         0 grep { $_ } @{toarrayref($hr_params->{chart_tag_new})}
  0         0  
950             ],
951 0         0 chart_markings => [map{{
952 0         0 chart_marking_name => $_,
953             chart_marking_color => shift @a_chart_marking_color,
954             chart_marking_x_from => get_undef_on_empty_string( shift @a_chart_marking_x_from ),
955             chart_marking_x_to => get_undef_on_empty_string( shift @a_chart_marking_x_to ),
956             chart_marking_x_format => get_undef_on_empty_string( shift @a_chart_marking_x_format ),
957             chart_marking_y_from => get_undef_on_empty_string( shift @a_chart_marking_y_from ),
958             chart_marking_y_to => get_undef_on_empty_string( shift @a_chart_marking_y_to),
959             chart_marking_y_format => get_undef_on_empty_string( shift @a_chart_marking_y_format ),
960             }} @a_chart_marking_name],
961             };
962              
963             # column values for chart lines
964 0         0 my @a_chart_line_names = @{toarrayref($hr_params->{chart_line_name})};
  0         0  
965 0         0 my @a_chart_line_x_columns = @{toarrayref($hr_params->{chart_axis_x_column})};
  0         0  
966 0         0 my @a_chart_line_y_columns = @{toarrayref($hr_params->{chart_axis_y_column})};
  0         0  
967 0         0 my @a_chart_line_x_counters = @{toarrayref($hr_params->{chart_axis_x_counter})};
  0         0  
968 0         0 my @a_chart_line_y_counters = @{toarrayref($hr_params->{chart_axis_y_counter})};
  0         0  
969 0         0 my @a_chart_line_x_formats = @{toarrayref($hr_params->{chart_axis_x_format})};
  0         0  
970 0         0 my @a_chart_line_y_formats = @{toarrayref($hr_params->{chart_axis_y_format})};
  0         0  
971              
972             # column values chart line statements
973 0         0 my @a_chart_where_counter = @{toarrayref($hr_params->{chart_where_counter})};
  0         0  
974 0         0 my @a_chart_where_column = @{toarrayref($hr_params->{chart_line_where_column})};
  0         0  
975 0         0 my @a_chart_where_operator = @{toarrayref($hr_params->{chart_line_where_operator})};
  0         0  
976 0         0 my @a_chart_value_counter = @{toarrayref($hr_params->{chart_line_where_counter})};
  0         0  
977 0         0 my @a_chart_where_value = @{toarrayref($hr_params->{chart_line_where_value})};
  0         0  
978 0         0 my @a_chart_line_where_template = @{toarrayref($hr_params->{chart_line_where_template})};
  0         0  
979 0         0 my @a_chart_line_where_numeric = @{toarrayref($hr_params->{chart_line_where_numeric})};
  0         0  
980              
981             # additional column data
982 0         0 my @a_chart_add_counter = @{toarrayref($hr_params->{chart_additional_counter})};
  0         0  
983 0         0 my @a_chart_add_columns = @{toarrayref($hr_params->{chart_additional_column})};
  0         0  
984 0         0 my @a_chart_add_urls = @{toarrayref($hr_params->{chart_additional_url})};
  0         0  
985              
986             # get default columns for check
987 0         0 while ( my $s_chart_line_name = shift @a_chart_line_names ) {
988              
989 0         0 my $s_chart_line_x_format = shift @a_chart_line_x_formats;
990 0         0 my $s_chart_line_y_format = shift @a_chart_line_y_formats;
991 0         0 my $i_chart_where_counter = shift @a_chart_where_counter;
992 0         0 my $i_chart_add_counter = shift @a_chart_add_counter;
993 0         0 my $i_chart_line_x_counter = shift @a_chart_line_x_counters;
994 0         0 my $i_chart_line_y_counter = shift @a_chart_line_y_counters;
995              
996 0         0 my @a_act_chart_line_x_columns;
997 0         0 for my $i_chart_line_x_counter ( 1..$i_chart_line_x_counter ) {
998 0         0 my $s_chart_line_x_column = shift @a_chart_line_x_columns;
999 0 0       0 if ( $or_self->is_column( $or_c, $s_chart_line_x_column ) ) {
1000 0         0 push @a_act_chart_line_x_columns, [ 'column', $s_chart_line_x_column ];
1001             }
1002             else {
1003 0         0 push @a_act_chart_line_x_columns, [ 'separator', $s_chart_line_x_column ];
1004             }
1005             }
1006              
1007 0         0 my @a_act_chart_line_y_columns;
1008 0         0 for my $i_chart_line_y_counter ( 1..$i_chart_line_y_counter ) {
1009 0         0 my $s_chart_line_y_column = shift @a_chart_line_y_columns;
1010 0 0       0 if ( $or_self->is_column( $or_c, $s_chart_line_y_column ) ) {
1011 0         0 push @a_act_chart_line_y_columns, [ 'column', $s_chart_line_y_column ];
1012             }
1013             else {
1014 0         0 push @a_act_chart_line_y_columns, [ 'separator', $s_chart_line_y_column ];
1015             }
1016             }
1017              
1018 0         0 my @a_chart_line_restriction;
1019 0         0 for my $i_where_counter ( 1..$i_chart_where_counter ) {
1020 0         0 my $i_chart_value_counter = shift @a_chart_value_counter;
1021             push @a_chart_line_restriction, {
1022             is_template_restriction => shift @a_chart_line_where_template,
1023             is_numeric_restriction => shift @a_chart_line_where_numeric,
1024             chart_line_restriction_operator => shift @a_chart_where_operator,
1025             chart_line_restriction_column => shift @a_chart_where_column,
1026 0         0 chart_line_restriction_values => [map { shift @a_chart_where_value } 1..$i_chart_value_counter],
  0         0  
1027             };
1028             }
1029              
1030 0   0     0 push @{$hr_chart->{chart_lines}}, {
  0   0     0  
1031             chart_line_name => $s_chart_line_name,
1032             chart_line_x_column => \@a_act_chart_line_x_columns,
1033             chart_line_x_format => $s_chart_line_x_format || undef,
1034             chart_line_y_column => \@a_act_chart_line_y_columns,
1035             chart_line_y_format => $s_chart_line_y_format || undef,
1036             chart_line_restrictions => \@a_chart_line_restriction,
1037             chart_additionals => [],
1038             };
1039              
1040 0         0 for my $i_add_counter ( 1..$i_chart_add_counter ) {
1041 0         0 push @{$hr_chart->{chart_lines}[-1]{chart_additionals}}, {
  0         0  
1042             chart_line_additional_column => shift @a_chart_add_columns,
1043             chart_line_additional_url => shift @a_chart_add_urls,
1044             };
1045             }
1046              
1047             }
1048              
1049 0         0 return $hr_chart;
1050              
1051 10     10   24391 }
  10         42  
  10         69  
1052              
1053             sub save_chart : Local {
1054              
1055 0     0 0 0 my ( $or_self, $or_c ) = @_;
1056              
1057 0         0 my $or_schema = $or_c->model('TestrunDB');
1058 0         0 my $hr_params = $or_c->req->params;
1059             my $hr_search_param = {
1060             'chart.active' => 1,
1061             'chart_name' => $hr_params->{chart_name},
1062 0         0 'chart_version' => \'>= (
1063             SELECT MAX(cv.chart_version)
1064             FROM chart_versions cv
1065             WHERE cv.chart_id = me.chart_id
1066             )',
1067             };
1068              
1069 0 0       0 if ( $hr_params->{chart_id} ) {
1070 0 0       0 if (! $hr_params->{asnew} ) {
1071 0         0 $hr_search_param->{-not} = { 'me.chart_id' => $hr_params->{chart_id} };
1072             }
1073             }
1074              
1075             # serialize input data
1076 0         0 $or_c->stash->{chart} = $or_self->get_edit_page_chart_hash_by_params(
1077             $or_c, $hr_params, $or_schema,
1078             );
1079              
1080 0         0 my @a_charts = $or_schema->resultset('ChartVersions')->search( $hr_search_param, { join => 'chart' } );
1081 0 0       0 if ( @a_charts ) {
1082 0         0 $or_c->stash->{error} = 'chart name already exists';
1083 0         0 $or_c->go('/tapper/metareports/edit_chart');
1084             }
1085              
1086 0         0 my $i_chart_id;
1087             try {
1088             $or_schema->txn_do(sub {
1089 0 0       0 if ( $hr_params->{chart_version_id} ) {
1090             $or_c->stash->{error} = $or_self->remove_chart_version(
1091 0         0 $hr_params->{chart_version_id}, $or_schema
1092             );
1093             }
1094 0         0 $or_self->insert_chart( $or_c, $or_schema );
1095 0         0 $or_self->insert_chart_tags( $or_c, $or_schema );
1096 0         0 $or_self->insert_chart_markings( $or_c, $or_schema, );
1097 0     0   0 });
1098             }
1099             catch {
1100 0     0   0 $or_c->stash->{error} = "Transaction failed: $_";
1101 0         0 $or_c->go('/tapper/metareports/edit_chart');
1102 0         0 };
1103              
1104             $or_c->redirect(
1105             '/tapper/metareports/detail?chart_tag='
1106             . $or_c->req->params->{chart_tag}
1107             . '&amp;chart_id='
1108             . $or_c->stash->{chart}{chart_id}
1109 0         0 );
1110 0         0 $or_c->detach();
1111              
1112 0         0 return 1;
1113              
1114 10     10   14425 }
  10         47  
  10         60  
1115              
1116             sub toarrayref : Private {
1117              
1118 0     0 0 0 my ( $value ) = @_;
1119              
1120 0 0       0 if ( not defined $value ) {
    0          
1121 0         0 return [];
1122             }
1123             elsif ( ref( $value ) ne 'ARRAY' ) {
1124 0         0 return [ $value ];
1125             }
1126              
1127 0         0 return $value;
1128              
1129 10     10   10906 }
  10         44  
  10         56  
1130              
1131             sub delete_chart : Local {
1132              
1133 0     0 0 0 my ( $or_self, $or_c ) = @_;
1134              
1135 0         0 my $or_schema = $or_c->model('TestrunDB');
1136              
1137             try {
1138             $or_schema->txn_do(sub {
1139 0 0       0 if (
1140             my $s_error = $or_self->remove_chart(
1141             $or_c->req->params->{chart_id}, $or_schema
1142             )
1143             ) {
1144 0         0 die "Transaction failed: $s_error";
1145             }
1146 0     0   0 });
1147             }
1148             catch {
1149 0     0   0 $or_c->stash->{error} = "Transaction failed: $_";
1150 0         0 };
1151              
1152 0 0       0 if (! $or_c->stash->{error} ) {
1153 0         0 $or_c->stash->{message} = 'Chart successfully deleted';
1154             }
1155              
1156 0         0 $or_c->redirect('/tapper/metareports/chart_overview?chart_tag=' . $or_c->req->params->{chart_tag});
1157 0         0 $or_c->detach();
1158              
1159 0         0 return 1;
1160              
1161 10     10   12425 }
  10         30  
  10         81  
1162              
1163             sub insert_chart : Private {
1164              
1165 0     0 0 0 my ( $or_self, $or_c, $or_schema ) = @_;
1166              
1167 0         0 my $hr_params = $or_c->stash->{chart};
1168 0         0 my $i_chart_id = $hr_params->{chart_id};
1169              
1170 0         0 my $NOW = DateTime->now();
1171 0 0       0 if (! $i_chart_id ) {
1172 0         0 my $or_chart = $or_schema->resultset('Charts')->new({
1173             active => 1,
1174             created_at => $NOW,
1175             });
1176 0         0 $or_chart->insert();
1177 0         0 $i_chart_id = $or_chart->chart_id;
1178             }
1179              
1180             my $or_chart_version = $or_schema->resultset('ChartVersions')->new({
1181             chart_id => $i_chart_id,
1182             chart_type_id => $hr_params->{chart_type_id},
1183             chart_axis_type_x_id => $hr_params->{chart_axis_type_x_id},
1184             chart_axis_type_y_id => $hr_params->{chart_axis_type_y_id},
1185             chart_version => $hr_params->{chart_id}
1186             ? $or_schema
1187             ->resultset('ChartVersions')
1188             ->search({ chart_id => $i_chart_id })
1189             ->get_column('chart_version')
1190             ->max + 1
1191             : 1,
1192             chart_name => $hr_params->{chart_name},
1193             order_by_x_axis => $hr_params->{order_by_x_axis},
1194             order_by_y_axis => $hr_params->{order_by_y_axis},
1195 0 0       0 created_at => $NOW,
1196             });
1197 0         0 $or_chart_version->insert();
1198              
1199 0 0       0 if ( my $i_chart_version_id = $or_chart_version->chart_version_id() ) {
1200              
1201 0         0 my $ar_columns = $or_self->get_columns( $or_c );
1202 0         0 for my $hr_chart_line ( @{$hr_params->{chart_lines}} ) {
  0         0  
1203              
1204             my $or_chart_line = $or_c->model('TestrunDB')->resultset('ChartLines')->new({
1205             chart_version_id => $i_chart_version_id,
1206             chart_line_name => $hr_chart_line->{chart_line_name},
1207             chart_axis_x_column_format => $hr_chart_line->{chart_line_x_format} || undef,
1208             chart_axis_y_column_format => $hr_chart_line->{chart_line_y_format} || undef,
1209 0   0     0 created_at => $NOW,
      0        
1210             });
1211 0         0 $or_chart_line->insert();
1212              
1213 0 0       0 if ( my $i_chart_line_id = $or_chart_line->chart_line_id ) {
1214 0         0 for my $s_axis (qw/ x y /) {
1215 0         0 my $i_chart_line_number = 0;
1216 0         0 for my $ar_element ( @{$hr_chart_line->{'chart_line_' . $s_axis . '_column'}} ) {
  0         0  
1217 0         0 my $or_chart_element = $or_c->model('TestrunDB')->resultset('ChartLineAxisElements')->new({
1218             chart_line_id => $i_chart_line_id,
1219             chart_line_axis => $s_axis,
1220             chart_line_axis_element_number => ++$i_chart_line_number,
1221             });
1222 0         0 $or_chart_element->insert();
1223 0 0       0 if ( my $i_element_id = $or_chart_element->chart_line_axis_element_id ) {
1224 0 0       0 if ( $ar_element->[0] eq 'column' ) {
1225 0         0 $or_c->model('TestrunDB')->resultset('ChartLineAxisColumns')->new({
1226             chart_line_axis_element_id => $i_element_id,
1227             chart_line_axis_column => $ar_element->[1],
1228             })->insert();
1229             }
1230             else {
1231 0         0 $or_c->model('TestrunDB')->resultset('ChartLineAxisSeparators')->new({
1232             chart_line_axis_element_id => $i_element_id,
1233             chart_line_axis_separator => $ar_element->[1],
1234             })->insert();
1235             }
1236             }
1237             else {
1238 0         0 die 'cannot insert chart line element';
1239             }
1240             }
1241             }
1242              
1243 0         0 for my $hr_additionals ( @{$hr_chart_line->{chart_additionals}} ) {
  0         0  
1244             $or_c->model('TestrunDB')->resultset('ChartLineAdditionals')->new({
1245             chart_line_id => $i_chart_line_id,
1246             chart_line_additional_column => $hr_additionals->{chart_line_additional_column},
1247             chart_line_additional_url => $hr_additionals->{chart_line_additional_url} || undef,
1248 0   0     0 created_at => $NOW,
1249             })->insert();
1250             }
1251              
1252 0         0 for my $hr_chart_line_restriction ( @{$hr_chart_line->{chart_line_restrictions}} ) {
  0         0  
1253              
1254             my $or_chart_line_restriction = $or_c->model('TestrunDB')->resultset('ChartLineRestrictions')->new({
1255             chart_line_id => $i_chart_line_id,
1256             chart_line_restriction_column => $hr_chart_line_restriction->{chart_line_restriction_column},
1257             chart_line_restriction_operator => $hr_chart_line_restriction->{chart_line_restriction_operator},
1258             is_template_restriction => $hr_chart_line_restriction->{is_template_restriction},
1259             is_numeric_restriction => $hr_chart_line_restriction->{is_numeric_restriction},
1260 0         0 created_at => $NOW,
1261             });
1262 0         0 $or_chart_line_restriction->insert();
1263              
1264 0         0 for my $s_chart_line_restriction_value ( @{$hr_chart_line_restriction->{chart_line_restriction_values}} ) {
  0         0  
1265 0         0 $or_c->model('TestrunDB')->resultset('ChartLineRestrictionValues')->new({
1266             chart_line_restriction_id => $or_chart_line_restriction->chart_line_restriction_id(),
1267             chart_line_restriction_value => $s_chart_line_restriction_value,
1268             })->insert();
1269             }
1270              
1271             }
1272              
1273             # set new chart_id and chart_version_id for later use
1274 0         0 $hr_params->{chart_id} = $i_chart_id;
1275 0         0 $hr_params->{chart_version_id} = $i_chart_version_id;
1276              
1277             }
1278             else {
1279 0         0 die 'cannot insert chart line'
1280             }
1281              
1282             }
1283              
1284             }
1285             else {
1286 0         0 die 'cannot insert chart';
1287             }
1288              
1289 0         0 return 1;
1290              
1291 10     10   16691 }
  10         41  
  10         64  
1292              
1293             sub insert_chart_markings : Private {
1294              
1295 0     0 0 0 my ( $or_self, $or_c, $or_schema ) = @_;
1296              
1297 0         0 my $hr_params = $or_c->stash->{chart};
1298 0         0 for my $hr_marking ( @{$hr_params->{chart_markings}} ) {
  0         0  
1299             $or_schema
1300             ->resultset('ChartMarkings')
1301 0         0 ->new({ chart_version_id => $hr_params->{chart_version_id}, %{$hr_marking} })
  0         0  
1302             ->insert()
1303             ;
1304             }
1305              
1306 0         0 return 1;
1307              
1308 10     10   11442 }
  10         37  
  10         59  
1309              
1310             sub insert_chart_tags : Private {
1311              
1312 0     0 0 0 my ( $or_self, $or_c, $or_schema ) = @_;
1313              
1314 0         0 my $hr_params = $or_c->stash->{chart};
1315             my @a_chart_tags = $or_schema
1316             ->resultset('ChartTagRelations')
1317             ->search(
1318             { chart_id => $hr_params->{chart_id} },
1319 0         0 { prefetch => 'chart_tag' },
1320             )
1321             ;
1322              
1323 0         0 my %h_chart_tags_new = map { $_ => 1 } @{$hr_params->{chart_tag_new}};
  0         0  
  0         0  
1324 0         0 for my $or_chart_tag ( @a_chart_tags ) {
1325 0 0       0 if ( $h_chart_tags_new{$or_chart_tag->chart_tag->chart_tag} ) {
1326 0         0 delete $h_chart_tags_new{$or_chart_tag->chart_tag->chart_tag};
1327             }
1328             else {
1329 0         0 $or_chart_tag->delete();
1330             }
1331             }
1332              
1333 0         0 my $NOW = DateTime->now();
1334 0         0 for my $s_chart_tag ( keys %h_chart_tags_new ) {
1335             $or_schema
1336             ->resultset('ChartTagRelations')
1337             ->find_or_create({
1338             chart_id => $hr_params->{chart_id},
1339 0         0 chart_tag_id => $or_schema
1340             ->resultset('ChartTags')
1341             ->find_or_create(
1342             { chart_tag => $s_chart_tag, created_at => $NOW },
1343             { key => 'ux_chart_tags_01' },
1344             )->chart_tag_id
1345             ,
1346             created_at => $NOW,
1347             })
1348             ;
1349             }
1350              
1351 0         0 return 1;
1352              
1353 10     10   12426 }
  10         42  
  10         61  
1354              
1355             sub remove_chart : Private {
1356              
1357 0     0 0 0 my ( $or_self, $i_chart_id, $or_schema ) = @_;
1358              
1359 0 0       0 if (! $i_chart_id ) {
1360 0         0 return 'chart_id is missing';
1361             }
1362              
1363 0         0 my $or_chart = $or_schema->resultset('Charts')->find(
1364             $i_chart_id,
1365             );
1366              
1367 0         0 my $NOW = DateTime->now();
1368 0         0 $or_chart->active(0);
1369 0         0 $or_chart->updated_at($NOW);
1370 0         0 $or_chart->update();
1371              
1372 0         0 return q##;
1373              
1374 10     10   11316 }
  10         38  
  10         61  
1375              
1376             sub remove_chart_version : Private {
1377              
1378 0     0 0 0 my ( $or_self, $i_chart_version_id, $or_schema ) = @_;
1379              
1380 0 0       0 if (! $i_chart_version_id ) {
1381 0         0 return 'chart_version_id is missing';
1382             }
1383              
1384 0         0 my $or_chart = $or_schema->resultset('ChartVersions')->find(
1385             $i_chart_version_id
1386             );
1387              
1388 0         0 my $NOW = DateTime->now();
1389 0         0 $or_chart->active(0);
1390 0         0 $or_chart->updated_at($NOW);
1391 0         0 $or_chart->update();
1392              
1393 0         0 return q##;
1394              
1395 10     10   11040 }
  10         31  
  10         53  
1396              
1397             sub get_benchmark_operators : Private {
1398              
1399 0     0 0 0 my ( $or_self, $or_c ) = @_;
1400              
1401 0         0 require Tapper::Config;
1402 0         0 require BenchmarkAnything::Storage::Frontend::Lib;
1403              
1404             my $balib = BenchmarkAnything::Storage::Frontend::Lib->new
1405 0         0 (cfgfile => Tapper::Config->subconfig->{_last_used_tapper_config_file});
1406              
1407 0 0       0 return @{$balib->_get_benchmark_operators || []};
  0         0  
1408              
1409 10     10   11062 }
  10         42  
  10         58  
1410              
1411             sub base : Chained PathPrefix CaptureArgs(0) {
1412 0     0 0 0 my ( $self, $c ) = @_;
1413 0         0 my $rule = File::Find::Rule->new;
1414 0         0 $c->stash(rule => $rule);
1415 10     10   10576 }
  10         60  
  10         60  
1416              
1417             sub prepare_navi : Private {
1418 0     0 0   my ( $self, $c ) = @_;
1419              
1420             $c->stash->{navi} = [
1421             {
1422 0           title => "Metareports",
1423             href => "/tapper/metareports/",
1424             },
1425             ];
1426              
1427 10     10   10637 }
  10         47  
  10         53  
1428              
1429             1;
1430              
1431             __END__
1432              
1433             =pod
1434              
1435             =encoding UTF-8
1436              
1437             =head1 NAME
1438              
1439             Tapper::Reports::Web::Controller::Tapper::Metareports - Tapper - Catalyst Controller Metareports
1440              
1441             =head1 AUTHORS
1442              
1443             =over 4
1444              
1445             =item *
1446              
1447             AMD OSRC Tapper Team <tapper@amd64.org>
1448              
1449             =item *
1450              
1451             Tapper Team <tapper-ops@amazon.com>
1452              
1453             =back
1454              
1455             =head1 COPYRIGHT AND LICENSE
1456              
1457             This software is Copyright (c) 2019 by Advanced Micro Devices, Inc..
1458              
1459             This is free software, licensed under:
1460              
1461             The (two-clause) FreeBSD License
1462              
1463             =cut