use of org.apache.cayenne.ejbql.EJBQLExpression 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;
}
use of org.apache.cayenne.ejbql.EJBQLExpression in project cayenne by apache.
the class EJBQLJoinAppender method ejbqlQualifierForEntityAndSubclasses.
private EJBQLExpression ejbqlQualifierForEntityAndSubclasses(Expression qualifier, String entityId) {
// parser only works on full queries, so prepend a dummy query and then strip it out...
String ejbqlChunk = qualifier.toEJBQL(entityId);
EJBQLExpression expression = EJBQLParserFactory.getParser().parse("DELETE FROM DUMMY WHERE " + ejbqlChunk);
final EJBQLExpression[] result = new EJBQLExpression[1];
expression.visit(new EJBQLBaseVisitor() {
@Override
public boolean visitWhere(EJBQLExpression expression) {
result[0] = expression.getChild(0);
return false;
}
});
return result[0];
}
use of org.apache.cayenne.ejbql.EJBQLExpression 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;
}
use of org.apache.cayenne.ejbql.EJBQLExpression in project cayenne by apache.
the class EJBQLAction method performAction.
@Override
public void performAction(Connection connection, OperationObserver observer) throws Exception {
EJBQLCompiledExpression compiledExpression = query.getExpression(dataNode.getEntityResolver());
final EJBQLTranslatorFactory translatorFactory = dataNode.getAdapter().getEjbqlTranslatorFactory();
final EJBQLTranslationContext context = new EJBQLTranslationContext(dataNode.getEntityResolver(), query, compiledExpression, translatorFactory, dataNode.getAdapter().getQuotingStrategy());
compiledExpression.getExpression().visit(new EJBQLBaseVisitor(false) {
@Override
public boolean visitSelect(EJBQLExpression expression) {
EJBQLExpressionVisitor visitor = translatorFactory.getSelectTranslator(context);
expression.visit(visitor);
return false;
}
@Override
public boolean visitDelete(EJBQLExpression expression) {
EJBQLExpressionVisitor visitor = translatorFactory.getDeleteTranslator(context);
expression.visit(visitor);
return false;
}
@Override
public boolean visitUpdate(EJBQLExpression expression) {
EJBQLExpressionVisitor visitor = translatorFactory.getUpdateTranslator(context);
expression.visit(visitor);
return false;
}
});
SQLTemplate sqlQuery = context.getQuery();
// update with metadata
QueryMetadata md = query.getMetaData(dataNode.getEntityResolver());
sqlQuery.setFetchLimit(md.getFetchLimit());
sqlQuery.setFetchOffset(md.getFetchOffset());
sqlQuery.setResult(compiledExpression.getResult());
sqlQuery.setPageSize(md.getPageSize());
if (md.getStatementFetchSize() != 0) {
sqlQuery.setStatementFetchSize(md.getStatementFetchSize());
}
int queryTimeout = md.getQueryTimeout();
if (queryTimeout != QueryMetadata.QUERY_TIMEOUT_DEFAULT) {
sqlQuery.setQueryTimeout(queryTimeout);
}
actionFactory.sqlAction(sqlQuery).performAction(connection, observer);
}
use of org.apache.cayenne.ejbql.EJBQLExpression 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;
}
Aggregations