use of io.micronaut.data.runtime.mapper.sql.SqlResultEntityTypeMapper in project micronaut-data by micronaut-projects.
the class DefaultJdbcRepositoryOperations method entityStream.
@NonNull
@Override
public <T> Stream<T> entityStream(@NonNull ResultSet resultSet, @Nullable String prefix, @NonNull Class<T> rootEntity) {
ArgumentUtils.requireNonNull("resultSet", resultSet);
ArgumentUtils.requireNonNull("rootEntity", rootEntity);
TypeMapper<ResultSet, T> mapper = new SqlResultEntityTypeMapper<>(prefix, getEntity(rootEntity), columnNameResultSetReader, jsonCodec, conversionService);
Iterable<T> iterable = () -> new Iterator<T>() {
boolean fetched = false;
boolean end = false;
@Override
public boolean hasNext() {
if (fetched) {
return true;
}
if (end) {
return false;
}
try {
if (resultSet.next()) {
fetched = true;
} else {
end = true;
}
} catch (SQLException e) {
throw new DataAccessException("Error retrieving next JDBC result: " + e.getMessage(), e);
}
return !end;
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
fetched = false;
return mapper.map(resultSet, rootEntity);
}
};
return StreamSupport.stream(iterable.spliterator(), false);
}
use of io.micronaut.data.runtime.mapper.sql.SqlResultEntityTypeMapper in project micronaut-data by micronaut-projects.
the class DefaultJdbcRepositoryOperations method findOne.
@Nullable
@Override
public <T, R> R findOne(@NonNull PreparedQuery<T, R> preparedQuery) {
return executeRead(connection -> {
RuntimePersistentEntity<T> persistentEntity = getEntity(preparedQuery.getRootEntity());
try (PreparedStatement ps = prepareStatement(connection, connection::prepareStatement, preparedQuery, false, true)) {
try (ResultSet rs = ps.executeQuery()) {
Class<R> resultType = preparedQuery.getResultType();
if (preparedQuery.getResultDataType() == DataType.ENTITY) {
RuntimePersistentEntity<R> resultPersistentEntity = getEntity(resultType);
final Set<JoinPath> joinFetchPaths = preparedQuery.getJoinFetchPaths();
SqlResultEntityTypeMapper<ResultSet, R> mapper = new SqlResultEntityTypeMapper<>(resultPersistentEntity, columnNameResultSetReader, joinFetchPaths, jsonCodec, (loadedEntity, o) -> {
if (loadedEntity.hasPostLoadEventListeners()) {
return triggerPostLoad(o, loadedEntity, preparedQuery.getAnnotationMetadata());
} else {
return o;
}
}, conversionService);
SqlResultEntityTypeMapper.PushingMapper<ResultSet, R> oneMapper = mapper.readOneWithJoins();
if (rs.next()) {
oneMapper.processRow(rs);
}
while (!joinFetchPaths.isEmpty() && rs.next()) {
oneMapper.processRow(rs);
}
R result = oneMapper.getResult();
if (preparedQuery.hasResultConsumer()) {
preparedQuery.getParameterInRole(SqlResultConsumer.ROLE, SqlResultConsumer.class).ifPresent(consumer -> consumer.accept(result, newMappingContext(rs)));
}
return result;
} else if (rs.next()) {
if (preparedQuery.isDtoProjection()) {
TypeMapper<ResultSet, R> introspectedDataMapper = new DTOMapper<>(persistentEntity, columnNameResultSetReader, jsonCodec, conversionService);
return introspectedDataMapper.map(rs, resultType);
} else {
Object v = columnIndexResultSetReader.readDynamic(rs, 1, preparedQuery.getResultDataType());
if (v == null) {
return null;
} else if (resultType.isInstance(v)) {
return (R) v;
} else {
return columnIndexResultSetReader.convertRequired(v, resultType);
}
}
}
}
} catch (SQLException e) {
throw new DataAccessException("Error executing SQL Query: " + e.getMessage(), e);
}
return null;
});
}
use of io.micronaut.data.runtime.mapper.sql.SqlResultEntityTypeMapper in project micronaut-data by micronaut-projects.
the class DefaultJdbcRepositoryOperations method findStream.
private <T, R> Stream<R> findStream(@NonNull PreparedQuery<T, R> preparedQuery, Connection connection) {
Class<R> resultType = preparedQuery.getResultType();
AtomicBoolean finished = new AtomicBoolean();
PreparedStatement ps;
try {
ps = prepareStatement(connection, connection::prepareStatement, preparedQuery, false, false);
} catch (Exception e) {
throw new DataAccessException("SQL Error preparing Query: " + e.getMessage(), e);
}
ResultSet openedRs = null;
ResultSet rs;
try {
openedRs = ps.executeQuery();
rs = openedRs;
boolean dtoProjection = preparedQuery.isDtoProjection();
boolean isEntity = preparedQuery.getResultDataType() == DataType.ENTITY;
Spliterator<R> spliterator;
if (isEntity || dtoProjection) {
SqlResultConsumer sqlMappingConsumer = preparedQuery.hasResultConsumer() ? preparedQuery.getParameterInRole(SqlResultConsumer.ROLE, SqlResultConsumer.class).orElse(null) : null;
SqlTypeMapper<ResultSet, R> mapper;
final RuntimePersistentEntity<R> persistentEntity = getEntity(resultType);
if (dtoProjection) {
mapper = new SqlDTOMapper<>(persistentEntity, columnNameResultSetReader, jsonCodec, conversionService);
} else {
Set<JoinPath> joinFetchPaths = preparedQuery.getJoinFetchPaths();
SqlResultEntityTypeMapper<ResultSet, R> entityTypeMapper = new SqlResultEntityTypeMapper<>(persistentEntity, columnNameResultSetReader, joinFetchPaths, jsonCodec, (loadedEntity, o) -> {
if (loadedEntity.hasPostLoadEventListeners()) {
return triggerPostLoad(o, loadedEntity, preparedQuery.getAnnotationMetadata());
} else {
return o;
}
}, conversionService);
boolean onlySingleEndedJoins = isOnlySingleEndedJoins(getEntity(preparedQuery.getRootEntity()), joinFetchPaths);
// Cannot stream ResultSet for "many" joined query
if (!onlySingleEndedJoins) {
try {
SqlResultEntityTypeMapper.PushingMapper<ResultSet, List<R>> manyMapper = entityTypeMapper.readAllWithJoins();
while (rs.next()) {
manyMapper.processRow(rs);
}
return manyMapper.getResult().stream();
} finally {
closeResultSet(ps, rs, finished);
}
} else {
mapper = entityTypeMapper;
}
}
spliterator = new Spliterators.AbstractSpliterator<R>(Long.MAX_VALUE, Spliterator.ORDERED | Spliterator.IMMUTABLE) {
@Override
public boolean tryAdvance(Consumer<? super R> action) {
if (finished.get()) {
return false;
}
boolean hasNext = mapper.hasNext(rs);
if (hasNext) {
R o = mapper.map(rs, resultType);
if (sqlMappingConsumer != null) {
sqlMappingConsumer.accept(rs, o);
}
action.accept(o);
} else {
closeResultSet(ps, rs, finished);
}
return hasNext;
}
};
} else {
spliterator = new Spliterators.AbstractSpliterator<R>(Long.MAX_VALUE, Spliterator.ORDERED | Spliterator.IMMUTABLE) {
@Override
public boolean tryAdvance(Consumer<? super R> action) {
if (finished.get()) {
return false;
}
try {
boolean hasNext = rs.next();
if (hasNext) {
Object v = columnIndexResultSetReader.readDynamic(rs, 1, preparedQuery.getResultDataType());
if (resultType.isInstance(v)) {
// noinspection unchecked
action.accept((R) v);
} else if (v != null) {
Object r = columnIndexResultSetReader.convertRequired(v, resultType);
if (r != null) {
action.accept((R) r);
}
}
} else {
closeResultSet(ps, rs, finished);
}
return hasNext;
} catch (SQLException e) {
throw new DataAccessException("Error retrieving next JDBC result: " + e.getMessage(), e);
}
}
};
}
return StreamSupport.stream(spliterator, false).onClose(() -> {
closeResultSet(ps, rs, finished);
});
} catch (Exception e) {
closeResultSet(ps, openedRs, finished);
throw new DataAccessException("SQL Error executing Query: " + e.getMessage(), e);
}
}
Aggregations