Search in sources :

Example 16 with DbEntity

use of org.apache.cayenne.map.DbEntity 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 17 with DbEntity

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

the class EJBQLIdentifierColumnsTranslator method appendColumn.

public void appendColumn(String identifier, DbAttribute column, String columnAlias, String dataRowKey, String javaType) {
    DbEntity table = column.getEntity();
    String alias = context.getTableAlias(identifier, context.getQuotingStrategy().quotedFullyQualifiedName(table));
    String columnName = alias + "." + context.getQuotingStrategy().quotedName(column);
    Set<String> columns = getColumns();
    if (columns.add(columnName)) {
        context.append(columns.size() > 1 ? ", " : " ");
        if (context.isAppendingResultColumns()) {
            context.append("#result('");
        }
        context.append(columnName);
        if (context.isAppendingResultColumns()) {
            if (javaType == null) {
                javaType = TypesMapping.getJavaBySqlType(column.getType());
            }
            // TODO: andrus 6/27/2007 - the last parameter is an unofficial
            // "jdbcType"
            // pending CAY-813 implementation, switch to #column directive
            context.append("' '").append(javaType).append("' '").append(columnAlias).append("' '").append(dataRowKey).append("' " + column.getType()).append(")");
        }
    }
}
Also used : DbEntity(org.apache.cayenne.map.DbEntity)

Example 18 with DbEntity

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

the class EJBQLJoinAppender method appendTable.

public String appendTable(EJBQLTableId id) {
    DbEntity dbEntity = id.getDbEntity(context);
    String tableName = context.getQuotingStrategy().quotedFullyQualifiedName(dbEntity);
    String alias;
    if (context.isUsingAliases()) {
        // TODO: andrus 1/5/2007 - if the same table is joined more than once, this
        // will create an incorrect alias.
        alias = context.getTableAlias(id.getEntityId(), tableName);
        // 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(' ').append(tableName).append(' ').append(alias);
        generateJoinsForFlattenedAttributes(id);
    } else {
        context.append(' ').append(tableName);
        alias = tableName;
    }
    // append inheritance qualifier...
    if (id.isPrimaryTable()) {
        Expression qualifier = context.getEntityDescriptor(id.getEntityId()).getEntityQualifier();
        if (qualifier != null) {
            EJBQLExpression ejbqlQualifier = ejbqlQualifierForEntityAndSubclasses(qualifier, id.getEntityId());
            context.pushMarker(context.makeWhereMarker(), true);
            context.append(" WHERE");
            context.popMarker();
            context.pushMarker(context.makeEntityQualifierMarker(), false);
            ejbqlQualifier.visit(context.getTranslatorFactory().getConditionTranslator(context));
            context.popMarker();
        }
    }
    return alias;
}
Also used : DbEntity(org.apache.cayenne.map.DbEntity) EJBQLExpression(org.apache.cayenne.ejbql.EJBQLExpression) Expression(org.apache.cayenne.exp.Expression) EJBQLExpression(org.apache.cayenne.ejbql.EJBQLExpression)

Example 19 with DbEntity

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

the class EJBQLPathTranslator method processTerminatingAttribute.

protected void processTerminatingAttribute(ObjAttribute attribute) {
    DbEntity table = null;
    Iterator<?> it = attribute.getDbPathIterator();
    while (it.hasNext()) {
        Object pathComponent = it.next();
        if (pathComponent instanceof DbAttribute) {
            table = (DbEntity) ((DbAttribute) pathComponent).getEntity();
        }
    }
    if (isUsingAliases()) {
        String alias = this.lastAlias != null ? lastAlias : context.getTableAlias(idPath, context.getQuotingStrategy().quotedFullyQualifiedName(table));
        context.append(' ').append(alias).append('.').append(context.getQuotingStrategy().quotedName(attribute.getDbAttribute()));
    } else {
        context.append(' ').append(context.getQuotingStrategy().quotedName(attribute.getDbAttribute()));
    }
}
Also used : DbEntity(org.apache.cayenne.map.DbEntity) DbAttribute(org.apache.cayenne.map.DbAttribute)

Example 20 with DbEntity

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

the class EJBQLPathTranslator method processTerminatingRelationship.

protected void processTerminatingRelationship(ObjRelationship relationship) {
    if (relationship.isSourceIndependentFromTargetChange()) {
        // (andrus) use an outer join for to-many matches.. This is somewhat
        // different
        // from traditional Cayenne SelectQuery, as EJBQL spec does not
        // allow regular
        // path matches done against to-many relationships, and instead
        // provides
        // MEMBER OF and IS EMPTY operators. Outer join is needed for IS
        // EMPTY... I
        // guess MEMBER OF could've been done with an inner join though..
        this.innerJoin = false;
        resolveJoin();
        DbRelationship dbRelationship = chooseDbRelationship(relationship);
        DbEntity table = (DbEntity) dbRelationship.getTargetEntity();
        String alias = this.lastAlias != null ? lastAlias : context.getTableAlias(idPath, context.getQuotingStrategy().quotedFullyQualifiedName(table));
        Collection<DbAttribute> pks = table.getPrimaryKeys();
        if (pks.size() == 1) {
            DbAttribute pk = pks.iterator().next();
            context.append(' ');
            if (isUsingAliases()) {
                context.append(alias).append('.');
            }
            context.append(context.getQuotingStrategy().quotedName(pk));
        } else {
            throw new EJBQLException("Multi-column PK to-many matches are not yet supported.");
        }
    } else {
        // match FK against the target object
        DbRelationship dbRelationship = chooseDbRelationship(relationship);
        DbEntity table = (DbEntity) dbRelationship.getSourceEntity();
        String alias = this.lastAlias != null ? lastAlias : context.getTableAlias(idPath, context.getQuotingStrategy().quotedFullyQualifiedName(table));
        List<DbJoin> joins = dbRelationship.getJoins();
        if (joins.size() == 1) {
            DbJoin join = joins.get(0);
            context.append(' ');
            if (isUsingAliases()) {
                context.append(alias).append('.');
            }
            context.append(context.getQuotingStrategy().quotedName(join.getSource()));
        } else {
            Map<String, String> multiColumnMatch = new HashMap<>(joins.size() + 2);
            for (DbJoin join : joins) {
                String column = isUsingAliases() ? alias + "." + join.getSourceName() : join.getSourceName();
                multiColumnMatch.put(join.getTargetName(), column);
            }
            appendMultiColumnPath(EJBQLMultiColumnOperand.getPathOperand(context, multiColumnMatch));
        }
    }
}
Also used : DbEntity(org.apache.cayenne.map.DbEntity) HashMap(java.util.HashMap) DbRelationship(org.apache.cayenne.map.DbRelationship) DbAttribute(org.apache.cayenne.map.DbAttribute) EJBQLException(org.apache.cayenne.ejbql.EJBQLException) DbJoin(org.apache.cayenne.map.DbJoin)

Aggregations

DbEntity (org.apache.cayenne.map.DbEntity)273 DbAttribute (org.apache.cayenne.map.DbAttribute)106 Test (org.junit.Test)106 ObjEntity (org.apache.cayenne.map.ObjEntity)64 DbRelationship (org.apache.cayenne.map.DbRelationship)55 DataMap (org.apache.cayenne.map.DataMap)47 ObjAttribute (org.apache.cayenne.map.ObjAttribute)26 ArrayList (java.util.ArrayList)25 DbJoin (org.apache.cayenne.map.DbJoin)24 MergerToken (org.apache.cayenne.dbsync.merge.token.MergerToken)20 ObjRelationship (org.apache.cayenne.map.ObjRelationship)19 CayenneRuntimeException (org.apache.cayenne.CayenneRuntimeException)16 JdbcAdapter (org.apache.cayenne.dba.JdbcAdapter)16 Entity (org.apache.cayenne.map.Entity)16 List (java.util.List)15 DbAdapter (org.apache.cayenne.dba.DbAdapter)15 EntityEvent (org.apache.cayenne.map.event.EntityEvent)14 HashMap (java.util.HashMap)12 SelectQuery (org.apache.cayenne.query.SelectQuery)12 DataChannelDescriptor (org.apache.cayenne.configuration.DataChannelDescriptor)11