use of org.apache.cayenne.map.DbRelationship in project cayenne by apache.
the class ObjRelationshipInfo method createRelationship.
/**
* Creates a new relationship connecting currently selected source entity
* with ObjRelationship target entity. User is allowed to edit the
* relationship, change its name, and create joins.
*/
protected void createRelationship() {
DbRelationship dbRel = getLastRelationship();
DbEntity source = dbRel != null ? dbRel.getTargetEntity() : null;
DbRelationshipTarget targetModel = new DbRelationshipTarget(mediator, getStartEntity(), source);
targetModel.startupAction();
if (!targetModel.isSavePressed()) {
return;
}
DbRelationship dbRelationship = new DbRelationship();
dbRelationship.setSourceEntity(targetModel.getSource());
dbRelationship.setTargetEntityName(targetModel.getTarget());
dbRelationship.setToMany(targetModel.isToMany());
dbRelationship.setName(createNamingStrategy(NameGeneratorPreferences.getInstance().getLastUsedStrategies().get(0)).relationshipName(dbRelationship));
targetModel.getSource().addRelationship(dbRelationship);
// TODO: creating relationship outside of ResolveDbRelationshipDialog
// confuses it to send incorrect event - CHANGE instead of ADD
ResolveDbRelationshipDialog dialog = new ResolveDbRelationshipDialog(dbRelationship);
dialog.setVisible(true);
if (dialog.isCancelPressed()) {
targetModel.getSource().removeRelationship(dbRelationship.getName());
} else {
MultiColumnBrowser pathBrowser = getPathBrowser();
Object[] oldPath = targetModel.isSource1Selected() ? new Object[] { getStartEntity() } : pathBrowser.getSelectionPath().getPath();
/**
* Update the view
*/
EntityTreeModel treeModel = (EntityTreeModel) pathBrowser.getModel();
treeModel.invalidate();
pathBrowser.setSelectionPath(new TreePath(new Object[] { getStartEntity() }));
pathBrowser.repaint();
Object[] path = new Object[oldPath.length + 1];
System.arraycopy(oldPath, 0, path, 0, path.length - 1);
path[path.length - 1] = dbRelationship;
pathBrowser.setSelectionPath(new TreePath(path));
}
dialog.dispose();
}
use of org.apache.cayenne.map.DbRelationship in project cayenne by apache.
the class ObjRelationshipInfo method setSavedDbRelationships.
public void setSavedDbRelationships(List<DbRelationship> rels) {
this.savedDbRelationships = rels;
String currPath = "";
for (DbRelationship rel : rels) {
currPath += "->" + rel.getName();
}
if (rels.size() > 0) {
currPath = currPath.substring(2);
}
currentPath = currPath;
view.currentPathLabel.setText(currPath);
}
use of org.apache.cayenne.map.DbRelationship in project cayenne by apache.
the class ObjRelationshipInfo method valueChanged.
/**
* Sets list of DB Relationships current ObjRelationship is mapped to
*/
public void valueChanged(TreeSelectionEvent e) {
TreePath selectedPath = e.getPath();
// at least two elements to constitute a valid ordering path
if (selectedPath == null || selectedPath.getPathCount() < 2) {
return;
}
Relationship rel = (Relationship) selectedPath.getLastPathComponent();
DbEntity target = (DbEntity) rel.getTargetEntity();
/**
* Initialize root with one of mapped ObjEntities.
*/
Collection<ObjEntity> objEntities = target.getDataMap().getMappedEntities(target);
List<DbRelationship> relPath = new Vector<DbRelationship>(selectedPath.getPathCount() - 1);
for (int i = 1; i < selectedPath.getPathCount(); i++) {
relPath.add((DbRelationship) selectedPath.getPathComponent(i));
}
setDbRelationships(relPath);
updateCollectionChoosers();
}
use of org.apache.cayenne.map.DbRelationship in project cayenne by apache.
the class DbArcIdTest method testEquals.
@Test
public void testEquals() {
DbArcId id1 = new DbArcId(new ObjectId("x", "k", "v"), new DbRelationship("r1"));
assertTrue(id1.equals(id1));
DbArcId id1_eq = new DbArcId(new ObjectId("x", "k", "v"), new DbRelationship("r1"));
assertTrue(id1.equals(id1_eq));
assertTrue(id1_eq.equals(id1));
DbArcId id2 = new DbArcId(new ObjectId("x", "k", "v"), new DbRelationship("r2"));
assertFalse(id1.equals(id2));
DbArcId id3 = new DbArcId(new ObjectId("y", "k", "v"), new DbRelationship("r1"));
assertFalse(id1.equals(id3));
assertFalse(id1.equals(new Object()));
}
use of org.apache.cayenne.map.DbRelationship in project cayenne by apache.
the class DefaultSelectTranslator method appendQueryColumns.
/**
* Appends columns needed for object SelectQuery to the provided columns
* list.
*/
<T> List<ColumnDescriptor> appendQueryColumns(final List<ColumnDescriptor> columns, SelectQuery<T> query, ClassDescriptor descriptor, final String tableAlias) {
final Set<ColumnTracker> attributes = new HashSet<>();
// fetched attributes include attributes that are either:
//
// * class properties
// * PK
// * FK used in relationship
// * joined prefetch PK
ObjEntity oe = descriptor.getEntity();
PropertyVisitor visitor = new PropertyVisitor() {
public boolean visitAttribute(AttributeProperty property) {
ObjAttribute oa = property.getAttribute();
resetJoinStack();
Iterator<CayenneMapEntry> dbPathIterator = oa.getDbPathIterator();
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) {
DbRelationship rel = (DbRelationship) pathPart;
dbRelationshipAdded(rel, JoinType.LEFT_OUTER, null);
} else if (pathPart instanceof DbAttribute) {
DbAttribute dbAttr = (DbAttribute) pathPart;
appendColumn(columns, oa, dbAttr, attributes, null, tableAlias);
}
}
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) {
resetJoinStack();
ObjRelationship rel = property.getRelationship();
DbRelationship dbRel = rel.getDbRelationships().get(0);
List<DbJoin> joins = dbRel.getJoins();
for (DbJoin join : joins) {
DbAttribute src = join.getSource();
appendColumn(columns, null, src, attributes, null, tableAlias);
}
}
};
descriptor.visitAllProperties(visitor);
// stack should be reset, because all root table attributes go with "t0"
// table alias
resetJoinStack();
// add remaining needed attrs from DbEntity
DbEntity table = oe.getDbEntity();
for (DbAttribute dba : table.getPrimaryKeys()) {
appendColumn(columns, null, dba, attributes, null, tableAlias);
}
if (query instanceof PrefetchSelectQuery) {
// for each relationship path add PK of the target entity...
for (String path : ((PrefetchSelectQuery) query).getResultPaths()) {
ASTDbPath pathExp = (ASTDbPath) oe.translateToDbPath(ExpressionFactory.exp(path));
// add joins and find terminating element
resetJoinStack();
PathComponent<DbAttribute, DbRelationship> lastComponent = null;
for (PathComponent<DbAttribute, DbRelationship> component : table.resolvePath(pathExp, getPathAliases())) {
if (component.getRelationship() != null) {
// do not invoke dbRelationshipAdded(), invoke
// pushJoin() instead. This is to prevent
// 'forcingDistinct' flipping to true, that will result
// in unneeded extra processing and sometimes in invalid
// results (see CAY-1979). Distinctness of each row is
// guaranteed by the prefetch query semantics - we
// include target ID in the result columns
getJoinStack().pushJoin(component.getRelationship(), component.getJoinType(), null);
}
lastComponent = component;
}
// process terminating element
if (lastComponent != null) {
DbRelationship relationship = lastComponent.getRelationship();
if (relationship != null) {
String labelPrefix = pathExp.getPath();
DbEntity targetEntity = relationship.getTargetEntity();
for (DbAttribute pk : targetEntity.getPrimaryKeys()) {
// note that we my select a source attribute, but
// label it as
// target for simplified snapshot processing
appendColumn(columns, null, pk, attributes, labelPrefix + '.' + pk.getName());
}
}
}
}
}
// handle joint prefetches directly attached to this query...
if (query.getPrefetchTree() != null) {
// perform some sort of union or sub-queries.
for (PrefetchTreeNode prefetch : query.getPrefetchTree().getChildren()) {
prefetch.setEntityName(oe.getName());
}
for (PrefetchTreeNode prefetch : query.getPrefetchTree().adjacentJointNodes()) {
// for each prefetch add all joins plus columns from the target
// entity
Expression prefetchExp = ExpressionFactory.exp(prefetch.getPath());
ASTDbPath dbPrefetch = (ASTDbPath) oe.translateToDbPath(prefetchExp);
resetJoinStack();
DbRelationship r = null;
for (PathComponent<DbAttribute, DbRelationship> component : table.resolvePath(dbPrefetch, getPathAliases())) {
r = component.getRelationship();
dbRelationshipAdded(r, JoinType.LEFT_OUTER, null);
}
if (r == null) {
throw new CayenneRuntimeException("Invalid joint prefetch '%s' for entity: %s", prefetch, oe.getName());
}
// add columns from the target entity, including those that are matched
// against the FK of the source entity.
// This is needed to determine whether optional relationships are null
// go via target OE to make sure that Java types are mapped correctly...
ObjRelationship targetRel = (ObjRelationship) prefetchExp.evaluate(oe);
ObjEntity targetEntity = targetRel.getTargetEntity();
String labelPrefix = dbPrefetch.getPath();
PropertyVisitor prefetchVisitor = new PropertyVisitor() {
public boolean visitAttribute(AttributeProperty property) {
ObjAttribute oa = property.getAttribute();
Iterator<CayenneMapEntry> dbPathIterator = oa.getDbPathIterator();
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) {
DbRelationship rel = (DbRelationship) pathPart;
dbRelationshipAdded(rel, JoinType.INNER, null);
} else if (pathPart instanceof DbAttribute) {
DbAttribute dbAttr = (DbAttribute) pathPart;
appendColumn(columns, oa, dbAttr, attributes, labelPrefix + '.' + dbAttr.getName());
}
}
return true;
}
public boolean visitToMany(ToManyProperty property) {
return true;
}
public boolean visitToOne(ToOneProperty property) {
return true;
}
};
ClassDescriptor prefetchClassDescriptor = entityResolver.getClassDescriptor(targetEntity.getName());
prefetchClassDescriptor.visitAllProperties(prefetchVisitor);
// append remaining target attributes such as keys
DbEntity targetDbEntity = r.getTargetEntity();
for (DbAttribute attribute : targetDbEntity.getAttributes()) {
appendColumn(columns, null, attribute, attributes, labelPrefix + '.' + attribute.getName());
}
}
}
return columns;
}
Aggregations