use of org.apache.cayenne.ejbql.EJBQLException 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;
}
use of org.apache.cayenne.ejbql.EJBQLException in project cayenne by apache.
the class EJBQLPathAnaliserTranslator method visitMemberOf.
@Override
public boolean visitMemberOf(EJBQLExpression expression) {
if (expression.getChildrenCount() != 2) {
throw new EJBQLException("MEMBER OF must have exactly two children, got: " + expression.getChildrenCount());
}
if (!(expression.getChild(1) instanceof EJBQLPath)) {
throw new EJBQLException("Second child of the MEMBER OF must be a collection path, got: " + expression.getChild(1));
}
QuotingStrategy quoter = context.getQuotingStrategy();
EJBQLPath path = (EJBQLPath) expression.getChild(1);
// make sure the ID for the path does not overlap with other condition
// joins...
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);
for (DbJoin join : correlatedJoinRelationship.getJoins()) {
context.append(' ').append(subqueryRootAlias).append('.').append(join.getTargetName()).append(" = ");
context.append(correlatedTableAlias).append('.').append(quoter.quotedSourceName(join));
context.append(" AND");
}
// translate subquery_root_id = LHS_of_memberof
EJBQLEquals equals = new EJBQLEquals(-1);
EJBQLIdentificationVariable identifier = new EJBQLIdentificationVariable(-1);
identifier.setText(subqueryId);
equals.jjtAddChild(identifier, 0);
equals.jjtAddChild((Node) expression.getChild(0), 1);
equals.visit(this);
context.append(")");
return false;
}
use of org.apache.cayenne.ejbql.EJBQLException in project cayenne by apache.
the class EJBQLPathAnaliserTranslator method visitIdentificationVariable.
@Override
public boolean visitIdentificationVariable(EJBQLExpression expression) {
// this is a match on a variable, like "x = :x"
ClassDescriptor descriptor = context.getEntityDescriptor(expression.getText());
if (descriptor == null) {
throw new EJBQLException("Invalid identification variable: " + expression.getText());
}
DbEntity table = descriptor.getEntity().getDbEntity();
String alias = context.getTableAlias(expression.getText(), context.getQuotingStrategy().quotedFullyQualifiedName(table));
Collection<DbAttribute> pks = table.getPrimaryKeys();
if (pks.size() == 1) {
DbAttribute pk = pks.iterator().next();
context.append(' ').append(alias).append('.').append(context.getQuotingStrategy().quotedName(pk));
} else {
throw new EJBQLException("Multi-column PK to-many matches are not yet supported.");
}
return false;
}
use of org.apache.cayenne.ejbql.EJBQLException in project cayenne by apache.
the class EJBQLPathAnaliserTranslator method visitIntegerLiteral.
@Override
public boolean visitIntegerLiteral(EJBQLIntegerLiteral expression) {
if (expression.getText() == null) {
context.append("null");
} else {
String text = expression.getText();
if (expression.isNegative() && text != null) {
if (text.startsWith("-")) {
text = text.substring(1);
} else {
text = "-" + text;
}
}
Long longValue;
try {
longValue = Long.valueOf(text);
} catch (NumberFormatException nfex) {
throw new EJBQLException("Invalid integer: " + expression.getText());
}
if (longValue > Integer.MAX_VALUE) {
String var = context.bindParameter(longValue);
context.append(" #bind($").append(var).append(" 'BIGINT')");
} else {
String var = context.bindParameter(longValue.intValue());
context.append(" #bind($").append(var).append(" 'INTEGER')");
}
}
return true;
}
use of org.apache.cayenne.ejbql.EJBQLException in project cayenne by apache.
the class EJBQLJoinAppender method appendJoin.
protected void appendJoin(String marker, EJBQLTableId lhsId, EJBQLTableId rhsId, String semantics) {
List<DbRelationship> joinRelationships = context.getIncomingRelationships(rhsId);
if (joinRelationships.isEmpty()) {
throw new EJBQLException("No join configured for id " + rhsId);
}
QuotingStrategy quoter = context.getQuotingStrategy();
DbRelationship incomingDB = joinRelationships.get(0);
// TODO: andrus, 1/6/2008 - move reusable join check here...
DbEntity sourceEntity = incomingDB.getSourceEntity();
String tableName = quoter.quotedFullyQualifiedName(sourceEntity);
String sourceAlias = context.getTableAlias(lhsId.getEntityId(), tableName);
if (marker != null) {
context.pushMarker(marker, false);
}
try {
context.append(" ").append(semantics);
if (joinRelationships.size() > 1) {
// if size of relationship list greater than 1,
// it's a flattened relationship
context.append(" ");
for (int i = 1; i < joinRelationships.size(); i++) {
DbRelationship dbRelationship = joinRelationships.get(i);
String subquerySourceTableName = quoter.quotedFullyQualifiedName(dbRelationship.getSourceEntity());
String subquerySourceAlias = context.getTableAlias(subquerySourceTableName, subquerySourceTableName);
String subqueryTargetTableName = quoter.quotedFullyQualifiedName(dbRelationship.getTargetEntity());
String subqueryTargetAlias;
if (i == joinRelationships.size() - 1) {
// it's the last table alias
subqueryTargetAlias = context.getTableAlias(rhsId.getEntityId(), subqueryTargetTableName);
} else {
subqueryTargetAlias = context.getTableAlias(subqueryTargetTableName, subqueryTargetTableName);
}
if (i == 1) {
// first apply the joins defined in query
context.append(subquerySourceTableName).append(' ').append(subquerySourceAlias);
generateJoiningExpression(incomingDB, sourceAlias, subquerySourceAlias);
}
context.append(" JOIN ");
context.append(subqueryTargetTableName).append(' ').append(subqueryTargetAlias);
generateJoiningExpression(dbRelationship, subquerySourceAlias, subqueryTargetAlias);
}
} else {
// non-flattened relationship
String targetAlias = appendTable(rhsId);
// apply the joins defined in query
generateJoiningExpression(incomingDB, sourceAlias, targetAlias);
}
} finally {
if (marker != null) {
context.popMarker();
}
}
}
Aggregations