File Coverage

blib/lib/OPTIMADE/Filter/AndOr.pm
Criterion Covered Total %
statement 66 95 69.4
branch 15 34 44.1
condition 8 12 66.6
subroutine 10 14 71.4
pod 0 10 0.0
total 99 165 60.0


line stmt bran cond sub pod time code
1             package OPTIMADE::Filter::AndOr;
2              
3 5     5   38 use strict;
  5         10  
  5         156  
4 5     5   29 use warnings;
  5         9  
  5         177  
5              
6 5     5   2403 use parent 'OPTIMADE::Filter::Modifiable';
  5         1464  
  5         28  
7              
8 5     5   300 use Scalar::Util qw(blessed);
  5         10  
  5         13113  
9              
10             sub new {
11 130     130 0 232 my $class = shift;
12 130         213 my $operator;
13             my @operands;
14              
15 130 50       356 if( @_ == 2 ) {
    50          
16 0         0 @operands = @_;
17             } elsif( @_ == 3 ) {
18 130         320 ( $operands[0], $operator, $operands[1] ) = @_;
19             }
20 130         540 return bless { operands => \@operands,
21             operator => $operator }, $class;
22             }
23              
24             sub operator {
25 204     204 0 351 my( $self, $operator ) = @_;
26 204         332 my $previous_operator = $self->{operator};
27 204 50       404 $self->{operator} = $operator if defined $operator;
28 204         532 return $previous_operator;
29             }
30              
31             sub push_operand
32             {
33 0     0 0 0 my( $self, $operand ) = @_;
34 0 0       0 die 'attempt to insert more than two operands' if @{$self->{operands}} >= 2;
  0         0  
35 0         0 push @{$self->{operands}}, $operand;
  0         0  
36             }
37              
38             sub unshift_operand
39             {
40 0     0 0 0 my( $self, $operand ) = @_;
41 0 0       0 die 'attempt to insert more than two operands' if @{$self->{operands}} >= 2;
  0         0  
42 0         0 unshift @{$self->{operands}}, $operand;
  0         0  
43             }
44              
45             sub left
46             {
47 0     0 0 0 my( $self, $operand ) = @_;
48 0         0 my $previous_operand = $self->{operands}[0];
49 0 0       0 $self->{operands}[0] = $operand if defined $operand;
50 0         0 return $previous_operand;
51             }
52              
53             sub right
54             {
55 0     0 0 0 my( $self, $operand ) = @_;
56 0         0 my $previous_operand = $self->{operands}[1];
57 0 0       0 $self->{operands}[1] = $operand if defined $operand;
58 0         0 return $previous_operand;
59             }
60              
61             sub to_filter
62             {
63 128     128 0 20425 my( $self ) = @_;
64 128         316 $self->validate;
65              
66 128         254 my $operator = $self->{operator};
67 128         187 my @operands;
68 128         182 for my $i (0..$#{$self->{operands}}) {
  128         308  
69 256         420 my $arg = $self->{operands}[$i];
70 256 50 33     1347 if( blessed $arg && $arg->can( 'to_filter' ) ) {
71 256         611 $arg = $arg->to_filter;
72             } else {
73 0         0 $arg =~ s/\\/\\\\/g;
74 0         0 $arg =~ s/"/\\"/g;
75 0         0 $arg = "\"$arg\"";
76             }
77 256         563 push @operands, $arg;
78             }
79              
80 128         512 return "($operands[0] $operator $operands[1])";
81             }
82              
83             sub to_SQL
84             {
85 64     64 0 358 my( $self, $options ) = @_;
86 64         145 $self->validate;
87              
88 64 50       140 $options = {} unless $options;
89             my( $delim, $flatten, $placeholder ) = (
90             $options->{delim},
91             $options->{flatten},
92             $options->{placeholder},
93 64         155 );
94 64 50       182 $delim = "'" unless $delim;
95              
96 64         111 my $operator = $self->{operator};
97 64         91 my @operands;
98             my @values;
99 64         90 for my $i (0..$#{$self->{operands}}) {
  64         164  
100 128         205 my $arg = $self->{operands}[$i];
101 128 50 33     692 if( blessed $arg && $arg->can( 'to_SQL' ) ) {
102 128         251 my $values = [];
103 128         201 eval { ( $arg, $values ) = $arg->to_SQL( $options ) };
  128         314  
104 128 100       299 if( $@ ) {
105 14         27 chomp $@;
106 14         31 $arg = "<$@>";
107             }
108 128 100 100     509 if( $self->{operands}[$i]->isa( OPTIMADE::Filter::AndOr:: ) &&
      100        
109             (!$flatten || $self->operator ne $self->{operands}[$i]->operator) ) {
110 39         99 $arg = "($arg)";
111             }
112 128         359 push @values, @$values;
113             } else {
114 0         0 push @values, $arg;
115 0 0       0 if( $placeholder ) {
116 0         0 $arg = $placeholder;
117             } else {
118 0         0 $arg =~ s/"/""/g;
119 0         0 $arg = "\"$arg\"";
120             }
121             }
122 128         286 push @operands, $arg;
123             }
124              
125 64 100       129 if( wantarray ) {
126 48         186 return ( "$operands[0] $operator $operands[1]", \@values );
127             } else {
128 16         148 return "$operands[0] $operator $operands[1]";
129             }
130             }
131              
132             sub modify
133             {
134 2     2 0 5 my $self = shift;
135 2         3 my $code = shift;
136              
137 4         37 $self->{operands} = [ map { OPTIMADE::Filter::Modifiable::modify( $_, $code, @_ ) }
138 2         4 @{$self->{operands}} ];
  2         6  
139 2         20 return $code->( $self, @_ );
140             }
141              
142             sub validate
143             {
144 192     192 0 296 my $self = shift;
145              
146 192 50       259 if( @{$self->{operands}} != 2 ) {
  192         458  
147             die 'number of operands for OPTIMADE::Filter::AndOr must be 2, ' .
148 0         0 'got ' . @{$self->{operands}};
  0         0  
149             }
150 192 50       426 die 'operator undefined for OPTIMADE::Filter::AndOr' if !$self->operator;
151             }
152              
153             1;