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   41 use strict;
  5         12  
  5         197  
4 5     5   25 use warnings;
  5         9  
  5         325  
5              
6 5     5   2370 use parent 'OPTIMADE::Filter::Modifiable';
  5         1544  
  5         31  
7 5     5   378 use Scalar::Util qw(blessed);
  5         24  
  5         6844  
8              
9             our $VERSION = '0.11.0'; # VERSION
10              
11             sub new {
12 142     142 0 335 my $class = shift;
13 142         275 my $operator;
14             my @operands;
15              
16 142 50       581 if( @_ == 2 ) {
    50          
17 0         0 @operands = @_;
18             } elsif( @_ == 3 ) {
19 142         448 ( $operands[0], $operator, $operands[1] ) = @_;
20             }
21 142         914 return bless { operands => \@operands,
22             operator => $operator }, $class;
23             }
24              
25             sub operator {
26 222     222 0 443 my( $self, $operator ) = @_;
27 222         435 my $previous_operator = $self->{operator};
28 222 50       574 $self->{operator} = $operator if defined $operator;
29 222         710 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 140     140 0 38739 my( $self ) = @_;
65 140         411 $self->validate;
66              
67 140         297 my $operator = $self->{operator};
68 140         234 my @operands;
69 140         233 for my $i (0..$#{$self->{operands}}) {
  140         517  
70 280         602 my $arg = $self->{operands}[$i];
71 280 50 33     1650 if( blessed $arg && $arg->can( 'to_filter' ) ) {
72 280         858 $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 280         671 push @operands, $arg;
79             }
80              
81 140         739 return "($operands[0] $operator $operands[1])";
82             }
83              
84             sub to_SQL
85             {
86 70     70 0 643 my( $self, $options ) = @_;
87 70         199 $self->validate;
88              
89 70 50       176 $options = {} unless $options;
90             my( $delim, $flatten, $placeholder ) = (
91             $options->{delim},
92             $options->{flatten},
93             $options->{placeholder},
94 70         222 );
95 70 50       194 $delim = "'" unless $delim;
96              
97 70         151 my $operator = $self->{operator};
98 70         131 my @operands;
99             my @values;
100 70         158 for my $i (0..$#{$self->{operands}}) {
  70         276  
101 140         898 my $arg = $self->{operands}[$i];
102 140 50 33     735 if( blessed $arg && $arg->can( 'to_SQL' ) ) {
103 140         266 my $values = [];
104 140         264 eval { ( $arg, $values ) = $arg->to_SQL( $options ) };
  140         428  
105 140 100       344 if( $@ ) {
106 24         48 chomp $@;
107 24         47 $arg = "<$@>";
108             }
109 140 100 100     803 if( $self->{operands}[$i]->isa( OPTIMADE::Filter::AndOr:: ) &&
      100        
110             (!$flatten || $self->operator ne $self->{operands}[$i]->operator) ) {
111 41         98 $arg = "($arg)";
112             }
113 140         435 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 140         336 push @operands, $arg;
124             }
125              
126 70 100       163 if( wantarray ) {
127 50         227 return ( "$operands[0] $operator $operands[1]", \@values );
128             } else {
129 20         141 return "$operands[0] $operator $operands[1]";
130             }
131             }
132              
133             sub modify
134             {
135 2     2 0 5 my $self = shift;
136 2         4 my $code = shift;
137              
138 4         30 $self->{operands} = [ map { OPTIMADE::Filter::Modifiable::modify( $_, $code, @_ ) }
139 2         4 @{$self->{operands}} ];
  2         9  
140 2         12 return $code->( $self, @_ );
141             }
142              
143             sub validate
144             {
145 210     210 0 376 my $self = shift;
146              
147 210 50       364 if( @{$self->{operands}} != 2 ) {
  210         651  
148             die 'number of operands for OPTIMADE::Filter::AndOr must be 2, ' .
149 0         0 'got ' . @{$self->{operands}};
  0         0  
150             }
151 210 50       550 die 'operator undefined for OPTIMADE::Filter::AndOr' if !$self->operator;
152             }
153              
154             1;