Search in sources :

Example 1 with SqlResultConsumer

use of io.micronaut.data.jdbc.mapper.SqlResultConsumer 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);
    }
}
Also used : JoinPath(io.micronaut.data.model.query.JoinPath) SQLException(java.sql.SQLException) SqlResultConsumer(io.micronaut.data.jdbc.mapper.SqlResultConsumer) ResultSet(java.sql.ResultSet) ArrayList(java.util.ArrayList) List(java.util.List) SqlResultEntityTypeMapper(io.micronaut.data.runtime.mapper.sql.SqlResultEntityTypeMapper) DataAccessException(io.micronaut.data.exceptions.DataAccessException) PreparedStatement(java.sql.PreparedStatement) SQLException(java.sql.SQLException) DataAccessException(io.micronaut.data.exceptions.DataAccessException) NoSuchElementException(java.util.NoSuchElementException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Spliterators(java.util.Spliterators)

Aggregations

DataAccessException (io.micronaut.data.exceptions.DataAccessException)1 SqlResultConsumer (io.micronaut.data.jdbc.mapper.SqlResultConsumer)1 JoinPath (io.micronaut.data.model.query.JoinPath)1 SqlResultEntityTypeMapper (io.micronaut.data.runtime.mapper.sql.SqlResultEntityTypeMapper)1 PreparedStatement (java.sql.PreparedStatement)1 ResultSet (java.sql.ResultSet)1 SQLException (java.sql.SQLException)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 NoSuchElementException (java.util.NoSuchElementException)1 Spliterators (java.util.Spliterators)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1