1# See bottom of file for license and copyright information
2package Foswiki::Query::ConditionalOP;
3
4=begin TML
5
6---+ package Foswiki::Query::ConditionalOP
7Base class for binary conditional operators.
8
9=cut
10
11use strict;
12use warnings;
13use Foswiki::Query::OP;
14our @ISA = ('Foswiki::Query::OP');
15
16sub new {
17    my $class = shift;
18    return $class->SUPER::new( arity => 2, @_ );
19}
20
21=begin TML
22
23---++ StaticMethod compare($a, $b, \&fn) -> $boolean
24
25Apply a binary comparison function to two data, tolerant
26of whether they are numeric or not. =\&fn= takes a single parameter,
27which is the result of a =<=>= comparison on =$a= and =$b=. The result
28of applying =\&fn= is returned.
29
30=cut
31
32sub compare {
33    my ( $a, $b, $sub ) = @_;
34    if ( !defined($a) ) {
35        return &$sub(0) unless defined($b);
36        return -&$sub(1);
37    }
38    elsif ( !defined($b) ) {
39        return &$sub(1);
40    }
41    if (   Foswiki::Query::OP::isNumber($a)
42        && Foswiki::Query::OP::isNumber($b) )
43    {
44        return &$sub( $a <=> $b );
45    }
46    else {
47        return &$sub( $a cmp $b );
48    }
49}
50
51=begin TML
52
53---++ ObjectMethod evalTest($node, $clientData, \&fn) -> $result
54Evaluate a node using the comparison function passed in. Extra parameters
55are passed on to the comparison function. If the LHS of the node
56evaluates to an array, the result will be an array made by
57applying =\&fn= to each member of the LHS array. The RHS is passed on
58untouched to \&fn. Thus =(1,-1) > 1= will yield (1,0)
59
60=cut
61
62sub evalTest {
63    my $this       = shift;
64    my $node       = shift;
65    my $clientData = shift;
66    my $sub        = shift;
67    my $a          = $node->{params}[0];
68    my $b          = $node->{params}[1];
69    my $ea         = $a->evaluate( @{$clientData} );
70    my $eb         = $b->evaluate( @{$clientData} );
71    $ea = '' unless defined $ea;
72    $eb = '' unless defined $eb;
73
74    if ( ref($ea) eq 'ARRAY' ) {
75        my @res;
76        foreach my $lhs (@$ea) {
77            push( @res, $lhs ) if &$sub( $lhs, $eb, @_ );
78        }
79        if ( scalar(@res) == 0 ) {
80            return;
81        }
82        elsif ( scalar(@res) == 1 ) {
83            return $res[0];
84        }
85        return \@res;
86    }
87    else {
88        return &$sub( $ea, $eb, @_ );
89    }
90}
91
921;
93__END__
94Author: Crawford Currie http://c-dot.co.uk
95
96Foswiki - The Free and Open Source Wiki, http://foswiki.org/
97
98Copyright (C) 2008-2011 Foswiki Contributors. Foswiki Contributors
99are listed in the AUTHORS file in the root of this distribution.
100NOTE: Please extend that file, not this notice.
101
102This program is free software; you can redistribute it and/or
103modify it under the terms of the GNU General Public License
104as published by the Free Software Foundation; either version 2
105of the License, or (at your option) any later version. For
106more details read LICENSE in the root of this distribution.
107
108This program is distributed in the hope that it will be useful,
109but WITHOUT ANY WARRANTY; without even the implied warranty of
110MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
111
112As per the GPL, removal of this notice is prohibited.
113