[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