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         16  
  5         175  
4 5     5   28 use warnings;
  5         9  
  5         181  
5              
6 5     5   2588 use parent 'OPTIMADE::Filter::Modifiable';
  5         1521  
  5         27  
7 5     5   288 use Scalar::Util qw(blessed);
  5         11  
  5         13706  
8              
9             our $VERSION = '0.10.2'; # VERSION
10              
11             sub new {
12 130     130 0 278 my $class = shift;
13 130         191 my $operator;
14             my @operands;
15              
16 130 50       353 if( @_ == 2 ) {
    50          
17 0         0 @operands = @_;
18             } elsif( @_ == 3 ) {
19 130         311 ( $operands[0], $operator, $operands[1] ) = @_;
20             }
21 130         554 return bless { operands => \@operands,
22             operator => $operator }, $class;
23             }
24              
25             sub operator {
26 204     204 0 368 my( $self, $operator ) = @_;
27 204         346 my $previous_operator = $self->{operator};
28 204 50       383 $self->{operator} = $operator if defined $operator;
29 204         541 return $previous_operator;
30             }
31              
32             sub push_operand
33             {
34 0     0 0 0 my( $self, $operand ) = @_;
35 0 0       0 die 'attempt to insert more than two operands' if @{$self->{operands}} >= 2;
  0         0  
36 0         0 push @{$self->{operands}}, $operand;
  0         0  
37             }
38              
39             sub unshift_operand
40             {
41 0     0 0 0 my( $self, $operand ) = @_;
42 0 0       0 die 'attempt to insert more than two operands' if @{$self->{operands}} >= 2;
  0         0  
43 0         0 unshift @{$self->{operands}}, $operand;
  0         0  
44             }
45              
46             sub left
47             {
48 0     0 0 0 my( $self, $operand ) = @_;
49 0         0 my $previous_operand = $self->{operands}[0];
50 0 0       0 $self->{operands}[0] = $operand if defined $operand;
51 0         0 return $previous_operand;
52             }
53              
54             sub right
55             {
56 0     0 0 0 my( $self, $operand ) = @_;
57 0         0 my $previous_operand = $self->{operands}[1];
58 0 0       0 $self->{operands}[1] = $operand if defined $operand;
59 0         0 return $previous_operand;
60             }
61              
62             sub to_filter
63             {
64 128     128 0 19708 my( $self ) = @_;
65 128         302 $self->validate;
66              
67 128         240 my $operator = $self->{operator};
68 128         182 my @operands;
69 128         168 for my $i (0..$#{$self->{operands}}) {
  128         305  
70 256         421 my $arg = $self->{operands}[$i];
71 256 50 33     1324 if( blessed $arg && $arg->can( 'to_filter' ) ) {
72 256         610 $arg = $arg->to_filter;
73             } else {
74 0         0 $arg =~ s/\\/\\\\/g;
75 0         0 $arg =~ s/"/\\"/g;
76 0         0 $arg = "\"$arg\"";
77             }
78 256         586 push @operands, $arg;
79             }
80              
81 128         556 return "($operands[0] $operator $operands[1])";
82             }
83              
84             sub to_SQL
85             {
86 64     64 0 332 my( $self, $options ) = @_;
87 64         141 $self->validate;
88              
89 64 50       141 $options = {} unless $options;
90             my( $delim, $flatten, $placeholder ) = (
91             $options->{delim},
92             $options->{flatten},
93             $options->{placeholder},
94 64         135 );
95 64 50       129 $delim = "'" unless $delim;
96              
97 64         97 my $operator = $self->{operator};
98 64         95 my @operands;
99             my @values;
100 64         94 for my $i (0..$#{$self->{operands}}) {
  64         149  
101 128         202 my $arg = $self->{operands}[$i];
102 128 50 33     615 if( blessed $arg && $arg->can( 'to_SQL' ) ) {
103 128         301 my $values = [];
104 128         199 eval { ( $arg, $values ) = $arg->to_SQL( $options ) };
  128         314  
105 128 100       271 if( $@ ) {
106 14         24 chomp $@;
107 14         31 $arg = "<$@>";
108             }
109 128 100 100     472 if( $self->{operands}[$i]->isa( OPTIMADE::Filter::AndOr:: ) &&
      100        
110             (!$flatten || $self->operator ne $self->{operands}[$i]->operator) ) {
111 39         89 $arg = "($arg)";
112             }
113 128         311 push @values, @$values;
114             } else {
115 0         0 push @values, $arg;
116 0 0       0 if( $placeholder ) {
117 0         0 $arg = $placeholder;
118             } else {
119 0         0 $arg =~ s/"/""/g;
120 0         0 $arg = "\"$arg\"";
121             }
122             }
123 128         258 push @operands, $arg;
124             }
125              
126 64 100       127 if( wantarray ) {
127 48         181 return ( "$operands[0] $operator $operands[1]", \@values );
128             } else {
129 16         104 return "$operands[0] $operator $operands[1]";
130             }
131             }
132              
133             sub modify
134             {
135 2     2 0 4 my $self = shift;
136 2         4 my $code = shift;
137              
138 4         38 $self->{operands} = [ map { OPTIMADE::Filter::Modifiable::modify( $_, $code, @_ ) }
139 2         6 @{$self->{operands}} ];
  2         19  
140 2         30 return $code->( $self, @_ );
141             }
142              
143             sub validate
144             {
145 192     192 0 292 my $self = shift;
146              
147 192 50       267 if( @{$self->{operands}} != 2 ) {
  192         470  
148             die 'number of operands for OPTIMADE::Filter::AndOr must be 2, ' .
149 0         0 'got ' . @{$self->{operands}};
  0         0  
150             }
151 192 50       368 die 'operator undefined for OPTIMADE::Filter::AndOr' if !$self->operator;
152             }
153              
154             1;