@@ -184,6 +184,11 @@ sub process_rest_request {
184
184
}
185
185
}
186
186
187
+ my $wrapped ;
188
+ $wrapped = 1 if ($c -> req-> header(" x-thruk-outputformat" ) && $c -> req-> header(" x-thruk-outputformat" ) eq ' wrapped_json' );
189
+ $wrapped = 1 if (defined $c -> req-> parameters-> {' headers' } && $c -> req-> parameters-> {' headers' } eq ' wrapped_json' );
190
+ $c -> stash-> {' meta_column_info' } = {};
191
+
187
192
if (!$data ) {
188
193
eval {
189
194
$data = _fetch($c , $path_info , $method );
@@ -207,9 +212,6 @@ sub process_rest_request {
207
212
}
208
213
209
214
# add columns meta data, ex.: used in the thruk grafana datasource
210
- my $wrapped ;
211
- $wrapped = 1 if ($c -> req-> header(" x-thruk-outputformat" ) && $c -> req-> header(" x-thruk-outputformat" ) eq ' wrapped_json' );
212
- $wrapped = 1 if (defined $c -> req-> parameters-> {' headers' } && $c -> req-> parameters-> {' headers' } eq ' wrapped_json' );
213
215
if ($wrapped ) {
214
216
# wrap data along with column meta data
215
217
my $request_method = $method || $c -> req-> method;
@@ -785,7 +787,7 @@ sub get_request_columns {
785
787
if ($_ =~ m /\s +as\s +([^\s ]+)\s *$ / mx ) {
786
788
$_ =~ s / ^.*?\s +as\s +([^\s ]+)\s *$/ $1 / mx ; # strip "as alias" from column
787
789
} else {
788
- $_ =~ s / ^[^:]+:(. *?)$/ $1 / gmx ; # strip alias
790
+ $_ =~ s / ^[^:]+:([^"'] *?)$/ $1 / gmx ; # strip alias
789
791
}
790
792
}
791
793
}
@@ -794,7 +796,7 @@ sub get_request_columns {
794
796
if ($_ =~ m /\s +as\s +([^\s ]+)\s *$ / mx ) {
795
797
$_ =~ s /\s +as\s +([^\s ]+)\s *$// mx ; # strip "as alias" from column
796
798
} else {
797
- $_ =~ s / ^([^:]+):. *?$/ $1 / gmx ; # strip alias
799
+ $_ =~ s / ^([^:]+):[^"'] *?$/ $1 / gmx ; # strip alias
798
800
}
799
801
$_ =~ s / ^.*\( ([^)]+)\) $/ $1 / gmx ; # extract column name from aggregation function
800
802
}
@@ -821,7 +823,7 @@ sub get_aliased_columns {
821
823
if ($col =~ m / ^([^:]+)\s +as\s +(.*)$ / mx ) {
822
824
$alias_columns -> {$2 } = $1 ;
823
825
}
824
- elsif ($col =~ m / ^([^:]+):(. *)$ / mx ) {
826
+ elsif ($col =~ m / ^([^:]+):([^"'] *)$ / mx ) {
825
827
$alias_columns -> {$2 } = $1 ;
826
828
}
827
829
}
@@ -929,15 +931,27 @@ sub _apply_columns {
929
931
}
930
932
}
931
933
934
+ # extract helpful meta information from data
935
+ my $firstrow ;
936
+ if ($data && $data -> [0]) {
937
+ $firstrow = $data -> [0];
938
+ }
939
+ for my $col (@{$columns }) {
940
+ $c -> stash-> {' meta_column_info' }-> {$col -> {' orig' }} = $col ;
941
+ if ($firstrow && $firstrow -> {$col -> {' column' }." _unit" }) {
942
+ $col -> {' unit' } = $firstrow -> {$col -> {' column' }." _unit" };
943
+ }
944
+ }
945
+
932
946
my $res = [];
933
947
for my $d (@{$data }) {
934
948
my $row = {};
935
- for my $c (@{$columns }) {
936
- my $val = $d -> {$c -> {' orig' }} // $d -> {$c -> {' column' }};
937
- for my $f (@{$c -> {' func' }}) {
938
- $val = _apply_data_function($f , $val );
949
+ for my $col (@{$columns }) {
950
+ my $val = $d -> {$col -> {' orig' }} // $d -> {$col -> {' column' }};
951
+ for my $f (@{$col -> {' func' }}) {
952
+ $val = _apply_data_function($col , $ f , $val );
939
953
}
940
- $row -> {$c -> {' alias' }} = $val ;
954
+ $row -> {$col -> {' alias' }} = $val ;
941
955
}
942
956
push @{$res }, $row ;
943
957
}
@@ -947,7 +961,7 @@ sub _apply_columns {
947
961
948
962
# #########################################################
949
963
sub _apply_data_function {
950
- my ($f , $val ) = @_ ;
964
+ my ($col , $ f , $val ) = @_ ;
951
965
my ($name , $args ) = @{$f };
952
966
if ($name eq ' lower' || $name eq ' lc' ) {
953
967
return lc ($val // ' ' );
@@ -962,7 +976,41 @@ sub _apply_data_function {
962
976
if (defined $args -> [0]) {
963
977
return (substr ($val // ' ' , $args -> [0]));
964
978
}
965
- die (" usage: substr(value, start[, length])" );
979
+ die (" usage: substr(column, start[, length])" );
980
+ }
981
+ if ($name eq ' calc' ) {
982
+ my $op = _trim_quotes($args -> [0]);
983
+ my $v = _trim_quotes($args -> [1]);
984
+ die (" usage: calc(column, 'operator', 'value')" ) if (!defined $op || !defined $v );
985
+ if ($op eq ' *' ) {
986
+ $val *= $v ;
987
+ } elsif ($op eq ' /' ) {
988
+ $val = $val / $v ;
989
+ } elsif ($op eq ' +' || $op eq ' ' || $op eq ' ' ) { # assume space as +, might have been url decoded
990
+ $val = $val + $v ;
991
+ } elsif ($op eq ' -' ) {
992
+ $val = $val - $v ;
993
+ } else {
994
+ die (" unsupported operator, use one of: + - * /" );
995
+ }
996
+ return $val ;
997
+ }
998
+ if ($name eq ' s' ) {
999
+ my $regexp = _trim_quotes($args -> [0]);
1000
+ my $replace = _trim_quotes($args -> [1]);
1001
+ die (" usage: s(column, 'regexp', 'replacement')" ) if (!$regexp || !defined $replace );
1002
+ $regexp = _trim_re($regexp );
1003
+ # # no critic
1004
+ my $re = qr ($regexp ) ;
1005
+ $val =~ s / $re/ $replace / g ;
1006
+ # # use critic
1007
+ return $val ;
1008
+ }
1009
+
1010
+ # just set the unit, do not change the value
1011
+ if ($name eq ' unit' ) {
1012
+ $col -> {' unit' } = _trim_quotes($args -> [0]);
1013
+ return $val ;
966
1014
}
967
1015
968
1016
die (" unknown function: " .$name );
@@ -1315,14 +1363,20 @@ sub _get_columns_meta_for_path {
1315
1363
last ;
1316
1364
}
1317
1365
1318
- return unless scalar keys %{$columns } > 0;
1319
-
1320
1366
my $meta = [];
1321
1367
for my $d (@{$req_columns }) {
1322
1368
my $col = $columns -> {$alias_columns -> {$d } // $d } // {};
1323
1369
$col -> {' name' } = $d ;
1370
+ my $hint = $c -> stash-> {' meta_column_info' }-> {$alias_columns -> {$d } // $d } // $c -> stash-> {' meta_column_info' }-> {$d };
1371
+ if ((!defined $col -> {' config' } || !defined $col -> {' config' }-> {' unit' }) && $hint ) {
1372
+ if (defined $hint -> {' unit' }) {
1373
+ $col -> {' config' }-> {' unit' } = $hint -> {' unit' };
1374
+ $col -> {' type' } = ' number' unless $col -> {' type' };
1375
+ }
1376
+ }
1324
1377
push @{$meta }, $col ;
1325
1378
}
1379
+
1326
1380
return $meta ;
1327
1381
}
1328
1382
@@ -2498,7 +2552,7 @@ sub _parse_columns_data {
2498
2552
if ($c =~ m / ^(.+)\s +as\s +(.*?)$ / gmx ) {
2499
2553
$name = $1 ;
2500
2554
$alias = $2 ;
2501
- } elsif ($c =~ m / ^(.+):(. *?)$ / gmx ) {
2555
+ } elsif ($c =~ m / ^(.+):([^"'] *?)$ / gmx ) {
2502
2556
$name = $1 ;
2503
2557
$alias = $2 ;
2504
2558
}
@@ -2586,6 +2640,31 @@ sub _split_by_comma {
2586
2640
return @res ;
2587
2641
}
2588
2642
2643
+ # #########################################################
2644
+ # remove quotes from string
2645
+ sub _trim_quotes {
2646
+ my ($val ) = @_ ;
2647
+ return unless defined $val ;
2648
+ if ($val =~ s / ^'(.*)'$/ $1 / mx ) {
2649
+ return $val ;
2650
+ }
2651
+ if ($val =~ s / ^"(.*)"$/ $1 / mx ) {
2652
+ return $val ;
2653
+ }
2654
+ return $val ;
2655
+ }
2656
+
2657
+ # #########################################################
2658
+ # remove slashes from string
2659
+ sub _trim_re {
2660
+ my ($val ) = @_ ;
2661
+ return unless defined $val ;
2662
+ if ($val =~ s | ^/(.*)/$| $1 | mx ) {
2663
+ return $val ;
2664
+ }
2665
+ return $val ;
2666
+ }
2667
+
2589
2668
# #########################################################
2590
2669
2591
2670
1;
0 commit comments