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,