Search in sources :

Example 6 with DbRelationship

use of org.apache.cayenne.map.DbRelationship in project cayenne by apache.

the class PrefetchProcessorJointNode method buildRowMapping.

/**
 * Configures row columns mapping for this node entity.
 */
private void buildRowMapping() {
    final Map<String, ColumnDescriptor> targetSource = new TreeMap<>();
    // build a DB path .. find parent node that terminates the joint group...
    PrefetchTreeNode jointRoot = this;
    while (jointRoot.getParent() != null && !jointRoot.isDisjointPrefetch() && !jointRoot.isDisjointByIdPrefetch()) {
        jointRoot = jointRoot.getParent();
    }
    final String prefix;
    if (jointRoot != this) {
        Expression objectPath = ExpressionFactory.exp(getPath(jointRoot));
        ASTPath translated = (ASTPath) ((PrefetchProcessorNode) jointRoot).getResolver().getEntity().translateToDbPath(objectPath);
        // make sure we do not include "db:" prefix
        prefix = translated.getOperand(0) + ".";
    } else {
        prefix = "";
    }
    if (getParent() != null && !getParent().isPhantom() && getIncoming() != null && !getIncoming().getRelationship().isFlattened()) {
        DbRelationship r = getIncoming().getRelationship().getDbRelationships().get(0);
        for (final DbJoin join : r.getJoins()) {
            appendColumn(targetSource, join.getTargetName(), prefix + join.getTargetName());
        }
    }
    ClassDescriptor descriptor = resolver.getDescriptor();
    descriptor.visitAllProperties(new PropertyVisitor() {

        public boolean visitAttribute(AttributeProperty property) {
            String target = property.getAttribute().getDbAttributePath();
            appendColumn(targetSource, target, prefix + target);
            return true;
        }

        public boolean visitToMany(ToManyProperty property) {
            return visitRelationship(property);
        }

        public boolean visitToOne(ToOneProperty property) {
            return visitRelationship(property);
        }

        private boolean visitRelationship(ArcProperty arc) {
            DbRelationship dbRel = arc.getRelationship().getDbRelationships().get(0);
            for (DbAttribute attribute : dbRel.getSourceAttributes()) {
                String target = attribute.getName();
                appendColumn(targetSource, target, prefix + target);
            }
            return true;
        }
    });
    // append id columns ... (some may have been appended already via relationships)
    for (String pkName : descriptor.getEntity().getPrimaryKeyNames()) {
        appendColumn(targetSource, pkName, prefix + pkName);
    }
    // append inheritance discriminator columns...
    for (ObjAttribute column : descriptor.getDiscriminatorColumns()) {
        String target = column.getDbAttributePath();
        appendColumn(targetSource, target, prefix + target);
    }
    int size = targetSource.size();
    this.rowCapacity = (int) Math.ceil(size / 0.75);
    this.columns = new ColumnDescriptor[size];
    targetSource.values().toArray(columns);
}
Also used : ArcProperty(org.apache.cayenne.reflect.ArcProperty) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) ObjAttribute(org.apache.cayenne.map.ObjAttribute) ColumnDescriptor(org.apache.cayenne.access.jdbc.ColumnDescriptor) DbAttribute(org.apache.cayenne.map.DbAttribute) TreeMap(java.util.TreeMap) AttributeProperty(org.apache.cayenne.reflect.AttributeProperty) ToOneProperty(org.apache.cayenne.reflect.ToOneProperty) ToManyProperty(org.apache.cayenne.reflect.ToManyProperty) Expression(org.apache.cayenne.exp.Expression) PrefetchTreeNode(org.apache.cayenne.query.PrefetchTreeNode) DbRelationship(org.apache.cayenne.map.DbRelationship) DbJoin(org.apache.cayenne.map.DbJoin) ASTPath(org.apache.cayenne.exp.parser.ASTPath) PropertyVisitor(org.apache.cayenne.reflect.PropertyVisitor)

Example 7 with DbRelationship

use of org.apache.cayenne.map.DbRelationship in project cayenne by apache.

the class EJBQLPathAnaliserTranslator method visitSize.

@Override
public boolean visitSize(EJBQLExpression expression) {
    if (expression.getChildrenCount() != 1) {
        throw new EJBQLException("SIZE must have exactly one child, got: " + expression.getChildrenCount());
    }
    if (!(expression.getChild(0) instanceof EJBQLPath)) {
        throw new EJBQLException("First child of SIZE must be a collection path, got: " + expression.getChild(1));
    }
    QuotingStrategy quoter = context.getQuotingStrategy();
    EJBQLPath path = (EJBQLPath) expression.getChild(0);
    String id = path.getAbsolutePath();
    String correlatedEntityId = path.getId();
    ClassDescriptor correlatedEntityDescriptor = context.getEntityDescriptor(correlatedEntityId);
    String correlatedTableName = quoter.quotedFullyQualifiedName(correlatedEntityDescriptor.getEntity().getDbEntity());
    String correlatedTableAlias = context.getTableAlias(correlatedEntityId, correlatedTableName);
    String subqueryId = context.createIdAlias(id);
    ClassDescriptor targetDescriptor = context.getEntityDescriptor(subqueryId);
    if (expression.isNegated()) {
        context.append(" NOT");
    }
    context.append(" EXISTS (SELECT 1 FROM ");
    String subqueryTableName = quoter.quotedFullyQualifiedName(targetDescriptor.getEntity().getDbEntity());
    String subqueryRootAlias = context.getTableAlias(subqueryId, subqueryTableName);
    ObjRelationship relationship = correlatedEntityDescriptor.getEntity().getRelationship(path.getRelativePath());
    if (relationship.getDbRelationshipPath().contains(".")) {
        // if the DbRelationshipPath contains '.', the relationship is
        // flattened
        subqueryRootAlias = processFlattenedRelationShip(subqueryRootAlias, relationship);
    } else {
        // not using "AS" to separate table name and alias name - OpenBase
        // doesn't
        // support "AS", and the rest of the databases do not care
        context.append(subqueryTableName).append(' ').append(subqueryRootAlias);
    }
    context.append(" WHERE");
    DbRelationship correlatedJoinRelationship = context.getIncomingRelationships(new EJBQLTableId(id)).get(0);
    Iterator<DbJoin> it = correlatedJoinRelationship.getJoins().iterator();
    while (it.hasNext()) {
        DbJoin join = it.next();
        context.append(' ').append(subqueryRootAlias).append('.').append(join.getTargetName()).append(" = ");
        context.append(correlatedTableAlias).append('.').append(quoter.quotedSourceName(join));
        if (it.hasNext()) {
            context.append(" AND");
        }
    }
    context.append(")");
    return false;
}
Also used : ObjRelationship(org.apache.cayenne.map.ObjRelationship) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) DbRelationship(org.apache.cayenne.map.DbRelationship) EJBQLException(org.apache.cayenne.ejbql.EJBQLException) DbJoin(org.apache.cayenne.map.DbJoin) QuotingStrategy(org.apache.cayenne.dba.QuotingStrategy) EJBQLPath(org.apache.cayenne.ejbql.parser.EJBQLPath)

Example 8 with DbRelationship

use of org.apache.cayenne.map.DbRelationship in project cayenne by apache.

the class EJBQLDbPathTranslator method processIntermediatePathComponent.

private void processIntermediatePathComponent() {
    DbRelationship relationship = currentEntity.getRelationship(lastPathComponent);
    if (relationship == null) {
        throw new EJBQLException("Unknown relationship '" + lastPathComponent + "' for entity '" + currentEntity.getName() + "'");
    }
    this.currentEntity = (DbEntity) relationship.getTargetEntity();
}
Also used : DbRelationship(org.apache.cayenne.map.DbRelationship) EJBQLException(org.apache.cayenne.ejbql.EJBQLException)

Example 9 with DbRelationship

use of org.apache.cayenne.map.DbRelationship in project cayenne by apache.

the class EJBQLDbPathTranslator method resolveJoin.

protected void resolveJoin() {
    EJBQLJoinAppender joinAppender = context.getTranslatorFactory().getJoinAppender(context);
    String newPath = idPath + '.' + lastPathComponent;
    String oldPath = joinAppender.registerReusableJoin(idPath, lastPathComponent, newPath);
    this.fullPath = fullPath + '.' + lastPathComponent;
    if (oldPath != null) {
        this.idPath = oldPath;
        DbRelationship lastRelationship = currentEntity.getRelationship(lastPathComponent);
        if (lastRelationship != null) {
            DbEntity targetEntity = lastRelationship.getTargetEntity();
            this.lastAlias = context.getTableAlias(fullPath, context.getQuotingStrategy().quotedFullyQualifiedName(targetEntity));
        } else {
            String tableName = context.getQuotingStrategy().quotedFullyQualifiedName(currentEntity);
            this.lastAlias = context.getTableAlias(oldPath, tableName);
        }
    } else {
        DbRelationship lastRelationship = currentEntity.getRelationship(lastPathComponent);
        DbEntity targetEntity = null;
        if (lastRelationship != null) {
            targetEntity = lastRelationship.getTargetEntity();
        } else {
            targetEntity = currentEntity;
        }
        // register join
        joinAppender.appendInnerJoin(joinMarker, new EJBQLTableId(idPath), new EJBQLTableId(fullPath));
        // TODO: outer joins handling
        this.lastAlias = context.getTableAlias(fullPath, context.getQuotingStrategy().quotedFullyQualifiedName(targetEntity));
        this.idPath = newPath;
    }
}
Also used : DbEntity(org.apache.cayenne.map.DbEntity) DbRelationship(org.apache.cayenne.map.DbRelationship)

Example 10 with DbRelationship

use of org.apache.cayenne.map.DbRelationship in project cayenne by apache.

the class EJBQLGroupByTranslator method visitPath.

@Override
public boolean visitPath(EJBQLExpression expression, int finishedChildIndex) {
    if (itemCount++ > 0) {
        context.append(',');
    }
    EJBQLExpressionVisitor childVisitor = new EJBQLPathTranslator(context) {

        @Override
        protected void appendMultiColumnPath(EJBQLMultiColumnOperand operand) {
            throw new EJBQLException("Can't GROUP BY on multi-column paths or objects");
        }

        @Override
        public boolean visitIdentificationVariable(EJBQLExpression expression) {
            String idVariableAbsolutePath = fullPath + "." + expression.getText();
            ClassDescriptor descriptor = context.getEntityDescriptor(idVariableAbsolutePath);
            if (descriptor != null) {
                this.lastAlias = context.getTableAlias(idVariableAbsolutePath, context.getQuotingStrategy().quotedFullyQualifiedName(descriptor.getEntity().getDbEntity()));
            }
            resolveLastPathComponent(expression.getText());
            this.fullPath = fullPath + '.' + lastPathComponent;
            return true;
        }

        @Override
        protected void processTerminatingRelationship(ObjRelationship relationship) {
            Collection<DbAttribute> dbAttr = ((ObjEntity) relationship.getTargetEntity()).getDbEntity().getAttributes();
            DbRelationship dbRelationship = relationship.getDbRelationships().get(0);
            DbEntity table = (DbEntity) dbRelationship.getTargetEntity();
            Iterator<DbAttribute> it = dbAttr.iterator();
            String alias = this.lastAlias != null ? lastAlias : context.getTableAlias(idPath, context.getQuotingStrategy().quotedFullyQualifiedName(table));
            boolean first = true;
            while (it.hasNext()) {
                context.append(!first ? ", " : " ");
                DbAttribute dbAttribute = it.next();
                context.append(alias).append('.').append(context.getQuotingStrategy().quotedName(dbAttribute));
                first = false;
            }
        }
    };
    expression.visit(childVisitor);
    return false;
}
Also used : ObjRelationship(org.apache.cayenne.map.ObjRelationship) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) EJBQLException(org.apache.cayenne.ejbql.EJBQLException) DbAttribute(org.apache.cayenne.map.DbAttribute) EJBQLExpressionVisitor(org.apache.cayenne.ejbql.EJBQLExpressionVisitor) DbEntity(org.apache.cayenne.map.DbEntity) DbRelationship(org.apache.cayenne.map.DbRelationship) EJBQLExpression(org.apache.cayenne.ejbql.EJBQLExpression)

Aggregations

DbRelationship (org.apache.cayenne.map.DbRelationship)106 DbEntity (org.apache.cayenne.map.DbEntity)59 DbAttribute (org.apache.cayenne.map.DbAttribute)35 DbJoin (org.apache.cayenne.map.DbJoin)35 ObjEntity (org.apache.cayenne.map.ObjEntity)30 ObjRelationship (org.apache.cayenne.map.ObjRelationship)28 ObjAttribute (org.apache.cayenne.map.ObjAttribute)20 Test (org.junit.Test)15 ClassDescriptor (org.apache.cayenne.reflect.ClassDescriptor)13 ArrayList (java.util.ArrayList)11 CayenneRuntimeException (org.apache.cayenne.CayenneRuntimeException)10 EJBQLException (org.apache.cayenne.ejbql.EJBQLException)9 DataMap (org.apache.cayenne.map.DataMap)9 Entity (org.apache.cayenne.map.Entity)8 AttributeProperty (org.apache.cayenne.reflect.AttributeProperty)8 PropertyVisitor (org.apache.cayenne.reflect.PropertyVisitor)8 ToManyProperty (org.apache.cayenne.reflect.ToManyProperty)8 ToOneProperty (org.apache.cayenne.reflect.ToOneProperty)8 HashMap (java.util.HashMap)6 ObjectId (org.apache.cayenne.ObjectId)6