use of io.micronaut.data.model.Embedded in project micronaut-data by micronaut-projects.
the class AbstractSqlRepositoryOperations method idPropertiesWithValues.
private Stream<Map.Entry<PersistentProperty, Object>> idPropertiesWithValues(PersistentProperty property, Object value) {
Object propertyValue = ((RuntimePersistentProperty) property).getProperty().get(value);
if (property instanceof Embedded) {
Embedded embedded = (Embedded) property;
PersistentEntity embeddedEntity = embedded.getAssociatedEntity();
return embeddedEntity.getPersistentProperties().stream().flatMap(prop -> idPropertiesWithValues(prop, propertyValue));
} else if (property instanceof Association) {
Association association = (Association) property;
if (association.isForeignKey()) {
return Stream.empty();
}
PersistentEntity associatedEntity = association.getAssociatedEntity();
PersistentProperty identity = associatedEntity.getIdentity();
if (identity == null) {
throw new IllegalStateException("Identity cannot be missing for: " + associatedEntity);
}
return idPropertiesWithValues(identity, propertyValue);
}
return Stream.of(new AbstractMap.SimpleEntry<>(property, propertyValue));
}
use of io.micronaut.data.model.Embedded in project micronaut-data by micronaut-projects.
the class MongoQueryBuilder method findPropertyInternal.
private PersistentPropertyPath findPropertyInternal(QueryState queryState, PersistentEntity entity, String name, Class criterionType) {
PersistentPropertyPath propertyPath = entity.getPropertyPath(name);
if (propertyPath != null) {
if (propertyPath.getAssociations().isEmpty()) {
return propertyPath;
}
Association joinAssociation = null;
StringJoiner joinPathJoiner = new StringJoiner(".");
for (Association association : propertyPath.getAssociations()) {
joinPathJoiner.add(association.getName());
if (association instanceof Embedded) {
continue;
}
if (joinAssociation == null) {
joinAssociation = association;
continue;
}
if (association != joinAssociation.getAssociatedEntity().getIdentity()) {
if (!queryState.isAllowJoins()) {
throw new IllegalArgumentException("Joins cannot be used in a DELETE or UPDATE operation");
}
String joinStringPath = joinPathJoiner.toString();
if (!queryState.isJoined(joinStringPath)) {
throw new IllegalArgumentException("Property is not joined at path: " + joinStringPath);
}
// lastJoinAlias = joinInPath(queryState, joinStringPath);
// Continue to look for a joined property
joinAssociation = association;
} else {
// We don't need to join to access the id of the relation
joinAssociation = null;
}
}
PersistentProperty property = propertyPath.getProperty();
if (joinAssociation != null) {
if (property != joinAssociation.getAssociatedEntity().getIdentity()) {
String joinStringPath = joinPathJoiner.toString();
if (!queryState.isJoined(joinStringPath)) {
throw new IllegalArgumentException("Property is not joined at path: " + joinStringPath);
}
}
// We don't need to join to access the id of the relation
}
} else if (TypeRole.ID.equals(name) && entity.getIdentity() != null) {
// special case handling for ID
return PersistentPropertyPath.of(Collections.emptyList(), entity.getIdentity(), entity.getIdentity().getName());
}
if (propertyPath == null) {
if (criterionType == null || criterionType == Sort.Order.class) {
throw new IllegalArgumentException("Cannot order on non-existent property path: " + name);
} else {
throw new IllegalArgumentException("Cannot use [" + criterionType.getSimpleName() + "] criterion on non-existent property path: " + name);
}
}
return propertyPath;
}
use of io.micronaut.data.model.Embedded in project micronaut-data by micronaut-projects.
the class AbstractSqlLikeQueryBuilder method traversePersistentProperties.
private void traversePersistentProperties(List<Association> associations, PersistentProperty property, BiConsumer<List<Association>, PersistentProperty> consumerProperty) {
if (property instanceof Embedded) {
Embedded embedded = (Embedded) property;
PersistentEntity embeddedEntity = embedded.getAssociatedEntity();
Collection<? extends PersistentProperty> embeddedProperties = embeddedEntity.getPersistentProperties();
List<Association> newAssociations = new ArrayList<>(associations);
newAssociations.add((Association) property);
for (PersistentProperty embeddedProperty : embeddedProperties) {
traversePersistentProperties(newAssociations, embeddedProperty, consumerProperty);
}
} else if (property instanceof Association) {
Association association = (Association) property;
if (association.isForeignKey()) {
return;
}
List<Association> newAssociations = new ArrayList<>(associations);
newAssociations.add((Association) property);
PersistentEntity associatedEntity = association.getAssociatedEntity();
PersistentProperty assocIdentity = associatedEntity.getIdentity();
if (assocIdentity == null) {
throw new IllegalStateException("Identity cannot be missing for: " + associatedEntity);
}
if (assocIdentity instanceof Association) {
traversePersistentProperties(newAssociations, assocIdentity, consumerProperty);
} else {
consumerProperty.accept(newAssociations, assocIdentity);
}
} else {
consumerProperty.accept(associations, property);
}
}
use of io.micronaut.data.model.Embedded in project micronaut-data by micronaut-projects.
the class AbstractSqlLikeQueryBuilder method buildSelect.
private void buildSelect(QueryState queryState, StringBuilder queryString, List<QueryModel.Projection> projectionList, String tableAlias, PersistentEntity entity) {
if (projectionList.isEmpty()) {
selectAllColumns(queryState, queryString);
} else {
for (Iterator i = projectionList.iterator(); i.hasNext(); ) {
QueryModel.Projection projection = (QueryModel.Projection) i.next();
if (projection instanceof QueryModel.LiteralProjection) {
queryString.append(asLiteral(((QueryModel.LiteralProjection) projection).getValue()));
} else if (projection instanceof QueryModel.CountProjection) {
appendProjectionRowCount(queryString, tableAlias);
} else if (projection instanceof QueryModel.DistinctProjection) {
queryString.append("DISTINCT(").append(tableAlias).append(CLOSE_BRACKET);
} else if (projection instanceof QueryModel.IdProjection) {
if (entity.hasCompositeIdentity()) {
for (PersistentProperty identity : entity.getCompositeIdentity()) {
appendPropertyProjection(queryString, asQueryPropertyPath(queryState.getRootAlias(), identity));
queryString.append(COMMA);
}
queryString.setLength(queryString.length() - 1);
} else if (entity.hasIdentity()) {
PersistentProperty identity = entity.getIdentity();
if (identity == null) {
throw new IllegalArgumentException("Cannot query on ID with entity that has no ID");
}
appendPropertyProjection(queryString, asQueryPropertyPath(queryState.getRootAlias(), identity));
} else {
throw new IllegalArgumentException("Cannot query on ID with entity that has no ID");
}
} else if (projection instanceof QueryModel.PropertyProjection) {
QueryModel.PropertyProjection pp = (QueryModel.PropertyProjection) projection;
String alias = pp.getAlias().orElse(null);
if (projection instanceof QueryModel.AvgProjection) {
appendFunctionProjection(queryState.getEntity(), AVG, pp, tableAlias, queryString);
} else if (projection instanceof QueryModel.DistinctPropertyProjection) {
appendFunctionProjection(queryState.getEntity(), DISTINCT, pp, tableAlias, queryString);
} else if (projection instanceof QueryModel.SumProjection) {
appendFunctionProjection(queryState.getEntity(), SUM, pp, tableAlias, queryString);
} else if (projection instanceof QueryModel.MinProjection) {
appendFunctionProjection(queryState.getEntity(), MIN, pp, tableAlias, queryString);
} else if (projection instanceof QueryModel.MaxProjection) {
appendFunctionProjection(queryState.getEntity(), MAX, pp, tableAlias, queryString);
} else if (projection instanceof QueryModel.CountDistinctProjection) {
appendFunctionProjection(queryState.getEntity(), COUNT_DISTINCT, pp, tableAlias, queryString);
queryString.append(CLOSE_BRACKET);
} else {
String propertyName = pp.getPropertyName();
PersistentPropertyPath propertyPath = entity.getPropertyPath(propertyName);
if (propertyPath == null) {
throw new IllegalArgumentException("Cannot project on non-existent property: " + propertyName);
}
PersistentProperty property = propertyPath.getProperty();
if (property instanceof Association && !(property instanceof Embedded)) {
if (!queryState.isJoined(propertyPath.getPath())) {
queryString.setLength(queryString.length() - 1);
continue;
}
String joinAlias = queryState.computeAlias(propertyPath.getPath());
selectAllColumns(((Association) property).getAssociatedEntity(), joinAlias, queryString);
} else {
appendPropertyProjection(queryString, findProperty(queryState, propertyName, null));
}
}
if (alias != null) {
queryString.append(AS_CLAUSE).append(alias);
}
}
if (i.hasNext()) {
queryString.append(COMMA);
}
}
}
}
use of io.micronaut.data.model.Embedded in project micronaut-data by micronaut-projects.
the class JpaQueryBuilder method buildJoin.
@Override
protected String[] buildJoin(String alias, JoinPath joinPath, String joinType, StringBuilder target, Map<String, String> appliedJoinPaths, QueryState queryState) {
Association[] associationPath = joinPath.getAssociationPath();
String[] joinAliases;
if (ArrayUtils.isEmpty(associationPath)) {
throw new IllegalArgumentException("Invalid association path [" + joinPath.getPath() + "]");
}
List<Association> joinAssociationsPath = new ArrayList<>(associationPath.length);
joinAliases = new String[associationPath.length];
StringJoiner pathSoFar = new StringJoiner(".");
List<String> aliases = new ArrayList<>();
for (int i = 0; i < associationPath.length; i++) {
Association association = associationPath[i];
pathSoFar.add(association.getName());
if (association instanceof Embedded) {
joinAssociationsPath.add(association);
continue;
}
String currentPath = pathSoFar.toString();
String existingAlias = appliedJoinPaths.get(currentPath);
if (existingAlias != null) {
joinAliases[i] = existingAlias;
aliases.add(existingAlias);
} else {
int finalI = i;
JoinPath joinPathToUse = queryState.getQueryModel().getJoinPath(currentPath).orElseGet(() -> new JoinPath(currentPath, Arrays.copyOfRange(associationPath, 0, finalI + 1), joinPath.getJoinType(), joinPath.getAlias().orElse(null)));
String currentAlias = getAliasName(joinPathToUse);
joinAliases[i] = currentAlias;
String lastJoinAlias = aliases.isEmpty() ? alias : CollectionUtils.last(aliases);
target.append(joinType).append(lastJoinAlias).append(DOT).append(association.getName()).append(SPACE).append(joinAliases[i]);
aliases.add(currentAlias);
}
joinAssociationsPath.clear();
}
return joinAliases;
}
Aggregations