cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aadamc...@apache.org
Subject svn commit: r902926 - in /cayenne/main/branches/STABLE-3.0: docs/doc/src/main/resources/ framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/ framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/ fr...
Date Mon, 25 Jan 2010 19:00:19 GMT
Author: aadamchik
Date: Mon Jan 25 19:00:19 2010
New Revision: 902926

URL: http://svn.apache.org/viewvc?rev=902926&view=rev
Log:
CAY-1367 EJBQL: Implement support for relationship-ending paths in GROUP BY clause

patch by Ksenia Khailenko
(I changed the code cloning result arrays as this may cause preformance degradation on the
large lists)

(cherry picked from commit d30557a96231579b717ca6d757692c1963fe0c41)

Modified:
    cayenne/main/branches/STABLE-3.0/docs/doc/src/main/resources/RELEASE-NOTES.txt
    cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataRowStore.java
    cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/ObjectResolver.java
    cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLAggregateColumnTranslator.java
    cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLGroupByTranslator.java
    cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/Compiler.java
    cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLGroupByHavingTest.java
    cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/test/resources/dml/access.DataContextEJBQLGroupByHavingTest.xml

Modified: cayenne/main/branches/STABLE-3.0/docs/doc/src/main/resources/RELEASE-NOTES.txt
URL: http://svn.apache.org/viewvc/cayenne/main/branches/STABLE-3.0/docs/doc/src/main/resources/RELEASE-NOTES.txt?rev=902926&r1=902925&r2=902926&view=diff
==============================================================================
--- cayenne/main/branches/STABLE-3.0/docs/doc/src/main/resources/RELEASE-NOTES.txt (original)
+++ cayenne/main/branches/STABLE-3.0/docs/doc/src/main/resources/RELEASE-NOTES.txt Mon Jan
25 19:00:19 2010
@@ -31,6 +31,7 @@
 CAY-1355 Warning if rename Embeddable.
 CAY-1361 SelectQuery.aliasPathSplits does nothing
 CAY-1365 "= NULL" being used instead of "IS NULL" on an EJBQL expression..
+CAY-1367 EJBQL: Implement support for relationship-ending paths in GROUP BY clause
 CAY-1368 Left Join and Prefetches do not work together
 CAY-1369 EJBQL: Fix likeIgnoreCase issues
 

Modified: cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataRowStore.java
URL: http://svn.apache.org/viewvc/cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataRowStore.java?rev=902926&r1=902925&r2=902926&view=diff
==============================================================================
--- cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataRowStore.java
(original)
+++ cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataRowStore.java
Mon Jan 25 19:00:19 2010
@@ -233,6 +233,11 @@
         synchronized (this) {
             for (int i = 0; i < size; i++) {
                 Persistent object = (Persistent) objects.get(i);
+                
+                // skip null objects... possible since 3.0 in some EJBQL results
+                if (object == null) {
+                    continue;
+                }
 
                 // skip HOLLOW objects as they likely were created from partial snapshots
                 if (object.getPersistenceState() == PersistenceState.HOLLOW) {

Modified: cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/ObjectResolver.java
URL: http://svn.apache.org/viewvc/cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/ObjectResolver.java?rev=902926&r1=902925&r2=902926&view=diff
==============================================================================
--- cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/ObjectResolver.java
(original)
+++ cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/ObjectResolver.java
Mon Jan 25 19:00:19 2010
@@ -108,21 +108,13 @@
         }
 
         List<Persistent> results = new ArrayList<Persistent>(rows.size());
-
         for (DataRow row : rows) {
-
-            Persistent object = objectFromDataRow(row);
-
-            if (object == null) {
-                throw new CayenneRuntimeException("Can't build Object from row: " + row);
-            }
-
-            results.add(object);
+            // nulls are possible here since 3.0 for soem varieties of EJBQL
+            results.add(objectFromDataRow(row));
         }
 
         // now deal with snapshots
         cache.snapshotsUpdatedForObjects(results, rows, refreshObjects);
-
         return results;
     }
 

Modified: cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLAggregateColumnTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLAggregateColumnTranslator.java?rev=902926&r1=902925&r2=902926&view=diff
==============================================================================
--- cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLAggregateColumnTranslator.java
(original)
+++ cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLAggregateColumnTranslator.java
Mon Jan 25 19:00:19 2010
@@ -18,13 +18,21 @@
  ****************************************************************/
 package org.apache.cayenne.access.jdbc;
 
+import java.util.Collection;
+import java.util.Iterator;
+
 import org.apache.cayenne.ejbql.EJBQLBaseVisitor;
 import org.apache.cayenne.ejbql.EJBQLException;
 import org.apache.cayenne.ejbql.EJBQLExpression;
 import org.apache.cayenne.ejbql.EJBQLExpressionVisitor;
 import org.apache.cayenne.ejbql.parser.EJBQLAggregateColumn;
+import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.DbRelationship;
 import org.apache.cayenne.map.ObjAttribute;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.map.ObjRelationship;
+import org.apache.cayenne.reflect.ClassDescriptor;
 
 /**
  * @since 3.0
@@ -116,13 +124,45 @@
         protected void processTerminatingAttribute(ObjAttribute attribute) {
 
             EJBQLAggregateColumnTranslator.this.attributeType = attribute.getType();
-
+            
             DbEntity table = currentEntity.getDbEntity();
             String alias = this.lastAlias != null ? lastAlias : context.getTableAlias(
                     idPath,
                     table.getFullyQualifiedName());
             context.append(alias).append('.').append(attribute.getDbAttributeName());
         }
+        @Override
+        public boolean visitIdentificationVariable(EJBQLExpression expression) {
+
+            String idVariableAbsolutePath = idPath+"."+expression.getText();
+            ClassDescriptor descriptor = context.getEntityDescriptor(idVariableAbsolutePath);
+            if (descriptor != null) {
+                this.lastAlias = context.getTableAlias(idVariableAbsolutePath, descriptor.getEntity().getDbEntityName());
+            }
+
+            this.lastPathComponent = expression.getText();
+            
+            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();
+
+            if (dbAttr.size() > 0) {
+                this.resolveJoin(false);
+            }
+
+            String alias = this.lastAlias != null ? lastAlias : context
+                    .getTableAlias(idPath, table.getFullyQualifiedName());
+
+            context.append(alias).append(".*");
+        }
     }
 
     class CountColumnVisitor extends EJBQLBaseVisitor {

Modified: cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLGroupByTranslator.java
URL: http://svn.apache.org/viewvc/cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLGroupByTranslator.java?rev=902926&r1=902925&r2=902926&view=diff
==============================================================================
--- cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLGroupByTranslator.java
(original)
+++ cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/EJBQLGroupByTranslator.java
Mon Jan 25 19:00:19 2010
@@ -18,10 +18,19 @@
  ****************************************************************/
 package org.apache.cayenne.access.jdbc;
 
+import java.util.Collection;
+import java.util.Iterator;
+
 import org.apache.cayenne.ejbql.EJBQLBaseVisitor;
 import org.apache.cayenne.ejbql.EJBQLException;
 import org.apache.cayenne.ejbql.EJBQLExpression;
 import org.apache.cayenne.ejbql.EJBQLExpressionVisitor;
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.DbRelationship;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.map.ObjRelationship;
+import org.apache.cayenne.reflect.ClassDescriptor;
 
 /**
  * @since 3.0
@@ -60,8 +69,54 @@
                 throw new EJBQLException(
                         "Can't GROUP BY on multi-column paths or objects");
             }
+            
+            @Override
+            public boolean visitIdentificationVariable(EJBQLExpression expression) {
+
+                String idVariableAbsolutePath = idPath+"."+expression.getText();
+                ClassDescriptor descriptor = context.getEntityDescriptor(idVariableAbsolutePath);
+                if (descriptor != null) {
+                    this.lastAlias = context.getTableAlias(idVariableAbsolutePath, descriptor.getEntity().getDbEntityName());
+                }
+
+                this.lastPathComponent = expression.getText();
+                
+                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, table.getFullyQualifiedName());
+
+                boolean first = true;
+                while (it.hasNext()) {
+
+                    context.append(!first ? ", " : " ");
+
+                    DbAttribute dbAttribute = it.next();
+                    context.append(alias).append('.').append(dbAttribute.getName());
+
+                    first = false;
+                }
+
+            }
+            
         };
+       
         expression.visit(childVisitor);
+        
         return false;
     }
 }

Modified: cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/Compiler.java
URL: http://svn.apache.org/viewvc/cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/Compiler.java?rev=902926&r1=902925&r2=902926&view=diff
==============================================================================
--- cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/Compiler.java
(original)
+++ cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/ejbql/parser/Compiler.java
Mon Jan 25 19:00:19 2010
@@ -606,9 +606,10 @@
         @Override
         public boolean visitAggregate(EJBQLExpression expression) {
             addResultSetColumn();
+            expression.getChild(0).getChild(0).visit(pathVisitor);
             return false;
         }
-
+        
         @Override
         public boolean visitPath(EJBQLExpression expression, int finishedChildIndex) {
             addPath((EJBQLPath) expression);

Modified: cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLGroupByHavingTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLGroupByHavingTest.java?rev=902926&r1=902925&r2=902926&view=diff
==============================================================================
--- cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLGroupByHavingTest.java
(original)
+++ cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextEJBQLGroupByHavingTest.java
Mon Jan 25 19:00:19 2010
@@ -19,9 +19,14 @@
 package org.apache.cayenne.access;
 
 import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.apache.art.Artist;
+import org.apache.art.Gallery;
 import org.apache.cayenne.query.EJBQLQuery;
 import org.apache.cayenne.unit.CayenneCase;
 
@@ -171,4 +176,64 @@
         assertEquals(new BigDecimal(1d), row0[0], 0.001d);
         assertEquals(new Long(3l), row0[1]);
     }
+    
+    public void testGroupByJoinedRelatedEntities() throws Exception {
+        createTestData("testGroupByRelatedEntity");
+        EJBQLQuery query = new EJBQLQuery(
+                "SELECT COUNT(p), p.toArtist FROM Painting p GROUP BY p.toArtist ");
+        List<Object[]> data = createDataContext().performQuery(query);
+        assertNotNull(data);
+        assertEquals(2, data.size());
+        
+        List<String> expectedArtists=new ArrayList<String>();
+        expectedArtists.add("AA1");
+        expectedArtists.add("AA2");
+        
+        Object[]row = data.get(0);
+        String artistName = ((Artist)row[1]).getArtistName();
+        assertEquals(1L, row[0]);
+        assertTrue("error artistName:"+artistName, expectedArtists.contains(artistName));
+        
+        row = data.get(1);
+        artistName = ((Artist)row[1]).getArtistName();
+        assertEquals(1L, row[0]);
+        assertTrue("error artistName:"+artistName, expectedArtists.contains(artistName));
+    }
+
+    public void testGroupByJoinedEntities() throws Exception {
+        createTestData("testGroupByEntities");
+        EJBQLQuery query = new EJBQLQuery(
+                "SELECT COUNT(p), p.toArtist, p.toGallery FROM Painting p " +
+                "GROUP BY p.toGallery, p.toArtist ");
+        List<Object[]> data = createDataContext().performQuery(query);
+        assertNotNull(data);
+        assertEquals(5, data.size());
+        
+        HashSet<List> expectedResults=new HashSet<List>();
+        expectedResults.add(Arrays.asList(3L, null,null));
+        expectedResults.add(Arrays.asList(1L, "AA1",null));
+        expectedResults.add(Arrays.asList(1L, "AA2",null));
+        expectedResults.add(Arrays.asList(1L, "AA2","gallery1"));
+        expectedResults.add(Arrays.asList(1L, "AA1","gallery2"));
+        
+        for(Object[] row:data){
+            assertFalse(expectedResults.add(Arrays.asList(
+                    row[0], 
+                    row[1]==null?null:((Artist)row[1]).getArtistName(),
+                    row[2]==null?null:((Gallery)row[2]).getGalleryName())));
+        }
+    }
+
+    public void testGroupByJoinedEntityInCount() throws Exception {
+        createTestData("testGroupByEntities");
+        EJBQLQuery query = new EJBQLQuery(
+                "SELECT COUNT(p.toArtist) FROM Painting p GROUP BY p.toArtist");
+        List<Long> data = createDataContext().performQuery(query);
+        assertNotNull(data);
+        assertEquals(3, data.size());
+        for(Long result:data){
+            assertTrue(result==3L||result==2L);
+        }
+    }
+    
 }

Modified: cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/test/resources/dml/access.DataContextEJBQLGroupByHavingTest.xml
URL: http://svn.apache.org/viewvc/cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/test/resources/dml/access.DataContextEJBQLGroupByHavingTest.xml?rev=902926&r1=902925&r2=902926&view=diff
==============================================================================
--- cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/test/resources/dml/access.DataContextEJBQLGroupByHavingTest.xml
(original)
+++ cayenne/main/branches/STABLE-3.0/framework/cayenne-jdk1.5-unpublished/src/test/resources/dml/access.DataContextEJBQLGroupByHavingTest.xml
Mon Jan 25 19:00:19 2010
@@ -83,6 +83,44 @@
 		</value></constructor-arg>
 	</bean>
 
+
+	<bean id="P111" class="org.apache.cayenne.unit.util.UpdatingSQLTemplate">
+		<constructor-arg type="java.lang.Class">
+			<value>org.apache.art.Painting</value>
+		</constructor-arg>
+		<constructor-arg>
+			<value>
+				INSERT INTO PAINTING (PAINTING_ID, GALLERY_ID, PAINTING_TITLE, ARTIST_ID, ESTIMATED_PRICE)
+				VALUES (33009, 33001, 'P111', 33002, 5000)
+			</value>
+		</constructor-arg>
+	</bean>
+	
+	<bean id="P112" class="org.apache.cayenne.unit.util.UpdatingSQLTemplate">
+		<constructor-arg type="java.lang.Class">
+			<value>org.apache.art.Painting</value>
+		</constructor-arg>
+		<constructor-arg>
+			<value>
+				INSERT INTO PAINTING (PAINTING_ID, GALLERY_ID, PAINTING_TITLE, ARTIST_ID, ESTIMATED_PRICE)
+				VALUES (33010, 33002, 'P112', 33001, 5000)
+			</value>
+		</constructor-arg>
+	</bean>
+	
+	<bean id="G1" class="org.apache.cayenne.unit.util.UpdatingSQLTemplate">
+		<constructor-arg type="java.lang.Class"><value>org.apache.art.Gallery</value></constructor-arg>
+		<constructor-arg><value>
+		INSERT INTO GALLERY (GALLERY_ID, GALLERY_NAME) VALUES (33001, 'gallery1')
+		</value></constructor-arg>
+	</bean>
+	
+	<bean id="G2" class="org.apache.cayenne.unit.util.UpdatingSQLTemplate">
+		<constructor-arg type="java.lang.Class"><value>org.apache.art.Gallery</value></constructor-arg>
+		<constructor-arg><value>
+		INSERT INTO GALLERY (GALLERY_ID, GALLERY_NAME) VALUES (33002, 'gallery2')
+		</value></constructor-arg>
+	</bean>
 	<!-- ======================================= -->
 	<!-- Data Sets -->
 	<!-- ======================================= -->	
@@ -111,4 +149,24 @@
 			</list>
 		</constructor-arg>
 	</bean>
+	
+	<bean id="testGroupByEntities" class="java.util.ArrayList">
+		<constructor-arg>
+			<list>
+				<ref bean="A1"/>
+				<ref bean="A2"/>
+				<ref bean="A3"/>
+				<ref bean="A4"/>
+				<ref bean="P1"/>
+				<ref bean="P2"/>
+				<ref bean="P3"/>
+				<ref bean="P11"/>
+				<ref bean="P12"/>
+				<ref bean="G1"/>
+				<ref bean="G2"/>
+				<ref bean="P111"/>
+				<ref bean="P112"/>
+			</list>
+		</constructor-arg>
+	</bean>
 </beans>
\ No newline at end of file



Mime
View raw message