File Coverage

blib/lib/OPTiMaDe/Filter/AndOr.pm
Criterion Covered Total %
statement 61 90 67.7
branch 14 32 43.7
condition 2 6 33.3
subroutine 9 13 69.2
pod 0 10 0.0
total 86 151 56.9


line stmt bran cond sub pod time code
1             package OPTiMaDe::Filter::AndOr;
2              
3 5     5   34 use strict;
  5         8  
  5         142  
4 5     5   24 use warnings;
  5         9  
  5         120  
5 5     5   25 use Scalar::Util qw(blessed);
  5         8  
  5         4959  
6              
7             sub new {
8 116     116 0 177 my $class = shift;
9 116         165 my $operator;
10             my @operands;
11              
12 116 50       325 if( @_ == 2 ) {
    50          
13 0         0 @operands = @_;
14             } elsif( @_ == 3 ) {
15 116         274 ( $operands[0], $operator, $operands[1] ) = @_;
16             }
17 116         417 return bless { operands => \@operands,
18             operator => $operator }, $class;
19             }
20              
21             sub operator {
22 171     171 0 247 my( $self, $operator ) = @_;
23 171         237 my $previous_operator = $self->{operator};
24 171 50       273 $self->{operator} = $operator if defined $operator;
25 171         379 return $previous_operator;
26             }
27              
28             sub push_operand
29             {
30 0     0 0 0 my( $self, $operand ) = @_;
31 0 0       0 die 'attempt to insert more than two operands' if @{$self->{operands}} >= 2;
  0         0  
32 0         0 push @{$self->{operands}}, $operand;
  0         0  
33             }
34              
35             sub unshift_operand
36             {
37 0     0 0 0 my( $self, $operand ) = @_;
38 0 0       0 die 'attempt to insert more than two operands' if @{$self->{operands}} >= 2;
  0         0  
39 0         0 unshift @{$self->{operands}}, $operand;
  0         0  
40             }
41              
42             sub left
43             {
44 0     0 0 0 my( $self, $operand ) = @_;
45 0         0 my $previous_operand = $self->{operands}[0];
46 0 0       0 $self->{operands}[0] = $operand if defined $operand;
47 0         0 return $previous_operand;
48             }
49              
50             sub right
51             {
52 0     0 0 0 my( $self, $operand ) = @_;
53 0         0 my $previous_operand = $self->{operands}[1];
54 0 0       0 $self->{operands}[1] = $operand if defined $operand;
55 0         0 return $previous_operand;
56             }
57              
58             sub to_filter
59             {
60 114     114 0 29465 my( $self ) = @_;
61 114         243 $self->validate;
62              
63 114         176 my $operator = $self->{operator};
64 114         145 my @operands;
65 114         139 for my $i (0..$#{$self->{operands}}) {
  114         258  
66 228         345 my $arg = $self->{operands}[$i];
67 228 50 33     1045 if( blessed $arg && $arg->can( 'to_filter' ) ) {
68 228         456 $arg = $arg->to_filter;
69             } else {
70 0         0 $arg =~ s/\\/\\\\/g;
71 0         0 $arg =~ s/"/\\"/g;
72 0         0 $arg = "\"$arg\"";
73             }
74 228         417 push @operands, $arg;
75             }
76              
77 114         392 return "($operands[0] $operator $operands[1])";
78             }
79              
80             sub to_SQL
81             {
82 57     57 0 292 my( $self, $options ) = @_;
83 57         103 $self->validate;
84              
85 57 100       156 $options = {} unless $options;
86             my( $delim, $placeholder ) = (
87             $options->{delim},
88             $options->{placeholder},
89 57         119 );
90 57 50       98 $delim = "'" unless $delim;
91              
92 57         89 my $operator = $self->{operator};
93 57         77 my @operands;
94             my @values;
95 57         72 for my $i (0..$#{$self->{operands}}) {
  57         139  
96 114         173 my $arg = $self->{operands}[$i];
97 114 50 33     496 if( blessed $arg && $arg->can( 'to_SQL' ) ) {
98 114         176 my $values = [];
99 114         144 eval { ( $arg, $values ) = $arg->to_SQL( $options ) };
  114         237  
100 114 100       219 if( $@ ) {
101 14         25 chomp $@;
102 14         25 $arg = "<$@>";
103             }
104 114         223 push @values, @$values;
105             } else {
106 0         0 push @values, $arg;
107 0 0       0 if( $placeholder ) {
108 0         0 $arg = $placeholder;
109             } else {
110 0         0 $arg =~ s/"/""/g;
111 0         0 $arg = "\"$arg\"";
112             }
113             }
114 114         207 push @operands, $arg;
115             }
116              
117 57 100       108 if( wantarray ) {
118 42         146 return ( "($operands[0] $operator $operands[1])", \@values );
119             } else {
120 15         99 return "($operands[0] $operator $operands[1])";
121             }
122             }
123              
124             sub modify
125             {
126 2     2 0 4 my $self = shift;
127 2         3 my $code = shift;
128              
129 4         36 $self->{operands} = [ map { OPTiMaDe::Filter::modify( $_, $code, @_ ) }
130 2         3 @{$self->{operands}} ];
  2         5  
131 2         19 return $code->( $self, @_ );
132             }
133              
134             sub validate
135             {
136 171     171 0 236 my $self = shift;
137              
138 171 50       194 if( @{$self->{operands}} != 2 ) {
  171         349  
139             die 'number of operands for OPTiMaDe::Filter::AndOr must be 2, ' .
140 0         0 'got ' . @{$self->{operands}};
  0         0  
141             }
142 171 50       286 die 'operator undefined for OPTiMaDe::Filter::AndOr' if !$self->operator;
143             }
144              
145             1;