Search in sources :

Example 21 with DbJoin

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

the class OpenBaseAdapter method createFkConstraint.

/**
 * Returns a SQL string that can be used to create a foreign key constraint
 * for the relationship.
 */
@Override
public String createFkConstraint(DbRelationship rel) {
    StringBuilder buf = new StringBuilder();
    // OpendBase Specifics is that we need to create a constraint going
    // from destination to source for this to work...
    DbEntity sourceEntity = (DbEntity) rel.getSourceEntity();
    DbEntity targetEntity = (DbEntity) rel.getTargetEntity();
    String toMany = (!rel.isToMany()) ? "'1'" : "'0'";
    // TODO: doesn't seem like OpenBase supports compound joins...
    // need to doublecheck that
    int joinsLen = rel.getJoins().size();
    if (joinsLen == 0) {
        throw new CayenneRuntimeException("Relationship has no joins: %s", rel.getName());
    } else if (joinsLen > 1) {
    // ignore extra joins
    }
    DbJoin join = rel.getJoins().get(0);
    buf.append("INSERT INTO _SYS_RELATIONSHIP (").append("dest_table, dest_column, source_table, source_column, ").append("block_delete, cascade_delete, one_to_many, operator, relationshipName").append(") VALUES ('").append(sourceEntity.getFullyQualifiedName()).append("', '").append(join.getSourceName()).append("', '").append(targetEntity.getFullyQualifiedName()).append("', '").append(join.getTargetName()).append("', 0, 0, ").append(toMany).append(", '=', '").append(rel.getName()).append("')");
    return buf.toString();
}
Also used : DbEntity(org.apache.cayenne.map.DbEntity) CayenneRuntimeException(org.apache.cayenne.CayenneRuntimeException) DbJoin(org.apache.cayenne.map.DbJoin)

Example 22 with DbJoin

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

the class Oracle8JoinStack method appendQualifierSubtree.

protected void appendQualifierSubtree(StringBuilder out, JoinTreeNode node) {
    DbRelationship relationship = node.getRelationship();
    String srcAlias = node.getSourceTableAlias();
    String targetAlias = node.getTargetTableAlias();
    List<DbJoin> joins = relationship.getJoins();
    int len = joins.size();
    for (int i = 0; i < len; i++) {
        DbJoin join = joins.get(i);
        if (i > 0) {
            out.append(" AND ");
        }
        out.append(srcAlias).append('.').append(join.getSourceName());
        switch(node.getJoinType()) {
            case INNER:
                out.append(" = ");
                break;
            case LEFT_OUTER:
                out.append(" * ");
                break;
            default:
                throw new IllegalArgumentException("Unsupported join type: " + node.getJoinType());
        }
        out.append(targetAlias).append('.').append(join.getTargetName());
    }
    for (JoinTreeNode child : node.getChildren()) {
        out.append(" AND ");
        appendQualifierSubtree(out, child);
    }
}
Also used : DbRelationship(org.apache.cayenne.map.DbRelationship) DbJoin(org.apache.cayenne.map.DbJoin) JoinTreeNode(org.apache.cayenne.access.translator.select.JoinTreeNode)

Example 23 with DbJoin

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

the class Compiler method compileEntityResultWithPrefetch.

private EntityResult compileEntityResultWithPrefetch(EntityResult compiledResult, EJBQLExpression prefetchExpression) {
    final EntityResult result = compiledResult;
    String id = prefetchExpression.getText().toLowerCase();
    ClassDescriptor descriptor = descriptorsById.get(id);
    if (descriptor == null) {
        descriptor = descriptorsById.get(prefetchExpression.getText());
    }
    final String prefix = prefetchExpression.getText().substring(prefetchExpression.getText().indexOf(".") + 1);
    final Set<String> visited = new HashSet<String>();
    PropertyVisitor visitor = new PropertyVisitor() {

        public boolean visitAttribute(AttributeProperty property) {
            ObjAttribute oa = property.getAttribute();
            if (visited.add(oa.getDbAttributePath())) {
                result.addObjectField(oa.getEntity().getName(), "fetch." + prefix + "." + oa.getName(), prefix + "." + oa.getDbAttributeName());
            }
            return true;
        }

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

        public boolean visitToOne(ToOneProperty property) {
            ObjRelationship rel = property.getRelationship();
            DbRelationship dbRel = rel.getDbRelationships().get(0);
            for (DbJoin join : dbRel.getJoins()) {
                DbAttribute src = join.getSource();
                if (src.isForeignKey() && visited.add(src.getName())) {
                    result.addDbField("fetch." + prefix + "." + src.getName(), prefix + "." + src.getName());
                }
            }
            return true;
        }
    };
    descriptor.visitAllProperties(visitor);
    // append id columns ... (some may have been appended already via relationships)
    for (String pkName : descriptor.getEntity().getPrimaryKeyNames()) {
        if (visited.add(pkName)) {
            result.addDbField("fetch." + prefix + "." + pkName, prefix + "." + pkName);
        }
    }
    // append inheritance discriminator columns...
    for (ObjAttribute column : descriptor.getDiscriminatorColumns()) {
        if (visited.add(column.getName())) {
            result.addDbField("fetch." + prefix + "." + column.getDbAttributePath(), prefix + "." + column.getDbAttributePath());
        }
    }
    return result;
}
Also used : ObjRelationship(org.apache.cayenne.map.ObjRelationship) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) ObjAttribute(org.apache.cayenne.map.ObjAttribute) DbAttribute(org.apache.cayenne.map.DbAttribute) EntityResult(org.apache.cayenne.map.EntityResult) AttributeProperty(org.apache.cayenne.reflect.AttributeProperty) ToOneProperty(org.apache.cayenne.reflect.ToOneProperty) ToManyProperty(org.apache.cayenne.reflect.ToManyProperty) DbRelationship(org.apache.cayenne.map.DbRelationship) DbJoin(org.apache.cayenne.map.DbJoin) PropertyVisitor(org.apache.cayenne.reflect.PropertyVisitor) HashSet(java.util.HashSet)

Example 24 with DbJoin

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

the class Compiler method compileEntityResult.

private EntityResult compileEntityResult(EJBQLExpression expression, int position) {
    String id = expression.getText().toLowerCase();
    ClassDescriptor descriptor = descriptorsById.get(id);
    if (descriptor == null) {
        descriptor = descriptorsById.get(expression.getText());
    }
    if (descriptor == null) {
        throw new EJBQLException("the entity variable '" + id + "' does not refer to any entity in the FROM clause");
    }
    final EntityResult entityResult = new EntityResult(descriptor.getObjectClass());
    final String prefix = "ec" + position + "_";
    final int[] index = { 0 };
    final Set<String> visited = new HashSet<String>();
    PropertyVisitor visitor = new PropertyVisitor() {

        public boolean visitAttribute(AttributeProperty property) {
            ObjAttribute oa = property.getAttribute();
            if (visited.add(oa.getDbAttributePath())) {
                entityResult.addObjectField(oa.getEntity().getName(), oa.getName(), prefix + index[0]++);
            }
            return true;
        }

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

        public boolean visitToOne(ToOneProperty property) {
            ObjRelationship rel = property.getRelationship();
            DbRelationship dbRel = rel.getDbRelationships().get(0);
            for (DbJoin join : dbRel.getJoins()) {
                DbAttribute src = join.getSource();
                if (src.isForeignKey() && visited.add(src.getName())) {
                    entityResult.addDbField(src.getName(), prefix + index[0]++);
                }
            }
            return true;
        }
    };
    descriptor.visitAllProperties(visitor);
    // append id columns ... (some may have been appended already via relationships)
    for (String pkName : descriptor.getEntity().getPrimaryKeyNames()) {
        if (visited.add(pkName)) {
            entityResult.addDbField(pkName, prefix + index[0]++);
        }
    }
    // append inheritance discriminator columns...
    for (ObjAttribute column : descriptor.getDiscriminatorColumns()) {
        if (visited.add(column.getName())) {
            entityResult.addDbField(column.getDbAttributePath(), prefix + index[0]++);
        }
    }
    return entityResult;
}
Also used : ObjRelationship(org.apache.cayenne.map.ObjRelationship) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) ObjAttribute(org.apache.cayenne.map.ObjAttribute) EJBQLException(org.apache.cayenne.ejbql.EJBQLException) DbAttribute(org.apache.cayenne.map.DbAttribute) EntityResult(org.apache.cayenne.map.EntityResult) AttributeProperty(org.apache.cayenne.reflect.AttributeProperty) ToOneProperty(org.apache.cayenne.reflect.ToOneProperty) ToManyProperty(org.apache.cayenne.reflect.ToManyProperty) DbRelationship(org.apache.cayenne.map.DbRelationship) DbJoin(org.apache.cayenne.map.DbJoin) PropertyVisitor(org.apache.cayenne.reflect.PropertyVisitor) HashSet(java.util.HashSet)

Example 25 with DbJoin

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

the class SelectQueryMetadata method buildEntityResultForColumn.

/**
 * Collect metadata for column that will be unwrapped to full entity in the final SQL
 * (possibly including joint prefetch).
 * This information will be used to correctly create Persistent object back from raw result.
 *
 * This method is actually repeating logic of
 * {@link org.apache.cayenne.access.translator.select.DefaultSelectTranslator#appendQueryColumns}.
 * Here we don't care about intermediate joins and few other things so it's shorter.
 * Logic of these methods should be unified and simplified, possibly to a single source of metadata,
 * generated only once and used everywhere.
 *
 * @param query original query
 * @param column full object column
 * @param resolver entity resolver to get ObjEntity and ClassDescriptor
 * @return Entity result
 */
private EntityResult buildEntityResultForColumn(SelectQuery<?> query, Property<?> column, EntityResolver resolver) {
    final EntityResult result = new EntityResult(column.getType());
    // Collecting visitor for ObjAttributes and toOne relationships
    PropertyVisitor visitor = new PropertyVisitor() {

        public boolean visitAttribute(AttributeProperty property) {
            ObjAttribute oa = property.getAttribute();
            Iterator<CayenneMapEntry> dbPathIterator = oa.getDbPathIterator();
            while (dbPathIterator.hasNext()) {
                CayenneMapEntry pathPart = dbPathIterator.next();
                if (pathPart instanceof DbAttribute) {
                    result.addDbField(pathPart.getName(), pathPart.getName());
                }
            }
            return true;
        }

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

        public boolean visitToOne(ToOneProperty property) {
            DbRelationship dbRel = property.getRelationship().getDbRelationships().get(0);
            List<DbJoin> joins = dbRel.getJoins();
            for (DbJoin join : joins) {
                if (!join.getSource().isPrimaryKey()) {
                    result.addDbField(join.getSource().getName(), join.getSource().getName());
                }
            }
            return true;
        }
    };
    ObjEntity oe = resolver.getObjEntity(column.getType());
    DbEntity table = oe.getDbEntity();
    // Additionally collect PKs
    for (DbAttribute dba : table.getPrimaryKeys()) {
        result.addDbField(dba.getName(), dba.getName());
    }
    ClassDescriptor descriptor = resolver.getClassDescriptor(oe.getName());
    descriptor.visitAllProperties(visitor);
    // Collection columns for joint prefetch
    if (query.getPrefetchTree() != null) {
        for (PrefetchTreeNode prefetch : query.getPrefetchTree().adjacentJointNodes()) {
            // for each prefetch add columns from the target entity
            Expression prefetchExp = ExpressionFactory.exp(prefetch.getPath());
            ASTDbPath dbPrefetch = (ASTDbPath) oe.translateToDbPath(prefetchExp);
            DbRelationship r = findRelationByPath(table, dbPrefetch);
            if (r == null) {
                throw new CayenneRuntimeException("Invalid joint prefetch '%s' for entity: %s", prefetch, oe.getName());
            }
            // go via target OE to make sure that Java types are mapped correctly...
            ObjRelationship targetRel = (ObjRelationship) prefetchExp.evaluate(oe);
            ObjEntity targetEntity = targetRel.getTargetEntity();
            prefetch.setEntityName(targetRel.getSourceEntity().getName());
            String labelPrefix = dbPrefetch.getPath();
            Set<String> seenNames = new HashSet<>();
            for (ObjAttribute oa : targetEntity.getAttributes()) {
                Iterator<CayenneMapEntry> dbPathIterator = oa.getDbPathIterator();
                while (dbPathIterator.hasNext()) {
                    Object pathPart = dbPathIterator.next();
                    if (pathPart instanceof DbAttribute) {
                        DbAttribute attribute = (DbAttribute) pathPart;
                        if (seenNames.add(attribute.getName())) {
                            result.addDbField(labelPrefix + '.' + attribute.getName(), labelPrefix + '.' + attribute.getName());
                        }
                    }
                }
            }
            // append remaining target attributes such as keys
            DbEntity targetDbEntity = r.getTargetEntity();
            for (DbAttribute attribute : targetDbEntity.getAttributes()) {
                if (seenNames.add(attribute.getName())) {
                    result.addDbField(labelPrefix + '.' + attribute.getName(), labelPrefix + '.' + attribute.getName());
                }
            }
        }
    }
    return result;
}
Also used : ObjRelationship(org.apache.cayenne.map.ObjRelationship) ObjAttribute(org.apache.cayenne.map.ObjAttribute) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) ASTDbPath(org.apache.cayenne.exp.parser.ASTDbPath) DbAttribute(org.apache.cayenne.map.DbAttribute) CayenneRuntimeException(org.apache.cayenne.CayenneRuntimeException) EntityResult(org.apache.cayenne.map.EntityResult) AttributeProperty(org.apache.cayenne.reflect.AttributeProperty) ToOneProperty(org.apache.cayenne.reflect.ToOneProperty) CayenneMapEntry(org.apache.cayenne.util.CayenneMapEntry) ObjEntity(org.apache.cayenne.map.ObjEntity) ToManyProperty(org.apache.cayenne.reflect.ToManyProperty) DbEntity(org.apache.cayenne.map.DbEntity) Expression(org.apache.cayenne.exp.Expression) DbRelationship(org.apache.cayenne.map.DbRelationship) DbJoin(org.apache.cayenne.map.DbJoin) PropertyVisitor(org.apache.cayenne.reflect.PropertyVisitor) HashSet(java.util.HashSet)

Aggregations

DbJoin (org.apache.cayenne.map.DbJoin)49 DbRelationship (org.apache.cayenne.map.DbRelationship)35 DbEntity (org.apache.cayenne.map.DbEntity)24 DbAttribute (org.apache.cayenne.map.DbAttribute)18 ObjRelationship (org.apache.cayenne.map.ObjRelationship)14 ObjAttribute (org.apache.cayenne.map.ObjAttribute)12 ObjEntity (org.apache.cayenne.map.ObjEntity)11 ClassDescriptor (org.apache.cayenne.reflect.ClassDescriptor)9 CayenneRuntimeException (org.apache.cayenne.CayenneRuntimeException)8 ArrayList (java.util.ArrayList)7 AttributeProperty (org.apache.cayenne.reflect.AttributeProperty)7 PropertyVisitor (org.apache.cayenne.reflect.PropertyVisitor)7 ToManyProperty (org.apache.cayenne.reflect.ToManyProperty)7 ToOneProperty (org.apache.cayenne.reflect.ToOneProperty)7 HashMap (java.util.HashMap)6 Test (org.junit.Test)6 QuotingStrategy (org.apache.cayenne.dba.QuotingStrategy)5 EJBQLException (org.apache.cayenne.ejbql.EJBQLException)5 HashSet (java.util.HashSet)4 List (java.util.List)3