Refactor internals DefaultRelationalQueryEngine.findListMapper()

- Remove findListMapper() method
- Introduce RowReader interface
- Combine findList internals for both SqlRow and RowMapper use
This commit is contained in:
rbygrave
2021-06-09 14:58:08 +12:00
parent 4613f63c66
commit 3add4472ef
6 changed files with 76 additions and 107 deletions
@@ -20,17 +20,17 @@ public interface RelationalQueryEngine {
/**
* Find a list of beans using relational query.
*/
List<SqlRow> findList(RelationalQueryRequest request);
<T> List<T> findList(RelationalQueryRequest request, RowReader<T> reader);
/**
* Find each query using relational query.
*/
void findEach(RelationalQueryRequest request, Consumer<SqlRow> consumer);
<T> void findEach(RelationalQueryRequest request, RowReader<T> reader, Consumer<T> consumer);
/**
* Find each while query using relational query.
*/
void findEach(RelationalQueryRequest request, Predicate<SqlRow> consumer);
<T> void findEach(RelationalQueryRequest request, RowReader<T> reader, Predicate<T> consumer);
/**
* Find single attribute.
@@ -47,11 +47,6 @@ public interface RelationalQueryEngine {
*/
<T> T findOneMapper(RelationalQueryRequest request, RowMapper<T> mapper);
/**
* Find list via mapper.
*/
<T> List<T> findListMapper(RelationalQueryRequest request, RowMapper<T> mapper);
/**
* Find each via raw consumer.
*/
@@ -1,10 +1,6 @@
package io.ebeaninternal.server.core;
import io.ebean.RowConsumer;
import io.ebean.RowMapper;
import io.ebean.SqlQuery;
import io.ebean.SqlRow;
import io.ebean.Transaction;
import io.ebean.*;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiSqlBinding;
@@ -63,7 +59,7 @@ public final class RelationalQueryRequest extends AbstractSqlQueryRequest {
<T> List<T> findListMapper(RowMapper<T> mapper) {
flushJdbcBatchOnQuery();
return queryEngine.findListMapper(this, mapper);
return queryEngine.findList(this, () -> mapper.map(resultSet, rows++));
}
<T> T findOneMapper(RowMapper<T> mapper) {
@@ -83,17 +79,17 @@ public final class RelationalQueryRequest extends AbstractSqlQueryRequest {
public void findEach(Consumer<SqlRow> consumer) {
flushJdbcBatchOnQuery();
queryEngine.findEach(this, consumer);
queryEngine.findEach(this, this::createNewRow, consumer);
}
public void findEachWhile(Predicate<SqlRow> consumer) {
flushJdbcBatchOnQuery();
queryEngine.findEach(this, consumer);
queryEngine.findEach(this, this::createNewRow, consumer);
}
public List<SqlRow> findList() {
flushJdbcBatchOnQuery();
return queryEngine.findList(this);
return queryEngine.findList(this, this::createNewRow);
}
/**
@@ -135,21 +131,14 @@ public final class RelationalQueryRequest extends AbstractSqlQueryRequest {
return resultSet;
}
public void incrementRows() {
rows++;
}
@Override
public boolean next() throws SQLException {
return resultSet.next();
}
public <T> List<T> mapList(RowMapper<T> mapper) throws SQLException {
List<T> list = new ArrayList<>();
while (next()) {
list.add(mapper.map(resultSet, rows++));
if (!resultSet.next()) {
return false;
} else {
rows++;
return true;
}
return list;
}
public <T> T mapOne(RowMapper<T> mapper) throws SQLException {
@@ -0,0 +1,14 @@
package io.ebeaninternal.server.core;
import java.sql.SQLException;
/**
* Read a row building a result for that row.
*/
public interface RowReader<T> {
/**
* Build and return a result for a row.
*/
T read() throws SQLException;
}
@@ -3,6 +3,7 @@ package io.ebeaninternal.server.query;
import io.ebean.RowConsumer;
import io.ebean.RowMapper;
import io.ebean.SqlRow;
import io.ebean.core.type.DataReader;
import io.ebean.core.type.ScalarType;
import io.ebean.meta.MetricVisitor;
import io.ebean.metric.MetricFactory;
@@ -10,10 +11,10 @@ import io.ebean.metric.TimedMetricMap;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.server.core.RelationalQueryEngine;
import io.ebeaninternal.server.core.RelationalQueryRequest;
import io.ebeaninternal.server.core.RowReader;
import io.ebeaninternal.server.persist.Binder;
import javax.persistence.PersistenceException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
@@ -59,12 +60,11 @@ public class DefaultRelationalQueryEngine implements RelationalQueryEngine {
}
@Override
public void findEach(RelationalQueryRequest request, Predicate<SqlRow> consumer) {
public <T> void findEach(RelationalQueryRequest request, RowReader<T> reader, Predicate<T> consumer) {
try {
request.executeSql(binder, SpiQuery.Type.ITERATE);
while (request.next()) {
if (!consumer.test(readRow(request))) {
if (!consumer.test(reader.read())) {
break;
}
}
@@ -79,12 +79,11 @@ public class DefaultRelationalQueryEngine implements RelationalQueryEngine {
}
@Override
public void findEach(RelationalQueryRequest request, Consumer<SqlRow> consumer) {
public <T> void findEach(RelationalQueryRequest request, RowReader<T> reader, Consumer<T> consumer) {
try {
request.executeSql(binder, SpiQuery.Type.ITERATE);
while (request.next()) {
consumer.accept(readRow(request));
consumer.accept(reader.read());
}
request.logSummary();
@@ -112,22 +111,6 @@ public class DefaultRelationalQueryEngine implements RelationalQueryEngine {
}
}
@Override
public <T> List<T> findListMapper(RelationalQueryRequest request, RowMapper<T> mapper) {
try {
request.executeSql(binder, SpiQuery.Type.LIST);
List<T> list = request.mapList(mapper);
request.logSummary();
return list;
} catch (Exception e) {
throw new PersistenceException(errMsg(e.getMessage(), request.getSql()), e);
} finally {
request.close();
}
}
@Override
public void findEachRow(RelationalQueryRequest request, RowConsumer consumer) {
try {
@@ -143,51 +126,17 @@ public class DefaultRelationalQueryEngine implements RelationalQueryEngine {
}
}
@SuppressWarnings("unchecked")
@Override
public <T> List<T> findSingleAttributeList(RelationalQueryRequest request, Class<T> cls) {
ScalarType<T> scalarType = (ScalarType<T>) binder.getScalarType(cls);
return findScalarList(request, scalarType);
}
private <T> List<T> findScalarList(RelationalQueryRequest request, ScalarType<T> scalarType) {
try {
request.executeSql(binder, SpiQuery.Type.ATTRIBUTE);
List<T> list = new ArrayList<>();
while (request.next()) {
request.incrementRows();
list.add(scalarType.read(binder.createDataReader(request.getResultSet())));
}
request.logSummary();
return list;
} catch (Exception e) {
throw new PersistenceException(errMsg(e.getMessage(), request.getSql()), e);
} finally {
request.close();
}
}
@SuppressWarnings("unchecked")
@Override
public <T> T findSingleAttribute(RelationalQueryRequest request, Class<T> cls) {
ScalarType<T> scalarType = (ScalarType<T>) binder.getScalarType(cls);
return findScalar(request, scalarType);
}
private <T> T findScalar(RelationalQueryRequest request, ScalarType<T> scalarType) {
try {
request.executeSql(binder, SpiQuery.Type.ATTRIBUTE);
final DataReader dataReader = binder.createDataReader(request.getResultSet());
T value = null;
if (request.next()) {
request.incrementRows();
value = scalarType.read(binder.createDataReader(request.getResultSet()));
if (dataReader.next()) {
value = scalarType.read(dataReader);
}
request.logSummary();
return value;
@@ -199,16 +148,17 @@ public class DefaultRelationalQueryEngine implements RelationalQueryEngine {
}
}
@SuppressWarnings("unchecked")
@Override
public List<SqlRow> findList(RelationalQueryRequest request) {
public <T> List<T> findSingleAttributeList(RelationalQueryRequest request, Class<T> cls) {
ScalarType<T> scalarType = (ScalarType<T>) binder.getScalarType(cls);
try {
request.executeSql(binder, SpiQuery.Type.LIST);
List<SqlRow> rows = new ArrayList<>();
while (request.next()) {
rows.add(readRow(request));
request.executeSql(binder, SpiQuery.Type.ATTRIBUTE);
final DataReader dataReader = binder.createDataReader(request.getResultSet());
List<T> rows = new ArrayList<>();
while (dataReader.next()) {
rows.add(scalarType.read(dataReader));
}
request.logSummary();
return rows;
@@ -220,11 +170,22 @@ public class DefaultRelationalQueryEngine implements RelationalQueryEngine {
}
}
/**
* Read the row from the ResultSet and return as a MapBean.
*/
private SqlRow readRow(RelationalQueryRequest request) throws SQLException {
return request.createNewRow();
@Override
public <T> List<T> findList(RelationalQueryRequest request, RowReader<T> reader) {
try {
request.executeSql(binder, SpiQuery.Type.LIST);
List<T> rows = new ArrayList<>();
while (request.next()) {
rows.add(reader.read());
}
request.logSummary();
return rows;
} catch (Exception e) {
throw new PersistenceException(errMsg(e.getMessage(), request.getSql()), e);
} finally {
request.close();
}
}
}
@@ -23,9 +23,9 @@ public class DefaultRelationalQuery implements SpiSqlQuery {
private final transient SpiEbeanServer server;
private String label;
private final String query;
private String query;
private String label;
private int firstRow;
@@ -208,19 +208,25 @@ public class DefaultRelationalQuery implements SpiSqlQuery {
return query;
}
<T> T mapperFindOne(RowMapper<T> mapper) {
private <T> T mapperFindOne(RowMapper<T> mapper) {
return server.findOneMapper(this, mapper);
}
<T> List<T> mapperFindList(RowMapper<T> mapper) {
private <T> List<T> mapperFindList(RowMapper<T> mapper) {
return server.findListMapper(this, mapper);
}
private <T> void mapperFindEach(RowMapper<T> mapper, Consumer<T> consumer) {
server.findEachRow(this, (resultSet, rowNum) -> consumer.accept(mapper.map(resultSet, rowNum)));
}
@SuppressWarnings({"rawtypes", "unchecked"})
@Override
public <T> TypeQuery<T> mapToScalar(Class<T> attributeType) {
return new Scalar(attributeType);
}
@SuppressWarnings({"rawtypes", "unchecked"})
@Override
public <T> TypeQuery<T> mapTo(RowMapper<T> mapper) {
return new Mapper(mapper);
@@ -272,5 +278,10 @@ public class DefaultRelationalQuery implements SpiSqlQuery {
public List<T> findList() {
return mapperFindList(mapper);
}
//@Override
public void findEach(Consumer<T> consumer) {
mapperFindEach(mapper, consumer);
}
}
}
@@ -2,7 +2,6 @@ package org.tests.query.sqlquery;
import io.ebean.BaseTestCase;
import io.ebean.DB;
import io.ebean.Ebean;
import io.ebean.RowMapper;
import io.ebean.SqlQuery;
import io.ebean.SqlRow;
@@ -361,7 +360,7 @@ public class SqlQueryTests extends BaseTestCase {
ResetBasicData.reset();
int expectedRows = Ebean.find(Order.class).findCount();
int expectedRows = DB.find(Order.class).findCount();
final AtomicInteger count = new AtomicInteger();