Author: norman
Date: Wed Jun 30 11:13:13 2010
New Revision: 959263

URL: http://svn.apache.org/viewvc?rev=959263&view=rev
Log:
Some more query improvements

Modified:
    
james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMessageMapper.java
    
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/mail/JPAMessageMapper.java

Modified: 
james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMessageMapper.java
URL: 
http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMessageMapper.java?rev=959263&r1=959262&r2=959263&view=diff
==============================================================================
--- 
james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMessageMapper.java
 (original)
+++ 
james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/mail/JCRMessageMapper.java
 Wed Jun 30 11:13:13 2010
@@ -519,10 +519,9 @@ public class JCRMessageMapper extends Ab
     public List<MailboxMembership<String>> searchMailbox(String uuid, 
SearchQuery query) throws StorageException {
         try {
             List<MailboxMembership<String>> list = new 
ArrayList<MailboxMembership<String>>();
-            final String xpathQuery = formulateXPath(uuid, query);
+            final Query xQuery = formulateXPath(uuid, query);
             
-            QueryManager manager = 
getSession().getWorkspace().getQueryManager();
-            QueryResult result = manager.createQuery(xpathQuery, 
Query.XPATH).execute();
+            QueryResult result = xQuery.execute();
             
             NodeIterator it = result.getNodes();
             while (it.hasNext()) {
@@ -543,18 +542,18 @@ public class JCRMessageMapper extends Ab
      * @throws RepositoryException 
      * @throws ItemNotFoundException 
      */
-    private String formulateXPath(String uuid, SearchQuery query) throws 
ItemNotFoundException, RepositoryException {
+    private Query formulateXPath(String uuid, SearchQuery query) throws 
ItemNotFoundException, RepositoryException {
         final StringBuilder queryBuilder = new StringBuilder();
         queryBuilder.append("/jcr:root" + getMailboxPath(uuid) + 
"//element(*,jamesMailbox:message)");
         final List<Criterion> criteria = query.getCriterias();
-        boolean crit = false;
         boolean range = false;
+        int rangeLength = -1;
         if (criteria.size() == 1) {
             final Criterion firstCriterion = criteria.get(0);
             if (firstCriterion instanceof SearchQuery.UidCriterion) {
                 final SearchQuery.UidCriterion uidCriterion = 
(SearchQuery.UidCriterion) firstCriterion;
                 final NumericRange[] ranges = 
uidCriterion.getOperator().getRange();
-                crit = ranges.length > 0;
+                rangeLength = ranges.length;
                 for (int i = 0; i < ranges.length; i++) {
                     final long low = ranges[i].getLowValue();
                     final long high = ranges[i].getHighValue();
@@ -576,13 +575,20 @@ public class JCRMessageMapper extends Ab
                 }
             }
         }
-        if (crit) queryBuilder.append("]");
+        if (rangeLength > 0) queryBuilder.append("]");
         
-        if (crit == false || (crit && range)) {
+        if (rangeLength != 0 || range) {
             queryBuilder.append(" order by @" + JCRMessage.UID_PROPERTY);
         }
-        final String jql = queryBuilder.toString();
-        return jql;
+        
+        QueryManager manager = getSession().getWorkspace().getQueryManager();
+        Query xQuery = manager.createQuery(queryBuilder.toString(), 
Query.XPATH);
+        
+        // Check if we only need to fetch 1 message, if so we can set a limit 
to speed up things
+        if (rangeLength == 1 && range == false) {
+            xQuery.setLimit(1);
+        }
+        return xQuery;
     }
     
     /*

Modified: 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/mail/JPAMessageMapper.java
URL: 
http://svn.apache.org/viewvc/james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/mail/JPAMessageMapper.java?rev=959263&r1=959262&r2=959263&view=diff
==============================================================================
--- 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/mail/JPAMessageMapper.java
 (original)
+++ 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/mail/JPAMessageMapper.java
 Wed Jun 30 11:13:13 2010
@@ -191,38 +191,55 @@ public class JPAMessageMapper extends JP
     @SuppressWarnings("unchecked")
     public List<MailboxMembership<Long>> searchMailbox(Long mailboxId, 
SearchQuery query) throws StorageException {
         try {
-            final String jql = formulateJQL(mailboxId, query);
-            return getEntityManager().createQuery(jql).getResultList();
+            final Query jQuery = formulateJQL(mailboxId, query);
+            return jQuery.getResultList();
         } catch (PersistenceException e) {
             throw new StorageException(HumanReadableText.SEARCH_FAILED, e);
         }
     }
 
-    private String formulateJQL(Long mailboxId, SearchQuery query) {
+    private Query formulateJQL(Long mailboxId, SearchQuery query) {
         final StringBuilder queryBuilder = new StringBuilder(50);
         queryBuilder.append("SELECT membership FROM Membership membership 
WHERE membership.mailboxId = ").append(mailboxId);
         final List<Criterion> criteria = query.getCriterias();
+        boolean range = false;
+        int rangeLength = -1;
+        
         if (criteria.size() == 1) {
             final Criterion firstCriterion = criteria.get(0);
             if (firstCriterion instanceof SearchQuery.UidCriterion) {
                 final SearchQuery.UidCriterion uidCriterion = 
(SearchQuery.UidCriterion) firstCriterion;
                 final NumericRange[] ranges = 
uidCriterion.getOperator().getRange();
+                rangeLength = ranges.length;
+
                 for (int i = 0; i < ranges.length; i++) {
                     final long low = ranges[i].getLowValue();
                     final long high = ranges[i].getHighValue();
 
                     if (low == Long.MAX_VALUE) {
                         queryBuilder.append(" AND 
membership.uid<=").append(high);
+                        range = true;
                     } else if (low == high) {
                         queryBuilder.append(" AND 
membership.uid=").append(low);
+                        range = false;
                     } else {
                         queryBuilder.append(" AND membership.uid BETWEEN 
").append(low).append(" AND ").append(high);
+                        range = true;
                     }
                 }
             }
+        }        
+        if (rangeLength != 0 || range) {
+            queryBuilder.append(" order by membership.uid");
+        }
+        
+        Query jQuery = getEntityManager().createQuery(queryBuilder.toString());
+
+        // Check if we only need to fetch 1 message, if so we can set a limit 
to speed up things
+        if (rangeLength == 1 && range == false) {
+            jQuery.setMaxResults(1);
         }
-        final String jql = queryBuilder.toString();
-        return jql;
+        return jQuery;
     }
 
     /*



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to