use of org.apache.cayenne.map.DbRelationship in project cayenne by apache.
the class PrefetchProcessorJointNode method buildRowMapping.
/**
* Configures row columns mapping for this node entity.
*/
private void buildRowMapping() {
final Map<String, ColumnDescriptor> targetSource = new TreeMap<>();
// build a DB path .. find parent node that terminates the joint group...
PrefetchTreeNode jointRoot = this;
while (jointRoot.getParent() != null && !jointRoot.isDisjointPrefetch() && !jointRoot.isDisjointByIdPrefetch()) {
jointRoot = jointRoot.getParent();
}
final String prefix;
if (jointRoot != this) {
Expression objectPath = ExpressionFactory.exp(getPath(jointRoot));
ASTPath translated = (ASTPath) ((PrefetchProcessorNode) jointRoot).getResolver().getEntity().translateToDbPath(objectPath);
// make sure we do not include "db:" prefix
prefix = translated.getOperand(0) + ".";
} else {
prefix = "";
}
if (getParent() != null && !getParent().isPhantom() && getIncoming() != null && !getIncoming().getRelationship().isFlattened()) {
DbRelationship r = getIncoming().getRelationship().getDbRelationships().get(0);
for (final DbJoin join : r.getJoins()) {
appendColumn(targetSource, join.getTargetName(), prefix + join.getTargetName());
}
}
ClassDescriptor descriptor = resolver.getDescriptor();
descriptor.visitAllProperties(new PropertyVisitor() {
public boolean visitAttribute(AttributeProperty property) {
String target = property.getAttribute().getDbAttributePath();
appendColumn(targetSource, target, prefix + target);
return true;
}
public boolean visitToMany(ToManyProperty property) {
return visitRelationship(property);
}
public boolean visitToOne(ToOneProperty property) {
return visitRelationship(property);
}
private boolean visitRelationship(ArcProperty arc) {
DbRelationship dbRel = arc.getRelationship().getDbRelationships().get(0);
for (DbAttribute attribute : dbRel.getSourceAttributes()) {
String target = attribute.getName();
appendColumn(targetSource, target, prefix + target);
}
return true;
}
});
// append id columns ... (some may have been appended already via relationships)
for (String pkName : descriptor.getEntity().getPrimaryKeyNames()) {
appendColumn(targetSource, pkName, prefix + pkName);
}
// append inheritance discriminator columns...
for (ObjAttribute column : descriptor.getDiscriminatorColumns()) {
String target = column.getDbAttributePath();
appendColumn(targetSource, target, prefix + target);
}
int size = targetSource.size();
this.rowCapacity = (int) Math.ceil(size / 0.75);
this.columns = new ColumnDescriptor[size];
targetSource.values().toArray(columns);
}
use of org.apache.cayenne.map.DbRelationship in project cayenne by apache.
the class EJBQLPathAnaliserTranslator method visitSize.
@Override
public boolean visitSize(EJBQLExpression expression) {
if (expression.getChildrenCount() != 1) {
throw new EJBQLException("SIZE must have exactly one child, got: " + expression.getChildrenCount());
}
if (!(expression.getChild(0) instanceof EJBQLPath)) {
throw new EJBQLException("First child of SIZE must be a collection path, got: " + expression.getChild(1));
}
QuotingStrategy quoter = context.getQuotingStrategy();
EJBQLPath path = (EJBQLPath) expression.getChild(0);
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);
Iterator<DbJoin> it = correlatedJoinRelationship.getJoins().iterator();
while (it.hasNext()) {
DbJoin join = it.next();
context.append(' ').append(subqueryRootAlias).append('.').append(join.getTargetName()).append(" = ");
context.append(correlatedTableAlias).append('.').append(quoter.quotedSourceName(join));
if (it.hasNext()) {
context.append(" AND");
}
}
context.append(")");
return false;
}
use of org.apache.cayenne.map.DbRelationship in project cayenne by apache.
the class EJBQLDbPathTranslator method processIntermediatePathComponent.
private void processIntermediatePathComponent() {
DbRelationship relationship = currentEntity.getRelationship(lastPathComponent);
if (relationship == null) {
throw new EJBQLException("Unknown relationship '" + lastPathComponent + "' for entity '" + currentEntity.getName() + "'");
}
this.currentEntity = (DbEntity) relationship.getTargetEntity();
}
use of org.apache.cayenne.map.DbRelationship in project cayenne by apache.
the class EJBQLDbPathTranslator method resolveJoin.
protected void resolveJoin() {
EJBQLJoinAppender joinAppender = context.getTranslatorFactory().getJoinAppender(context);
String newPath = idPath + '.' + lastPathComponent;
String oldPath = joinAppender.registerReusableJoin(idPath, lastPathComponent, newPath);
this.fullPath = fullPath + '.' + lastPathComponent;
if (oldPath != null) {
this.idPath = oldPath;
DbRelationship lastRelationship = currentEntity.getRelationship(lastPathComponent);
if (lastRelationship != null) {
DbEntity targetEntity = lastRelationship.getTargetEntity();
this.lastAlias = context.getTableAlias(fullPath, context.getQuotingStrategy().quotedFullyQualifiedName(targetEntity));
} else {
String tableName = context.getQuotingStrategy().quotedFullyQualifiedName(currentEntity);
this.lastAlias = context.getTableAlias(oldPath, tableName);
}
} else {
DbRelationship lastRelationship = currentEntity.getRelationship(lastPathComponent);
DbEntity targetEntity = null;
if (lastRelationship != null) {
targetEntity = lastRelationship.getTargetEntity();
} else {
targetEntity = currentEntity;
}
// register join
joinAppender.appendInnerJoin(joinMarker, new EJBQLTableId(idPath), new EJBQLTableId(fullPath));
// TODO: outer joins handling
this.lastAlias = context.getTableAlias(fullPath, context.getQuotingStrategy().quotedFullyQualifiedName(targetEntity));
this.idPath = newPath;
}
}
use of org.apache.cayenne.map.DbRelationship 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;
}
Aggregations