Search in sources :

Example 6 with ObjRelationship

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

the class ObjectDiff method addDiff.

void addDiff(NodeDiff diff, ObjectStore parent) {
    boolean addDiff = true;
    if (diff instanceof ArcOperation) {
        ArcOperation arcDiff = (ArcOperation) diff;
        Object targetId = arcDiff.getTargetNodeId();
        String arcId = arcDiff.getArcId().toString();
        ArcProperty property = (ArcProperty) getClassDescriptor().getProperty(arcId);
        if (property == null && arcId.startsWith(ASTDbPath.DB_PREFIX)) {
            addPhantomFkDiff(arcDiff);
            addDiff = false;
        } else if (property instanceof ToManyProperty) {
            // record flattened op changes
            ObjRelationship relationship = property.getRelationship();
            if (relationship.isFlattened()) {
                if (flatIds == null) {
                    flatIds = new HashMap<>();
                }
                ArcOperation oldOp = flatIds.put(arcDiff, arcDiff);
                // "delete" cancels "create" and vice versa...
                if (oldOp != null && oldOp.isDelete() != arcDiff.isDelete()) {
                    addDiff = false;
                    flatIds.remove(arcDiff);
                    if (otherDiffs != null) {
                        otherDiffs.remove(oldOp);
                    }
                }
            } else if (property.getComplimentaryReverseArc() == null) {
                // register complimentary arc diff
                String arc = ASTDbPath.DB_PREFIX + property.getComplimentaryReverseDbRelationshipPath();
                ArcOperation complimentartyOp = new ArcOperation(targetId, arcDiff.getNodeId(), arc, arcDiff.isDelete());
                parent.registerDiff(targetId, complimentartyOp);
            }
        } else if (property instanceof ToOneProperty) {
            if (currentArcSnapshot == null) {
                currentArcSnapshot = new HashMap<>();
            }
            currentArcSnapshot.put(arcId, targetId);
        } else {
            String message = (property == null) ? "No property for arcId " + arcId : "Unrecognized property for arcId " + arcId + ": " + property;
            throw new CayenneRuntimeException(message);
        }
    }
    if (addDiff) {
        if (otherDiffs == null) {
            otherDiffs = new ArrayList<>(3);
        }
        otherDiffs.add(diff);
    }
}
Also used : ObjRelationship(org.apache.cayenne.map.ObjRelationship) ArcProperty(org.apache.cayenne.reflect.ArcProperty) ToManyProperty(org.apache.cayenne.reflect.ToManyProperty) HashMap(java.util.HashMap) CayenneRuntimeException(org.apache.cayenne.CayenneRuntimeException) ToOneProperty(org.apache.cayenne.reflect.ToOneProperty)

Example 7 with ObjRelationship

use of org.apache.cayenne.map.ObjRelationship 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 ObjRelationship

use of org.apache.cayenne.map.ObjRelationship 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)

Example 9 with ObjRelationship

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

the class EJBQLIdentifierColumnsTranslator method visitIdentifier.

@Override
public boolean visitIdentifier(EJBQLExpression expression) {
    Map<String, String> xfields = null;
    if (context.isAppendingResultColumns()) {
        xfields = context.nextEntityResult().getFields();
    }
    // assign whatever we have to a final ivar so that it can be accessed
    // within
    // the inner class
    final Map<String, String> fields = xfields;
    final String idVar = expression.getText();
    // append all table columns ... the trick is to follow the algorithm for
    // describing the fields in the expression compiler, so that we could
    // assign
    // columns labels from FieldResults in the order we encounter them
    // here...
    // TODO: andrus 2008/02/17 - this is a bit of a hack, think of a better
    // solution
    ClassDescriptor descriptor = context.getEntityDescriptor(idVar);
    PropertyVisitor visitor = new PropertyVisitor() {

        public boolean visitAttribute(AttributeProperty property) {
            ObjAttribute oa = property.getAttribute();
            Iterator<?> dbPathIterator = oa.getDbPathIterator();
            EJBQLJoinAppender joinAppender = null;
            String marker = null;
            EJBQLTableId lhsId = new EJBQLTableId(idVar);
            while (dbPathIterator.hasNext()) {
                Object pathPart = dbPathIterator.next();
                if (pathPart == null) {
                    throw new CayenneRuntimeException("ObjAttribute has no component: %s", oa.getName());
                } else if (pathPart instanceof DbRelationship) {
                    if (marker == null) {
                        marker = EJBQLJoinAppender.makeJoinTailMarker(idVar);
                        joinAppender = context.getTranslatorFactory().getJoinAppender(context);
                    }
                    DbRelationship dr = (DbRelationship) pathPart;
                    EJBQLTableId rhsId = new EJBQLTableId(lhsId, dr.getName());
                    joinAppender.appendOuterJoin(marker, lhsId, rhsId);
                    lhsId = rhsId;
                } else if (pathPart instanceof DbAttribute) {
                    appendColumn(idVar, oa, (DbAttribute) pathPart, fields, oa.getType());
                }
            }
            return true;
        }

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

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

        private void visitRelationship(ArcProperty property) {
            ObjRelationship rel = property.getRelationship();
            DbRelationship dbRel = rel.getDbRelationships().get(0);
            for (DbJoin join : dbRel.getJoins()) {
                DbAttribute src = join.getSource();
                appendColumn(idVar, null, src, fields);
            }
        }
    };
    // EJBQL queries are polymorphic by definition - there is no distinction
    // between
    // inheritance/no-inheritance fetch
    descriptor.visitAllProperties(visitor);
    // append id columns ... (some may have been appended already via
    // relationships)
    DbEntity table = descriptor.getEntity().getDbEntity();
    for (DbAttribute pk : table.getPrimaryKeys()) {
        appendColumn(idVar, null, pk, fields);
    }
    // append inheritance discriminator columns...
    for (ObjAttribute column : descriptor.getDiscriminatorColumns()) {
        appendColumn(idVar, column, column.getDbAttribute(), fields);
    }
    addPrefetchedColumnsIfAny(idVar);
    return false;
}
Also used : ObjRelationship(org.apache.cayenne.map.ObjRelationship) ArcProperty(org.apache.cayenne.reflect.ArcProperty) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) ObjAttribute(org.apache.cayenne.map.ObjAttribute) CayenneRuntimeException(org.apache.cayenne.CayenneRuntimeException) DbAttribute(org.apache.cayenne.map.DbAttribute) AttributeProperty(org.apache.cayenne.reflect.AttributeProperty) ToOneProperty(org.apache.cayenne.reflect.ToOneProperty) ToManyProperty(org.apache.cayenne.reflect.ToManyProperty) DbEntity(org.apache.cayenne.map.DbEntity) DbRelationship(org.apache.cayenne.map.DbRelationship) DbJoin(org.apache.cayenne.map.DbJoin) PropertyVisitor(org.apache.cayenne.reflect.PropertyVisitor)

Example 10 with ObjRelationship

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

the class EJBQLPathTranslator method processLastPathComponent.

protected void processLastPathComponent() {
    ObjAttribute attribute = currentEntity.getAttribute(lastPathComponent);
    if (attribute != null) {
        processTerminatingAttribute(attribute);
        return;
    }
    ObjRelationship relationship = currentEntity.getRelationship(lastPathComponent);
    if (relationship != null) {
        processTerminatingRelationship(relationship);
        return;
    }
    throw new IllegalStateException("Invalid path component: " + lastPathComponent);
}
Also used : ObjRelationship(org.apache.cayenne.map.ObjRelationship) ObjAttribute(org.apache.cayenne.map.ObjAttribute)

Aggregations

ObjRelationship (org.apache.cayenne.map.ObjRelationship)84 ObjEntity (org.apache.cayenne.map.ObjEntity)48 ObjAttribute (org.apache.cayenne.map.ObjAttribute)27 DbRelationship (org.apache.cayenne.map.DbRelationship)26 Test (org.junit.Test)24 DbEntity (org.apache.cayenne.map.DbEntity)18 DbAttribute (org.apache.cayenne.map.DbAttribute)15 DbJoin (org.apache.cayenne.map.DbJoin)14 CayenneRuntimeException (org.apache.cayenne.CayenneRuntimeException)12 ClassDescriptor (org.apache.cayenne.reflect.ClassDescriptor)12 ObjectId (org.apache.cayenne.ObjectId)10 ToManyProperty (org.apache.cayenne.reflect.ToManyProperty)9 ToOneProperty (org.apache.cayenne.reflect.ToOneProperty)9 ArrayList (java.util.ArrayList)8 AttributeProperty (org.apache.cayenne.reflect.AttributeProperty)8 PropertyVisitor (org.apache.cayenne.reflect.PropertyVisitor)8 List (java.util.List)7 EJBQLException (org.apache.cayenne.ejbql.EJBQLException)7 DataMap (org.apache.cayenne.map.DataMap)7 HashMap (java.util.HashMap)6