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 {