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);
}
}
}
}
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());
}
}
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);
}
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);
}
}
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]]));
}
Aggregations