Search in sources :

Example 1 with PersistentPropertyPath

use of io.micronaut.data.model.PersistentPropertyPath in project micronaut-data by micronaut-projects.

the class PreparedQueryDBOperation method setParameters.

@Override
public <K, Cnt, PS> void setParameters(OpContext<Cnt, PS> context, Cnt connection, PS stmt, RuntimePersistentEntity<K> persistentEntity, K entity, Map<QueryParameterBinding, Object> previousValues) {
    int index = context.shiftIndex(0);
    Object[] parameterArray = preparedQuery.getParameterArray();
    Argument[] parameterArguments = preparedQuery.getArguments();
    for (QueryParameterBinding queryParameterBinding : preparedQuery.getQueryBindings()) {
        Class<?> parameterConverter = queryParameterBinding.getParameterConverterClass();
        Object value;
        if (queryParameterBinding.getParameterIndex() != -1) {
            value = resolveParameterValue(queryParameterBinding, parameterArray);
        } else if (queryParameterBinding.isAutoPopulated()) {
            String[] propertyPath = queryParameterBinding.getRequiredPropertyPath();
            PersistentPropertyPath pp = persistentEntity.getPropertyPath(propertyPath);
            if (pp == null) {
                throw new IllegalStateException("Cannot find auto populated property: " + String.join(".", propertyPath));
            }
            RuntimePersistentProperty<?> persistentProperty = (RuntimePersistentProperty) pp.getProperty();
            Object previousValue = null;
            QueryParameterBinding previousPopulatedValueParameter = queryParameterBinding.getPreviousPopulatedValueParameter();
            if (previousPopulatedValueParameter != null) {
                if (previousPopulatedValueParameter.getParameterIndex() == -1) {
                    throw new IllegalStateException("Previous value parameter cannot be bind!");
                }
                previousValue = resolveParameterValue(previousPopulatedValueParameter, parameterArray);
            }
            value = context.getRuntimeEntityRegistry().autoPopulateRuntimeProperty(persistentProperty, previousValue);
            value = context.convert(connection, value, persistentProperty);
            parameterConverter = null;
        } else {
            throw new IllegalStateException("Invalid query [" + query + "]. Unable to establish parameter value for parameter at position: " + (index + 1));
        }
        DataType dataType = queryParameterBinding.getDataType();
        List<Object> values = queryParameterBinding.isExpandable() ? expandValue(value, dataType) : Collections.singletonList(value);
        if (values != null && values.isEmpty()) {
            // Empty collections / array should always set at least one value
            value = null;
            values = null;
        }
        if (values == null) {
            if (parameterConverter != null) {
                int parameterIndex = queryParameterBinding.getParameterIndex();
                Argument<?> argument = parameterIndex > -1 ? parameterArguments[parameterIndex] : null;
                value = context.convert(parameterConverter, connection, value, argument);
            }
            context.setStatementParameter(stmt, index++, dataType, value, dialect);
        } else {
            for (Object v : values) {
                if (parameterConverter != null) {
                    int parameterIndex = queryParameterBinding.getParameterIndex();
                    Argument<?> argument = parameterIndex > -1 ? parameterArguments[parameterIndex] : null;
                    v = context.convert(parameterConverter, connection, v, argument);
                }
                context.setStatementParameter(stmt, index++, dataType, v, dialect);
            }
        }
    }
}
Also used : QueryParameterBinding(io.micronaut.data.model.runtime.QueryParameterBinding) Argument(io.micronaut.core.type.Argument) PersistentPropertyPath(io.micronaut.data.model.PersistentPropertyPath) DataType(io.micronaut.data.model.DataType) RuntimePersistentProperty(io.micronaut.data.model.runtime.RuntimePersistentProperty)

Example 2 with PersistentPropertyPath

use of io.micronaut.data.model.PersistentPropertyPath in project micronaut-data by micronaut-projects.

the class StoredSqlOperation method getQueryParameterValueSize.

/**
 * Get parameter value size.
 *
 * @param parameter        The parameter
 * @param persistentEntity The persistent entity
 * @param entity           The entity object
 * @param <T>              The type
 * @return The size of the value
 */
protected <T> int getQueryParameterValueSize(QueryParameterBinding parameter, RuntimePersistentEntity<T> persistentEntity, T entity) {
    String[] stringPropertyPath = parameter.getRequiredPropertyPath();
    PersistentPropertyPath propertyPath = persistentEntity.getPropertyPath(stringPropertyPath);
    if (propertyPath == null) {
        throw new IllegalStateException("Unrecognized path: " + String.join(".", stringPropertyPath));
    }
    return sizeOf(propertyPath.getPropertyValue(entity));
}
Also used : PersistentPropertyPath(io.micronaut.data.model.PersistentPropertyPath)

Example 3 with PersistentPropertyPath

use of io.micronaut.data.model.PersistentPropertyPath in project micronaut-data by micronaut-projects.

the class StoredSqlOperation method setParameters.

@Override
public <T, Cnt, PS> void setParameters(OpContext<Cnt, PS> context, Cnt connection, PS stmt, RuntimePersistentEntity<T> persistentEntity, T entity, Map<QueryParameterBinding, Object> previousValues) {
    int index = context.shiftIndex(0);
    for (QueryParameterBinding binding : queryParameterBindings) {
        String[] stringPropertyPath = binding.getRequiredPropertyPath();
        PersistentPropertyPath pp = persistentEntity.getPropertyPath(stringPropertyPath);
        if (pp == null) {
            throw new IllegalStateException("Unrecognized path: " + String.join(".", stringPropertyPath));
        }
        if (binding.isAutoPopulated() && binding.isRequiresPreviousPopulatedValue()) {
            if (previousValues != null) {
                Object previousValue = previousValues.get(binding);
                if (previousValue != null) {
                    index = setStatementParameter(context, stmt, index, pp.getProperty().getDataType(), previousValue, dialect, binding.isExpandable());
                    continue;
                }
            }
            continue;
        }
        Object value = pp.getPropertyValue(entity);
        RuntimePersistentProperty<?> property = (RuntimePersistentProperty<?>) pp.getProperty();
        DataType type = property.getDataType();
        if (value == null && type == DataType.ENTITY) {
            RuntimePersistentEntity<?> referencedEntity = context.getEntity(property.getType());
            RuntimePersistentProperty<?> identity = referencedEntity.getIdentity();
            if (identity == null) {
                throw new IllegalStateException("Cannot set an entity value without identity: " + referencedEntity);
            }
            property = identity;
            type = identity.getDataType();
        }
        value = context.convert(connection, value, property);
        index = setStatementParameter(context, stmt, index, type, value, dialect, binding.isExpandable());
    }
}
Also used : QueryParameterBinding(io.micronaut.data.model.runtime.QueryParameterBinding) DataType(io.micronaut.data.model.DataType) PersistentPropertyPath(io.micronaut.data.model.PersistentPropertyPath) RuntimePersistentProperty(io.micronaut.data.model.runtime.RuntimePersistentProperty)

Example 4 with PersistentPropertyPath

use of io.micronaut.data.model.PersistentPropertyPath in project micronaut-data by micronaut-projects.

the class HibernateJpaOperations method bindParameters.

private <T, R> void bindParameters(Query<?> q, @NonNull PreparedQuery<T, R> preparedQuery, String query) {
    for (QueryParameterBinding queryParameterBinding : preparedQuery.getQueryBindings()) {
        String parameterName = Objects.requireNonNull(queryParameterBinding.getName(), "Parameter name cannot be null!");
        Object value;
        if (queryParameterBinding.getParameterIndex() != -1) {
            value = resolveParameterValue(queryParameterBinding, preparedQuery.getParameterArray());
        } else if (queryParameterBinding.isAutoPopulated()) {
            String[] propertyPath = queryParameterBinding.getRequiredPropertyPath();
            RuntimePersistentEntity<T> persistentEntity = getEntity(preparedQuery.getRootEntity());
            PersistentPropertyPath pp = persistentEntity.getPropertyPath(propertyPath);
            if (pp == null) {
                throw new IllegalStateException("Cannot find auto populated property: " + String.join(".", propertyPath));
            }
            RuntimePersistentProperty<?> persistentProperty = (RuntimePersistentProperty) pp.getProperty();
            Object previousValue = null;
            QueryParameterBinding previousPopulatedValueParameter = queryParameterBinding.getPreviousPopulatedValueParameter();
            if (previousPopulatedValueParameter != null) {
                if (previousPopulatedValueParameter.getParameterIndex() == -1) {
                    throw new IllegalStateException("Previous value parameter cannot be bind!");
                }
                previousValue = resolveParameterValue(previousPopulatedValueParameter, preparedQuery.getParameterArray());
            }
            value = runtimeEntityRegistry.autoPopulateRuntimeProperty(persistentProperty, previousValue);
        } else {
            throw new IllegalStateException("Invalid query [" + query + "]. Unable to establish parameter value for parameter at name: " + parameterName);
        }
        if (preparedQuery.isNative()) {
            int parameterIndex = queryParameterBinding.getParameterIndex();
            Argument<?> argument = preparedQuery.getArguments()[parameterIndex];
            Class<?> argumentType = argument.getType();
            if (Collection.class.isAssignableFrom(argumentType)) {
                Type valueType = sessionFactory.getTypeHelper().heuristicType(argument.getFirstTypeVariable().orElse(Argument.OBJECT_ARGUMENT).getType().getName());
                if (valueType != null) {
                    q.setParameterList(parameterName, value == null ? Collections.emptyList() : (Collection<?>) value, valueType);
                    continue;
                }
            } else if (Object[].class.isAssignableFrom(argumentType)) {
                q.setParameterList(parameterName, value == null ? ArrayUtils.EMPTY_OBJECT_ARRAY : (Object[]) value);
                continue;
            } else if (value == null) {
                Type type = sessionFactory.getTypeHelper().heuristicType(argumentType.getName());
                if (type != null) {
                    q.setParameter(parameterName, null, type);
                    continue;
                }
            }
        }
        q.setParameter(parameterName, value);
    }
}
Also used : DataType(io.micronaut.data.model.DataType) FlushModeType(javax.persistence.FlushModeType) Type(org.hibernate.type.Type) QueryParameterBinding(io.micronaut.data.model.runtime.QueryParameterBinding) RuntimePersistentEntity(io.micronaut.data.model.runtime.RuntimePersistentEntity) Collection(java.util.Collection) PersistentPropertyPath(io.micronaut.data.model.PersistentPropertyPath) TypeHint(io.micronaut.core.annotation.TypeHint) QueryHint(io.micronaut.data.annotation.QueryHint) RuntimePersistentProperty(io.micronaut.data.model.runtime.RuntimePersistentProperty)

Example 5 with PersistentPropertyPath

use of io.micronaut.data.model.PersistentPropertyPath in project micronaut-data by micronaut-projects.

the class MongoQueryBuilder method findPropertyInternal.

private PersistentPropertyPath findPropertyInternal(QueryState queryState, PersistentEntity entity, String name, Class criterionType) {
    PersistentPropertyPath propertyPath = entity.getPropertyPath(name);
    if (propertyPath != null) {
        if (propertyPath.getAssociations().isEmpty()) {
            return propertyPath;
        }
        Association joinAssociation = null;
        StringJoiner joinPathJoiner = new StringJoiner(".");
        for (Association association : propertyPath.getAssociations()) {
            joinPathJoiner.add(association.getName());
            if (association instanceof Embedded) {
                continue;
            }
            if (joinAssociation == null) {
                joinAssociation = association;
                continue;
            }
            if (association != joinAssociation.getAssociatedEntity().getIdentity()) {
                if (!queryState.isAllowJoins()) {
                    throw new IllegalArgumentException("Joins cannot be used in a DELETE or UPDATE operation");
                }
                String joinStringPath = joinPathJoiner.toString();
                if (!queryState.isJoined(joinStringPath)) {
                    throw new IllegalArgumentException("Property is not joined at path: " + joinStringPath);
                }
                // lastJoinAlias = joinInPath(queryState, joinStringPath);
                // Continue to look for a joined property
                joinAssociation = association;
            } else {
                // We don't need to join to access the id of the relation
                joinAssociation = null;
            }
        }
        PersistentProperty property = propertyPath.getProperty();
        if (joinAssociation != null) {
            if (property != joinAssociation.getAssociatedEntity().getIdentity()) {
                String joinStringPath = joinPathJoiner.toString();
                if (!queryState.isJoined(joinStringPath)) {
                    throw new IllegalArgumentException("Property is not joined at path: " + joinStringPath);
                }
            }
        // We don't need to join to access the id of the relation
        }
    } else if (TypeRole.ID.equals(name) && entity.getIdentity() != null) {
        // special case handling for ID
        return PersistentPropertyPath.of(Collections.emptyList(), entity.getIdentity(), entity.getIdentity().getName());
    }
    if (propertyPath == null) {
        if (criterionType == null || criterionType == Sort.Order.class) {
            throw new IllegalArgumentException("Cannot order on non-existent property path: " + name);
        } else {
            throw new IllegalArgumentException("Cannot use [" + criterionType.getSimpleName() + "] criterion on non-existent property path: " + name);
        }
    }
    return propertyPath;
}
Also used : Association(io.micronaut.data.model.Association) PersistentPropertyPath(io.micronaut.data.model.PersistentPropertyPath) Embedded(io.micronaut.data.model.Embedded) PersistentProperty(io.micronaut.data.model.PersistentProperty) StringJoiner(java.util.StringJoiner)

Aggregations

PersistentPropertyPath (io.micronaut.data.model.PersistentPropertyPath)26 Association (io.micronaut.data.model.Association)10 QueryParameterBinding (io.micronaut.data.model.query.builder.QueryParameterBinding)10 PersistentProperty (io.micronaut.data.model.PersistentProperty)8 NonNull (io.micronaut.core.annotation.NonNull)7 DataType (io.micronaut.data.model.DataType)7 Map (java.util.Map)7 ParameterElement (io.micronaut.inject.ast.ParameterElement)6 ArrayList (java.util.ArrayList)6 Embedded (io.micronaut.data.model.Embedded)5 QueryResult (io.micronaut.data.model.query.builder.QueryResult)5 Arrays (java.util.Arrays)5 List (java.util.List)5 StringJoiner (java.util.StringJoiner)5 AnnotationMetadata (io.micronaut.core.annotation.AnnotationMetadata)4 BindingParameter (io.micronaut.data.model.query.BindingParameter)4 QueryModel (io.micronaut.data.model.query.QueryModel)4 MatchFailedException (io.micronaut.data.processor.visitors.MatchFailedException)4 ClassElement (io.micronaut.inject.ast.ClassElement)4 Collections (java.util.Collections)4