All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.micronaut.data.runtime.operations.internal.sql.DefaultSqlStoredQuery Maven / Gradle / Ivy

There is a newer version: 4.10.5
Show newest version
/*
 * Copyright 2017-2021 original authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.micronaut.data.runtime.operations.internal.sql;

import io.micronaut.core.annotation.AnnotationValue;
import io.micronaut.core.annotation.Internal;
import io.micronaut.core.beans.BeanWrapper;
import io.micronaut.core.type.Argument;
import io.micronaut.data.annotation.QueryResult;
import io.micronaut.data.model.JsonDataType;
import io.micronaut.data.model.query.builder.sql.Dialect;
import io.micronaut.data.model.query.builder.sql.SqlQueryBuilder2;
import io.micronaut.data.model.runtime.QueryParameterBinding;
import io.micronaut.data.model.runtime.QueryResultInfo;
import io.micronaut.data.model.runtime.RuntimePersistentEntity;
import io.micronaut.data.model.runtime.StoredQuery;
import io.micronaut.data.runtime.operations.internal.query.DefaultBindableParametersStoredQuery;

import java.util.AbstractMap;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * Implementation of {@link SqlStoredQuery}.
 *
 * @param  The entity type
 * @param  The result type
 * @author Denis Stepanov
 * @since 3.5.0
 */
@Internal
public class DefaultSqlStoredQuery extends DefaultBindableParametersStoredQuery implements SqlStoredQuery {

    private final boolean expandableQuery;
    private final SqlQueryBuilder2 queryBuilder;
    private final QueryResultInfo queryResultInfo;

    /**
     * @param storedQuery             The stored query
     * @param runtimePersistentEntity The persistent entity
     * @param queryBuilder            The query builder
     */
    public DefaultSqlStoredQuery(StoredQuery storedQuery, RuntimePersistentEntity runtimePersistentEntity, SqlQueryBuilder2 queryBuilder) {
        super(storedQuery, runtimePersistentEntity);
        this.queryBuilder = queryBuilder;
        Objects.requireNonNull(storedQuery, "Query cannot be null");
        Objects.requireNonNull(queryBuilder, "Builder cannot be null");
        String[] expandableQueryParts = storedQuery.getExpandableQueryParts();
        List queryParameterBindings = storedQuery.getQueryBindings();
        this.expandableQuery = expandableQueryParts.length > 1 && queryParameterBindings.stream().anyMatch(QueryParameterBinding::isExpandable);
        if (expandableQuery && expandableQueryParts.length != queryParameterBindings.size() + 1) {
            throw new IllegalStateException("Expandable query parts size should be the same as parameters size + 1. " + expandableQueryParts.length + " != 1 + " + queryParameterBindings.size() + " " + storedQuery.getQuery() + " " + Arrays.toString(expandableQueryParts));
        }

        if (storedQuery.getAnnotationMetadata().hasAnnotation(QueryResult.class)) {
            AnnotationValue queryResultAnn = storedQuery.getAnnotationMetadata().getAnnotation(QueryResult.class);
            QueryResult.Type type = queryResultAnn.enumValue("type", QueryResult.Type.class).orElse(QueryResult.Type.JSON);
            String columnName = queryResultAnn.getRequiredValue("column", String.class);
            JsonDataType jsonDataType = type == QueryResult.Type.JSON ? queryResultAnn.enumValue("jsonDataType", JsonDataType.class).orElse(JsonDataType.DEFAULT) : null;
            queryResultInfo = new QueryResultInfo(type, columnName, jsonDataType);
        } else {
            queryResultInfo = null;
        }
    }

    @Override
    public QueryResultInfo getQueryResultInfo() {
        return queryResultInfo;
    }

    @Override
    public boolean isExpandableQuery() {
        return expandableQuery;
    }

    @Override
    public Dialect getDialect() {
        return queryBuilder.getDialect();
    }

    @Override
    public SqlQueryBuilder2 getQueryBuilder() {
        return queryBuilder;
    }

    @Override
    public Map collectAutoPopulatedPreviousValues(E entity) {
        StoredQuery storedQuery = getStoredQueryDelegate();
        if (storedQuery.getQueryBindings().isEmpty()) {
            return null;
        }
        return storedQuery.getQueryBindings().stream()
            .filter(b -> b.isAutoPopulated() && b.isRequiresPreviousPopulatedValue())
            .map(b -> {
                if (b.getPropertyPath() == null) {
                    throw new IllegalStateException("Missing property path for query parameter: " + b);
                }
                Object value = entity;
                for (String property : b.getPropertyPath()) {
                    if (value == null) {
                        break;
                    }
                    value = BeanWrapper.getWrapper(value).getRequiredProperty(property, Argument.OBJECT_ARGUMENT);
                }
                return new AbstractMap.SimpleEntry<>(b, value);
            })
            .filter(e -> e.getValue() != null)
            .collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue));
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy