Search in sources :

Example 1 with Embedded

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));
}
Also used : AbstractMap(java.util.AbstractMap) RuntimeAssociation(io.micronaut.data.model.runtime.RuntimeAssociation) Association(io.micronaut.data.model.Association) PersistentEntity(io.micronaut.data.model.PersistentEntity) RuntimePersistentEntity(io.micronaut.data.model.runtime.RuntimePersistentEntity) Embedded(io.micronaut.data.model.Embedded) PersistentProperty(io.micronaut.data.model.PersistentProperty) RuntimePersistentProperty(io.micronaut.data.model.runtime.RuntimePersistentProperty)

Example 2 with Embedded

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;
}
Also used : Association(io.micronaut.data.model.Association) PersistentPropertyPath(io.micronaut.data.model.PersistentPropertyPath) Embedded(io.micronaut.data.model.Embedded) PersistentProperty(io.micronaut.data.model.PersistentProperty) StringJoiner(java.util.StringJoiner)

Example 3 with Embedded

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);
    }
}
Also used : Association(io.micronaut.data.model.Association) PersistentEntity(io.micronaut.data.model.PersistentEntity) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) Embedded(io.micronaut.data.model.Embedded) PersistentProperty(io.micronaut.data.model.PersistentProperty)

Example 4 with Embedded

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);
            }
        }
    }
}
Also used : PersistentProperty(io.micronaut.data.model.PersistentProperty) PersistentPropertyPath(io.micronaut.data.model.PersistentPropertyPath) QueryModel(io.micronaut.data.model.query.QueryModel) Association(io.micronaut.data.model.Association) Iterator(java.util.Iterator) Embedded(io.micronaut.data.model.Embedded)

Example 5 with Embedded

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;
}
Also used : Association(io.micronaut.data.model.Association) JoinPath(io.micronaut.data.model.query.JoinPath) ArrayList(java.util.ArrayList) Embedded(io.micronaut.data.model.Embedded) StringJoiner(java.util.StringJoiner)

Aggregations

Embedded (io.micronaut.data.model.Embedded)13 Association (io.micronaut.data.model.Association)11 PersistentProperty (io.micronaut.data.model.PersistentProperty)7 PersistentEntity (io.micronaut.data.model.PersistentEntity)6 ArrayList (java.util.ArrayList)6 List (java.util.List)5 StringJoiner (java.util.StringJoiner)5 PersistentPropertyPath (io.micronaut.data.model.PersistentPropertyPath)4 AnnotationMetadata (io.micronaut.core.annotation.AnnotationMetadata)3 Relation (io.micronaut.data.annotation.Relation)3 JoinPath (io.micronaut.data.model.query.JoinPath)3 RuntimeAssociation (io.micronaut.data.model.runtime.RuntimeAssociation)3 Internal (io.micronaut.core.annotation.Internal)2 BeanProperty (io.micronaut.core.beans.BeanProperty)2 CollectionUtils (io.micronaut.core.util.CollectionUtils)2 Arrays (java.util.Arrays)2 Collections (java.util.Collections)2 ListIterator (java.util.ListIterator)2 Pattern (java.util.regex.Pattern)2 Parameter (io.micronaut.context.annotation.Parameter)1