use of org.apache.cayenne.map.DbAttribute in project cayenne by apache.
the class EJBQLDbPathTranslator method processTerminatingRelationship.
protected void processTerminatingRelationship(DbRelationship relationship) {
if (relationship.isToMany()) {
// use an outer join for to-many matches
resolveJoin(false);
DbEntity table = (DbEntity) relationship.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
DbEntity table = (DbEntity) relationship.getSourceEntity();
String alias = this.lastAlias != null ? lastAlias : context.getTableAlias(idPath, context.getQuotingStrategy().quotedFullyQualifiedName(table));
List<DbJoin> joins = relationship.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));
}
}
}
use of org.apache.cayenne.map.DbAttribute 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.map.DbAttribute in project cayenne by apache.
the class EJBQLIdColumnsTranslator method visitIdentifier.
@Override
public boolean visitIdentifier(EJBQLExpression expression) {
Map<String, String> fields = null;
if (context.isAppendingResultColumns()) {
fields = context.nextEntityResult().getFields();
}
String idVar = expression.getText();
ClassDescriptor descriptor = context.getEntityDescriptor(idVar);
ObjEntity oe = descriptor.getEntity();
for (ObjAttribute oa : oe.getPrimaryKeys()) {
DbAttribute t = oe.getDbEntity().getAttribute(oa.getDbAttributeName());
appendColumn(idVar, oa, t, fields, oa.getType());
}
return false;
}
use of org.apache.cayenne.map.DbAttribute in project cayenne by apache.
the class EJBQLIdentifierColumnsTranslator method addPrefetchedColumnsIfAny.
private void addPrefetchedColumnsIfAny(final String visitedIdentifier) {
PrefetchTreeNode prefetchTree = context.getCompiledExpression().getPrefetchTree();
if (prefetchTree != null) {
for (PrefetchTreeNode prefetch : prefetchTree.adjacentJointNodes()) {
ClassDescriptor descriptor = context.getEntityDescriptor(prefetch.getEjbqlPathEntityId());
if (visitedIdentifier.equals(prefetch.getEjbqlPathEntityId())) {
DbEntity table = descriptor.getRootDbEntities().iterator().next();
ObjEntity objectEntity = descriptor.getEntity();
prefetch.setEntityName(objectEntity.getName());
Expression prefetchExp = ExpressionFactory.exp(prefetch.getPath());
Expression dbPrefetch = objectEntity.translateToDbPath(prefetchExp);
DbRelationship r = null;
for (PathComponent<DbAttribute, DbRelationship> component : table.resolvePath(dbPrefetch, context.getMetadata().getPathSplitAliases())) {
r = component.getRelationship();
}
if (r == null) {
throw new CayenneRuntimeException("Invalid joint prefetch '%s' for entity: %s", prefetch, objectEntity.getName());
}
for (DbAttribute attribute : r.getTargetEntity().getAttributes()) {
appendColumn(prefetch.getEjbqlPathEntityId() + "." + prefetch.getPath(), attribute, "", prefetch.getPath() + "." + attribute.getName(), null);
}
}
}
}
}
use of org.apache.cayenne.map.DbAttribute 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;
}
Aggregations