Search in sources :

Example 1 with SqlResultEntityTypeMapper

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);
}
Also used : SQLException(java.sql.SQLException) ResultSet(java.sql.ResultSet) Iterator(java.util.Iterator) SqlResultEntityTypeMapper(io.micronaut.data.runtime.mapper.sql.SqlResultEntityTypeMapper) DataAccessException(io.micronaut.data.exceptions.DataAccessException) NoSuchElementException(java.util.NoSuchElementException) NonNull(io.micronaut.core.annotation.NonNull)

Example 2 with SqlResultEntityTypeMapper

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;
    });
}
Also used : TypeMapper(io.micronaut.data.runtime.mapper.TypeMapper) SqlTypeMapper(io.micronaut.data.runtime.mapper.sql.SqlTypeMapper) SqlResultEntityTypeMapper(io.micronaut.data.runtime.mapper.sql.SqlResultEntityTypeMapper) JoinPath(io.micronaut.data.model.query.JoinPath) SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) SqlResultConsumer(io.micronaut.data.jdbc.mapper.SqlResultConsumer) ResultSet(java.sql.ResultSet) SqlResultEntityTypeMapper(io.micronaut.data.runtime.mapper.sql.SqlResultEntityTypeMapper) DataAccessException(io.micronaut.data.exceptions.DataAccessException) Nullable(io.micronaut.core.annotation.Nullable)

Example 3 with SqlResultEntityTypeMapper

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);
    }
}
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)3 SqlResultEntityTypeMapper (io.micronaut.data.runtime.mapper.sql.SqlResultEntityTypeMapper)3 ResultSet (java.sql.ResultSet)3 SQLException (java.sql.SQLException)3 SqlResultConsumer (io.micronaut.data.jdbc.mapper.SqlResultConsumer)2 JoinPath (io.micronaut.data.model.query.JoinPath)2 PreparedStatement (java.sql.PreparedStatement)2 NoSuchElementException (java.util.NoSuchElementException)2 NonNull (io.micronaut.core.annotation.NonNull)1 Nullable (io.micronaut.core.annotation.Nullable)1 TypeMapper (io.micronaut.data.runtime.mapper.TypeMapper)1 SqlTypeMapper (io.micronaut.data.runtime.mapper.sql.SqlTypeMapper)1 ArrayList (java.util.ArrayList)1 Iterator (java.util.Iterator)1 List (java.util.List)1 Spliterators (java.util.Spliterators)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1