[#795] Add <T> List<T> fetch(int, Class<T>) and fetch(String, Class<T>) convenience methods

This commit is contained in:
Lukas Eder 2011-08-25 17:51:28 +00:00
parent b838cb1caf
commit 7fe22e497d
7 changed files with 193 additions and 1 deletions

View File

@ -1419,6 +1419,60 @@ public abstract class jOOQAbstractTest<
assertEquals(new Timestamp(1), SQLDataType.TIMESTAMP.convert(new Timestamp(1)));
}
@Test
public void testConversionResult() throws Exception {
assertEquals(
Arrays.asList((byte) 1, (byte) 2),
create().selectFrom(TAuthor()).orderBy(TAuthor_ID()).fetch(0, Byte.class));
assertEquals(
Arrays.asList((short) 1, (short) 2),
create().selectFrom(TAuthor()).orderBy(TAuthor_ID()).fetch(0, Short.class));
assertEquals(
Arrays.asList(1, 2),
create().selectFrom(TAuthor()).orderBy(TAuthor_ID()).fetch(0, Integer.class));
assertEquals(
Arrays.asList(1L, 2L),
create().selectFrom(TAuthor()).orderBy(TAuthor_ID()).fetch(0, Long.class));
assertEquals(
Arrays.asList(1.0f, 2.0f),
create().selectFrom(TAuthor()).orderBy(TAuthor_ID()).fetch(0, Float.class));
assertEquals(
Arrays.asList(1.0, 2.0),
create().selectFrom(TAuthor()).orderBy(TAuthor_ID()).fetch(0, Double.class));
assertEquals(
Arrays.asList(new BigInteger("1"), new BigInteger("2")),
create().selectFrom(TAuthor()).orderBy(TAuthor_ID()).fetch(0, BigInteger.class));
assertEquals(
Arrays.asList(new BigDecimal("1"), new BigDecimal("2")),
create().selectFrom(TAuthor()).orderBy(TAuthor_ID()).fetch(0, BigDecimal.class));
assertEquals(
Arrays.asList((byte) 1, (byte) 2),
create().selectFrom(TAuthor()).orderBy(TAuthor_ID()).fetch(TAuthor_ID().getName(), Byte.class));
assertEquals(
Arrays.asList((short) 1, (short) 2),
create().selectFrom(TAuthor()).orderBy(TAuthor_ID()).fetch(TAuthor_ID().getName(), Short.class));
assertEquals(
Arrays.asList(1, 2),
create().selectFrom(TAuthor()).orderBy(TAuthor_ID()).fetch(TAuthor_ID().getName(), Integer.class));
assertEquals(
Arrays.asList(1L, 2L),
create().selectFrom(TAuthor()).orderBy(TAuthor_ID()).fetch(TAuthor_ID().getName(), Long.class));
assertEquals(
Arrays.asList(1.0f, 2.0f),
create().selectFrom(TAuthor()).orderBy(TAuthor_ID()).fetch(TAuthor_ID().getName(), Float.class));
assertEquals(
Arrays.asList(1.0, 2.0),
create().selectFrom(TAuthor()).orderBy(TAuthor_ID()).fetch(TAuthor_ID().getName(), Double.class));
assertEquals(
Arrays.asList(new BigInteger("1"), new BigInteger("2")),
create().selectFrom(TAuthor()).orderBy(TAuthor_ID()).fetch(TAuthor_ID().getName(), BigInteger.class));
assertEquals(
Arrays.asList(new BigDecimal("1"), new BigDecimal("2")),
create().selectFrom(TAuthor()).orderBy(TAuthor_ID()).fetch(TAuthor_ID().getName(), BigDecimal.class));
}
@Test
public void testForUpdateClauses() throws Exception {
switch (getDialect()) {

View File

@ -1267,6 +1267,16 @@ public interface Result<R extends Record> extends FieldProvider, List<R>, Attach
*/
List<?> getValues(int fieldIndex);
/**
* Convenience method to fetch all values for a given field. This is
* especially useful, when selecting only a single field.
*
* @param fieldIndex The values' field index
* @param type The type used for type conversion
* @return The values
*/
<T> List<T> getValues(int fieldIndex, Class<? extends T> type);
/**
* Convenience method to fetch all values for a given field. This is
* especially useful, when selecting only a single field.
@ -1276,6 +1286,16 @@ public interface Result<R extends Record> extends FieldProvider, List<R>, Attach
*/
List<?> getValues(String fieldName);
/**
* Convenience method to fetch all values for a given field. This is
* especially useful, when selecting only a single field.
*
* @param fieldName The values' field name
* @param type The type used for type conversion
* @return The values
*/
<T> List<T> getValues(String fieldName, Class<? extends T> type);
/**
* Convenience method to fetch all values for a given field. This is
* especially useful, when selecting only a single field.

View File

@ -114,6 +114,17 @@ public interface ResultQuery<R extends Record> extends Query {
*/
List<?> fetch(int fieldIndex) throws SQLException;
/**
* Execute the query and return all values for a field index from the
* generated result.
* <p>
* This is the same as calling {@link #fetch()} and then
* {@link Result#getValues(int, Class)}
*
* @return The resulting values.
*/
<T> List<T> fetch(int fieldIndex, Class<? extends T> type) throws SQLException;
/**
* Execute the query and return all values for a field name from the
* generated result.
@ -125,6 +136,17 @@ public interface ResultQuery<R extends Record> extends Query {
*/
List<?> fetch(String fieldName) throws SQLException;
/**
* Execute the query and return all values for a field name from the
* generated result.
* <p>
* This is the same as calling {@link #fetch()} and then
* {@link Result#getValues(String, Class)}
*
* @return The resulting values.
*/
<T> List<T> fetch(String fieldName, Class<? extends T> type) throws SQLException;
/**
* Execute the query and return return at most one resulting value for a
* field from the generated result.

View File

@ -116,11 +116,21 @@ abstract class AbstractDelegatingSelect<R extends Record> extends AbstractQueryP
return query.fetch(fieldIndex);
}
@Override
public final <T> List<T> fetch(int fieldIndex, Class<? extends T> type) throws SQLException {
return query.fetch(fieldIndex, type);
}
@Override
public final List<?> fetch(String fieldName) throws SQLException {
return query.fetch(fieldName);
}
@Override
public final <T> List<T> fetch(String fieldName, Class<? extends T> type) throws SQLException {
return query.fetch(fieldName, type);
}
@Override
public final <T> T fetchOne(Field<T> field) throws SQLException {
return query.fetchOne(field);

View File

@ -155,11 +155,21 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
return fetch().getValues(fieldIndex);
}
@Override
public final <T> List<T> fetch(int fieldIndex, Class<? extends T> type) throws SQLException {
return fetch().getValues(fieldIndex, type);
}
@Override
public final List<?> fetch(String fieldName) throws SQLException {
return fetch().getValues(fieldName);
}
@Override
public final <T> List<T> fetch(String fieldName, Class<? extends T> type) throws SQLException {
return fetch().getValues(fieldName, type);
}
@Override
public final <T> T fetchOne(Field<T> field) throws SQLException {
R record = fetchOne();

View File

@ -630,11 +630,21 @@ class ResultImpl<R extends Record> implements Result<R>, AttachableInternal {
return getValues(getField(fieldIndex));
}
@Override
public final <T> List<T> getValues(int fieldIndex, Class<? extends T> type) {
return TypeUtils.convert(getValues(fieldIndex), type);
}
@Override
public final List<?> getValues(String fieldName) {
return getValues(getField(fieldName));
}
@Override
public final <T> List<T> getValues(String fieldName, Class<? extends T> type) {
return TypeUtils.convert(getValues(fieldName), type);
}
@Override
public final List<BigDecimal> getValuesAsBigDecimal(Field<?> field) {
List<BigDecimal> result = new ArrayList<BigDecimal>();

View File

@ -41,8 +41,10 @@ import java.math.BigInteger;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.jooq.SQLDialectNotSupportedException;
@ -77,7 +79,7 @@ final class TypeUtils {
}
@SuppressWarnings("unchecked")
public static Object[] convertArray(Object[] from, Class<?> toClass) {
static Object[] convertArray(Object[] from, Class<?> toClass) {
if (from == null) {
return null;
}
@ -108,6 +110,52 @@ final class TypeUtils {
}
}
/**
* Convert an object to a type. These are the conversion rules:
* <ul>
* <li><code>null</code> is always converted to <code>null</code>,
* regardless of the target type.</li>
* <li>Identity conversion is always possible</li>
* <li>All types can be converted to <code>String</code></li>
* <li>All types can be converted to <code>Object</code></li>
* <li>All <code>Number</code> types can be converted to other
* <code>Number</code> types</li>
* <li>All <code>Number</code> or <code>String</code> types can be converted
* to <code>Boolean</code>. Possible (case-insensitive) values for
* <code>true</code>:
* <ul>
* <li><code>1</code></li>
* <li><code>y</code></li>
* <li><code>yes</code></li>
* <li><code>true</code></li>
* <li><code>on</code></li>
* <li><code>enabled</code></li>
* </ul>
* <p>
* Possible (case-insensitive) values for <code>false</code>:
* <ul>
* <li><code>0</code></li>
* <li><code>n</code></li>
* <li><code>no</code></li>
* <li><code>false</code></li>
* <li><code>off</code></li>
* <li><code>disabled</code></li>
* </ul>
* <p>
* All other values evaluate to <code>null</code></li>
* <li>All <code>Date</code> types can be converted into each other</li>
* <li><code>byte[]</code> can be converted into <code>String</code>, using
* the platform's default charset</li>
* <li><code>Object[]</code> can be converted into any other array type, if
* array elements can be converted, too</li>
* <li><b>All other combinations that are not listed above will result in an
* undisclosed unchecked exception.</b></li>
* </ul>
*
* @param from The object to convert
* @param toClass The target type
* @return The converted object
*/
@SuppressWarnings("unchecked")
public static <T> T convert(Object from, Class<? extends T> toClass) {
if (from == null) {
@ -190,5 +238,23 @@ final class TypeUtils {
throw new SQLDialectNotSupportedException("Cannot convert from " + from + " to " + toClass);
}
/**
* Convert a list of objects to a list of <code>T</code>, using
* {@link #convert(Object, Class)}
*
* @param list The list of objects
* @param type The target type
* @return The list of converted objects
*/
public static <T> List<T> convert(List<?> list, Class<? extends T> type) {
List<T> result = new ArrayList<T>();
for (Object o : list) {
result.add(convert(o, type));
}
return result;
}
private TypeUtils() {}
}