]> source.dussan.org Git - jackcess.git/commitdiff
add ability to get original expression; implement some parsing tests
authorJames Ahlborn <jtahlborn@yahoo.com>
Tue, 17 Jul 2018 02:27:04 +0000 (02:27 +0000)
committerJames Ahlborn <jtahlborn@yahoo.com>
Tue, 17 Jul 2018 02:27:04 +0000 (02:27 +0000)
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@1181 f203690c-595d-4dc9-a70b-905162fa7fd2

src/main/java/com/healthmarketscience/jackcess/expr/Expression.java
src/main/java/com/healthmarketscience/jackcess/impl/BaseEvalContext.java
src/main/java/com/healthmarketscience/jackcess/impl/expr/Expressionator.java
src/test/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctionsTest.java
src/test/java/com/healthmarketscience/jackcess/impl/expr/ExpressionatorTest.java

index 09fd03bf79f977a005be12f5765de31a4b0154b3..963af7bd94e3bd2030a11d715e6996bc413cefbb 100644 (file)
@@ -22,12 +22,14 @@ import java.util.Collection;
  *
  * @author James Ahlborn
  */
-public interface Expression 
+public interface Expression
 {
   public Object eval(EvalContext ctx);
 
   public String toDebugString();
 
+  public String toRawString();
+
   public boolean isConstant();
 
   public void collectIdentifiers(Collection<Identifier> identifiers);
index 640be964de7184b8bdf2cfb1a011aae3e0124f95..4566225c8149420389da3971de25f62b3d756170 100644 (file)
@@ -195,6 +195,10 @@ public abstract class BaseEvalContext implements EvalContext
       return "<raw>{" + _exprStr + "}";
     }
 
+    public String toRawString() {
+      return _exprStr;
+    }
+
     public boolean isConstant() {
       return getExpr().isConstant();
     }
index c9af94840fed3e8264fae65e1fc274aa633a8f09..04c8aa0b1b74a7a64c27939b4290665f7cf030b7 100644 (file)
@@ -427,7 +427,7 @@ public class Expressionator
 
       // this is handled as a literal string value, not an expression.  no
       // need to memo-ize cause it's a simple literal value
-      return new ExprWrapper(
+      return new ExprWrapper(exprStr,
           new ELiteralValue(Value.Type.STRING, exprStr, null), resultType);
     }
 
@@ -447,15 +447,15 @@ public class Expressionator
       return (expr.isConstant() ?
               // for now, just cache at top-level for speed (could in theory
               // cache intermediate values?)
-              new MemoizedExprWrapper(expr, resultType) :
-              new ExprWrapper(expr, resultType));
+              new MemoizedExprWrapper(exprStr, expr, resultType) :
+              new ExprWrapper(exprStr, expr, resultType));
     case FIELD_VALIDATOR:
     case RECORD_VALIDATOR:
       return (expr.isConstant() ?
               // for now, just cache at top-level for speed (could in theory
               // cache intermediate values?)
-              new MemoizedCondExprWrapper(expr) :
-              new CondExprWrapper(expr));
+              new MemoizedCondExprWrapper(exprStr, expr) :
+              new CondExprWrapper(exprStr, expr));
     default:
       throw new ParseException("unexpected expression type " + exprType);
     }
@@ -910,7 +910,7 @@ public class Expressionator
         t = buf.next();
       }
       if(!isDelim(t, OPEN_PAREN)) {
-        throw new ParseException("Malformed In expression " + buf);
+        throw new ParseException("Malformed 'In' expression " + buf);
       }
 
       List<Expr> exprs = findParenExprs(buf, true);
@@ -2007,9 +2007,11 @@ public class Expressionator
    */
   private static abstract class BaseExprWrapper implements Expression
   {
+    private final String _rawExprStr;
     private final Expr _expr;
 
-    private BaseExprWrapper(Expr expr) {
+    private BaseExprWrapper(String rawExprStr, Expr expr) {
+      _rawExprStr = rawExprStr;
       _expr = expr;
     }
 
@@ -2017,6 +2019,10 @@ public class Expressionator
       return _expr.toDebugString();
     }
 
+    public String toRawString() {
+      return _rawExprStr;
+    }
+
     public boolean isConstant() {
       return _expr.isConstant();
     }
@@ -2080,8 +2086,8 @@ public class Expressionator
   {
     private final Value.Type _resultType;
 
-    private ExprWrapper(Expr expr, Value.Type resultType) {
-      super(expr);
+    private ExprWrapper(String rawExprStr, Expr expr, Value.Type resultType) {
+      super(rawExprStr, expr);
       _resultType = resultType;
     }
 
@@ -2096,8 +2102,8 @@ public class Expressionator
    */
   private static class CondExprWrapper extends BaseExprWrapper
   {
-    private CondExprWrapper(Expr expr) {
-      super(expr);
+    private CondExprWrapper(String rawExprStr, Expr expr) {
+      super(rawExprStr, expr);
     }
 
     public Object eval(EvalContext ctx) {
@@ -2113,8 +2119,9 @@ public class Expressionator
   {
     private Object _val;
 
-    private MemoizedExprWrapper(Expr expr, Value.Type resultType) {
-      super(expr, resultType);
+    private MemoizedExprWrapper(String rawExprStr, Expr expr,
+                                Value.Type resultType) {
+      super(rawExprStr, expr, resultType);
     }
 
     @Override
@@ -2134,8 +2141,8 @@ public class Expressionator
   {
     private Object _val;
 
-    private MemoizedCondExprWrapper(Expr expr) {
-      super(expr);
+    private MemoizedCondExprWrapper(String rawExprStr, Expr expr) {
+      super(rawExprStr, expr);
     }
 
     @Override
index 0b028886a812788f38e7ee22856f1ff43d3dcfbe..c95fbaf8f76147f653a290308315c1284ec2393c 100644 (file)
@@ -33,6 +33,8 @@ public class DefaultFunctionsTest extends TestCase
     super(name);
   }
 
+  // FIXME, test more number/string functions
+
   public void testFuncs() throws Exception
   {
     assertEquals("foo", eval("=IIf(10 > 1, \"foo\", \"bar\")"));
index f4915264b327352a42a1dfb3e1cf4da73e48d49f..6c525cc1832dc5fb4455e21ce9e3e531d0251c1c 100644 (file)
@@ -31,6 +31,7 @@ import com.healthmarketscience.jackcess.expr.EvalContext;
 import com.healthmarketscience.jackcess.expr.Expression;
 import com.healthmarketscience.jackcess.expr.FunctionLookup;
 import com.healthmarketscience.jackcess.expr.Identifier;
+import com.healthmarketscience.jackcess.expr.ParseException;
 import com.healthmarketscience.jackcess.expr.TemporalConfig;
 import com.healthmarketscience.jackcess.expr.Value;
 import com.healthmarketscience.jackcess.impl.BaseEvalContext;
@@ -462,6 +463,35 @@ public class ExpressionatorTest extends TestCase
     br.close();
   }
 
+  public void testInvalidExpressions() throws Exception
+  {
+    doTestEvalFail("", "empty");
+    doTestEvalFail("=", "found?");
+    doTestEvalFail("=(34 + 5", "closing");
+    doTestEvalFail("=(34 + )", "found?");
+    doTestEvalFail("=(34 + [A].[B].[C].[D])", "object reference");
+    doTestEvalFail("=34 + 5,", "delimiter");
+    doTestEvalFail("=Foo()", "find function");
+    doTestEvalFail("=(/37)", "left expression");
+    doTestEvalFail("=(>37)", "left expression");
+    doTestEvalFail("=(And 37)", "left expression");
+    doTestEvalFail("=37 In 42", "'In' expression");
+    doTestEvalFail("=37 Between 42", "'Between' expression");
+    doTestEvalFail("=(3 + 5) Rnd()", "multiple expressions");
+    // doTestEvalFail("=Blah", "");
+  }
+
+  private static void doTestEvalFail(String exprStr, String msgStr) {
+    try {
+      eval(exprStr);
+      fail("ParseException should have been thrown");
+    } catch(ParseException pe) {
+      // success
+      System.out.println("FOO " + pe);
+      assertTrue(pe.getMessage().contains(msgStr));
+    }
+  }
+
   private static void validateExpr(String exprStr, String debugStr) {
     validateExpr(exprStr, debugStr, exprStr);
   }
@@ -479,6 +509,7 @@ public class ExpressionatorTest extends TestCase
       assertEquals(debugStr, foundDebugStr);
     }
     assertEquals(cleanStr, expr.toString());
+    assertEquals(exprStr, expr.toRawString());
   }
 
   static Object eval(String exprStr) {