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;
}
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(")");
}
}
}
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;
}
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()));
}
}
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));
}
}
}
Aggregations