use of io.micronaut.data.model.query.builder.QueryResult in project micronaut-data by micronaut-projects.
the class AbstractSqlRepositoryOperations method resolveEntityUpdate.
/**
* Resolves a stored update for the given entity.
*
* @param annotationMetadata The repository annotation metadata
* @param repositoryType The repository type
* @param rootEntity The root entity
* @param persistentEntity The persistent entity
* @return The insert
*/
@NonNull
protected DBOperation resolveEntityUpdate(AnnotationMetadata annotationMetadata, Class<?> repositoryType, @NonNull Class<?> rootEntity, @NonNull RuntimePersistentEntity<?> persistentEntity) {
final QueryKey key = new QueryKey(repositoryType, rootEntity);
// noinspection unchecked
return entityUpdates.computeIfAbsent(key, (queryKey) -> {
final SqlQueryBuilder queryBuilder = queryBuilders.getOrDefault(repositoryType, DEFAULT_SQL_BUILDER);
final String idName;
final PersistentProperty identity = persistentEntity.getIdentity();
if (identity != null) {
idName = identity.getName();
} else {
idName = TypeRole.ID;
}
final QueryModel queryModel = QueryModel.from(persistentEntity).idEq(new QueryParameter(idName));
List<String> updateProperties = persistentEntity.getPersistentProperties().stream().filter(p -> !((p instanceof Association) && ((Association) p).isForeignKey()) && p.getAnnotationMetadata().booleanValue(AutoPopulated.class, "updateable").orElse(true)).map(PersistentProperty::getName).collect(Collectors.toList());
final QueryResult queryResult = queryBuilder.buildUpdate(annotationMetadata, queryModel, updateProperties);
return new QueryResultSqlOperation(queryBuilder, queryResult);
});
}
use of io.micronaut.data.model.query.builder.QueryResult 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.query.builder.QueryResult in project micronaut-data by micronaut-projects.
the class MongoRawQueryMethodMatcher method buildRawQuery.
private void buildRawQuery(@NonNull MethodMatchContext matchContext, MethodMatchInfo methodMatchInfo, ParameterElement entityParameter, ParameterElement entitiesParameter, DataMethod.OperationType operationType) {
MethodElement methodElement = matchContext.getMethodElement();
List<ParameterElement> parameters = Arrays.asList(matchContext.getParameters());
ParameterElement entityParam = null;
SourcePersistentEntity persistentEntity = null;
if (entityParameter != null) {
entityParam = entityParameter;
persistentEntity = matchContext.getEntity(entityParameter.getGenericType());
} else if (entitiesParameter != null) {
entityParam = entitiesParameter;
persistentEntity = matchContext.getEntity(entitiesParameter.getGenericType().getFirstTypeArgument().orElseThrow(IllegalStateException::new));
}
QueryResult queryResult;
if (operationType == DataMethod.OperationType.UPDATE) {
queryResult = getUpdateQueryResult(matchContext, parameters, entityParam, persistentEntity);
} else {
queryResult = getQueryResult(matchContext, parameters, entityParam, persistentEntity);
}
boolean encodeEntityParameters = persistentEntity != null || operationType == DataMethod.OperationType.INSERT;
methodElement.annotate(Query.class, builder -> {
if (queryResult.getUpdate() != null) {
builder.member("update", queryResult.getUpdate());
}
builder.value(queryResult.getQuery());
});
methodMatchInfo.encodeEntityParameters(encodeEntityParameters).queryResult(queryResult).countQueryResult(null);
}
use of io.micronaut.data.model.query.builder.QueryResult 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();
}
};
}
use of io.micronaut.data.model.query.builder.QueryResult 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());
}
Aggregations