Author: cbegin
Date: Sat Dec  5 05:08:06 2009
New Revision: 887495

URL: http://svn.apache.org/viewvc?rev=887495&view=rev
Log:
iBATIS-700 resultMaps with type derived from java.util.Map need explicit per 
result javaTypes

Modified:
    
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/JdbcType.java
    
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/TypeHandlerRegistry.java
    
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/UnknownTypeHandler.java
    
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/type/BaseTypeHandlerTest.java
    
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/type/UnknownTypeHandlerTest.java

Modified: 
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/JdbcType.java
URL: 
http://svn.apache.org/viewvc/ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/JdbcType.java?rev=887495&r1=887494&r2=887495&view=diff
==============================================================================
--- 
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/JdbcType.java
 (original)
+++ 
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/JdbcType.java
 Sat Dec  5 05:08:06 2009
@@ -1,6 +1,7 @@
 package org.apache.ibatis.type;
 
 import java.sql.Types;
+import java.util.*;
 
 public enum JdbcType {
 
@@ -35,9 +36,20 @@
   NCLOB(2011);
 
   public final int TYPE_CODE;
+  private static Map<Integer,JdbcType> codeLookup = new 
HashMap<Integer,JdbcType>();
+
+  static {
+    for (JdbcType type : JdbcType.values()) {
+      codeLookup.put(type.TYPE_CODE, type);
+    }
+  }
 
   JdbcType(int code) {
     this.TYPE_CODE = code;
   }
 
+  static JdbcType forCode(int code)  {
+    return codeLookup.get(code);
+  }
+
 }

Modified: 
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/TypeHandlerRegistry.java
URL: 
http://svn.apache.org/viewvc/ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/TypeHandlerRegistry.java?rev=887495&r1=887494&r2=887495&view=diff
==============================================================================
--- 
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/TypeHandlerRegistry.java
 (original)
+++ 
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/TypeHandlerRegistry.java
 Sat Dec  5 05:08:06 2009
@@ -19,51 +19,75 @@
     }
   };
 
+  private final Map<JdbcType, TypeHandler> JDBC_TYPE_HANDLER_MAP = new 
HashMap<JdbcType, TypeHandler>();
   private final Map<Class, Map<JdbcType, TypeHandler>> TYPE_HANDLER_MAP = new 
HashMap<Class, Map<JdbcType, TypeHandler>>();
   private final TypeHandler UNKNOWN_TYPE_HANDLER = new 
UnknownTypeHandler(this);
 
   public TypeHandlerRegistry() {
     register(Boolean.class, new BooleanTypeHandler());
     register(boolean.class, new BooleanTypeHandler());
+    register(JdbcType.BOOLEAN, new BooleanTypeHandler());
+    register(JdbcType.BIT, new BooleanTypeHandler());
 
     register(Byte.class, new ByteTypeHandler());
     register(byte.class, new ByteTypeHandler());
+    register(JdbcType.TINYINT, new ByteTypeHandler());
 
     register(Short.class, new ShortTypeHandler());
     register(short.class, new ShortTypeHandler());
+    register(JdbcType.SMALLINT, new ShortTypeHandler());
 
     register(Integer.class, new IntegerTypeHandler());
     register(int.class, new IntegerTypeHandler());
+    register(JdbcType.INTEGER, new IntegerTypeHandler());
 
     register(Long.class, new LongTypeHandler());
     register(long.class, new LongTypeHandler());
 
     register(Float.class, new FloatTypeHandler());
     register(float.class, new FloatTypeHandler());
+    register(JdbcType.FLOAT, new FloatTypeHandler());
 
     register(Double.class, new DoubleTypeHandler());
     register(double.class, new DoubleTypeHandler());
+    register(JdbcType.DOUBLE, new DoubleTypeHandler());
 
     register(String.class, new StringTypeHandler());
     register(String.class, JdbcType.CHAR, new StringTypeHandler());
     register(String.class, JdbcType.CLOB, new ClobTypeHandler());
+    register(String.class, JdbcType.VARCHAR, new ClobTypeHandler());
     register(String.class, JdbcType.LONGVARCHAR, new ClobTypeHandler());
     register(String.class, JdbcType.NVARCHAR, new NStringTypeHandler());
     register(String.class, JdbcType.NCHAR, new NStringTypeHandler());
     register(String.class, JdbcType.NCLOB, new NClobTypeHandler());
+    register(JdbcType.CHAR, new StringTypeHandler());
+    register(JdbcType.VARCHAR, new StringTypeHandler());
+    register(JdbcType.CLOB, new ClobTypeHandler());
+    register(JdbcType.LONGVARCHAR, new ClobTypeHandler());
+    register(JdbcType.NVARCHAR, new NStringTypeHandler());
+    register(JdbcType.NCHAR, new NStringTypeHandler());
+    register(JdbcType.NCLOB, new NClobTypeHandler());
 
     register(BigDecimal.class, new BigDecimalTypeHandler());
+    register(JdbcType.BIGINT, new BigDecimalTypeHandler());
+    register(JdbcType.REAL, new BigDecimalTypeHandler());
 
     register(byte[].class, new ByteArrayTypeHandler());
     register(byte[].class, JdbcType.BLOB, new BlobTypeHandler());
     register(byte[].class, JdbcType.LONGVARBINARY, new BlobTypeHandler());
+    register(JdbcType.LONGVARBINARY, new BlobTypeHandler());
+    register(JdbcType.BLOB, new BlobTypeHandler());
 
     register(Object.class, UNKNOWN_TYPE_HANDLER);
     register(Object.class, JdbcType.OTHER, UNKNOWN_TYPE_HANDLER);
+    register(JdbcType.OTHER, UNKNOWN_TYPE_HANDLER);
 
     register(Date.class, new DateTypeHandler());
     register(Date.class, JdbcType.DATE, new DateOnlyTypeHandler());
     register(Date.class, JdbcType.TIME, new TimeOnlyTypeHandler());
+    register(JdbcType.TIMESTAMP, new DateTypeHandler());
+    register(JdbcType.DATE, new DateOnlyTypeHandler());
+    register(JdbcType.TIME, new TimeOnlyTypeHandler());
 
     register(java.sql.Date.class, new SqlDateTypeHandler());
     register(java.sql.Time.class, new SqlTimeTypeHandler());
@@ -82,6 +106,10 @@
     return getTypeHandler(type, null);
   }
 
+  public TypeHandler getTypeHandler(JdbcType jdbcType) {
+    return JDBC_TYPE_HANDLER_MAP.get(jdbcType);
+  }
+
   public TypeHandler getTypeHandler(Class type, JdbcType jdbcType) {
     Map jdbcHandlerMap = TYPE_HANDLER_MAP.get(type);
     TypeHandler handler = null;
@@ -101,6 +129,10 @@
     return UNKNOWN_TYPE_HANDLER;
   }
 
+  public void register(JdbcType jdbcType, TypeHandler handler) {
+    JDBC_TYPE_HANDLER_MAP.put(jdbcType, handler);
+  }
+
   public void register(Class type, TypeHandler handler) {
     register(type, null, handler);
   }

Modified: 
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/UnknownTypeHandler.java
URL: 
http://svn.apache.org/viewvc/ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/UnknownTypeHandler.java?rev=887495&r1=887494&r2=887495&view=diff
==============================================================================
--- 
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/UnknownTypeHandler.java
 (original)
+++ 
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/main/java/org/apache/ibatis/type/UnknownTypeHandler.java
 Sat Dec  5 05:08:06 2009
@@ -1,9 +1,9 @@
 package org.apache.ibatis.type;
 
-import java.sql.CallableStatement;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
+import org.apache.ibatis.exceptions.IbatisException;
+
+import java.sql.*;
+import java.util.*;
 
 public class UnknownTypeHandler extends BaseTypeHandler {
 
@@ -23,7 +23,8 @@
 
   public Object getNullableResult(ResultSet rs, String columnName)
       throws SQLException {
-    return rs.getObject(columnName);
+    TypeHandler handler = resolveTypeHandler(rs, columnName);
+    return handler.getResult(rs, columnName);
   }
 
   public Object getNullableResult(CallableStatement cs, int columnIndex)
@@ -44,4 +45,31 @@
     return handler;
   }
 
+  private TypeHandler resolveTypeHandler(ResultSet rs, String column) {
+    try {
+      Map<String,Integer> columnIndexLookup;
+      columnIndexLookup = new HashMap<String,Integer>();
+      ResultSetMetaData rsmd = rs.getMetaData();
+      int count = rsmd.getColumnCount();
+      for (int i=1; i <= count; i++) {
+        String name = rsmd.getColumnName(i);
+        columnIndexLookup.put(name,i);
+      }
+      Integer columnIndex = columnIndexLookup.get(column);
+      TypeHandler handler = null;
+      if (columnIndex != null) {
+        int jdbcTypeInt = rsmd.getColumnType(columnIndex);
+        JdbcType jdbcType = JdbcType.forCode(jdbcTypeInt);
+
+        handler = typeHandlerRegistry.getTypeHandler(jdbcType);
+      }
+      if (handler == null || handler instanceof UnknownTypeHandler) {
+        handler = OBJECT_TYPE_HANDLER;
+      }
+      return handler;
+    } catch (SQLException e) {
+      throw new TypeException("Error determining JDBC type for column " + 
column + ".  Cause: " + e, e);
+    }
+  }
+
 }

Modified: 
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/type/BaseTypeHandlerTest.java
URL: 
http://svn.apache.org/viewvc/ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/type/BaseTypeHandlerTest.java?rev=887495&r1=887494&r2=887495&view=diff
==============================================================================
--- 
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/type/BaseTypeHandlerTest.java
 (original)
+++ 
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/type/BaseTypeHandlerTest.java
 Sat Dec  5 05:08:06 2009
@@ -3,9 +3,7 @@
 import org.jmock.Mockery;
 import org.jmock.lib.legacy.ClassImposteriser;
 
-import java.sql.CallableStatement;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
+import java.sql.*;
 
 public abstract class BaseTypeHandlerTest {
 
@@ -18,6 +16,7 @@
   protected final ResultSet rs = mockery.mock(ResultSet.class);
   protected final PreparedStatement ps = mockery.mock(PreparedStatement.class);
   protected final CallableStatement cs = mockery.mock(CallableStatement.class);
+  protected final ResultSetMetaData rsmd = 
mockery.mock(ResultSetMetaData.class);
 
   public abstract void shouldSetParameter()
       throws Exception;

Modified: 
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/type/UnknownTypeHandlerTest.java
URL: 
http://svn.apache.org/viewvc/ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/type/UnknownTypeHandlerTest.java?rev=887495&r1=887494&r2=887495&view=diff
==============================================================================
--- 
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/type/UnknownTypeHandlerTest.java
 (original)
+++ 
ibatis/java/ibatis-3/trunk/ibatis-3-core/src/test/java/org/apache/ibatis/type/UnknownTypeHandlerTest.java
 Sat Dec  5 05:08:06 2009
@@ -25,9 +25,17 @@
       throws Exception {
     mockery.checking(new Expectations() {
       {
-        one(rs).getObject(with(any(String.class)));
+        one(rs).getMetaData();
+        will(returnValue(rsmd));
+        one(rsmd).getColumnCount();
+        will(returnValue(1));
+        one(rsmd).getColumnName(with(any(int.class)));
+        will(returnValue("column"));
+        one(rsmd).getColumnType(with(any(int.class)));
+        will(returnValue(JdbcType.VARCHAR.TYPE_CODE));
+        one(rs).getString(with(any(String.class)));
         will(returnValue("Hello"));
-        one(rs).wasNull();
+        allowing(rs).wasNull();
         will(returnValue(false));
       }
     });


Reply via email to