Search in sources :

Example 1 with QueryParameterBinding

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

the class MongoRawQueryMethodMatcher method getQueryResult.

private QueryResult getQueryResult(MethodMatchContext matchContext, List<ParameterElement> parameters, ParameterElement entityParam, SourcePersistentEntity persistentEntity) {
    String filterQueryString;
    if (matchContext.getMethodElement().hasAnnotation(MongoAnnotations.AGGREGATION_QUERY)) {
        filterQueryString = matchContext.getMethodElement().stringValue(MongoAnnotations.AGGREGATION_QUERY).orElseThrow(() -> new MatchFailedException("The pipeline value is missing!"));
        // Mapped to query
        removeAnnotation(matchContext.getAnnotationMetadata(), MongoAnnotations.AGGREGATION_QUERY);
    } else if (matchContext.getMethodElement().hasAnnotation(MongoAnnotations.FIND_QUERY)) {
        filterQueryString = matchContext.getMethodElement().stringValue(MongoAnnotations.FILTER).orElseThrow(() -> new MatchFailedException("The filter value is missing!"));
        // Mapped to query
        removeAnnotation(matchContext.getAnnotationMetadata(), MongoAnnotations.FILTER);
        // Mapped to query
        removeAnnotation(matchContext.getAnnotationMetadata(), MongoAnnotations.FIND_QUERY);
    } else if (matchContext.getMethodElement().hasAnnotation(MongoAnnotations.DELETE_QUERY)) {
        filterQueryString = matchContext.getMethodElement().stringValue(MongoAnnotations.FILTER).orElseThrow(() -> new MatchFailedException("The filter value is missing!"));
        // Mapped to query
        removeAnnotation(matchContext.getAnnotationMetadata(), MongoAnnotations.FILTER);
        // Mapped to query
        removeAnnotation(matchContext.getAnnotationMetadata(), MongoAnnotations.DELETE_QUERY);
    } else {
        throw new MatchFailedException("Unknown custom query annotation!");
    }
    List<QueryParameterBinding> parameterBindings = new ArrayList<>(parameters.size());
    String filterQuery = processCustomQuery(matchContext, filterQueryString, parameters, entityParam, persistentEntity, parameterBindings);
    return new QueryResult() {

        @Override
        public String getQuery() {
            return filterQuery;
        }

        @Override
        public List<String> getQueryParts() {
            return Collections.emptyList();
        }

        @Override
        public List<QueryParameterBinding> getParameterBindings() {
            return parameterBindings;
        }

        @Override
        public Map<String, String> getAdditionalRequiredParameters() {
            return Collections.emptyMap();
        }
    };
}
Also used : QueryResult(io.micronaut.data.model.query.builder.QueryResult) MatchFailedException(io.micronaut.data.processor.visitors.MatchFailedException) QueryParameterBinding(io.micronaut.data.model.query.builder.QueryParameterBinding) ArrayList(java.util.ArrayList)

Example 2 with QueryParameterBinding

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

the class SqlQueryBuilder method buildInsert.

@NonNull
@Override
public QueryResult buildInsert(AnnotationMetadata repositoryMetadata, PersistentEntity entity) {
    boolean escape = shouldEscape(entity);
    final String unescapedTableName = getUnescapedTableName(entity);
    NamingStrategy namingStrategy = entity.getNamingStrategy();
    Collection<? extends PersistentProperty> persistentProperties = entity.getPersistentProperties();
    List<QueryParameterBinding> parameterBindings = new ArrayList<>();
    List<String> columns = new ArrayList<>();
    List<String> values = new ArrayList<>();
    for (PersistentProperty prop : persistentProperties) {
        if (!prop.isGenerated()) {
            traversePersistentProperties(prop, (associations, property) -> {
                addWriteExpression(values, prop);
                String key = String.valueOf(values.size());
                String[] path = asStringPath(associations, property);
                parameterBindings.add(new QueryParameterBinding() {

                    @Override
                    public String getKey() {
                        return key;
                    }

                    @Override
                    public DataType getDataType() {
                        return property.getDataType();
                    }

                    @Override
                    public String[] getPropertyPath() {
                        return path;
                    }
                });
                String columnName = namingStrategy.mappedName(associations, property);
                if (escape) {
                    columnName = quote(columnName);
                }
                columns.add(columnName);
            });
        }
    }
    PersistentProperty version = entity.getVersion();
    if (version != null) {
        addWriteExpression(values, version);
        String key = String.valueOf(values.size());
        parameterBindings.add(new QueryParameterBinding() {

            @Override
            public String getKey() {
                return key;
            }

            @Override
            public DataType getDataType() {
                return version.getDataType();
            }

            @Override
            public String[] getPropertyPath() {
                return new String[] { version.getName() };
            }
        });
        String columnName = namingStrategy.mappedName(Collections.emptyList(), version);
        if (escape) {
            columnName = quote(columnName);
        }
        columns.add(columnName);
    }
    PersistentProperty identity = entity.getIdentity();
    if (identity != null) {
        traversePersistentProperties(identity, (associations, property) -> {
            boolean isSequence = false;
            if (isNotForeign(associations)) {
                Optional<AnnotationValue<GeneratedValue>> generated = property.findAnnotation(GeneratedValue.class);
                if (generated.isPresent()) {
                    GeneratedValue.Type idGeneratorType = generated.flatMap(av -> av.enumValue(GeneratedValue.Type.class)).orElseGet(() -> selectAutoStrategy(property));
                    if (idGeneratorType == GeneratedValue.Type.SEQUENCE) {
                        isSequence = true;
                    } else if (dialect != Dialect.MYSQL || property.getDataType() != DataType.UUID) {
                        // Property skipped
                        return;
                    }
                }
            }
            if (isSequence) {
                values.add(getSequenceStatement(unescapedTableName, property));
            } else {
                addWriteExpression(values, property);
                String key = String.valueOf(values.size());
                String[] path = asStringPath(associations, property);
                parameterBindings.add(new QueryParameterBinding() {

                    @Override
                    public String getKey() {
                        return key;
                    }

                    @Override
                    public DataType getDataType() {
                        return property.getDataType();
                    }

                    @Override
                    public String[] getPropertyPath() {
                        return path;
                    }
                });
            }
            String columnName = namingStrategy.mappedName(associations, property);
            if (escape) {
                columnName = quote(columnName);
            }
            columns.add(columnName);
        });
    }
    String builder = INSERT_INTO + getTableName(entity) + " (" + String.join(",", columns) + CLOSE_BRACKET + " " + "VALUES (" + String.join(String.valueOf(COMMA), values) + CLOSE_BRACKET;
    return QueryResult.of(builder, Collections.emptyList(), parameterBindings, Collections.emptyMap());
}
Also used : DataType(io.micronaut.data.model.DataType) SqlMembers(io.micronaut.data.annotation.sql.SqlMembers) Arrays(java.util.Arrays) IDENTITY(io.micronaut.data.annotation.GeneratedValue.Type.IDENTITY) ListIterator(java.util.ListIterator) ArrayUtils(io.micronaut.core.util.ArrayUtils) SEQUENCE(io.micronaut.data.annotation.GeneratedValue.Type.SEQUENCE) MappedProperty(io.micronaut.data.annotation.MappedProperty) GeneratedValue(io.micronaut.data.annotation.GeneratedValue) Locale(java.util.Locale) Map(java.util.Map) QueryResult(io.micronaut.data.model.query.builder.QueryResult) ArgumentUtils(io.micronaut.core.util.ArgumentUtils) PersistentPropertyPath(io.micronaut.data.model.PersistentPropertyPath) PersistentProperty(io.micronaut.data.model.PersistentProperty) Index(io.micronaut.data.annotation.Index) MappingException(io.micronaut.data.exceptions.MappingException) Collection(java.util.Collection) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) AUTO(io.micronaut.data.annotation.GeneratedValue.Type.AUTO) StringUtils(io.micronaut.core.util.StringUtils) AbstractSqlLikeQueryBuilder(io.micronaut.data.model.query.builder.AbstractSqlLikeQueryBuilder) List(java.util.List) Stream(java.util.stream.Stream) UUID(io.micronaut.data.annotation.GeneratedValue.Type.UUID) AnnotationValue(io.micronaut.core.annotation.AnnotationValue) Annotation(java.lang.annotation.Annotation) Optional(java.util.Optional) Experimental(io.micronaut.core.annotation.Experimental) Pattern(java.util.regex.Pattern) Relation(io.micronaut.data.annotation.Relation) IntStream(java.util.stream.IntStream) QueryParameterBinding(io.micronaut.data.model.query.builder.QueryParameterBinding) Join(io.micronaut.data.annotation.Join) Creator(io.micronaut.core.annotation.Creator) QueryModel(io.micronaut.data.model.query.QueryModel) MappedEntity(io.micronaut.data.annotation.MappedEntity) HashMap(java.util.HashMap) OptionalInt(java.util.OptionalInt) Function(java.util.function.Function) ArrayList(java.util.ArrayList) Embedded(io.micronaut.data.model.Embedded) Pageable(io.micronaut.data.model.Pageable) BiConsumer(java.util.function.BiConsumer) Clob(java.sql.Clob) NamingStrategy(io.micronaut.data.model.naming.NamingStrategy) Indexes(io.micronaut.data.annotation.Indexes) NonNull(io.micronaut.core.annotation.NonNull) JoinPath(io.micronaut.data.model.query.JoinPath) Association(io.micronaut.data.model.Association) PersistentEntity(io.micronaut.data.model.PersistentEntity) CollectionUtils(io.micronaut.core.util.CollectionUtils) StringJoiner(java.util.StringJoiner) QueryBuilder(io.micronaut.data.model.query.builder.QueryBuilder) Repository(io.micronaut.data.annotation.Repository) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata) Blob(java.sql.Blob) Collections(java.util.Collections) QueryParameterBinding(io.micronaut.data.model.query.builder.QueryParameterBinding) ArrayList(java.util.ArrayList) PersistentProperty(io.micronaut.data.model.PersistentProperty) GeneratedValue(io.micronaut.data.annotation.GeneratedValue) NamingStrategy(io.micronaut.data.model.naming.NamingStrategy) DataType(io.micronaut.data.model.DataType) AnnotationValue(io.micronaut.core.annotation.AnnotationValue) NonNull(io.micronaut.core.annotation.NonNull)

Example 3 with QueryParameterBinding

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

the class RepositoryTypeElementVisitor method bindAdditionalParameters.

private void bindAdditionalParameters(MatchContext matchContext, SourcePersistentEntity entity, List<QueryParameterBinding> parameterBinding, ParameterElement[] parameters, Map<String, String> params) {
    if (CollectionUtils.isNotEmpty(params)) {
        Map<String, DataType> configuredDataTypes = Utils.getConfiguredDataTypes(matchContext.getRepositoryClass());
        for (Map.Entry<String, String> param : params.entrySet()) {
            ParameterElement parameter = Arrays.stream(parameters).filter(p -> p.stringValue(Parameter.class).orElse(p.getName()).equals(param.getValue())).findFirst().orElse(null);
            if (parameter == null) {
                throw new MatchFailedException("A @Where(..) definition requires a parameter called [" + param.getValue() + "] which is not present in the method signature.");
            }
            PersistentPropertyPath propertyPath = entity.getPropertyPath(parameter.getName());
            BindingParameter.BindingContext bindingContext = BindingParameter.BindingContext.create().name(param.getKey()).incomingMethodParameterProperty(propertyPath).outgoingQueryParameterProperty(propertyPath);
            QueryParameterBinding binding = new SourceParameterExpressionImpl(configuredDataTypes, matchContext.parameters, parameter, false).bind(bindingContext);
            parameterBinding.add(binding);
        }
    }
}
Also used : QueryParameterBinding(io.micronaut.data.model.query.builder.QueryParameterBinding) SourceParameterExpressionImpl(io.micronaut.data.processor.model.criteria.impl.SourceParameterExpressionImpl) PersistentPropertyPath(io.micronaut.data.model.PersistentPropertyPath) BindingParameter(io.micronaut.data.model.query.BindingParameter) DataType(io.micronaut.data.model.DataType) Parameter(io.micronaut.context.annotation.Parameter) BindingParameter(io.micronaut.data.model.query.BindingParameter) DataMethodQueryParameter(io.micronaut.data.intercept.annotation.DataMethodQueryParameter) ParameterElement(io.micronaut.inject.ast.ParameterElement) Map(java.util.Map) HashMap(java.util.HashMap)

Example 4 with QueryParameterBinding

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

the class RepositoryTypeElementVisitor method processMethodInfo.

private void processMethodInfo(MethodMatchContext methodMatchContext, MethodMatchInfo methodInfo) {
    QueryBuilder queryEncoder = methodMatchContext.getQueryBuilder();
    MethodElement element = methodMatchContext.getMethodElement();
    SourcePersistentEntity entity = methodMatchContext.getRootEntity();
    ParameterElement[] parameters = methodMatchContext.getParameters();
    // populate parameter roles
    for (Map.Entry<String, Element> entry : methodMatchContext.getParametersInRole().entrySet()) {
        methodInfo.addParameterRole(entry.getKey(), entry.getValue().getName());
    }
    List<QueryParameterBinding> parameterBinding = null;
    boolean encodeEntityParameters = false;
    boolean supportsImplicitQueries = methodMatchContext.supportsImplicitQueries();
    QueryResult queryResult = methodInfo.getQueryResult();
    if (queryResult != null) {
        if (methodInfo.isRawQuery()) {
            // no need to annotation since already annotated, just replace the
            // the computed parameter names
            parameterBinding = queryResult.getParameterBindings();
            element.annotate(Query.class, (builder) -> builder.member(DataMethod.META_MEMBER_RAW_QUERY, element.stringValue(Query.class).map(q -> addRawQueryParameterPlaceholders(queryEncoder, queryResult.getQuery(), queryResult.getQueryParts())).orElse(null)));
            ClassElement genericReturnType = methodMatchContext.getReturnType();
            if (methodMatchContext.isTypeInRole(genericReturnType, TypeRole.PAGE) || element.isPresent(Query.class, "countQuery")) {
                QueryResult countQueryResult = methodInfo.getCountQueryResult();
                if (countQueryResult == null) {
                    throw new MatchFailedException("Query returns a Page and does not specify a 'countQuery' member.", element);
                } else {
                    element.annotate(Query.class, (builder) -> builder.member(DataMethod.META_MEMBER_RAW_COUNT_QUERY, addRawQueryParameterPlaceholders(queryEncoder, countQueryResult.getQuery(), countQueryResult.getQueryParts())));
                }
            }
            encodeEntityParameters = methodInfo.isEncodeEntityParameters();
        } else {
            encodeEntityParameters = methodInfo.isEncodeEntityParameters();
            parameterBinding = queryResult.getParameterBindings();
            bindAdditionalParameters(methodMatchContext, entity, parameterBinding, parameters, queryResult.getAdditionalRequiredParameters());
            QueryResult preparedCount = methodInfo.getCountQueryResult();
            if (preparedCount != null) {
                element.annotate(Query.class, annotationBuilder -> {
                    annotationBuilder.value(queryResult.getQuery());
                    annotationBuilder.member(DataMethod.META_MEMBER_COUNT_QUERY, preparedCount.getQuery());
                });
            } else {
                element.annotate(Query.class, annotationBuilder -> {
                    annotationBuilder.value(queryResult.getQuery());
                    String update = queryResult.getUpdate();
                    if (StringUtils.isNotEmpty(update)) {
                        annotationBuilder.member("update", update);
                    }
                });
            }
        }
    }
    ClassElement runtimeInterceptor = methodInfo.getRuntimeInterceptor();
    if (runtimeInterceptor == null) {
        throw new MatchFailedException("Unable to implement Repository method: " + currentRepository.getSimpleName() + "." + element.getName() + "(..). No possible runtime implementations found.", element);
    }
    boolean finalEncodeEntityParameters = encodeEntityParameters;
    List<QueryParameterBinding> finalParameterBinding = parameterBinding;
    element.annotate(DataMethod.class, annotationBuilder -> {
        annotationBuilder.member(DataMethod.META_MEMBER_OPERATION_TYPE, methodInfo.getOperationType());
        annotationBuilder.member(DataMethod.META_MEMBER_ROOT_ENTITY, new AnnotationClassValue<>(entity.getName()));
        // include the roles
        methodInfo.getParameterRoles().forEach(annotationBuilder::member);
        if (methodInfo.isDto()) {
            annotationBuilder.member(DataMethod.META_MEMBER_DTO, true);
        }
        if (methodInfo.isOptimisticLock()) {
            annotationBuilder.member(DataMethod.META_MEMBER_OPTIMISTIC_LOCK, true);
        }
        TypedElement resultType = methodInfo.getResultType();
        if (resultType != null) {
            annotationBuilder.member(DataMethod.META_MEMBER_RESULT_TYPE, new AnnotationClassValue<>(resultType.getName()));
            ClassElement type = resultType.getType();
            if (!TypeUtils.isVoid(type)) {
                annotationBuilder.member(DataMethod.META_MEMBER_RESULT_DATA_TYPE, TypeUtils.resolveDataType(type, dataTypes));
            }
        }
        String idType = resolveIdType(entity);
        if (idType != null) {
            annotationBuilder.member(DataMethod.META_MEMBER_ID_TYPE, idType);
        }
        annotationBuilder.member(DataMethod.META_MEMBER_INTERCEPTOR, new AnnotationClassValue<>(runtimeInterceptor.getName()));
        if (queryResult != null) {
            if (finalParameterBinding.stream().anyMatch(QueryParameterBinding::isExpandable)) {
                annotationBuilder.member(DataMethod.META_MEMBER_EXPANDABLE_QUERY, queryResult.getQueryParts().toArray(new String[0]));
                QueryResult preparedCount = methodInfo.getCountQueryResult();
                if (preparedCount != null) {
                    annotationBuilder.member(DataMethod.META_MEMBER_EXPANDABLE_COUNT_QUERY, preparedCount.getQueryParts().toArray(new String[0]));
                }
            }
            int max = queryResult.getMax();
            if (max > -1) {
                annotationBuilder.member(DataMethod.META_MEMBER_PAGE_SIZE, max);
            }
            long offset = queryResult.getOffset();
            if (offset > 0) {
                annotationBuilder.member(DataMethod.META_MEMBER_PAGE_INDEX, offset);
            }
        }
        Arrays.stream(parameters).filter(p -> p.getGenericType().isAssignable(entity.getName())).findFirst().ifPresent(parameterElement -> annotationBuilder.member(DataMethod.META_MEMBER_ENTITY, parameterElement.getName()));
        if (CollectionUtils.isNotEmpty(finalParameterBinding)) {
            bindParameters(supportsImplicitQueries, finalParameterBinding, finalEncodeEntityParameters, annotationBuilder);
        }
    });
}
Also used : DataType(io.micronaut.data.model.DataType) OrderUtil(io.micronaut.core.order.OrderUtil) Arrays(java.util.Arrays) TypeRole(io.micronaut.data.annotation.TypeRole) Internal(io.micronaut.core.annotation.Internal) DataMethod(io.micronaut.data.intercept.annotation.DataMethod) SoftServiceLoader(io.micronaut.core.io.service.SoftServiceLoader) SqlQueryBuilder(io.micronaut.data.model.query.builder.sql.SqlQueryBuilder) Map(java.util.Map) QueryResult(io.micronaut.data.model.query.builder.QueryResult) AnnotationClassValue(io.micronaut.core.annotation.AnnotationClassValue) PersistentPropertyPath(io.micronaut.data.model.PersistentPropertyPath) PersistentProperty(io.micronaut.data.model.PersistentProperty) SourceParameterExpressionImpl(io.micronaut.data.processor.model.criteria.impl.SourceParameterExpressionImpl) Sort(io.micronaut.data.model.Sort) Query(io.micronaut.data.annotation.Query) Set(java.util.Set) Collectors(java.util.stream.Collectors) GenericRepository(io.micronaut.data.repository.GenericRepository) StringUtils(io.micronaut.core.util.StringUtils) List(java.util.List) AnnotationValue(io.micronaut.core.annotation.AnnotationValue) MethodElement(io.micronaut.inject.ast.MethodElement) MethodMatchInfo(io.micronaut.data.processor.visitors.finders.MethodMatchInfo) QueryParameterBinding(io.micronaut.data.model.query.builder.QueryParameterBinding) Parameter(io.micronaut.context.annotation.Parameter) RepositoryConfiguration(io.micronaut.data.annotation.RepositoryConfiguration) SourcePersistentProperty(io.micronaut.data.processor.model.SourcePersistentProperty) ClassElement(io.micronaut.inject.ast.ClassElement) HashMap(java.util.HashMap) Function(java.util.function.Function) ParameterElement(io.micronaut.inject.ast.ParameterElement) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) TypeElementVisitor(io.micronaut.inject.visitor.TypeElementVisitor) TypedElement(io.micronaut.inject.ast.TypedElement) Nullable(io.micronaut.core.annotation.Nullable) MethodMatcher(io.micronaut.data.processor.visitors.finders.MethodMatcher) Page(io.micronaut.data.model.Page) Pageable(io.micronaut.data.model.Pageable) TypeUtils(io.micronaut.data.processor.visitors.finders.TypeUtils) Element(io.micronaut.inject.ast.Element) Iterator(java.util.Iterator) Slice(io.micronaut.data.model.Slice) SourcePersistentEntity(io.micronaut.data.processor.model.SourcePersistentEntity) NonNull(io.micronaut.core.annotation.NonNull) BindingParameter(io.micronaut.data.model.query.BindingParameter) VisitorContext(io.micronaut.inject.visitor.VisitorContext) AnnotationValueBuilder(io.micronaut.core.annotation.AnnotationValueBuilder) PersistentEntity(io.micronaut.data.model.PersistentEntity) CollectionUtils(io.micronaut.core.util.CollectionUtils) QueryBuilder(io.micronaut.data.model.query.builder.QueryBuilder) Repository(io.micronaut.data.annotation.Repository) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata) DataMethodQueryParameter(io.micronaut.data.intercept.annotation.DataMethodQueryParameter) Collections(java.util.Collections) QueryParameterBinding(io.micronaut.data.model.query.builder.QueryParameterBinding) Query(io.micronaut.data.annotation.Query) SourcePersistentEntity(io.micronaut.data.processor.model.SourcePersistentEntity) MethodElement(io.micronaut.inject.ast.MethodElement) ClassElement(io.micronaut.inject.ast.ClassElement) ParameterElement(io.micronaut.inject.ast.ParameterElement) TypedElement(io.micronaut.inject.ast.TypedElement) Element(io.micronaut.inject.ast.Element) TypedElement(io.micronaut.inject.ast.TypedElement) MethodElement(io.micronaut.inject.ast.MethodElement) ClassElement(io.micronaut.inject.ast.ClassElement) SqlQueryBuilder(io.micronaut.data.model.query.builder.sql.SqlQueryBuilder) QueryBuilder(io.micronaut.data.model.query.builder.QueryBuilder) QueryResult(io.micronaut.data.model.query.builder.QueryResult) ParameterElement(io.micronaut.inject.ast.ParameterElement) Map(java.util.Map) HashMap(java.util.HashMap)

Example 5 with QueryParameterBinding

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

the class RawQueryMethodMatcher method getQueryResult.

private QueryResult getQueryResult(MethodMatchContext matchContext, String queryString, List<ParameterElement> parameters, boolean namedParameters, ParameterElement entityParam, SourcePersistentEntity persistentEntity) {
    java.util.regex.Matcher matcher = VARIABLE_PATTERN.matcher(queryString.replace("\\:", ""));
    List<QueryParameterBinding> parameterBindings = new ArrayList<>(parameters.size());
    List<String> queryParts = new ArrayList<>();
    int index = 1;
    int lastOffset = 0;
    while (matcher.find()) {
        String prefix = queryString.substring(lastOffset, matcher.start(3) - 1);
        if (!prefix.isEmpty()) {
            queryParts.add(prefix);
        }
        lastOffset = matcher.end(3);
        String name = matcher.group(3);
        if (namedParameters) {
            Optional<ParameterElement> element = parameters.stream().filter(p -> p.stringValue(Parameter.class).orElse(p.getName()).equals(name)).findFirst();
            if (element.isPresent()) {
                PersistentPropertyPath propertyPath = matchContext.getRootEntity().getPropertyPath(name);
                BindingContext bindingContext = BindingContext.create().name(name).incomingMethodParameterProperty(propertyPath).outgoingQueryParameterProperty(propertyPath);
                parameterBindings.add(bindingParameter(matchContext, element.get()).bind(bindingContext));
            } else if (persistentEntity != null) {
                PersistentPropertyPath propertyPath = persistentEntity.getPropertyPath(name);
                if (propertyPath == null) {
                    throw new MatchFailedException("Cannot update non-existent property: " + name);
                } else {
                    BindingContext bindingContext = BindingContext.create().name(name).incomingMethodParameterProperty(propertyPath).outgoingQueryParameterProperty(propertyPath);
                    parameterBindings.add(bindingParameter(matchContext, entityParam, true).bind(bindingContext));
                }
            } else {
                throw new MatchFailedException("No method parameter found for named Query parameter: " + name);
            }
        } else {
            Optional<ParameterElement> element = parameters.stream().filter(p -> p.stringValue(Parameter.class).orElse(p.getName()).equals(name)).findFirst();
            if (element.isPresent()) {
                PersistentPropertyPath propertyPath = matchContext.getRootEntity().getPropertyPath(name);
                BindingContext bindingContext = BindingContext.create().index(index++).incomingMethodParameterProperty(propertyPath).outgoingQueryParameterProperty(propertyPath);
                parameterBindings.add(bindingParameter(matchContext, element.get()).bind(bindingContext));
            } else if (persistentEntity != null) {
                PersistentPropertyPath propertyPath = persistentEntity.getPropertyPath(name);
                if (propertyPath == null) {
                    matchContext.fail("Cannot update non-existent property: " + name);
                } else {
                    BindingContext bindingContext = BindingContext.create().index(index++).incomingMethodParameterProperty(propertyPath).outgoingQueryParameterProperty(propertyPath);
                    parameterBindings.add(bindingParameter(matchContext, entityParam, true).bind(bindingContext));
                }
            } else {
                throw new MatchFailedException("No method parameter found for named Query parameter: " + name);
            }
        }
    }
    queryString = queryString.replace("\\:", ":");
    if (queryParts.isEmpty()) {
        queryParts.add(queryString);
    } else if (lastOffset > 0) {
        queryParts.add(queryString.substring(lastOffset));
    }
    String finalQueryString = queryString;
    return new QueryResult() {

        @Override
        public String getQuery() {
            return finalQueryString;
        }

        @Override
        public List<String> getQueryParts() {
            return queryParts;
        }

        @Override
        public List<QueryParameterBinding> getParameterBindings() {
            return parameterBindings;
        }

        @Override
        public Map<String, String> getAdditionalRequiredParameters() {
            return Collections.emptyMap();
        }
    };
}
Also used : QueryParameterBinding(io.micronaut.data.model.query.builder.QueryParameterBinding) Arrays(java.util.Arrays) Parameter(io.micronaut.context.annotation.Parameter) RepositoryConfiguration(io.micronaut.data.annotation.RepositoryConfiguration) TypeRole(io.micronaut.data.annotation.TypeRole) MappedEntity(io.micronaut.data.annotation.MappedEntity) ClassElement(io.micronaut.inject.ast.ClassElement) DataInterceptor(io.micronaut.data.intercept.DataInterceptor) ParameterElement(io.micronaut.inject.ast.ParameterElement) ArrayList(java.util.ArrayList) DataMethod(io.micronaut.data.intercept.annotation.DataMethod) Locale(java.util.Locale) Map(java.util.Map) QueryResult(io.micronaut.data.model.query.builder.QueryResult) PersistentPropertyPath(io.micronaut.data.model.PersistentPropertyPath) SourceParameterExpressionImpl(io.micronaut.data.processor.model.criteria.impl.SourceParameterExpressionImpl) BindingContext(io.micronaut.data.model.query.BindingParameter.BindingContext) MatchFailedException(io.micronaut.data.processor.visitors.MatchFailedException) Query(io.micronaut.data.annotation.Query) Utils(io.micronaut.data.processor.visitors.Utils) SourcePersistentEntity(io.micronaut.data.processor.model.SourcePersistentEntity) Introspected(io.micronaut.core.annotation.Introspected) NonNull(io.micronaut.core.annotation.NonNull) List(java.util.List) MethodMatchContext(io.micronaut.data.processor.visitors.MethodMatchContext) MethodElement(io.micronaut.inject.ast.MethodElement) Optional(java.util.Optional) Pattern(java.util.regex.Pattern) Collections(java.util.Collections) QueryParameterBinding(io.micronaut.data.model.query.builder.QueryParameterBinding) MatchFailedException(io.micronaut.data.processor.visitors.MatchFailedException) ArrayList(java.util.ArrayList) PersistentPropertyPath(io.micronaut.data.model.PersistentPropertyPath) BindingContext(io.micronaut.data.model.query.BindingParameter.BindingContext) QueryResult(io.micronaut.data.model.query.builder.QueryResult) ParameterElement(io.micronaut.inject.ast.ParameterElement)

Aggregations

QueryParameterBinding (io.micronaut.data.model.query.builder.QueryParameterBinding)14 PersistentPropertyPath (io.micronaut.data.model.PersistentPropertyPath)10 QueryResult (io.micronaut.data.model.query.builder.QueryResult)8 ArrayList (java.util.ArrayList)8 Map (java.util.Map)8 NonNull (io.micronaut.core.annotation.NonNull)6 ParameterElement (io.micronaut.inject.ast.ParameterElement)5 Arrays (java.util.Arrays)5 HashMap (java.util.HashMap)5 List (java.util.List)5 Parameter (io.micronaut.context.annotation.Parameter)4 DataType (io.micronaut.data.model.DataType)4 BindingParameter (io.micronaut.data.model.query.BindingParameter)4 MatchFailedException (io.micronaut.data.processor.visitors.MatchFailedException)4 ClassElement (io.micronaut.inject.ast.ClassElement)4 AnnotationMetadata (io.micronaut.core.annotation.AnnotationMetadata)3 AnnotationValue (io.micronaut.core.annotation.AnnotationValue)3 MappedEntity (io.micronaut.data.annotation.MappedEntity)3 Query (io.micronaut.data.annotation.Query)3 TypeRole (io.micronaut.data.annotation.TypeRole)3