[#1974] Optimise various Executor.fetchOne() methods, which consume

the whole ResultSet before throwing an InvalidResultException
This commit is contained in:
Lukas Eder 2013-02-04 19:08:07 +01:00
parent b6cd1e4a94
commit be484c39bf
3 changed files with 27 additions and 17 deletions

View File

@ -70,7 +70,6 @@ import org.jooq.ResultQuery;
import org.jooq.SQLDialect;
import org.jooq.Table;
import org.jooq.exception.DataTypeException;
import org.jooq.exception.InvalidResultException;
import org.jooq.tools.Convert;
import org.jooq.tools.JooqLogger;
@ -409,16 +408,7 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
@Override
public final R fetchOne() {
Result<R> r = fetch();
if (r.size() == 1) {
return r.get(0);
}
else if (r.size() > 1) {
throw new InvalidResultException("Query returned more than one result");
}
return null;
return Utils.fetchOne(fetchLazy());
}
@Override

View File

@ -1316,7 +1316,7 @@ public class Executor implements Configuration {
*/
@Support
public final Record fetchOne(ResultSet rs) throws DataAccessException, InvalidResultException {
return Utils.filterOne(fetchLazy(rs).fetch());
return Utils.fetchOne(fetchLazy(rs));
}
/**
@ -1335,7 +1335,7 @@ public class Executor implements Configuration {
*/
@Support
public final Record fetchOne(ResultSet rs, Field<?>... fields) throws DataAccessException, InvalidResultException {
return Utils.filterOne(fetchLazy(rs, fields).fetch());
return Utils.fetchOne(fetchLazy(rs, fields));
}
/**
@ -1354,7 +1354,7 @@ public class Executor implements Configuration {
*/
@Support
public final Record fetchOne(ResultSet rs, DataType<?>... types) throws DataAccessException, InvalidResultException {
return Utils.filterOne(fetchLazy(rs, types).fetch());
return Utils.fetchOne(fetchLazy(rs, types));
}
/**
@ -1373,7 +1373,7 @@ public class Executor implements Configuration {
*/
@Support
public final Record fetchOne(ResultSet rs, Class<?>... types) throws DataAccessException, InvalidResultException {
return Utils.filterOne(fetchLazy(rs, types).fetch());
return Utils.fetchOne(fetchLazy(rs, types));
}
/**
@ -4163,7 +4163,7 @@ public class Executor implements Configuration {
*/
@Support
public final <R extends Record> R fetchOne(Table<R> table) throws DataAccessException, InvalidResultException {
return Utils.filterOne(fetch(table));
return Utils.fetchOne(fetchLazy(table));
}
/**
@ -4180,7 +4180,7 @@ public class Executor implements Configuration {
*/
@Support
public final <R extends Record> R fetchOne(Table<R> table, Condition condition) throws DataAccessException, InvalidResultException {
return Utils.filterOne(fetch(table, condition));
return Utils.fetchOne(fetchLazy(table, condition));
}
/**

View File

@ -84,6 +84,7 @@ import org.jooq.AttachableInternal;
import org.jooq.BindContext;
import org.jooq.Configuration;
import org.jooq.Converter;
import org.jooq.Cursor;
import org.jooq.DataType;
import org.jooq.EnumType;
import org.jooq.ExecuteContext;
@ -450,6 +451,25 @@ final class Utils {
return null;
}
/**
* Get the only element from a cursor or <code>null</code>, or throw an
* exception
*
* @param cursor The cursor
* @return The only element from the cursor or <code>null</code>
* @throws InvalidResultException Thrown if the cursor returns more than one
* element
*/
static <R extends Record> R fetchOne(Cursor<R> cursor) throws InvalidResultException {
R record = cursor.fetchOne();
if (cursor.hasNext()) {
throw new InvalidResultException("Cursor returned more than one result");
}
return record;
}
/**
* Render and bind a list of {@link QueryPart} to plain SQL
* <p>