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   43 use strict;
  5         11  
  5         154  
4 5     5   25 use warnings;
  5         11  
  5         132  
5 5     5   24 use Scalar::Util qw(blessed);
  5         9  
  5         5342  
6              
7             sub new {
8 116     116 0 207 my $class = shift;
9 116         191 my $operator;
10             my @operands;
11              
12 116 50       329 if( @_ == 2 ) {
    50          
13 0         0 @operands = @_;
14             } elsif( @_ == 3 ) {
15 116         285 ( $operands[0], $operator, $operands[1] ) = @_;
16             }
17 116         453 return bless { operands => \@operands,
18             operator => $operator }, $class;
19             }
20              
21             sub operator {
22 171     171 0 297 my( $self, $operator ) = @_;
23 171         288 my $previous_operator = $self->{operator};
24 171 50       319 $self->{operator} = $operator if defined $operator;
25 171         426 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 20756 my( $self ) = @_;
61 114         276 $self->validate;
62              
63 114         220 my $operator = $self->{operator};
64 114         149 my @operands;
65 114         171 for my $i (0..$#{$self->{operands}}) {
  114         299  
66 228         365 my $arg = $self->{operands}[$i];
67 228 50 33     1225 if( blessed $arg && $arg->can( 'to_filter' ) ) {
68 228         534 $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         505 push @operands, $arg;
75             }
76              
77 114         465 return "($operands[0] $operator $operands[1])";
78             }
79              
80             sub to_SQL
81             {
82 57     57 0 289 my( $self, $options ) = @_;
83 57         134 $self->validate;
84              
85 57 100       145 $options = {} unless $options;
86             my( $delim, $placeholder ) = (
87             $options->{delim},
88             $options->{placeholder},
89 57         125 );
90 57 50       127 $delim = "'" unless $delim;
91              
92 57         96 my $operator = $self->{operator};
93 57         87 my @operands;
94             my @values;
95 57         91 for my $i (0..$#{$self->{operands}}) {
  57         144  
96 114         196 my $arg = $self->{operands}[$i];
97 114 50 33     622 if( blessed $arg && $arg->can( 'to_SQL' ) ) {
98 114         215 my $values = [];
99 114         175 eval { ( $arg, $values ) = $arg->to_SQL( $options ) };
  114         296  
100 114 100       270 if( $@ ) {
101 14         26 chomp $@;
102 14         34 $arg = "<$@>";
103             }
104 114         267 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         250 push @operands, $arg;
115             }
116              
117 57 100       111 if( wantarray ) {
118 42         172 return ( "($operands[0] $operator $operands[1])", \@values );
119             } else {
120 15         113 return "($operands[0] $operator $operands[1])";
121             }
122             }
123              
124             sub modify
125             {
126 2     2 0 3 my $self = shift;
127 2         4 my $code = shift;
128              
129 4         38 $self->{operands} = [ map { OPTiMaDe::Filter::modify( $_, $code, @_ ) }
130 2         3 @{$self->{operands}} ];
  2         7  
131 2         22 return $code->( $self, @_ );
132             }
133              
134             sub validate
135             {
136 171     171 0 295 my $self = shift;
137              
138 171 50       244 if( @{$self->{operands}} != 2 ) {
  171         434  
139             die 'number of operands for OPTiMaDe::Filter::AndOr must be 2, ' .
140 0         0 'got ' . @{$self->{operands}};
  0         0  
141             }
142 171 50       379 die 'operator undefined for OPTiMaDe::Filter::AndOr' if !$self->operator;
143             }
144              
145             1;