[seam-commits] Seam SVN: r9321 - in trunk/src: test/unit/org/jboss/seam/test/unit and 1 other directory.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Tue Oct 14 18:56:40 EDT 2008


Author: dan.j.allen
Date: 2008-10-14 18:56:40 -0400 (Tue, 14 Oct 2008)
New Revision: 9321

Added:
   trunk/src/test/unit/org/jboss/seam/test/unit/QueryTest.java
Modified:
   trunk/src/main/org/jboss/seam/framework/Query.java
Log:
When creating the count query, replace any "join fetch" operator with "join"
lay the foundation for a JPA-compliant count query, but leave disabled


Modified: trunk/src/main/org/jboss/seam/framework/Query.java
===================================================================
--- trunk/src/main/org/jboss/seam/framework/Query.java	2008-10-14 22:52:15 UTC (rev 9320)
+++ trunk/src/main/org/jboss/seam/framework/Query.java	2008-10-14 22:56:40 UTC (rev 9321)
@@ -28,6 +28,7 @@
 public abstract class Query<T, E> 
       extends PersistenceController<T> //TODO: extend MutableController!
 {
+   private static final Pattern SUBJECT_PATTERN = Pattern.compile("^select (\\w+(\\.\\w+)*)\\s+from", Pattern.CASE_INSENSITIVE);
    private static final Pattern FROM_PATTERN = Pattern.compile("(^|\\s)(from)\\s",       Pattern.CASE_INSENSITIVE);
    private static final Pattern WHERE_PATTERN = Pattern.compile("\\s(where)\\s",         Pattern.CASE_INSENSITIVE);
    private static final Pattern ORDER_PATTERN = Pattern.compile("\\s(order)(\\s)+by\\s", Pattern.CASE_INSENSITIVE);
@@ -283,11 +284,25 @@
          throw new IllegalArgumentException("no from clause found in query");
       }
       int fromLoc = fromMatcher.start(2);
-      
+
       Matcher orderMatcher = ORDER_PATTERN.matcher(ejbql);
       int orderLoc = orderMatcher.find() ? orderMatcher.start(1) : ejbql.length();
 
-      return "select count(*) " + ejbql.substring(fromLoc, orderLoc);
+      Matcher whereMatcher = WHERE_PATTERN.matcher(ejbql);
+      int whereLoc = whereMatcher.find() ? whereMatcher.start(1) : orderLoc;
+
+      String subject = "*";
+      // TODO to be JPA-compliant, we need to make this query like "select count(u) from User u"
+      // however, Hibernate produces queries some databases cannot run when the primary key is composite
+//      Matcher subjectMatcher = SUBJECT_PATTERN.matcher(ejbql);
+//      if ( subjectMatcher.find() )
+//      {
+//         subject = subjectMatcher.group(1);
+//      }
+      
+      return new StringBuilder(ejbql.length() + 15).append("select count(").append(subject).append(") ").
+         append(ejbql.substring(fromLoc, whereLoc).replace("join fetch", "join")).
+         append(ejbql.substring(whereLoc, orderLoc)).toString().trim();
    }
    
    public String getEjbql()

Added: trunk/src/test/unit/org/jboss/seam/test/unit/QueryTest.java
===================================================================
--- trunk/src/test/unit/org/jboss/seam/test/unit/QueryTest.java	                        (rev 0)
+++ trunk/src/test/unit/org/jboss/seam/test/unit/QueryTest.java	2008-10-14 22:56:40 UTC (rev 9321)
@@ -0,0 +1,67 @@
+package org.jboss.seam.test.unit;
+
+import org.jboss.seam.framework.EntityQuery;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+public class QueryTest
+{
+   /**
+    * These tests verify that the count query is properly extracted from the rendered
+    * query. There are two points of focus. The first is that "join fetch" is replaced
+    * with "join" in the where clause. The second is that the subject of the query is
+    * used in the count() function unless the query does not have an explicit subject,
+    * in which case a * is used instead.
+    */
+   @Test
+   public void testCountQuery() {
+      UnitQuery query = new UnitQuery();
+      query.setEjbql("from Person p");
+      query.parseEjbql();
+      assertEquals(query.getCountEjbql(), "select count(*) from Person p");
+      
+      query.setEjbql("from Person p where p.location is not null");
+      query.setOrderColumn("username");
+      query.parseEjbql();
+      assertEquals(query.getCountEjbql(), "select count(*) from Person p where p.location is not null");
+      
+      query.setEjbql("select p from Person p");
+      query.setOrderColumn("username");
+      query.parseEjbql();
+      // TODO this should eventually become count(p)
+      assertEquals(query.getCountEjbql(), "select count(*) from Person p");
+      
+      query.setEjbql("select v from Vehicle v join fetch v.person");
+      query.setOrderColumn("make");
+      query.parseEjbql();
+      // TODO this should eventually become count(v)
+      assertEquals(query.getCountEjbql(), "select count(*) from Vehicle v join v.person");
+      
+      query.setEjbql("select v.person from Vehicle v left join fetch v.person");
+      query.parseEjbql();
+      // TODO this should eventually become count(v.person)
+      assertEquals(query.getCountEjbql(), "select count(*) from Vehicle v left join v.person");
+   }
+
+   class UnitQuery extends EntityQuery {
+
+      @Override
+      protected void parseEjbql()
+      {
+         super.parseEjbql();
+      }
+
+      @Override
+      protected String getRenderedEjbql()
+      {
+         return super.getRenderedEjbql();
+      }
+
+      @Override
+      protected String getCountEjbql()
+      {
+         return super.getCountEjbql();
+      }
+      
+   }
+}




More information about the seam-commits mailing list