Author: cbegin
Date: Sat Apr 11 04:00:19 2009
New Revision: 764160

URL: http://svn.apache.org/viewvc?rev=764160&view=rev
Log:
Added expression evaluator for dynamic SqlNodes and unit tests

Added:
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/ChooseSqlNode.java
      - copied, changed from r764155, 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/ConditionalSqlNode.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/ExpressionEvaluator.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/parser/xml/
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/parser/xml/dynamic/
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/parser/xml/dynamic/DynamicSqlSourceTest.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/parser/xml/dynamic/ExpressionEvaluatorTest.java
Removed:
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/ConditionalSqlNode.java
Modified:
    ibatis/trunk/java/ibatis-3/TODO
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/DynamicContext.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/DynamicSqlSource.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/IfSqlNode.java

Modified: ibatis/trunk/java/ibatis-3/TODO
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/TODO?rev=764160&r1=764159&r2=764160&view=diff
==============================================================================
--- ibatis/trunk/java/ibatis-3/TODO (original)
+++ ibatis/trunk/java/ibatis-3/TODO Sat Apr 11 04:00:19 2009
@@ -19,5 +19,5 @@
   <if prepend test>
       <else prepend>
 
-  <foreach prepend test item index open close conjuction >
+  <foreach prepend item index open close conjuction >
 

Copied: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/ChooseSqlNode.java
 (from r764155, 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/ConditionalSqlNode.java)
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/ChooseSqlNode.java?p2=ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/ChooseSqlNode.java&p1=ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/ConditionalSqlNode.java&r1=764155&r2=764160&rev=764160&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/ConditionalSqlNode.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/ChooseSqlNode.java
 Sat Apr 11 04:00:19 2009
@@ -2,11 +2,11 @@
 
 import java.util.List;
 
-public class ConditionalSqlNode implements SqlNode {
+public class ChooseSqlNode implements SqlNode {
   private MixedSqlNode defaultSqlNode;
   private List<IfSqlNode> ifSqlNodes;
 
-  public ConditionalSqlNode(List<IfSqlNode> ifSqlNodes, MixedSqlNode 
defaultSqlNode) {
+  public ChooseSqlNode(List<IfSqlNode> ifSqlNodes, MixedSqlNode 
defaultSqlNode) {
     this.ifSqlNodes = ifSqlNodes;
     this.defaultSqlNode = defaultSqlNode;
   }

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/DynamicContext.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/DynamicContext.java?rev=764160&r1=764159&r2=764160&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/DynamicContext.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/DynamicContext.java
 Sat Apr 11 04:00:19 2009
@@ -2,13 +2,24 @@
 
 public class DynamicContext {
 
+  private Object parameterObject;
   private StringBuilder sqlBuilder = new StringBuilder();
 
+  public DynamicContext(Object parameterObject) {
+    this.parameterObject = parameterObject;
+  }
+
+  public Object getParameterObject() {
+    return parameterObject;
+  }
+
   public void appendSql(String sql) {
     sqlBuilder.append(sql);
+    sqlBuilder.append(" ");
   }
 
   public String getSql() {
-    return sqlBuilder.toString();
+    return sqlBuilder.toString().trim();
   }
+
 }

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/DynamicSqlSource.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/DynamicSqlSource.java?rev=764160&r1=764159&r2=764160&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/DynamicSqlSource.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/DynamicSqlSource.java
 Sat Apr 11 04:00:19 2009
@@ -14,7 +14,7 @@
   }
 
   public BoundSql getBoundSql(Object parameterObject) {
-    DynamicContext context = new DynamicContext();
+    DynamicContext context = new DynamicContext(parameterObject);
     rootSqlNode.apply(context);
     SqlSourceParser sqlSourceParser = new SqlSourceParser(configuration);
     SqlSource sqlSource = sqlSourceParser.parse(context.getSql());

Added: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/ExpressionEvaluator.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/ExpressionEvaluator.java?rev=764160&view=auto
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/ExpressionEvaluator.java
 (added)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/ExpressionEvaluator.java
 Sat Apr 11 04:00:19 2009
@@ -0,0 +1,22 @@
+package org.apache.ibatis.parser.xml.dynamic;
+
+import org.apache.ibatis.ognl.*;
+import org.apache.ibatis.parser.ParserException;
+
+import java.math.BigDecimal;
+
+public class ExpressionEvaluator {
+
+  public boolean evaluate(String expression, Object parameterObject) {
+    try {
+      Object value = Ognl.getValue(expression, parameterObject);
+      if (value instanceof Boolean) return (Boolean) value;
+      if (value instanceof Number) return !new 
BigDecimal(String.valueOf(value)).equals(BigDecimal.ZERO);
+      return value != null;
+    } catch (OgnlException e) {
+      throw new ParserException("Error evaluating expression '"+expression+"'. 
Cause: " + e, e);
+    }
+  }
+
+
+}

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/IfSqlNode.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/IfSqlNode.java?rev=764160&r1=764159&r2=764160&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/IfSqlNode.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/parser/xml/dynamic/IfSqlNode.java
 Sat Apr 11 04:00:19 2009
@@ -1,16 +1,23 @@
 package org.apache.ibatis.parser.xml.dynamic;
 
+import org.apache.ibatis.ognl.*;
+import org.apache.ibatis.parser.ParserException;
+
+import java.math.BigDecimal;
+
 public class IfSqlNode implements SqlNode {
-  private boolean test;
+  private ExpressionEvaluator evaluator;
+  private String test;
   private MixedSqlNode contents;
 
   public IfSqlNode(String test, MixedSqlNode contents) {
-    this.test = Boolean.valueOf(test);
+    this.test = test;
     this.contents = contents;
+    this.evaluator = new ExpressionEvaluator();
   }
 
   public boolean apply(DynamicContext builder) {
-    if (test) {
+    if (evaluator.evaluate(test, builder.getParameterObject())) {
       contents.apply(builder);
       return true;
     }

Added: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/parser/xml/dynamic/DynamicSqlSourceTest.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/parser/xml/dynamic/DynamicSqlSourceTest.java?rev=764160&view=auto
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/parser/xml/dynamic/DynamicSqlSourceTest.java
 (added)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/parser/xml/dynamic/DynamicSqlSourceTest.java
 Sat Apr 11 04:00:19 2009
@@ -0,0 +1,118 @@
+package org.apache.ibatis.parser.xml.dynamic;
+
+import static org.junit.Assert.*;
+import org.junit.Test;
+import org.apache.ibatis.BaseDataTest;
+import org.apache.ibatis.ognl.Ognl;
+import org.apache.ibatis.mapping.*;
+import org.apache.ibatis.session.*;
+import org.apache.ibatis.io.Resources;
+
+import java.util.*;
+import java.io.*;
+import java.sql.SQLException;
+
+public class DynamicSqlSourceTest extends BaseDataTest {
+
+  @Test
+  public void shouldDemonstrateSimpleExpectedTextWithNoLoopsOrConditionals() 
throws Exception {
+    final String expected = "SELECT * FROM BLOG";
+    final MixedSqlNode sqlNode = mixedContents(new TextSqlNode(expected));
+    DynamicSqlSource source = createDynamicSqlSource(sqlNode);
+    BoundSql boundSql = source.getBoundSql(null);
+    assertEquals(expected, boundSql.getSql());
+  }
+
+  @Test
+  public void 
shouldDemonstrateMultipartExpectedTextWithNoLoopsOrConditionals() throws 
Exception {
+    final String expected = "SELECT * FROM BLOG WHERE ID = ?";
+    DynamicSqlSource source = createDynamicSqlSource(
+        new TextSqlNode("SELECT * FROM BLOG"),
+        new TextSqlNode("WHERE ID = ?"));
+    BoundSql boundSql = source.getBoundSql(null);
+    assertEquals(expected, boundSql.getSql());
+  }
+
+  @Test
+  public void shouldConditionallyIncludeWhere() throws Exception {
+    final String expected = "SELECT * FROM BLOG WHERE ID = ?";
+    DynamicSqlSource source = createDynamicSqlSource(
+        new TextSqlNode("SELECT * FROM BLOG"),
+        new IfSqlNode("true",
+            mixedContents(new TextSqlNode("WHERE ID = ?"))));
+    BoundSql boundSql = source.getBoundSql(null);
+    assertEquals(expected, boundSql.getSql());
+  }
+
+  @Test
+  public void shouldConditionallyExcludeWhere() throws Exception {
+    final String expected = "SELECT * FROM BLOG";
+    DynamicSqlSource source = createDynamicSqlSource(
+        new TextSqlNode("SELECT * FROM BLOG"),
+        new IfSqlNode("false",
+            mixedContents(new TextSqlNode("WHERE ID = ?"))));
+    BoundSql boundSql = source.getBoundSql(null);
+    assertEquals(expected, boundSql.getSql());
+  }
+
+  @Test
+  public void shouldConditionallyDefault() throws Exception {
+    final String expected = "SELECT * FROM BLOG WHERE CATEGORY = 'DEFAULT'";
+    DynamicSqlSource source = createDynamicSqlSource(
+        new TextSqlNode("SELECT * FROM BLOG"), 
+        new ChooseSqlNode(new ArrayList() {{
+          add(new IfSqlNode("false",
+            mixedContents(new TextSqlNode("WHERE CATEGORY = ?"))));
+          add(new IfSqlNode("false",
+            mixedContents(new TextSqlNode("WHERE CATEGORY = 'NONE'"))));
+        }},mixedContents(new TextSqlNode("WHERE CATEGORY = 'DEFAULT'"))));
+    BoundSql boundSql = source.getBoundSql(null);
+    assertEquals(expected, boundSql.getSql());
+  }
+
+  @Test
+  public void shouldConditionallyChooseFirst() throws Exception {
+    final String expected = "SELECT * FROM BLOG WHERE CATEGORY = ?";
+    DynamicSqlSource source = createDynamicSqlSource(
+        new TextSqlNode("SELECT * FROM BLOG"),
+        new ChooseSqlNode(new ArrayList() {{
+          add(new IfSqlNode("true",
+            mixedContents(new TextSqlNode("WHERE CATEGORY = ?"))));
+          add(new IfSqlNode("false",
+            mixedContents(new TextSqlNode("WHERE CATEGORY = 'NONE'"))));
+        }},mixedContents(new TextSqlNode("WHERE CATEGORY = 'DEFAULT'"))));
+    BoundSql boundSql = source.getBoundSql(null);
+    assertEquals(expected, boundSql.getSql());
+  }
+
+  @Test
+  public void shouldConditionallyChooseSecond() throws Exception {
+    final String expected = "SELECT * FROM BLOG WHERE CATEGORY = 'NONE'";
+    DynamicSqlSource source = createDynamicSqlSource(
+        new TextSqlNode("SELECT * FROM BLOG"),
+        new ChooseSqlNode(new ArrayList() {{
+          add(new IfSqlNode("false",
+            mixedContents(new TextSqlNode("WHERE CATEGORY = ?"))));
+          add(new IfSqlNode("true",
+            mixedContents(new TextSqlNode("WHERE CATEGORY = 'NONE'"))));
+        }},mixedContents(new TextSqlNode("WHERE CATEGORY = 'DEFAULT'"))));
+    BoundSql boundSql = source.getBoundSql(null);
+    assertEquals(expected, boundSql.getSql());
+  }
+
+
+  private DynamicSqlSource createDynamicSqlSource(SqlNode... contents) throws 
IOException, SQLException {
+    createBlogDataSource();
+    final String resource = "org/apache/ibatis/parser/MapperConfig.xml";
+    final Reader reader = Resources.getResourceAsReader(resource);
+    SqlSessionFactory sqlMapper = new SqlSessionFactoryBuilder().build(reader);
+    Configuration configuration = sqlMapper.getConfiguration();
+    MixedSqlNode sqlNode = mixedContents(contents);
+    return new DynamicSqlSource(configuration, sqlNode);
+  }
+
+  private MixedSqlNode mixedContents(SqlNode... contents) {
+    return new MixedSqlNode(Arrays.asList(contents));
+  }
+
+}

Added: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/parser/xml/dynamic/ExpressionEvaluatorTest.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/parser/xml/dynamic/ExpressionEvaluatorTest.java?rev=764160&view=auto
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/parser/xml/dynamic/ExpressionEvaluatorTest.java
 (added)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/parser/xml/dynamic/ExpressionEvaluatorTest.java
 Sat Apr 11 04:00:19 2009
@@ -0,0 +1,47 @@
+package org.apache.ibatis.parser.xml.dynamic;
+
+import static org.junit.Assert.*;
+import org.junit.Test;
+import domain.blog.*;
+
+public class ExpressionEvaluatorTest {
+
+  private ExpressionEvaluator evaluator = new ExpressionEvaluator();
+
+  @Test
+  public void shouldCompareStringsReturnTrue() {
+    boolean value = evaluator.evaluate("username == 'cbegin'", new 
Author(1,"cbegin","******","[email protected]","N/A", Section.NEWS));
+    assertEquals(true, value);
+  }
+
+  @Test
+  public void shouldCompareStringsReturnFalse() {
+    boolean value = evaluator.evaluate("username == 'norm'", new 
Author(1,"cbegin","******","[email protected]","N/A", Section.NEWS));
+    assertEquals(false, value);
+  }
+
+  @Test
+  public void shouldReturnTrueIfNotNull() {
+    boolean value = evaluator.evaluate("username", new 
Author(1,"cbegin","******","[email protected]","N/A", Section.NEWS));
+    assertEquals(true, value);
+  }
+
+  @Test
+  public void shouldReturnFalseIfNull() {
+    boolean value = evaluator.evaluate("password", new 
Author(1,"cbegin",null,"[email protected]","N/A", Section.NEWS));
+    assertEquals(false, value);
+  }
+
+  @Test
+  public void shouldReturnTrueIfNotZero() {
+    boolean value = evaluator.evaluate("id", new 
Author(1,"cbegin",null,"[email protected]","N/A", Section.NEWS));
+    assertEquals(true, value);
+  }
+
+  @Test
+  public void shouldReturnFalseIfZero() {
+    boolean value = evaluator.evaluate("id", new 
Author(0,"cbegin",null,"[email protected]","N/A", Section.NEWS));
+    assertEquals(false, value);
+  }
+
+}


Reply via email to