Search in sources :

Example 6 with EJBQLException

use of org.apache.cayenne.ejbql.EJBQLException in project cayenne by apache.

the class EJBQLDbPathTranslator method visitIdentifier.

@Override
public boolean visitIdentifier(EJBQLExpression expression) {
    // expression id is always rooted in an ObjEntity, even for DbPath...
    ClassDescriptor descriptor = context.getEntityDescriptor(expression.getText());
    if (descriptor == null) {
        throw new EJBQLException("Invalid identification variable: " + expression.getText());
    }
    this.currentEntity = descriptor.getEntity().getDbEntity();
    this.idPath = expression.getText();
    this.joinMarker = EJBQLJoinAppender.makeJoinTailMarker(idPath);
    this.fullPath = idPath;
    return true;
}
Also used : ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) EJBQLException(org.apache.cayenne.ejbql.EJBQLException)

Example 7 with EJBQLException

use of org.apache.cayenne.ejbql.EJBQLException 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 8 with EJBQLException

use of org.apache.cayenne.ejbql.EJBQLException in project cayenne by apache.

the class EJBQLOrderByTranslator method visitPath.

@Override
public boolean visitPath(EJBQLExpression expression, int finishedChildIndex) {
    EJBQLExpressionVisitor childVisitor = new EJBQLPathTranslator(context) {

        @Override
        protected void appendMultiColumnPath(EJBQLMultiColumnOperand operand) {
            throw new EJBQLException("Can't order on multi-column paths or objects");
        }
    };
    expression.visit(childVisitor);
    return false;
}
Also used : EJBQLException(org.apache.cayenne.ejbql.EJBQLException) EJBQLExpressionVisitor(org.apache.cayenne.ejbql.EJBQLExpressionVisitor)

Example 9 with EJBQLException

use of org.apache.cayenne.ejbql.EJBQLException 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)

Example 10 with EJBQLException

use of org.apache.cayenne.ejbql.EJBQLException in project cayenne by apache.

the class Compiler method compile.

CompiledExpression compile(String source, EJBQLExpression parsed) {
    parsed.visit(new CompilationVisitor());
    Map<EJBQLPath, Integer> pathsInSelect = new HashMap<>();
    for (int i = 0; i < parsed.getChildrenCount(); i++) {
        if (parsed.getChild(i) instanceof EJBQLSelectClause) {
            EJBQLExpression parsedTemp = parsed.getChild(i);
            boolean stop = false;
            while (parsedTemp.getChildrenCount() > 0 && !stop) {
                EJBQLExpression newParsedTemp = null;
                for (int j = 0; j < parsedTemp.getChildrenCount(); j++) {
                    if (parsedTemp.getChild(j) instanceof EJBQLSelectExpression) {
                        for (int k = 0; k < parsedTemp.getChild(j).getChildrenCount(); k++) {
                            if (parsedTemp.getChild(j).getChild(k) instanceof EJBQLPath) {
                                pathsInSelect.put((EJBQLPath) parsedTemp.getChild(j).getChild(k), j);
                            }
                        }
                    } else {
                        if (parsedTemp.getChild(j).getChildrenCount() == 0) {
                            stop = true;
                        } else {
                            newParsedTemp = parsedTemp.getChild(j);
                        }
                    }
                }
                if (!stop && newParsedTemp != null) {
                    parsedTemp = newParsedTemp;
                } else {
                    stop = true;
                }
            }
        }
    }
    // postprocess paths, now that all id vars are resolved
    if (paths != null) {
        for (EJBQLPath path : paths) {
            String id = normalizeIdPath(path.getId());
            ClassDescriptor descriptor = descriptorsById.get(id);
            if (descriptor == null) {
                throw new EJBQLException("Unmapped id variable: " + id);
            }
            StringBuilder buffer = new StringBuilder(id);
            ObjRelationship incoming = null;
            String pathRelationshipString = "";
            for (int i = 1; i < path.getChildrenCount(); i++) {
                String pathChunk = path.getChild(i).getText();
                if (pathChunk.endsWith(Entity.OUTER_JOIN_INDICATOR)) {
                    pathChunk = pathChunk.substring(0, pathChunk.length() - 1);
                }
                buffer.append('.').append(pathChunk);
                PropertyDescriptor property = descriptor.getProperty(pathChunk);
                if (property instanceof ArcProperty) {
                    incoming = ((ArcProperty) property).getRelationship();
                    descriptor = ((ArcProperty) property).getTargetDescriptor();
                    pathRelationshipString = buffer.substring(0, buffer.length());
                    descriptorsById.put(pathRelationshipString, descriptor);
                    incomingById.put(pathRelationshipString, incoming);
                }
            }
            if (pathsInSelect.size() > 0 && incoming != null && pathRelationshipString.length() > 0 && pathRelationshipString.equals(buffer.toString())) {
                EJBQLIdentifier ident = new EJBQLIdentifier(0);
                ident.text = pathRelationshipString;
                Integer integer = pathsInSelect.get(path);
                if (integer != null) {
                    resultComponents.remove(integer.intValue());
                    resultComponents.add(integer, ident);
                    rootId = pathRelationshipString;
                }
            }
        }
    }
    CompiledExpression compiled = new CompiledExpression();
    compiled.setExpression(parsed);
    compiled.setSource(source);
    compiled.setRootId(rootId);
    compiled.setDescriptorsById(descriptorsById);
    compiled.setIncomingById(incomingById);
    compiled.setPrefetchTree(prefetchTree);
    if (resultComponents != null) {
        SQLResult mapping = new SQLResult();
        for (int i = 0; i < resultComponents.size(); i++) {
            Object nextMapping = resultComponents.get(i);
            if (nextMapping instanceof String) {
                mapping.addColumnResult((String) nextMapping);
            } else if (nextMapping instanceof EJBQLExpression) {
                EntityResult compileEntityResult = compileEntityResult((EJBQLExpression) nextMapping, i);
                if (prefetchTree != null) {
                    for (PrefetchTreeNode prefetch : prefetchTree.getChildren()) {
                        if (((EJBQLExpression) nextMapping).getText().equals(prefetch.getEjbqlPathEntityId())) {
                            EJBQLIdentifier ident = new EJBQLIdentifier(0);
                            ident.text = prefetch.getEjbqlPathEntityId() + "." + prefetch.getPath();
                            compileEntityResult = compileEntityResultWithPrefetch(compileEntityResult, ident);
                        }
                    }
                }
                mapping.addEntityResult(compileEntityResult);
            }
        }
        compiled.setResult(mapping);
    }
    return compiled;
}
Also used : ObjRelationship(org.apache.cayenne.map.ObjRelationship) ArcProperty(org.apache.cayenne.reflect.ArcProperty) ClassDescriptor(org.apache.cayenne.reflect.ClassDescriptor) PropertyDescriptor(org.apache.cayenne.reflect.PropertyDescriptor) HashMap(java.util.HashMap) EJBQLException(org.apache.cayenne.ejbql.EJBQLException) EntityResult(org.apache.cayenne.map.EntityResult) EJBQLCompiledExpression(org.apache.cayenne.ejbql.EJBQLCompiledExpression) SQLResult(org.apache.cayenne.map.SQLResult) PrefetchTreeNode(org.apache.cayenne.query.PrefetchTreeNode) EJBQLExpression(org.apache.cayenne.ejbql.EJBQLExpression)

Aggregations

EJBQLException (org.apache.cayenne.ejbql.EJBQLException)19 DbRelationship (org.apache.cayenne.map.DbRelationship)9 ClassDescriptor (org.apache.cayenne.reflect.ClassDescriptor)9 DbAttribute (org.apache.cayenne.map.DbAttribute)7 DbEntity (org.apache.cayenne.map.DbEntity)7 ObjRelationship (org.apache.cayenne.map.ObjRelationship)7 DbJoin (org.apache.cayenne.map.DbJoin)5 HashMap (java.util.HashMap)3 QuotingStrategy (org.apache.cayenne.dba.QuotingStrategy)3 EJBQLExpression (org.apache.cayenne.ejbql.EJBQLExpression)2 EJBQLExpressionVisitor (org.apache.cayenne.ejbql.EJBQLExpressionVisitor)2 EJBQLPath (org.apache.cayenne.ejbql.parser.EJBQLPath)2 EntityResult (org.apache.cayenne.map.EntityResult)2 ObjAttribute (org.apache.cayenne.map.ObjAttribute)2 AttributeProperty (org.apache.cayenne.reflect.AttributeProperty)2 PropertyDescriptor (org.apache.cayenne.reflect.PropertyDescriptor)2 BigDecimal (java.math.BigDecimal)1 HashSet (java.util.HashSet)1 Map (java.util.Map)1 CayenneRuntimeException (org.apache.cayenne.CayenneRuntimeException)1