Author: cbegin
Date: Sun May 17 16:24:12 2009
New Revision: 775697

URL: http://svn.apache.org/viewvc?rev=775697&view=rev
Log:
 Replace foreach #{item} with #{__item_0} for simpler syntax 

Modified:
    ibatis/trunk/java/ibatis-3/TODO
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/xml/dynamic/ForEachSqlNode.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/builder/xml/dynamic/DynamicSqlSourceTest.java

Modified: ibatis/trunk/java/ibatis-3/TODO
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/TODO?rev=775697&r1=775696&r2=775697&view=diff
==============================================================================
--- ibatis/trunk/java/ibatis-3/TODO (original)
+++ ibatis/trunk/java/ibatis-3/TODO Sun May 17 16:24:12 2009
@@ -4,7 +4,6 @@
 
 Required:
 
-* Replace foreach ${item} with ${collection[1]} etc.
 * Wrap collection parameter objects in a map automatically
 * Allow lazy loading across connection boundaries
 

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/xml/dynamic/ForEachSqlNode.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/xml/dynamic/ForEachSqlNode.java?rev=775697&r1=775696&r2=775697&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/xml/dynamic/ForEachSqlNode.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/xml/dynamic/ForEachSqlNode.java
 Sun May 17 16:24:12 2009
@@ -1,5 +1,9 @@
 package org.apache.ibatis.builder.xml.dynamic;
 
+import org.apache.ibatis.parsing.GenericTokenParser;
+
+import java.util.Map;
+
 public class ForEachSqlNode implements SqlNode {
   private ExpressionEvaluator evaluator;
   private String collectionExpression;
@@ -22,30 +26,31 @@
   }
 
   public boolean apply(DynamicContext context) {
-    final Iterable iterable = evaluator.evaluateIterable(collectionExpression, 
context.getBindings());
+    final Iterable iterable = evaluator.evaluateIterable(collectionExpression, 
context.getBindings());    
     boolean first = true;
     applyOpen(context);
     int i = 0;
     for (Object o : iterable) {
       first = applySeparator(context, first);
-      i = applyIndex(context, i);
-      applyItem(context, o);
-      contents.apply(context);
+      applyItem(context, o, i);
+      applyIndex(context, i);
+      contents.apply(new FilteredDynamicContext(context, item, i));
+      i++;
     }
     applyClose(context);
     return true;
   }
 
-  private int applyIndex(DynamicContext context, int i) {
+  private void applyIndex(DynamicContext context, int i) {
     if (index != null) {
-      context.bind(index, i++);
+      context.bind(index, i);
     }
-    return i;
   }
 
-  private void applyItem(DynamicContext context, Object o) {
+  private void applyItem(DynamicContext context, Object o, int i) {
     if (item != null) {
       context.bind(item, o);
+      context.bind(itemizeItem(item,i), o);
     }
   }
 
@@ -72,4 +77,47 @@
     }
   }
 
+  private static String itemizeItem(String item, int i) {
+    return new 
StringBuilder("__").append(item).append("_").append(i).toString();
+  }
+
+
+  
+  private static class FilteredDynamicContext extends DynamicContext {
+    private DynamicContext delegate;
+    private int index;
+    private String item;
+
+    public FilteredDynamicContext(DynamicContext delegate, String item, int i) 
{
+      super(null);
+      this.delegate = delegate;
+      this.index = i;
+      this.item = item;
+    }
+
+    public Map<String, Object> getBindings() {
+      return delegate.getBindings();
+    }
+
+    public void bind(String name, Object value) {
+      delegate.bind(name, value);
+    }
+
+    public String getSql() {
+      return delegate.getSql();
+    }
+
+    public void appendSql(String sql) {
+      GenericTokenParser parser = new GenericTokenParser("#{", "}", new 
GenericTokenParser.TokenHandler() {
+        public String handleToken(String content) {
+          String newContent = content.replaceFirst(item, 
itemizeItem(item,index));
+          return new 
StringBuilder("#{").append(newContent).append("}").toString();
+        }
+      });
+
+      delegate.appendSql(parser.parse(sql));
+    }
+
+  }
+
 }

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/builder/xml/dynamic/DynamicSqlSourceTest.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/builder/xml/dynamic/DynamicSqlSourceTest.java?rev=775697&r1=775696&r2=775697&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/builder/xml/dynamic/DynamicSqlSourceTest.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/builder/xml/dynamic/DynamicSqlSourceTest.java
 Sun May 17 16:24:12 2009
@@ -197,10 +197,13 @@
     final String expected = "SELECT * FROM BLOG WHERE ID in ( one = ? AND two 
= ? AND three = ? )";
     DynamicSqlSource source = createDynamicSqlSource(
         new TextSqlNode("SELECT * FROM BLOG WHERE ID in"),
-        new ForEachSqlNode(mixedContents(new TextSqlNode("${item} = 
#{id[${index}]}")),"array","index","item","(",")","AND"));
+        new ForEachSqlNode(mixedContents(new TextSqlNode("${item} = 
#{item}")),"array","index","item","(",")","AND"));
     BoundSql boundSql = source.getBoundSql(parameterObject);
     assertEquals(expected, boundSql.getSql());
     assertEquals(3, boundSql.getParameterMappings().size());
+    assertEquals("__item_0", 
boundSql.getParameterMappings().get(0).getProperty());
+    assertEquals("__item_1", 
boundSql.getParameterMappings().get(1).getProperty());
+    assertEquals("__item_2", 
boundSql.getParameterMappings().get(2).getProperty());
   }
 
   private DynamicSqlSource createDynamicSqlSource(SqlNode... contents) throws 
IOException, SQLException {


Reply via email to