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 2008/01/06 19:14:43 UTC

svn commit: r609363 - in /cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src: main/java/org/apache/cayenne/access/jdbc/ main/java/org/apache/cayenne/map/ test/java/org/apache/cayenne/access/

Author: aadamchik
Date: Sun Jan  6 10:14:43 2008
New Revision: 609363

URL: http://svn.apache.org/viewvc?rev=609363&view=rev
Log:
CAY-954 EJBQL Query: Support for single table inheritance
(raw but working implementation)

Modified:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLJoinAppender.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLSelectTranslator.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/EntityInheritanceTree.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLInheritanceTest.java

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLJoinAppender.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLJoinAppender.java?rev=609363&r1=609362&r2=609363&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLJoinAppender.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLJoinAppender.java Sun Jan  6 10:14:43 2008
@@ -24,6 +24,7 @@
 import java.util.Map;
 
 import org.apache.cayenne.ejbql.EJBQLException;
+import org.apache.cayenne.ejbql.EJBQLExpression;
 import org.apache.cayenne.map.DbJoin;
 import org.apache.cayenne.map.DbRelationship;
 import org.apache.cayenne.map.EntityInheritanceTree;
@@ -176,11 +177,26 @@
                     .getEntityResolver()
                     .lookupInheritanceTree(entity);
             if (inheritanceTree != null) {
-                // TODO: andrus, 1/6/2008 - access to entity qualifier is pending CAY-956
-                // implementation...
-                // context.pushMarker(EJBQLSelectTranslator.makeWhereMarker(), true);
-                // context.append(" WHERE");
-                // context.popMarker();
+
+                EJBQLExpression qualifier = inheritanceTree
+                        .ejbqlQualifierForEntityAndSubclass(id.getEntityId());
+
+                if (qualifier != null) {
+
+                    context.pushMarker(EJBQLSelectTranslator.makeWhereMarker(), true);
+                    context.append(" WHERE");
+                    context.popMarker();
+
+                    context.pushMarker(
+                            EJBQLSelectTranslator.makeEntityQualifierMarker(),
+                            false);
+
+                    qualifier.visit(context
+                            .getTranslatorFactory()
+                            .getConditionTranslator(context));
+
+                    context.popMarker();
+                }
             }
         }
 

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLSelectTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLSelectTranslator.java?rev=609363&r1=609362&r2=609363&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLSelectTranslator.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLSelectTranslator.java Sun Jan  6 10:14:43 2008
@@ -38,6 +38,10 @@
     static String makeWhereMarker() {
         return "WHERE_MARKER";
     }
+    
+    static String makeEntityQualifierMarker() {
+        return "ENTITY_QUALIIER";
+    }
 
     EJBQLSelectTranslator(EJBQLTranslationContext context) {
         this.context = context;
@@ -61,6 +65,7 @@
         context.setAppendingResultColumns(false);
         expression.visit(context.getTranslatorFactory().getFromTranslator(context));
         context.markCurrentPosition(makeWhereMarker());
+        context.markCurrentPosition(makeEntityQualifierMarker());
         return false;
     }
 

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/EntityInheritanceTree.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/EntityInheritanceTree.java?rev=609363&r1=609362&r2=609363&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/EntityInheritanceTree.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/map/EntityInheritanceTree.java Sun Jan  6 10:14:43 2008
@@ -24,16 +24,20 @@
 import java.util.Collections;
 
 import org.apache.cayenne.DataRow;
+import org.apache.cayenne.ejbql.EJBQLBaseVisitor;
+import org.apache.cayenne.ejbql.EJBQLExpression;
+import org.apache.cayenne.ejbql.EJBQLParserFactory;
 import org.apache.cayenne.exp.Expression;
 
 /**
- * A tree structure representing inheritance hierarchy 
- * of an ObjEntity and its subentities.
+ * A tree structure representing inheritance hierarchy of an ObjEntity and its
+ * subentities.
  * 
  * @since 1.1
  * @author Andrus Adamchik
  */
 public class EntityInheritanceTree {
+
     protected ObjEntity entity;
     protected Collection<EntityInheritanceTree> subentities;
     protected Expression normalizedQualifier;
@@ -43,8 +47,8 @@
     }
 
     /**
-     * Returns a qualifier Expression that matches root entity
-     * of this tree and all its subentities.
+     * Returns a qualifier Expression that matches root entity of this tree and all its
+     * subentities.
      */
     public Expression qualifierForEntityAndSubclasses() {
         Expression qualifier = entity.getDeclaredQualifier();
@@ -58,7 +62,8 @@
             for (EntityInheritanceTree child : subentities) {
                 Expression childQualifier = child.qualifierForEntityAndSubclasses();
 
-                // if any child qualifier is null, just return null, since no filtering is possible
+                // if any child qualifier is null, just return null, since no filtering is
+                // possible
                 if (childQualifier == null) {
                     return null;
                 }
@@ -71,8 +76,39 @@
     }
 
     /**
-     * Returns the deepest possible entity in the inheritance hierarchy 
-     * that can be used to create objects from a given DataRow.
+     * @since 3.0
+     */
+    public EJBQLExpression ejbqlQualifierForEntityAndSubclass(String entityId) {
+
+        Expression qualifier = qualifierForEntityAndSubclasses();
+        if (qualifier == null) {
+            return null;
+        }
+
+        // TODO: andrus 1/6/2008 - extremely inefficient, cache inheritance qualifier in
+        // the ClassDescriptor
+
+        // parser only works on full queries, so prepend a dummy query and then strip it
+        // out...
+        String ejbqlChunk = qualifier.toEJBQL(entityId);
+        EJBQLExpression expression = EJBQLParserFactory.getParser().parse(
+                "DELETE FROM DUMMY WHERE " + ejbqlChunk);
+
+        final EJBQLExpression[] result = new EJBQLExpression[1];
+        expression.visit(new EJBQLBaseVisitor() {
+            @Override
+            public boolean visitWhere(EJBQLExpression expression) {
+                result[0] = expression.getChild(0);
+                return false;
+            }
+        });
+        
+        return result[0];
+    }
+
+    /**
+     * Returns the deepest possible entity in the inheritance hierarchy that can be used
+     * to create objects from a given DataRow.
      */
     public ObjEntity entityMatchingRow(DataRow row) {
         // match depth first

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLInheritanceTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLInheritanceTest.java?rev=609363&r1=609362&r2=609363&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLInheritanceTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLInheritanceTest.java Sun Jan  6 10:14:43 2008
@@ -70,15 +70,11 @@
         EJBQLQuery subclass = new EJBQLQuery("select e from Employee e ORDER BY e.name");
 
         List subclassResult = context.performQuery(subclass);
-        // assertEquals(4, subclassResult.size());
-        //
-        // assertEquals(Employee.class.getName(),
-        // subclassResult.get(0).getClass().getName());
-        // assertEquals(Employee.class.getName(),
-        // subclassResult.get(1).getClass().getName());
-        // assertEquals(Manager.class.getName(),
-        // subclassResult.get(2).getClass().getName());
-        // assertEquals(Manager.class.getName(),
-        // subclassResult.get(3).getClass().getName());
+         assertEquals(4, subclassResult.size());
+
+        assertEquals(Employee.class.getName(), subclassResult.get(0).getClass().getName());
+        assertEquals(Employee.class.getName(), subclassResult.get(1).getClass().getName());
+        assertEquals(Manager.class.getName(), subclassResult.get(2).getClass().getName());
+        assertEquals(Manager.class.getName(), subclassResult.get(3).getClass().getName());
     }
 }