Author: aadamchik
Date: Sun Aug 12 11:48:06 2007
New Revision: 565114
URL: http://svn.apache.org/viewvc?view=rev&rev=565114
Log:
CAY-846 EJBQL Support for Functional Expressions
(support for SIZE)
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLFunctionalExpressions.java
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java?view=diff&rev=565114&r1=565113&r2=565114
==============================================================================
---
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java
(original)
+++
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLConditionTranslator.java
Sun Aug 12 11:48:06 2007
@@ -116,6 +116,73 @@
return false;
}
+ public boolean visitSize(EJBQLExpression expression) {
+
+ // run as a correlated subquery.
+ // see "visitMemberOf" for correlated subquery logic
+
+ 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));
+ }
+
+ EJBQLPath path = (EJBQLPath) expression.getChild(0);
+
+ String id = path.getAbsolutePath();
+
+ String correlatedEntityId = path.getId();
+ ClassDescriptor correlatedEntityDescriptor = context
+ .getEntityDescriptor(correlatedEntityId);
+ String correlatedTableName = correlatedEntityDescriptor
+ .getEntity()
+ .getDbEntity()
+ .getFullyQualifiedName();
+ String correlatedTableAlias = context.getTableAlias(
+ correlatedEntityId,
+ correlatedTableName);
+
+ String subqueryId = context.createIdAlias(id);
+ ClassDescriptor targetDescriptor =
context.getEntityDescriptor(subqueryId);
+ String subqueryTableName = targetDescriptor
+ .getEntity()
+ .getDbEntity()
+ .getFullyQualifiedName();
+ String subqueryRootAlias = context.getTableAlias(subqueryId,
subqueryTableName);
+
+ context.append(" (SELECT COUNT(1) FROM ");
+ // 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");
+
+ ObjRelationship relationship = context.getIncomingRelationship(id);
+ // TODO: andrus, 8/11/2007 flattened?
+ DbRelationship correlatedJoinRelationship = (DbRelationship)
relationship
+ .getDbRelationships()
+ .get(0);
+ Iterator it = correlatedJoinRelationship.getJoins().iterator();
+ while (it.hasNext()) {
+ DbJoin join = (DbJoin) it.next();
+ context.append(' ').append(subqueryRootAlias).append('.').append(
+ join.getTargetName()).append(" = ");
+
context.append(correlatedTableAlias).append('.').append(join.getSourceName());
+
+ if (it.hasNext()) {
+ context.append(" AND");
+ }
+ }
+
+ context.append(")");
+
+ return false;
+ }
+
public boolean visitMemberOf(EJBQLExpression expression) {
// create a correlated subquery, using the following transformation:
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLFunctionalExpressions.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLFunctionalExpressions.java?view=diff&rev=565114&r1=565113&r2=565114
==============================================================================
---
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLFunctionalExpressions.java
(original)
+++
cayenne/main/trunk/framework/cayenne-jdk1.4-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLFunctionalExpressions.java
Sun Aug 12 11:48:06 2007
@@ -27,6 +27,7 @@
import org.apache.art.BigDecimalEntity;
import org.apache.art.BigIntegerEntity;
import org.apache.art.DateTestEntity;
+import org.apache.art.Painting;
import org.apache.cayenne.ObjectContext;
import org.apache.cayenne.query.EJBQLQuery;
import org.apache.cayenne.unit.CayenneCase;
@@ -168,36 +169,36 @@
assertTrue(objects.contains(o2));
}
- // public void testSIZE() {
- // ObjectContext context = createDataContext();
- //
- // Artist a1 = (Artist) context.newObject(Artist.class);
- // a1.setArtistName("a1");
- //
- // Artist a2 = (Artist) context.newObject(Artist.class);
- // a2.setArtistName("a2");
- //
- // Painting p12 = (Painting) context.newObject(Painting.class);
- // p12.setPaintingTitle("p12");
- // a2.addToPaintingArray(p12);
- // Painting p22 = (Painting) context.newObject(Painting.class);
- // p22.setPaintingTitle("p22");
- // a2.addToPaintingArray(p22);
- //
- // context.commitChanges();
- //
- // EJBQLQuery query = new EJBQLQuery(
- // "SELECT d FROM Artist d WHERE SIZE(d.paintingArray) = 2");
- // List objects = context.performQuery(query);
- // assertEquals(1, objects.size());
- // assertTrue(objects.contains(a2));
- //
- // EJBQLQuery query2 = new EJBQLQuery(
- // "SELECT d FROM Artist d WHERE SIZE(d.paintingArray) = 0");
- // List objects2 = context.performQuery(query2);
- // assertEquals(1, objects2.size());
- // assertTrue(objects2.contains(a1));
- // }
+ public void testSIZE() {
+ ObjectContext context = createDataContext();
+
+ Artist a1 = (Artist) context.newObject(Artist.class);
+ a1.setArtistName("a1");
+
+ Artist a2 = (Artist) context.newObject(Artist.class);
+ a2.setArtistName("a2");
+
+ Painting p12 = (Painting) context.newObject(Painting.class);
+ p12.setPaintingTitle("p12");
+ a2.addToPaintingArray(p12);
+ Painting p22 = (Painting) context.newObject(Painting.class);
+ p22.setPaintingTitle("p22");
+ a2.addToPaintingArray(p22);
+
+ context.commitChanges();
+
+ EJBQLQuery query = new EJBQLQuery(
+ "SELECT d FROM Artist d WHERE SIZE(d.paintingArray) = 2");
+ List objects = context.performQuery(query);
+ assertEquals(1, objects.size());
+ assertTrue(objects.contains(a2));
+
+ EJBQLQuery query2 = new EJBQLQuery(
+ "SELECT d FROM Artist d WHERE SIZE(d.paintingArray) = 0");
+ List objects2 = context.performQuery(query2);
+ assertEquals(1, objects2.size());
+ assertTrue(objects2.contains(a1));
+ }
public void testCONCAT() {
ObjectContext context = createDataContext();