提交 79965db6 authored 作者: Philippe Marschall's avatar Philippe Marschall

Add support for getObject(int|String, Class)

Both JdbcResultSet and JdbcCallableStatement currently do not support
getObject(int, Class) and getObject(String, Class) but support is easy
to add.

This commits contains the following changes:

 - add support for getObject(int, Class) and getObject(String, Class)
    with the following types: BigDecimal, String, Boolean, Byte, Short,
   Integer, Long, Float, Double, Date, Time, Timestamp, UUID,
   TimestampWithTimeZone and Geometry subclasses
 - extend the existing getObject tests to cover these new methods

Most notably missing is support for LOBs and arrays including primitive
arrays but this can always be added later.
上级 4e59f570
...@@ -1571,7 +1571,7 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements ...@@ -1571,7 +1571,7 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements
*/ */
@Override @Override
public <T> T getObject(int parameterIndex, Class<T> type) throws SQLException { public <T> T getObject(int parameterIndex, Class<T> type) throws SQLException {
throw unsupported("getObject"); return getOpenResultSet().getObject(parameterIndex, type);
} }
/** /**
...@@ -1582,7 +1582,7 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements ...@@ -1582,7 +1582,7 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements
*/ */
@Override @Override
public <T> T getObject(String parameterName, Class<T> type) throws SQLException { public <T> T getObject(String parameterName, Class<T> type) throws SQLException {
throw unsupported("getObject"); return getObject(getIndexForName(parameterName), type);
} }
private ResultSetMetaData getCheckedMetaData() throws SQLException { private ResultSetMetaData getCheckedMetaData() throws SQLException {
......
...@@ -27,7 +27,10 @@ import java.sql.Timestamp; ...@@ -27,7 +27,10 @@ import java.sql.Timestamp;
import java.util.Calendar; import java.util.Calendar;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.UUID;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.api.TimestampWithTimeZone;
import org.h2.engine.SysProperties; import org.h2.engine.SysProperties;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.message.TraceObject; import org.h2.message.TraceObject;
...@@ -55,6 +58,8 @@ import org.h2.value.ValueString; ...@@ -55,6 +58,8 @@ import org.h2.value.ValueString;
import org.h2.value.ValueTime; import org.h2.value.ValueTime;
import org.h2.value.ValueTimestamp; import org.h2.value.ValueTimestamp;
import com.vividsolutions.jts.geom.Geometry;
/** /**
* <p> * <p>
* Represents a result set. * Represents a result set.
...@@ -3679,25 +3684,86 @@ public class JdbcResultSet extends TraceObject implements ResultSet, JdbcResultS ...@@ -3679,25 +3684,86 @@ public class JdbcResultSet extends TraceObject implements ResultSet, JdbcResultS
} }
/** /**
* [Not supported] * Returns a column value as a Java object. The data is
* de-serialized into a Java object (on the client side).
* *
* @param columnIndex the column index (1, 2, ...) * @param columnIndex the column index (1, 2, ...)
* @param type the class of the returned value * @param type the class of the returned value
* @throws SQLException if the column is not found or if the result set is
* closed
*/ */
@Override @Override
public <T> T getObject(int columnIndex, Class<T> type) throws SQLException { public <T> T getObject(int columnIndex, Class<T> type) throws SQLException {
throw unsupported("getObject"); try {
if (type == null) {
throw DbException.getInvalidValueException("type", type);
}
debugCodeCall("getObject", columnIndex);
Value value = get(columnIndex);
return extractObjectOfType(type, value);
} catch (Exception e) {
throw logAndConvert(e);
}
} }
/** /**
* [Not supported] * Returns a column value as a Java object. The data is
* de-serialized into a Java object (on the client side).
* *
* @param columnName the column name * @param columnName the column name
* @param type the class of the returned value * @param type the class of the returned value
*/ */
@Override @Override
public <T> T getObject(String columnName, Class<T> type) throws SQLException { public <T> T getObject(String columnName, Class<T> type) throws SQLException {
throw unsupported("getObject"); try {
if (type == null) {
throw DbException.getInvalidValueException("type", type);
}
debugCodeCall("getObject", columnName);
Value value = get(columnName);
return extractObjectOfType(type, value);
} catch (Exception e) {
throw logAndConvert(e);
}
}
private <T> T extractObjectOfType(Class<T> type, Value value) throws SQLException {
if (value == ValueNull.INSTANCE) {
return null;
}
if (type == BigDecimal.class) {
return type.cast(value.getBigDecimal());
} else if (type == String.class) {
return type.cast(value.getString());
} else if (type == Boolean.class) {
return type.cast(value.getBoolean());
} else if (type == Byte.class) {
return type.cast(value.getByte());
} else if (type == Short.class) {
return type.cast(value.getShort());
} else if (type == Integer.class) {
return type.cast(value.getInt());
} else if (type == Long.class) {
return type.cast(value.getLong());
} else if (type == Float.class) {
return type.cast(value.getFloat());
} else if (type == Double.class) {
return type.cast(value.getDouble());
} else if (type == Date.class) {
return type.cast(value.getDate());
} else if (type == Time.class) {
return type.cast(value.getTime());
} else if (type == Timestamp.class) {
return type.cast(value.getTimestamp());
} else if (type == UUID.class) {
return type.cast(value.getObject());
} else if (type == TimestampWithTimeZone.class) {
return type.cast(value.getObject());
} else if (type.isAssignableFrom(Geometry.class)) {
return type.cast(value.getObject());
} else {
throw unsupported(type.getClass().getName());
}
} }
/** /**
......
...@@ -23,6 +23,7 @@ import java.sql.Types; ...@@ -23,6 +23,7 @@ import java.sql.Types;
import java.util.Collections; import java.util.Collections;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.jdbc.JdbcCallableStatementBackwardsCompat;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.tools.SimpleResultSet; import org.h2.tools.SimpleResultSet;
import org.h2.util.IOUtils; import org.h2.util.IOUtils;
...@@ -147,6 +148,7 @@ public class TestCallableStatement extends TestBase { ...@@ -147,6 +148,7 @@ public class TestCallableStatement extends TestBase {
assertEquals(1, call.getLong(1)); assertEquals(1, call.getLong(1));
assertEquals(1, call.getByte(1)); assertEquals(1, call.getByte(1));
assertEquals(1, ((Long) call.getObject(1)).longValue()); assertEquals(1, ((Long) call.getObject(1)).longValue());
assertEquals(1, ((JdbcCallableStatementBackwardsCompat) call).getObject(1, Long.class).longValue());
assertFalse(call.wasNull()); assertFalse(call.wasNull());
call.setFloat(2, 1.1f); call.setFloat(2, 1.1f);
......
...@@ -35,6 +35,7 @@ import java.util.Collections; ...@@ -35,6 +35,7 @@ import java.util.Collections;
import java.util.TimeZone; import java.util.TimeZone;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.jdbc.JdbcResultSetBackwardsCompat;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.util.IOUtils; import org.h2.util.IOUtils;
...@@ -670,10 +671,18 @@ public class TestResultSet extends TestBase { ...@@ -670,10 +671,18 @@ public class TestResultSet extends TestBase {
trace(o.getClass().getName()); trace(o.getClass().getName());
assertTrue(o instanceof Integer); assertTrue(o instanceof Integer);
assertTrue(((Integer) o).intValue() == -1); assertTrue(((Integer) o).intValue() == -1);
o = ((JdbcResultSetBackwardsCompat) rs).getObject("value", Integer.class);
trace(o.getClass().getName());
assertTrue(o instanceof Integer);
assertTrue(((Integer) o).intValue() == -1);
o = rs.getObject(2); o = rs.getObject(2);
trace(o.getClass().getName()); trace(o.getClass().getName());
assertTrue(o instanceof Integer); assertTrue(o instanceof Integer);
assertTrue(((Integer) o).intValue() == -1); assertTrue(((Integer) o).intValue() == -1);
o = ((JdbcResultSetBackwardsCompat) rs).getObject(2, Integer.class);
trace(o.getClass().getName());
assertTrue(o instanceof Integer);
assertTrue(((Integer) o).intValue() == -1);
assertTrue(rs.getBoolean("Value")); assertTrue(rs.getBoolean("Value"));
assertTrue(rs.getByte("Value") == (byte) -1); assertTrue(rs.getByte("Value") == (byte) -1);
assertTrue(rs.getShort("Value") == (short) -1); assertTrue(rs.getShort("Value") == (short) -1);
...@@ -721,6 +730,9 @@ public class TestResultSet extends TestBase { ...@@ -721,6 +730,9 @@ public class TestResultSet extends TestBase {
o = rs.getObject(2); o = rs.getObject(2);
assertTrue(o == null); assertTrue(o == null);
assertTrue(rs.wasNull()); assertTrue(rs.wasNull());
o = ((JdbcResultSetBackwardsCompat) rs).getObject(2, Integer.class);
assertTrue(o == null);
assertTrue(rs.wasNull());
assertFalse(rs.next()); assertFalse(rs.next());
assertEquals(0, rs.getRow()); assertEquals(0, rs.getRow());
// there is one more row, but because of setMaxRows we don't get it // there is one more row, but because of setMaxRows we don't get it
...@@ -780,6 +792,10 @@ public class TestResultSet extends TestBase { ...@@ -780,6 +792,10 @@ public class TestResultSet extends TestBase {
trace(o.getClass().getName()); trace(o.getClass().getName());
assertTrue(o instanceof String); assertTrue(o instanceof String);
assertTrue(o.toString().equals("Hi")); assertTrue(o.toString().equals("Hi"));
o = ((JdbcResultSetBackwardsCompat) rs).getObject("value", String.class);
trace(o.getClass().getName());
assertTrue(o instanceof String);
assertTrue(o.equals("Hi"));
rs.next(); rs.next();
value = rs.getString(2); value = rs.getString(2);
trace("Value: <" + value + "> (should be: < Hi >)"); trace("Value: <" + value + "> (should be: < Hi >)");
...@@ -845,6 +861,10 @@ public class TestResultSet extends TestBase { ...@@ -845,6 +861,10 @@ public class TestResultSet extends TestBase {
trace(o.getClass().getName()); trace(o.getClass().getName());
assertTrue(o instanceof BigDecimal); assertTrue(o instanceof BigDecimal);
assertTrue(((BigDecimal) o).compareTo(new BigDecimal("-1.00")) == 0); assertTrue(((BigDecimal) o).compareTo(new BigDecimal("-1.00")) == 0);
o = ((JdbcResultSetBackwardsCompat) rs).getObject(2, BigDecimal.class);
trace(o.getClass().getName());
assertTrue(o instanceof BigDecimal);
assertTrue(((BigDecimal) o).compareTo(new BigDecimal("-1.00")) == 0);
rs.next(); rs.next();
assertTrue(rs.getInt(1) == 2); assertTrue(rs.getInt(1) == 2);
...@@ -905,10 +925,18 @@ public class TestResultSet extends TestBase { ...@@ -905,10 +925,18 @@ public class TestResultSet extends TestBase {
trace(o.getClass().getName()); trace(o.getClass().getName());
assertTrue(o instanceof Double); assertTrue(o instanceof Double);
assertTrue(((Double) o).compareTo(new Double("-1.00")) == 0); assertTrue(((Double) o).compareTo(new Double("-1.00")) == 0);
o = ((JdbcResultSetBackwardsCompat) rs).getObject(2, Double.class);
trace(o.getClass().getName());
assertTrue(o instanceof Double);
assertTrue(((Double) o).compareTo(new Double("-1.00")) == 0);
o = rs.getObject(3); o = rs.getObject(3);
trace(o.getClass().getName()); trace(o.getClass().getName());
assertTrue(o instanceof Float); assertTrue(o instanceof Float);
assertTrue(((Float) o).compareTo(new Float("-1.00")) == 0); assertTrue(((Float) o).compareTo(new Float("-1.00")) == 0);
o = ((JdbcResultSetBackwardsCompat) rs).getObject(3, Float.class);
trace(o.getClass().getName());
assertTrue(o instanceof Float);
assertTrue(((Float) o).compareTo(new Float("-1.00")) == 0);
rs.next(); rs.next();
assertTrue(rs.getInt(1) == 2); assertTrue(rs.getInt(1) == 2);
assertTrue(!rs.wasNull()); assertTrue(!rs.wasNull());
...@@ -1009,6 +1037,12 @@ public class TestResultSet extends TestBase { ...@@ -1009,6 +1037,12 @@ public class TestResultSet extends TestBase {
assertTrue(((java.sql.Timestamp) o).equals( assertTrue(((java.sql.Timestamp) o).equals(
java.sql.Timestamp.valueOf("2011-11-11 00:00:00.0"))); java.sql.Timestamp.valueOf("2011-11-11 00:00:00.0")));
assertFalse(rs.wasNull()); assertFalse(rs.wasNull());
o = ((JdbcResultSetBackwardsCompat) rs).getObject(2, java.sql.Timestamp.class);
trace(o.getClass().getName());
assertTrue(o instanceof java.sql.Timestamp);
assertTrue(((java.sql.Timestamp) o).equals(
java.sql.Timestamp.valueOf("2011-11-11 00:00:00.0")));
assertFalse(rs.wasNull());
rs.next(); rs.next();
date = rs.getDate("VALUE"); date = rs.getDate("VALUE");
...@@ -1048,6 +1082,12 @@ public class TestResultSet extends TestBase { ...@@ -1048,6 +1082,12 @@ public class TestResultSet extends TestBase {
assertEquals("2001-02-03", date.toString()); assertEquals("2001-02-03", date.toString());
assertEquals("14:15:16", time.toString()); assertEquals("14:15:16", time.toString());
assertEquals("2007-08-09 10:11:12.141516171", ts.toString()); assertEquals("2007-08-09 10:11:12.141516171", ts.toString());
date = ((JdbcResultSetBackwardsCompat) rs).getObject(1, Date.class);
time = ((JdbcResultSetBackwardsCompat) rs).getObject(2, Time.class);
ts = ((JdbcResultSetBackwardsCompat) rs).getObject(3, Timestamp.class);
assertEquals("2001-02-03", date.toString());
assertEquals("14:15:16", time.toString());
assertEquals("2007-08-09 10:11:12.141516171", ts.toString());
stat.execute("DROP TABLE TEST"); stat.execute("DROP TABLE TEST");
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论