You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2015/05/23 14:34:16 UTC
cayenne git commit: CAY-1902 Implement resolving Db paths for
DataObjects
Repository: cayenne
Updated Branches:
refs/heads/master 81e879e12 -> 47428da03
CAY-1902 Implement resolving Db paths for DataObjects
* adapted 04/30/2015 patch by John Huss
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/47428da0
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/47428da0
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/47428da0
Branch: refs/heads/master
Commit: 47428da03e4ad08d431a37cf0447cb90a5093167
Parents: 81e879e
Author: aadamchik <aa...@apache.org>
Authored: Sat May 23 15:01:36 2015 +0300
Committer: aadamchik <aa...@apache.org>
Committed: Sat May 23 15:33:04 2015 +0300
----------------------------------------------------------------------
.../apache/cayenne/exp/parser/ASTDbPath.java | 66 +++++++++++++++++++-
.../apache/cayenne/exp/parser/ASTDbPathIT.java | 43 +++++++++++++
.../apache/cayenne/exp/parser/ASTEqualIT.java | 2 +-
docs/doc/src/main/resources/RELEASE-NOTES.txt | 1 +
4 files changed, 110 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cayenne/blob/47428da0/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDbPath.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDbPath.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDbPath.java
index ade49ee..7de3d75 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDbPath.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDbPath.java
@@ -20,15 +20,25 @@
package org.apache.cayenne.exp.parser;
import java.io.IOException;
+import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import org.apache.cayenne.Cayenne;
+import org.apache.cayenne.DataRow;
import org.apache.cayenne.ObjectContext;
import org.apache.cayenne.ObjectId;
import org.apache.cayenne.Persistent;
import org.apache.cayenne.access.DataContext;
import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.DbRelationship;
import org.apache.cayenne.map.Entity;
+import org.apache.cayenne.query.SelectById;
+import org.apache.cayenne.query.SelectQuery;
+import org.apache.cayenne.util.CayenneMapEntry;
/**
* Path expression traversing DB relationships and attributes.
@@ -62,7 +72,10 @@ public class ASTDbPath extends ASTPath {
}
Map<?, ?> map = toMap(o);
- return (map != null) ? map.get(path) : null;
+ int finalDotIndex = path.lastIndexOf('.');
+ String finalPathComponent = finalDotIndex == -1 ? path : path.substring(finalDotIndex + 1);
+
+ return (map != null) ? map.get(finalPathComponent) : null;
}
protected Map<?, ?> toMap(Object o) {
@@ -71,6 +84,7 @@ public class ASTDbPath extends ASTPath {
} else if (o instanceof ObjectId) {
return ((ObjectId) o).getIdSnapshot();
} else if (o instanceof Persistent) {
+
Persistent persistent = (Persistent) o;
// before reading full snapshot, check if we can use smaller ID
@@ -83,12 +97,62 @@ public class ASTDbPath extends ASTPath {
}
private Map<?, ?> toMap_AttachedObject(ObjectContext context, Persistent persistent) {
+ return path.indexOf('.') >= 0 ? toMap_AttchedObject_MultiStepPath(context, persistent)
+ : toMap_AttchedObject_SingleStepPath(context, persistent);
+ }
+
+ private Map<?, ?> toMap_AttchedObject_MultiStepPath(ObjectContext context, Persistent persistent) {
+ Iterator<CayenneMapEntry> pathComponents = Cayenne.getObjEntity(persistent).getDbEntity()
+ .resolvePathComponents(this);
+ LinkedList<DbRelationship> reversedPathComponents = new LinkedList<DbRelationship>();
+
+ while (pathComponents.hasNext()) {
+ CayenneMapEntry component = pathComponents.next();
+ if (component instanceof DbRelationship) {
+ DbRelationship rel = (DbRelationship) component;
+ DbRelationship reverseRelationship = rel.getReverseRelationship();
+ if (reverseRelationship == null) {
+ reverseRelationship = rel.createReverseRelationship();
+ }
+ reversedPathComponents.addFirst(reverseRelationship);
+ } else {
+ break; // an attribute can only occur at the end of the path
+ }
+ }
+
+ DbEntity finalEntity = reversedPathComponents.get(0).getSourceEntity();
+
+ StringBuilder reversedPathStr = new StringBuilder();
+ for (int i = 0; i < reversedPathComponents.size(); i++) {
+ reversedPathStr.append(reversedPathComponents.get(i).getName());
+ if (i < reversedPathComponents.size() - 1) {
+ reversedPathStr.append('.');
+ }
+ }
+
+ SelectQuery<DataRow> query = new SelectQuery<DataRow>(finalEntity, ExpressionFactory.matchDbExp(
+ reversedPathStr.toString(), persistent));
+
+ // TODO: DbEntity root option for ObjectSelect?
+ query.setFetchingDataRows(true);
+ DataRow result = persistent.getObjectContext().selectOne(query);
+ return result;
+ }
+
+ private Map<?, ?> toMap_AttchedObject_SingleStepPath(ObjectContext context, Persistent persistent) {
+ ObjectId oid = persistent.getObjectId();
// TODO: snapshotting API should not be limited to DataContext...
if (context instanceof DataContext) {
return ((DataContext) context).currentSnapshot(persistent);
}
+ if (oid != null) {
+
+ return SelectById.dataRowQuery(persistent.getObjectId()).selectOne(context);
+ }
+
+ // fallback to ID snapshot as a last resort
return toMap_DetachedObject(persistent);
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/47428da0/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTDbPathIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTDbPathIT.java b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTDbPathIT.java
index 8f5e69f..4ea0b6f 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTDbPathIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTDbPathIT.java
@@ -19,6 +19,7 @@
package org.apache.cayenne.exp.parser;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import org.apache.cayenne.Cayenne;
@@ -30,6 +31,7 @@ import org.apache.cayenne.map.DbAttribute;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.testdo.testmap.Artist;
+import org.apache.cayenne.testdo.testmap.Painting;
import org.apache.cayenne.unit.di.server.CayenneProjects;
import org.apache.cayenne.unit.di.server.ServerCase;
import org.apache.cayenne.unit.di.server.UseServerRuntime;
@@ -69,4 +71,45 @@ public class ASTDbPathIT extends ServerCase {
assertTrue(dbTarget instanceof DbAttribute);
}
+ @Test
+ public void testEvaluate_Related_DataObject() {
+
+ Artist a1 = context.newObject(Artist.class);
+ Artist a2 = context.newObject(Artist.class);
+ Painting p1 = context.newObject(Painting.class);
+ Painting p2 = context.newObject(Painting.class);
+ Painting p3 = context.newObject(Painting.class);
+
+ a1.setArtistName("a1");
+ a2.setArtistName("a2");
+ p1.setPaintingTitle("p1");
+ p2.setPaintingTitle("p2");
+ p3.setPaintingTitle("p3");
+
+ p1.setToArtist(a1);
+ p2.setToArtist(a2);
+
+ context.commitChanges();
+
+ Expression attributeOnlyPath = new ASTDbPath("PAINTING_TITLE");
+ Expression singleStepPath = new ASTDbPath("toArtist.ARTIST_NAME");
+ Expression multiStepPath = new ASTDbPath("toArtist.paintingArray.PAINTING_TITLE");
+
+ // attribute only path
+ assertEquals(p1.getPaintingTitle(), attributeOnlyPath.evaluate(p1));
+ assertEquals(p2.getPaintingTitle(), attributeOnlyPath.evaluate(p2));
+
+ // attribute only path - not in cache
+ p1.getObjectContext().invalidateObjects(p1, p2);
+ assertEquals(p1.getPaintingTitle(), attributeOnlyPath.evaluate(p1));
+ assertEquals(p2.getPaintingTitle(), attributeOnlyPath.evaluate(p2));
+
+ // single step relationship path
+ assertEquals(a1.getArtistName(), singleStepPath.evaluate(p1));
+ assertEquals(a2.getArtistName(), singleStepPath.evaluate(p2));
+ assertNull(singleStepPath.evaluate(p3));
+
+ assertEquals(p1.getPaintingTitle(), multiStepPath.evaluate(p1));
+ assertEquals(p2.getPaintingTitle(), multiStepPath.evaluate(p2));
+ }
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/47428da0/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTEqualIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTEqualIT.java b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTEqualIT.java
index 5b056f2..deec1a9 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTEqualIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTEqualIT.java
@@ -90,7 +90,7 @@ public class ASTEqualIT extends ServerCase {
Painting p1 = context.newObject(Painting.class);
Painting p2 = context.newObject(Painting.class);
Painting p3 = context.newObject(Painting.class);
-
+
a1.setArtistName("a1");
a2.setArtistName("a2");
p1.setPaintingTitle("p1");
http://git-wip-us.apache.org/repos/asf/cayenne/blob/47428da0/docs/doc/src/main/resources/RELEASE-NOTES.txt
----------------------------------------------------------------------
diff --git a/docs/doc/src/main/resources/RELEASE-NOTES.txt b/docs/doc/src/main/resources/RELEASE-NOTES.txt
index 3b827e8..0ab98b0 100644
--- a/docs/doc/src/main/resources/RELEASE-NOTES.txt
+++ b/docs/doc/src/main/resources/RELEASE-NOTES.txt
@@ -15,6 +15,7 @@ Date:
Changes/New Features:
CAY-1626 Add JodaTime DateTime support
+CAY-1902 Implement resolving Db paths for DataObjects
CAY-1991 More control over generated String property names
CAY-1992 Allow to exclude DataMap java class from Modeler class generation
CAY-1995 Add support for iterators to Select