Author: cbegin
Date: Sun May 17 06:49:09 2009
New Revision: 775585

URL: http://svn.apache.org/viewvc?rev=775585&view=rev
Log:
Implemented SelectKey XML

Modified:
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/xml/XMLStatementParser.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/xml/ibatis-3-mapper.dtd
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/BatchExecutor.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/keygen/Jdbc3KeyGenerator.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/keygen/KeyGenerator.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/keygen/SelectKeyGenerator.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/CallableStatementHandler.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/PreparedStatementHandler.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/SimpleStatementHandler.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/mapping/Configuration.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/binding/BoundAuthorMapper.xml
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/executor/BaseExecutorTest.java

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/xml/XMLStatementParser.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/xml/XMLStatementParser.java?rev=775585&r1=775584&r2=775585&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/xml/XMLStatementParser.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/xml/XMLStatementParser.java
 Sun May 17 06:49:09 2009
@@ -51,9 +51,15 @@
     boolean useCache = context.getBooleanAttribute("useCache", isSelect);
 
     String keyProperty = context.getStringAttribute("keyProperty");
-    KeyGenerator keyGenerator = context.getBooleanAttribute("useGeneratedKeys",
+    KeyGenerator keyGenerator;
+    String keyStatementId = id + SelectKeyGenerator.SELECT_KEY_SUFFIX;
+    if (configuration.hasKeyGenerator(keyStatementId)) {
+      keyGenerator = configuration.getKeyGenerator(keyStatementId);
+    } else {
+      keyGenerator = context.getBooleanAttribute("useGeneratedKeys",
         configuration.isUseGeneratedKeys() && 
SqlCommandType.INSERT.equals(sqlCommandType))
         ? new Jdbc3KeyGenerator() : null;
+    }
 
     sequentialBuilder.statement(id, sqlSource, statementType, sqlCommandType, 
fetchSize, timeout, parameterMap, parameterTypeClass,
         resultMap, resultTypeClass, resultSetTypeEnum, flushCache, useCache, 
keyGenerator,keyProperty);
@@ -110,6 +116,7 @@
       StatementType statementType = 
StatementType.valueOf(nodeToHandle.getStringAttribute("statementType", 
StatementType.PREPARED.toString()));
       String keyProperty = nodeToHandle.getStringAttribute("keyProperty");
       String parameterType = parent.getStringAttribute("parameterType");
+      boolean executeBefore = 
"BEFORE".equals(nodeToHandle.getStringAttribute("order","AFTER"));
       Class parameterTypeClass = resolveClass(parameterType);
 
       //defaults
@@ -130,6 +137,10 @@
       sequentialBuilder.statement(id, sqlSource, statementType, 
sqlCommandType, fetchSize, timeout, parameterMap, parameterTypeClass,
           resultMap, resultTypeClass, resultSetTypeEnum, flushCache, useCache,
           keyGenerator,keyProperty);
+
+      MappedStatement keyStatement = 
configuration.getMappedStatement(sequentialBuilder.applyNamespace(id));
+
+      configuration.addKeyGenerator(id, new 
SelectKeyGenerator(keyStatement,executeBefore));
     }
   }
 

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/xml/ibatis-3-mapper.dtd
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/xml/ibatis-3-mapper.dtd?rev=775585&r1=775584&r2=775585&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/xml/ibatis-3-mapper.dtd
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/xml/ibatis-3-mapper.dtd
 Sun May 17 06:49:09 2009
@@ -160,7 +160,7 @@
 resultType CDATA #IMPLIED
 statementType (STATEMENT|PREPARED|CALLABLE) #IMPLIED
 keyProperty CDATA #IMPLIED
-order (before|after) #IMPLIED
+order (BEFORE|AFTER) #IMPLIED
 >
 
 <!ELEMENT update (#PCDATA | include | prefix | where | set | foreach | choose 
| if)*>

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/BatchExecutor.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/BatchExecutor.java?rev=775585&r1=775584&r2=775585&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/BatchExecutor.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/BatchExecutor.java
 Sun May 17 06:49:09 2009
@@ -64,8 +64,10 @@
           batchResult.setUpdateCounts(stmt.executeBatch());
           MappedStatement ms = batchResult.getMappedStatement();
           Object parameter = batchResult.getParameterObject();
-          KeyGenerator keyGenerator = new Jdbc3KeyGenerator();
-          keyGenerator.processGeneratedKeys(this, ms, stmt, parameter);
+          KeyGenerator keyGenerator = ms.getKeyGenerator();
+          if (keyGenerator instanceof Jdbc3KeyGenerator) {
+            keyGenerator.processGeneratedKeys(this, ms, stmt, parameter);
+          }
         } catch (BatchUpdateException e) {
           StringBuffer message = new StringBuffer();
           message.append(batchResult.getMappedStatement().getId())

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/keygen/Jdbc3KeyGenerator.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/keygen/Jdbc3KeyGenerator.java?rev=775585&r1=775584&r2=775585&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/keygen/Jdbc3KeyGenerator.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/keygen/Jdbc3KeyGenerator.java
 Sun May 17 06:49:09 2009
@@ -9,6 +9,14 @@
 
 public class Jdbc3KeyGenerator implements KeyGenerator {
 
+  public boolean executeAfter() {
+    return true;
+  }
+
+  public boolean executeBefore() {
+    return false;
+  }
+
   public void processGeneratedKeys(Executor executor, MappedStatement ms, 
Statement stmt, Object parameter) {
     try {
       final Configuration configuration = ms.getConfiguration();

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/keygen/KeyGenerator.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/keygen/KeyGenerator.java?rev=775585&r1=775584&r2=775585&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/keygen/KeyGenerator.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/keygen/KeyGenerator.java
 Sun May 17 06:49:09 2009
@@ -7,7 +7,10 @@
 
 public interface KeyGenerator {
 
-  void processGeneratedKeys(Executor executor, MappedStatement ms, Statement 
stmt, Object parameter);
+  boolean executeBefore();
+
+  boolean executeAfter();
 
+  void processGeneratedKeys(Executor executor, MappedStatement ms, Statement 
stmt, Object parameter);
 
 }

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/keygen/SelectKeyGenerator.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/keygen/SelectKeyGenerator.java?rev=775585&r1=775584&r2=775585&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/keygen/SelectKeyGenerator.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/keygen/SelectKeyGenerator.java
 Sun May 17 06:49:09 2009
@@ -5,9 +5,25 @@
 import org.apache.ibatis.reflection.MetaObject;
 
 import java.sql.Statement;
+import java.util.List;
 
 public class SelectKeyGenerator implements KeyGenerator {
   public static final String SELECT_KEY_SUFFIX = "!selectKey";
+  private boolean executeBefore;
+  private MappedStatement keyStatement;
+
+  public SelectKeyGenerator(MappedStatement keyStatement, boolean 
executeBefore) {
+    this.executeBefore = executeBefore;
+    this.keyStatement = keyStatement;
+  }
+
+  public boolean executeBefore() {
+    return executeBefore;
+  }
+
+  public boolean executeAfter() {
+    return !executeBefore;
+  }
 
   public void processGeneratedKeys(Executor executor, MappedStatement ms, 
Statement stmt, Object parameter) {
     try {
@@ -15,7 +31,7 @@
       if (parameter != null) {
         String keyStatementName = ms.getId() + SELECT_KEY_SUFFIX;
         if (configuration.hasStatement(keyStatementName)) {
-          MappedStatement keyStatement = 
configuration.getMappedStatement(keyStatementName);
+
           if (keyStatement != null) {
             String keyProperty = keyStatement.getKeyProperty();
             final MetaObject metaParam = MetaObject.forObject(parameter);
@@ -23,8 +39,11 @@
               // Do not close keyExecutor.
               // The transaction will be closed by parent executor.
               Executor keyExecutor = 
configuration.newExecutor(executor.getTransaction(), ExecutorType.SIMPLE);
-              Object value = keyExecutor.query(ms, parameter, 
Executor.NO_ROW_OFFSET, Executor.NO_ROW_LIMIT, Executor.NO_RESULT_HANDLER);
-              metaParam.setValue(keyProperty, value);
+              List values = keyExecutor.query(keyStatement, parameter, 
Executor.NO_ROW_OFFSET, Executor.NO_ROW_LIMIT, Executor.NO_RESULT_HANDLER);
+              if (values.size() > 1) {
+                throw new ExecutorException("Select statement for 
SelectKeyGenerator returned more than one value.");
+              }
+              metaParam.setValue(keyProperty, values.get(0));
             }
           }
         }

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/CallableStatementHandler.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/CallableStatementHandler.java?rev=775585&r1=775584&r2=775585&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/CallableStatementHandler.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/CallableStatementHandler.java
 Sun May 17 06:49:09 2009
@@ -1,6 +1,7 @@
 package org.apache.ibatis.executor.statement;
 
 import org.apache.ibatis.executor.*;
+import org.apache.ibatis.executor.keygen.KeyGenerator;
 import org.apache.ibatis.executor.result.ResultHandler;
 import org.apache.ibatis.mapping.*;
 import org.apache.ibatis.type.JdbcType;
@@ -19,6 +20,11 @@
     CallableStatement cs = (CallableStatement) statement;
     cs.execute();
     int rows = cs.getUpdateCount();
+    Object parameterObject = boundSql.getParameterObject();
+    KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
+    if (keyGenerator != null && keyGenerator.executeAfter()) {
+      keyGenerator.processGeneratedKeys(executor, mappedStatement, cs, 
parameterObject);
+    }
     resultSetHandler.handleOutputParameters(cs);
     return rows;
   }
@@ -47,6 +53,10 @@
   }
 
   public void parameterize(Statement statement) throws SQLException {
+    KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
+    if (keyGenerator != null && keyGenerator.executeBefore()) {
+      keyGenerator.processGeneratedKeys(executor, mappedStatement, statement, 
boundSql.getParameterObject());
+    }
     registerOutputParameters((CallableStatement) statement);
     parameterHandler.setParameters((CallableStatement) statement);
   }

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/PreparedStatementHandler.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/PreparedStatementHandler.java?rev=775585&r1=775584&r2=775585&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/PreparedStatementHandler.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/PreparedStatementHandler.java
 Sun May 17 06:49:09 2009
@@ -18,13 +18,13 @@
       throws SQLException {
     PreparedStatement ps = (PreparedStatement) statement;
     ps.execute();
-    int result = ps.getUpdateCount();
+    int rows = ps.getUpdateCount();
     Object parameterObject = boundSql.getParameterObject();
     KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
-    if (keyGenerator != null) {
+    if (keyGenerator != null && keyGenerator.executeAfter()) {
       keyGenerator.processGeneratedKeys(executor, mappedStatement, ps, 
parameterObject);
     }
-    return result;
+    return rows;
   }
 
   public void batch(Statement statement)
@@ -53,6 +53,10 @@
 
   public void parameterize(Statement statement)
       throws SQLException {
+    KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
+    if (keyGenerator != null && keyGenerator.executeBefore()) {
+      keyGenerator.processGeneratedKeys(executor, mappedStatement, statement, 
boundSql.getParameterObject());
+    }
     parameterHandler.setParameters((PreparedStatement) statement);
   }
 

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/SimpleStatementHandler.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/SimpleStatementHandler.java?rev=775585&r1=775584&r2=775585&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/SimpleStatementHandler.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/statement/SimpleStatementHandler.java
 Sun May 17 06:49:09 2009
@@ -18,15 +18,23 @@
       throws SQLException {
     String sql = boundSql.getSql();
     Object parameterObject = boundSql.getParameterObject();
-    if (mappedStatement.getKeyGenerator() instanceof Jdbc3KeyGenerator) {
+    KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
+    int rows;
+    if (keyGenerator instanceof Jdbc3KeyGenerator) {
       statement.execute(sql, Statement.RETURN_GENERATED_KEYS);
+      rows = statement.getUpdateCount();
+      keyGenerator.processGeneratedKeys(executor, mappedStatement, statement, 
parameterObject);
+    } else if (keyGenerator instanceof SelectKeyGenerator) {
+      statement.execute(sql);
+      rows = statement.getUpdateCount();
+      if (keyGenerator.executeAfter()) {
+        keyGenerator.processGeneratedKeys(executor, mappedStatement, 
statement, parameterObject);
+      }
     } else {
       statement.execute(sql);
+      rows = statement.getUpdateCount();
     }
-    int result = statement.getUpdateCount();
-    KeyGenerator keyGenerator = new Jdbc3KeyGenerator();
-    keyGenerator.processGeneratedKeys(executor, mappedStatement, statement, 
parameterObject);
-    return result;
+    return rows;
   }
 
   public void batch(Statement statement)

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/mapping/Configuration.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/mapping/Configuration.java?rev=775585&r1=775584&r2=775585&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/mapping/Configuration.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/mapping/Configuration.java
 Sun May 17 06:49:09 2009
@@ -47,6 +47,7 @@
   private final Map<String, Cache> caches = new StrictMap<String, 
Cache>("Caches collection");
   private final Map<String, ResultMap> resultMaps = new StrictMap<String, 
ResultMap>("Result Maps collection");
   private final Map<String, ParameterMap> parameterMaps = new 
StrictMap<String, ParameterMap>("Parameter Maps collection");
+  private final Map<String, KeyGenerator> keyGenerators = new 
StrictMap<String, KeyGenerator>("Key Generators collection");
 
   public Configuration(Environment environment) {
     this();
@@ -202,6 +203,26 @@
     return executor;
   }
 
+  public void addKeyGenerator(String id, KeyGenerator keyGenerator) {
+    keyGenerators.put(id, keyGenerator);
+  }
+
+  public Collection<String> getKeyGeneratorNames() {
+    return keyGenerators.keySet();
+  }
+
+  public Collection<KeyGenerator> getKeyGenerators() {
+    return keyGenerators.values();
+  }
+
+  public KeyGenerator getKeyGenerator(String id) {
+    return keyGenerators.get(id);
+  }
+
+  public boolean hasKeyGenerator(String id) {
+    return keyGenerators.containsKey(id);
+  }
+
   public void addCache(Cache cache) {
     caches.put(cache.getId(), cache);
   }

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/binding/BoundAuthorMapper.xml
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/binding/BoundAuthorMapper.xml?rev=775585&r1=775584&r2=775585&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/binding/BoundAuthorMapper.xml
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/binding/BoundAuthorMapper.xml
 Sun May 17 06:49:09 2009
@@ -7,11 +7,9 @@
 <mapper>
 
   <insert id="insertAuthor" parameterType="domain.blog.Author">
-<!--
-    <selectKey keyProperty="id" resultType="int" >
+    <selectKey keyProperty="id" resultType="int" order="BEFORE">
       select CAST(RANDOM()*1000000 as INTEGER) a from SYSIBM.SYSDUMMY1
     </selectKey>
--->
     insert into Author (id,username,password,email,bio,favourite_section)
     values(
       #{id}, #{username}, #{password}, #{email}, #{bio}, 
#{favouriteSection,jdbcType=VARCHAR}

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/executor/BaseExecutorTest.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/executor/BaseExecutorTest.java?rev=775585&r1=775584&r2=775585&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/executor/BaseExecutorTest.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/executor/BaseExecutorTest.java
 Sun May 17 06:49:09 2009
@@ -6,7 +6,7 @@
 import org.apache.ibatis.transaction.Transaction;
 import org.apache.ibatis.transaction.jdbc.JdbcTransaction;
 import static org.junit.Assert.*;
-import org.junit.Test;
+import org.junit.*;
 
 import javax.sql.DataSource;
 import java.sql.Connection;


Reply via email to