Search in sources :

Example 1 with QueryParameterBinding

use of io.micronaut.data.model.runtime.QueryParameterBinding 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 QueryParameterBinding

use of io.micronaut.data.model.runtime.QueryParameterBinding 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 3 with QueryParameterBinding

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

the class AbstractSpecificationInterceptor method preparedQueryForCriteria.

protected final <E, QR> PreparedQuery<E, QR> preparedQueryForCriteria(RepositoryMethodKey methodKey, MethodInvocationContext<T, R> context, Type type) {
    Class<Object> rootEntity = getRequiredRootEntity(context);
    Pageable pageable = Pageable.UNPAGED;
    for (Object param : context.getParameterValues()) {
        if (param instanceof Pageable) {
            pageable = (Pageable) param;
            break;
        }
    }
    QueryBuilder sqlQueryBuilder = sqlQueryBuilderForRepositories.computeIfAbsent(methodKey, repositoryMethodKey -> {
        Class<QueryBuilder> builder = context.getAnnotationMetadata().classValue(RepositoryConfiguration.class, "queryBuilder").orElseThrow(() -> new IllegalStateException("Cannot determine QueryBuilder"));
        BeanIntrospection<QueryBuilder> introspection = BeanIntrospection.getIntrospection(builder);
        if (introspection.getConstructorArguments().length == 1 && introspection.getConstructorArguments()[0].getType() == AnnotationMetadata.class) {
            return introspection.instantiate(context.getAnnotationMetadata());
        }
        return introspection.instantiate();
    });
    QueryResult queryResult;
    if (type == Type.COUNT || type == Type.FIND_ALL || type == Type.FIND_ONE || type == Type.FIND_PAGE) {
        QuerySpecification<Object> specification = getQuerySpecification(context);
        PersistentEntityCriteriaQuery<Object> criteriaQuery = criteriaBuilder.createQuery();
        Root<Object> root = criteriaQuery.from(rootEntity);
        if (specification != null) {
            Predicate predicate = specification.toPredicate(root, criteriaQuery, criteriaBuilder);
            if (predicate != null) {
                criteriaQuery.where(predicate);
            }
        }
        if (type == Type.FIND_ALL) {
            for (Object param : context.getParameterValues()) {
                if (param instanceof Sort && param != pageable) {
                    Sort sort = (Sort) param;
                    if (sort.isSorted()) {
                        criteriaQuery.orderBy(getOrders(sort, root, criteriaBuilder));
                        break;
                    }
                }
            }
        } else if (type == Type.COUNT) {
            criteriaQuery.select(criteriaBuilder.count(root));
        }
        queryResult = ((QueryResultPersistentEntityCriteriaQuery) criteriaQuery).buildQuery(sqlQueryBuilder);
    } else if (type == Type.DELETE_ALL) {
        DeleteSpecification<Object> specification = getDeleteSpecification(context);
        PersistentEntityCriteriaDelete<Object> criteriaDelete = criteriaBuilder.createCriteriaDelete(rootEntity);
        Root<Object> root = criteriaDelete.from(rootEntity);
        if (specification != null) {
            Predicate predicate = specification.toPredicate(root, criteriaDelete, criteriaBuilder);
            if (predicate != null) {
                criteriaDelete.where(predicate);
            }
        }
        queryResult = ((QueryResultPersistentEntityCriteriaQuery) criteriaDelete).buildQuery(sqlQueryBuilder);
    } else if (type == Type.UPDATE_ALL) {
        UpdateSpecification<Object> specification = getUpdateSpecification(context);
        PersistentEntityCriteriaUpdate<Object> criteriaUpdate = criteriaBuilder.createCriteriaUpdate(rootEntity);
        Root<Object> root = criteriaUpdate.from(rootEntity);
        if (specification != null) {
            Predicate predicate = specification.toPredicate(root, criteriaUpdate, criteriaBuilder);
            if (predicate != null) {
                criteriaUpdate.where(predicate);
            }
        }
        queryResult = ((QueryResultPersistentEntityCriteriaQuery) criteriaUpdate).buildQuery(sqlQueryBuilder);
    } else {
        throw new IllegalStateException("Unknown criteria type: " + type);
    }
    String query = queryResult.getQuery();
    String update = queryResult.getUpdate();
    List<io.micronaut.data.model.query.builder.QueryParameterBinding> parameterBindings = queryResult.getParameterBindings();
    List<QueryParameterBinding> queryParameters = new ArrayList<>(parameterBindings.size());
    for (io.micronaut.data.model.query.builder.QueryParameterBinding p : parameterBindings) {
        queryParameters.add(new QueryResultParameterBinding(p, queryParameters));
    }
    String[] queryParts = queryParameters.stream().anyMatch(QueryParameterBinding::isExpandable) ? queryResult.getQueryParts().toArray(new String[0]) : null;
    StoredQuery<E, QR> storedQuery;
    if (type == Type.COUNT) {
        storedQuery = (StoredQuery<E, QR>) storedQueryResolver.createCountStoredQuery(context.getExecutableMethod(), DataMethod.OperationType.COUNT, context.getName(), context.getAnnotationMetadata(), rootEntity, query, queryParts, queryParameters);
    } else if (type == Type.FIND_ALL) {
        storedQuery = storedQueryResolver.createStoredQuery(context.getExecutableMethod(), DataMethod.OperationType.QUERY, context.getName(), context.getAnnotationMetadata(), rootEntity, query, null, queryParts, queryParameters, !pageable.isUnpaged(), false);
    } else {
        DataMethod.OperationType operationType;
        switch(type) {
            case COUNT:
                operationType = DataMethod.OperationType.COUNT;
                break;
            case DELETE_ALL:
                operationType = DataMethod.OperationType.DELETE;
                break;
            case UPDATE_ALL:
                operationType = DataMethod.OperationType.UPDATE;
                break;
            case FIND_ALL:
            case FIND_ONE:
            case FIND_PAGE:
                operationType = DataMethod.OperationType.QUERY;
                break;
            default:
                throw new IllegalStateException("Unknown value: " + type);
        }
        storedQuery = storedQueryResolver.createStoredQuery(context.getExecutableMethod(), operationType, context.getName(), context.getAnnotationMetadata(), rootEntity, query, update, queryParts, queryParameters, false, true);
    }
    return preparedQueryResolver.resolveQuery(context, storedQuery, pageable);
}
Also used : QueryParameterBinding(io.micronaut.data.model.runtime.QueryParameterBinding) DeleteSpecification(io.micronaut.data.repository.jpa.criteria.DeleteSpecification) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata) ArrayList(java.util.ArrayList) QueryBuilder(io.micronaut.data.model.query.builder.QueryBuilder) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata) Predicate(jakarta.persistence.criteria.Predicate) QueryResult(io.micronaut.data.model.query.builder.QueryResult) Pageable(io.micronaut.data.model.Pageable) Sort(io.micronaut.data.model.Sort) RepositoryConfiguration(io.micronaut.data.annotation.RepositoryConfiguration) Root(jakarta.persistence.criteria.Root) QueryResultPersistentEntityCriteriaQuery(io.micronaut.data.model.jpa.criteria.impl.QueryResultPersistentEntityCriteriaQuery) PersistentEntityCriteriaDelete(io.micronaut.data.model.jpa.criteria.PersistentEntityCriteriaDelete)

Example 4 with QueryParameterBinding

use of io.micronaut.data.model.runtime.QueryParameterBinding 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 QueryParameterBinding

use of io.micronaut.data.model.runtime.QueryParameterBinding in project micronaut-coherence by micronaut-projects.

the class DefaultCoherenceRepositoryOperations method createBindingMap.

/**
 * Creates a map of binding parameters names and their values.
 *
 * @param preparedQuery the {@link PreparedQuery} to build the binding map from
 *
 * @return the parameters necessary to execute a CohQL statement
 */
protected Map<String, Object> createBindingMap(PreparedQuery preparedQuery) {
    List<QueryParameterBinding> bindings = preparedQuery.getQueryBindings();
    int bindingsLen = bindings.size();
    String[] bindingNames = new String[bindingsLen];
    Integer[] bindingIndexes = new Integer[bindingsLen];
    for (int i = 0; i < bindingsLen; i++) {
        QueryParameterBinding binding = bindings.get(i);
        bindingNames[i] = binding.getName();
        bindingIndexes[i] = binding.getParameterIndex();
    }
    Object[] bindingValues = preparedQuery.getParameterArray();
    return IntStream.range(0, bindingNames.length).boxed().collect(Collectors.toMap(i -> bindingNames[i], i -> bindingValues[bindingIndexes[i]]));
}
Also used : IntStream(java.util.stream.IntStream) Coherence(com.tangosol.net.Coherence) QueryParameterBinding(io.micronaut.data.model.runtime.QueryParameterBinding) Parameter(io.micronaut.context.annotation.Parameter) RemoveEventSource(io.micronaut.coherence.data.annotation.RemoveEventSource) BeanContext(io.micronaut.context.BeanContext) BeanProperty(io.micronaut.core.beans.BeanProperty) QueryHelper(com.tangosol.util.QueryHelper) UpdateEventSource(io.micronaut.coherence.data.annotation.UpdateEventSource) HashMap(java.util.HashMap) Session(com.tangosol.net.Session) ConcurrentMap(java.util.concurrent.ConcurrentMap) LinkedHashMap(java.util.LinkedHashMap) ApplicationContext(io.micronaut.context.ApplicationContext) Logger(com.oracle.coherence.common.base.Logger) Nullable(io.micronaut.core.annotation.Nullable) Map(java.util.Map) Page(io.micronaut.data.model.Page) ArgumentUtils(io.micronaut.core.util.ArgumentUtils) DeleteOperation(io.micronaut.data.model.runtime.DeleteOperation) NamedMap(com.tangosol.net.NamedMap) PrintWriter(java.io.PrintWriter) PagedQuery(io.micronaut.data.model.runtime.PagedQuery) ExecutionContext(com.tangosol.coherence.dslquery.ExecutionContext) RuntimePersistentProperty(io.micronaut.data.model.runtime.RuntimePersistentProperty) Processors(com.tangosol.util.Processors) StringWriter(java.io.StringWriter) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) Statement(com.tangosol.coherence.dslquery.Statement) IOException(java.io.IOException) InsertBatchOperation(io.micronaut.data.model.runtime.InsertBatchOperation) Collectors(java.util.stream.Collectors) PreparedQuery(io.micronaut.data.model.runtime.PreparedQuery) Serializable(java.io.Serializable) PersistEventSource(io.micronaut.coherence.data.annotation.PersistEventSource) NonNull(io.micronaut.core.annotation.NonNull) List(java.util.List) Stream(java.util.stream.Stream) DeleteBatchOperation(io.micronaut.data.model.runtime.DeleteBatchOperation) InsertOperation(io.micronaut.data.model.runtime.InsertOperation) Optional(java.util.Optional) EachProperty(io.micronaut.context.annotation.EachProperty) RuntimePersistentEntity(io.micronaut.data.model.runtime.RuntimePersistentEntity) AsyncRepositoryOperations(io.micronaut.data.operations.async.AsyncRepositoryOperations) UpdateOperation(io.micronaut.data.model.runtime.UpdateOperation) Collections(java.util.Collections) QueryParameterBinding(io.micronaut.data.model.runtime.QueryParameterBinding)

Aggregations

QueryParameterBinding (io.micronaut.data.model.runtime.QueryParameterBinding)7 RuntimePersistentProperty (io.micronaut.data.model.runtime.RuntimePersistentProperty)5 DataType (io.micronaut.data.model.DataType)4 PersistentPropertyPath (io.micronaut.data.model.PersistentPropertyPath)4 RuntimePersistentEntity (io.micronaut.data.model.runtime.RuntimePersistentEntity)2 Logger (com.oracle.coherence.common.base.Logger)1 ExecutionContext (com.tangosol.coherence.dslquery.ExecutionContext)1 Statement (com.tangosol.coherence.dslquery.Statement)1 Coherence (com.tangosol.net.Coherence)1 NamedMap (com.tangosol.net.NamedMap)1 Session (com.tangosol.net.Session)1 Processors (com.tangosol.util.Processors)1 QueryHelper (com.tangosol.util.QueryHelper)1 PersistEventSource (io.micronaut.coherence.data.annotation.PersistEventSource)1 RemoveEventSource (io.micronaut.coherence.data.annotation.RemoveEventSource)1 UpdateEventSource (io.micronaut.coherence.data.annotation.UpdateEventSource)1 ApplicationContext (io.micronaut.context.ApplicationContext)1 BeanContext (io.micronaut.context.BeanContext)1 EachProperty (io.micronaut.context.annotation.EachProperty)1 Parameter (io.micronaut.context.annotation.Parameter)1