Author: spadkins
Date: Tue Sep 11 12:50:08 2007
New Revision: 9936

Modified:
   p5ee/trunk/App-Repository/CHANGES
   p5ee/trunk/App-Repository/lib/App/Repository.pm
   p5ee/trunk/App-Repository/t/Repository-expr.t

Log:
improve the constant expression evaluation with booleans and functions

Modified: p5ee/trunk/App-Repository/CHANGES
==============================================================================
--- p5ee/trunk/App-Repository/CHANGES   (original)
+++ p5ee/trunk/App-Repository/CHANGES   Tue Sep 11 12:50:08 2007
@@ -3,11 +3,15 @@
 #########################################
 
 0.966 (not yet released)
+ x App::Repository::create_temporary_object_set(): can create a temporary 
object set with data, not bound to the database
+ x App::Repository::create_temporary_object_domain(): can create a temporary 
object domain with data, not bound to the database
  x App::Repository::evaluate_expression(): can now supply defaults for null 
columns
  x App::Repository::evaluate_expression(): added column defaults
  x App::Repository::evaluate_expression(): fixed to be more efficient and to 
handle defaults on columns which are expressions themselves
  x App::Repository::evaluate_expression(): fixed a bug when evaluating 
expressions of columns that end in digits
  x App::Repository::evaluate_expression(): fixed a bug where using a hashref 
instead of arrayref
+ x App::Repository::evaluate_constant_expression(): can also do simple 
functions (abs(x), min(x,y), max(x,y), if(x,y,z), ifnull(x,y), 
case(x,y,a,z,b,c))
+ x App::Repository::evaluate_constant_expression(): can also do boolean 
operators (=, !=, <, <=, >, >=)
  x App::Repository::evaluate_constant_expression(): fix for div 0 and sci 
notation
  x App::Repository::summarize_rows(): can now summarize columns which have 
alternate aggregate levels
  x App::Repository::summarize_rows(): produce an undef if all values that are 
summed are undef

Modified: p5ee/trunk/App-Repository/lib/App/Repository.pm
==============================================================================
--- p5ee/trunk/App-Repository/lib/App/Repository.pm     (original)
+++ p5ee/trunk/App-Repository/lib/App/Repository.pm     Tue Sep 11 12:50:08 2007
@@ -3621,6 +3621,47 @@
                     $val = $vals[0] < 0 ? -$vals[0] : $vals[0];
                 }
             }
+            elsif ($func eq "ifnull") {
+                if ($#vals == 1) {
+                    if (! defined $vals[0] || $vals[0] eq "undef") {
+                        $val = $vals[1];
+                    }
+                    else {
+                        $val = $vals[0];
+                    }
+                }
+            }
+            elsif ($func eq "if") {
+                if ($#vals == 2) {
+                    $val = $vals[0] ? $vals[1] : $vals[2];
+                }
+            }
+            elsif ($func eq "case") {
+                if (! defined $vals[0]) {
+                    for (my $i = 1; $i <= $#vals; $i += 2) {
+                        if ($i == $#vals) {  # the default
+                            $val = $vals[$i];
+                            last;
+                        }
+                        elsif (! defined $vals[$i]) {
+                            $val = $vals[$i+1];
+                            last;
+                        }
+                    }
+                }
+                else {
+                    for (my $i = 1; $i <= $#vals; $i += 2) {
+                        if ($i == $#vals) {  # the default
+                            $val = $vals[$i];
+                            last;
+                        }
+                        elsif (defined $vals[$i] && $vals[$i] == $vals[0]) {
+                            $val = $vals[$i+1];
+                            last;
+                        }
+                    }
+                }
+            }
             else { # unknown function name
                 $val = "undef";
             }
@@ -3647,6 +3688,10 @@
             #print "EXPR: $1 $2 $3 = $value\n";
             # nothing else needed
         }
+        while ($value =~ s~($NUM)\s*(!=|=|<|<=|>|>=)\s*($NUM)~(!defined $1 || 
!defined $3) ? "undef" : $self->evaluate_boolean_expression($1,$2,$3)~e) {
+            #print "EXPR: $1 $2 $3 = $value\n";
+            # nothing else needed
+        }
         $value = undef if ($value =~ /undef/);
     }
 
@@ -3654,6 +3699,34 @@
     return($value);
 }
 
+sub evaluate_boolean_expression {
+    &App::sub_entry if ($App::trace);
+    my ($self, $lhs, $op, $rhs) = @_;
+    my $value = 0;
+    if (defined $lhs && defined $rhs) {
+        if ($op eq "=") {
+            $value = ($lhs == $rhs) ? 1 : 0;
+        }
+        elsif ($op eq "!=") {
+            $value = ($lhs != $rhs) ? 1 : 0;
+        }
+        elsif ($op eq "<=") {
+            $value = ($lhs <= $rhs) ? 1 : 0;
+        }
+        elsif ($op eq "<") {
+            $value = ($lhs < $rhs) ? 1 : 0;
+        }
+        elsif ($op eq ">=") {
+            $value = ($lhs >= $rhs) ? 1 : 0;
+        }
+        elsif ($op eq ">") {
+            $value = ($lhs > $rhs) ? 1 : 0;
+        }
+    }
+    &App::sub_exit($value) if ($App::trace);
+    return($value);
+}
+
 #############################################################################
 # serial()
 #############################################################################

Modified: p5ee/trunk/App-Repository/t/Repository-expr.t
==============================================================================
--- p5ee/trunk/App-Repository/t/Repository-expr.t       (original)
+++ p5ee/trunk/App-Repository/t/Repository-expr.t       Tue Sep 11 12:50:08 2007
@@ -42,6 +42,37 @@
     is(App::Repository->evaluate_constant_expression("min(-1,0,6,3)"), -1, 
"eval: min(-1,0,6,3)");
     ok(App::Repository->evaluate_constant_expression("max(-1.3,-3e-1)") == 
-.3, "eval: max(-1.3,-3e-1)");
     ok(App::Repository->evaluate_constant_expression("min(-1.3,-3e-1)") == 
-1.3, "eval: min(-1.3,-3e-1)");
+    is(App::Repository->evaluate_constant_expression("1 > 2"), 0, "eval: 1 > 
2");
+    is(App::Repository->evaluate_constant_expression("(1.5*3)>2"), 1, "eval: 
(1.5*3)>2");
+    is(App::Repository->evaluate_constant_expression("(1.5*3)=4.5"), 1, "eval: 
(1.5*3)=4.5");
+    is(App::Repository->evaluate_constant_expression("(1.5*3)=4"), 0, "eval: 
(1.5*3)=4");
+    is(App::Repository->evaluate_constant_expression("2<-1"),  0, "eval: 
2<-1");
+    is(App::Repository->evaluate_constant_expression("2<2"),   0, "eval: 2<2");
+    is(App::Repository->evaluate_constant_expression("0<2"),   1, "eval: 0<2");
+    is(App::Repository->evaluate_constant_expression("2<=-1"), 0, "eval: 
2<=-1");
+    is(App::Repository->evaluate_constant_expression("2<=2"),  1, "eval: 
2<=2");
+    is(App::Repository->evaluate_constant_expression("0<=2"),  1, "eval: 
0<=2");
+    is(App::Repository->evaluate_constant_expression("2>-1"),  1, "eval: 
2>-1");
+    is(App::Repository->evaluate_constant_expression("2>2"),   0, "eval: 2>2");
+    is(App::Repository->evaluate_constant_expression("0>2"),   0, "eval: 0>2");
+    is(App::Repository->evaluate_constant_expression("2>=-1"), 1, "eval: 
2>=-1");
+    is(App::Repository->evaluate_constant_expression("2>=2"),  1, "eval: 
2>=2");
+    is(App::Repository->evaluate_constant_expression("0>=2"),  0, "eval: 
0>=2");
+    is(App::Repository->evaluate_constant_expression("2=-1"),  0, "eval: 
2=-1");
+    is(App::Repository->evaluate_constant_expression("2=2"),   1, "eval: 2=2");
+    is(App::Repository->evaluate_constant_expression("0=2"),   0, "eval: 0=2");
+    is(App::Repository->evaluate_constant_expression("2!=-1"), 1, "eval: 
2!=-1");
+    is(App::Repository->evaluate_constant_expression("2!=2"),  0, "eval: 
2!=2");
+    is(App::Repository->evaluate_constant_expression("0!=2"),  1, "eval: 
0!=2");
+    is(App::Repository->evaluate_constant_expression("ifnull(undef,2)"), 2, 
"eval: ifnull(undef,2)");
+    is(App::Repository->evaluate_constant_expression("ifnull(3,2)"),     3, 
"eval: ifnull(3,2)");
+    is(App::Repository->evaluate_constant_expression("if(3>4,5,6)"),     6, 
"eval: if(3>4,5,6)");
+    is(App::Repository->evaluate_constant_expression("if(3<4,5,6)"),     5, 
"eval: if(3<4,5,6)");
+    is(App::Repository->evaluate_constant_expression("case(7)"),         
undef, "eval: case(7)");
+    is(App::Repository->evaluate_constant_expression("case(7,17)"),      17, 
"eval: case(7,17)");
+    is(App::Repository->evaluate_constant_expression("case(7+2,8,18,9,19)"), 
19, "eval: case(7+2,8,18,9,19)");
+    is(App::Repository->evaluate_constant_expression("case(7+2,8,18)"), undef, 
"eval: case(7+2,8,18)");
+    is(App::Repository->evaluate_constant_expression("case(7+2,8,18,20)"), 20, 
"eval: case(7+2,8,18,20)");
 
     my %values = (
         x  => 3,

Reply via email to