File Coverage

blib/lib/OPTIMADE/Filter/AndOr.pm
Criterion Covered Total %
statement 64 93 68.8
branch 14 32 43.7
condition 2 6 33.3
subroutine 10 14 71.4
pod 0 10 0.0
total 90 155 58.0


line stmt bran cond sub pod time code
1             package OPTIMADE::Filter::AndOr;
2              
3 5     5   37 use strict;
  5         10  
  5         158  
4 5     5   28 use warnings;
  5         9  
  5         216  
5              
6 5     5   2298 use parent 'OPTIMADE::Filter::Modifiable';
  5         1456  
  5         28  
7              
8 5     5   333 use Scalar::Util qw(blessed);
  5         10  
  5         12410  
9              
10             sub new {
11 116     116 0 237 my $class = shift;
12 116         170 my $operator;
13             my @operands;
14              
15 116 50       334 if( @_ == 2 ) {
    50          
16 0         0 @operands = @_;
17             } elsif( @_ == 3 ) {
18 116         275 ( $operands[0], $operator, $operands[1] ) = @_;
19             }
20 116         451 return bless { operands => \@operands,
21             operator => $operator }, $class;
22             }
23              
24             sub operator {
25 171     171 0 288 my( $self, $operator ) = @_;
26 171         270 my $previous_operator = $self->{operator};
27 171 50       321 $self->{operator} = $operator if defined $operator;
28 171         430 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 114     114 0 18878 my( $self ) = @_;
64 114         275 $self->validate;
65              
66 114         226 my $operator = $self->{operator};
67 114         165 my @operands;
68 114         174 for my $i (0..$#{$self->{operands}}) {
  114         280  
69 228         374 my $arg = $self->{operands}[$i];
70 228 50 33     1209 if( blessed $arg && $arg->can( 'to_filter' ) ) {
71 228         593 $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 228         505 push @operands, $arg;
78             }
79              
80 114         462 return "($operands[0] $operator $operands[1])";
81             }
82              
83             sub to_SQL
84             {
85 57     57 0 277 my( $self, $options ) = @_;
86 57         128 $self->validate;
87              
88 57 100       134 $options = {} unless $options;
89             my( $delim, $placeholder ) = (
90             $options->{delim},
91             $options->{placeholder},
92 57         116 );
93 57 50       112 $delim = "'" unless $delim;
94              
95 57         91 my $operator = $self->{operator};
96 57         87 my @operands;
97             my @values;
98 57         78 for my $i (0..$#{$self->{operands}}) {
  57         143  
99 114         180 my $arg = $self->{operands}[$i];
100 114 50 33     526 if( blessed $arg && $arg->can( 'to_SQL' ) ) {
101 114         203 my $values = [];
102 114         171 eval { ( $arg, $values ) = $arg->to_SQL( $options ) };
  114         325  
103 114 100       240 if( $@ ) {
104 14         28 chomp $@;
105 14         29 $arg = "<$@>";
106             }
107 114         274 push @values, @$values;
108             } else {
109 0         0 push @values, $arg;
110 0 0       0 if( $placeholder ) {
111 0         0 $arg = $placeholder;
112             } else {
113 0         0 $arg =~ s/"/""/g;
114 0         0 $arg = "\"$arg\"";
115             }
116             }
117 114         233 push @operands, $arg;
118             }
119              
120 57 100       100 if( wantarray ) {
121 42         177 return ( "($operands[0] $operator $operands[1])", \@values );
122             } else {
123 15         121 return "($operands[0] $operator $operands[1])";
124             }
125             }
126              
127             sub modify
128             {
129 2     2 0 5 my $self = shift;
130 2         3 my $code = shift;
131              
132 4         49 $self->{operands} = [ map { OPTIMADE::Filter::Modifiable::modify( $_, $code, @_ ) }
133 2         3 @{$self->{operands}} ];
  2         8  
134 2         20 return $code->( $self, @_ );
135             }
136              
137             sub validate
138             {
139 171     171 0 270 my $self = shift;
140              
141 171 50       271 if( @{$self->{operands}} != 2 ) {
  171         432  
142             die 'number of operands for OPTIMADE::Filter::AndOr must be 2, ' .
143 0         0 'got ' . @{$self->{operands}};
  0         0  
144             }
145 171 50       319 die 'operator undefined for OPTIMADE::Filter::AndOr' if !$self->operator;
146             }
147              
148             1;