You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ch...@apache.org on 2012/10/15 22:29:47 UTC

[4/50] [abbrv] CLOUDSTACK-332: intermediate checkin fixing count parameter in listCommands Fixes the count in commands:

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2855a3d6/server/src/com/cloud/tags/TaggedResourceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java
index db32f2c..237a677 100644
--- a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java
+++ b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java
@@ -322,7 +322,7 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager
     }
 
     @Override
-    public List<? extends ResourceTag> listTags(ListTagsCmd cmd) {
+    public Pair<List<? extends ResourceTag>, Integer> listTags(ListTagsCmd cmd) {
         Account caller = UserContext.current().getCaller();
         List<Long> permittedAccounts = new ArrayList<Long>();
         String key = cmd.getKey();
@@ -334,54 +334,56 @@ public class TaggedResourceManagerImpl implements TaggedResourceService, Manager
 
         Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = 
                 new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
-       _accountMgr.buildACLSearchParameters(caller, null, cmd.getAccountName(), 
-               cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll, false);
-           Long domainId = domainIdRecursiveListProject.first();
-       Boolean isRecursive = domainIdRecursiveListProject.second();
-       ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
-       Filter searchFilter = new Filter(ResourceTagVO.class, "resourceType", false, cmd.getStartIndex(), cmd.getPageSizeVal());
-       
-       SearchBuilder<ResourceTagVO> sb = _resourceTagDao.createSearchBuilder();
-       _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
 
-       sb.and("key", sb.entity().getKey(), SearchCriteria.Op.EQ);
-       sb.and("value", sb.entity().getValue(), SearchCriteria.Op.EQ);
-       
-       if (resourceId != null) {
-       sb.and().op("resourceId", sb.entity().getResourceId(), SearchCriteria.Op.EQ);
-       sb.or("resourceUuid", sb.entity().getResourceUuid(), SearchCriteria.Op.EQ);
-       sb.cp();
-       }
-       
-       sb.and("resourceType", sb.entity().getResourceType(), SearchCriteria.Op.EQ);
-       sb.and("customer", sb.entity().getCustomer(), SearchCriteria.Op.EQ);
-       
-       // now set the SC criteria...
-       SearchCriteria<ResourceTagVO> sc = sb.create();
-       _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
-       
-       if (key != null) {
-           sc.setParameters("key", key);
-       }
-       
-       if (value != null) {
-           sc.setParameters("value", value);
-       }
-       
-       if (resourceId != null) {
-           sc.setParameters("resourceId", resourceId);
-           sc.setParameters("resourceUuid", resourceId);
-       }
-       
-       if (resourceType != null) {
-           sc.setParameters("resourceType", resourceType);
-       }
-       
-       if (customerName != null) {
-           sc.setParameters("customer", customerName);
-       }
-       
-       return _resourceTagDao.search(sc, searchFilter);
+        _accountMgr.buildACLSearchParameters(caller, null, cmd.getAccountName(),
+                cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll, false);
+        Long domainId = domainIdRecursiveListProject.first();
+        Boolean isRecursive = domainIdRecursiveListProject.second();
+        ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
+        Filter searchFilter = new Filter(ResourceTagVO.class, "resourceType", false, cmd.getStartIndex(), cmd.getPageSizeVal());
+
+        SearchBuilder<ResourceTagVO> sb = _resourceTagDao.createSearchBuilder();
+        _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        sb.and("key", sb.entity().getKey(), SearchCriteria.Op.EQ);
+        sb.and("value", sb.entity().getValue(), SearchCriteria.Op.EQ);
+
+        if (resourceId != null) {
+            sb.and().op("resourceId", sb.entity().getResourceId(), SearchCriteria.Op.EQ);
+            sb.or("resourceUuid", sb.entity().getResourceUuid(), SearchCriteria.Op.EQ);
+            sb.cp();
+        }
+
+        sb.and("resourceType", sb.entity().getResourceType(), SearchCriteria.Op.EQ);
+        sb.and("customer", sb.entity().getCustomer(), SearchCriteria.Op.EQ);
+
+        // now set the SC criteria...
+        SearchCriteria<ResourceTagVO> sc = sb.create();
+        _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+
+        if (key != null) {
+            sc.setParameters("key", key);
+        }
+
+        if (value != null) {
+            sc.setParameters("value", value);
+        }
+
+        if (resourceId != null) {
+            sc.setParameters("resourceId", resourceId);
+            sc.setParameters("resourceUuid", resourceId);
+        }
+
+        if (resourceType != null) {
+            sc.setParameters("resourceType", resourceType);
+        }
+
+        if (customerName != null) {
+            sc.setParameters("customer", customerName);
+        }
+
+        Pair<List<ResourceTagVO>, Integer> result = _resourceTagDao.searchAndCount(sc, searchFilter);
+        return new Pair<List<? extends ResourceTag>, Integer> (result.first(), result.second());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2855a3d6/server/src/com/cloud/user/AccountManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java
index dcca74e..62d21be 100755
--- a/server/src/com/cloud/user/AccountManagerImpl.java
+++ b/server/src/com/cloud/user/AccountManagerImpl.java
@@ -1980,7 +1980,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag
     }
 
     @Override
-    public List<AccountVO> searchForAccounts(ListAccountsCmd cmd) {
+    public Pair<List<? extends Account>, Integer> searchForAccounts(ListAccountsCmd cmd) {
         Account caller = UserContext.current().getCaller();
         Long domainId = cmd.getDomainId();
         Long accountId = cmd.getId();
@@ -2095,11 +2095,12 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag
             }
         }
 
-        return _accountDao.search(sc, searchFilter);
+        Pair<List<AccountVO>, Integer> result = _accountDao.searchAndCount(sc, searchFilter);
+        return new Pair<List<? extends Account>, Integer>(result.first(), result.second());
     }
 
     @Override
-    public List<UserAccountVO> searchForUsers(ListUsersCmd cmd) throws PermissionDeniedException {
+    public Pair<List<? extends UserAccount>, Integer> searchForUsers(ListUsersCmd cmd) throws PermissionDeniedException {
         Account caller = UserContext.current().getCaller();
 
         Long domainId = cmd.getDomainId();
@@ -2129,7 +2130,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag
         if (id != null && id == 1) {
             // system user should NOT be searchable
             List<UserAccountVO> emptyList = new ArrayList<UserAccountVO>();
-            return emptyList;
+            return new Pair<List<? extends UserAccount>, Integer>(emptyList, 0);
         } else if (id != null) {
             sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
         } else {
@@ -2192,7 +2193,8 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag
             sc.setParameters("state", state);
         }
 
-        return _userAccountDao.search(sc, searchFilter);
+        Pair<List<UserAccountVO>, Integer> result = _userAccountDao.searchAndCount(sc, searchFilter);
+        return new Pair<List<? extends UserAccount>, Integer>(result.first(), result.second());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2855a3d6/server/src/com/cloud/user/DomainManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/user/DomainManagerImpl.java b/server/src/com/cloud/user/DomainManagerImpl.java
index 8905be0..c234616 100644
--- a/server/src/com/cloud/user/DomainManagerImpl.java
+++ b/server/src/com/cloud/user/DomainManagerImpl.java
@@ -47,6 +47,7 @@ import com.cloud.service.dao.ServiceOfferingDao;
 import com.cloud.storage.DiskOfferingVO;
 import com.cloud.storage.dao.DiskOfferingDao;
 import com.cloud.user.dao.AccountDao;
+import com.cloud.utils.Pair;
 import com.cloud.utils.component.Inject;
 import com.cloud.utils.component.Manager;
 import com.cloud.utils.db.DB;
@@ -349,7 +350,7 @@ public class DomainManagerImpl implements DomainManager, DomainService, Manager
     }
 
     @Override
-    public List<DomainVO> searchForDomains(ListDomainsCmd cmd) {
+    public Pair<List<? extends Domain>, Integer> searchForDomains(ListDomainsCmd cmd) {
         Account caller = UserContext.current().getCaller();
         Long domainId = cmd.getId();
         boolean listAll = cmd.listAll();
@@ -407,11 +408,12 @@ public class DomainManagerImpl implements DomainManager, DomainService, Manager
         // return only Active domains to the API
         sc.setParameters("state", Domain.State.Active);
 
-        return _domainDao.search(sc, searchFilter);
+        Pair<List<DomainVO>, Integer> result = _domainDao.searchAndCount(sc, searchFilter);
+        return new Pair<List<? extends Domain>, Integer>(result.first(), result.second());
     }
 
     @Override
-    public List<DomainVO> searchForDomainChildren(ListDomainChildrenCmd cmd) throws PermissionDeniedException {
+    public Pair<List<? extends Domain>, Integer> searchForDomainChildren(ListDomainChildrenCmd cmd) throws PermissionDeniedException {
         Long domainId = cmd.getId();
         String domainName = cmd.getDomainName();
         Boolean isRecursive = cmd.isRecursive();
@@ -433,12 +435,12 @@ public class DomainManagerImpl implements DomainManager, DomainService, Manager
         }
 
         Filter searchFilter = new Filter(DomainVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
-        List<DomainVO> domainList = searchForDomainChildren(searchFilter, domainId, domainName, keyword, path, true);
+        Pair<List<DomainVO>, Integer> result = searchForDomainChildren(searchFilter, domainId, domainName, keyword, path, true);
 
-        return domainList;
+        return new Pair<List<? extends Domain>, Integer>(result.first(), result.second());
     }
 
-    private List<DomainVO> searchForDomainChildren(Filter searchFilter, Long domainId, String domainName, Object keyword, String path, boolean listActiveOnly) {
+    private Pair<List<DomainVO>, Integer> searchForDomainChildren(Filter searchFilter, Long domainId, String domainName, Object keyword, String path, boolean listActiveOnly) {
         SearchCriteria<DomainVO> sc = _domainDao.createSearchCriteria();
 
         if (keyword != null) {
@@ -465,7 +467,7 @@ public class DomainManagerImpl implements DomainManager, DomainService, Manager
             sc.addAnd("state", SearchCriteria.Op.EQ, Domain.State.Active);
         }
 
-        return _domainDao.search(sc, searchFilter);
+        return _domainDao.searchAndCount(sc, searchFilter);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2855a3d6/server/src/com/cloud/vm/UserVmManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManager.java b/server/src/com/cloud/vm/UserVmManager.java
index 11d2c64..4ce9bfe 100755
--- a/server/src/com/cloud/vm/UserVmManager.java
+++ b/server/src/com/cloud/vm/UserVmManager.java
@@ -96,9 +96,9 @@ public interface UserVmManager extends VirtualMachineGuru<UserVmVO>, UserVmServi
      * @param listAll TODO
      * @param listProjectResourcesCriteria TODO
      * @param tags TODO
-     * @return List of UserVMs.
+     * @return List of UserVMs + count
      */
-    List<UserVmVO> searchForUserVMs(Criteria c, Account caller, Long domainId, boolean isRecursive, List<Long> permittedAccounts, boolean listAll, ListProjectResourcesCriteria listProjectResourcesCriteria, Map<String, String> tags);
+	Pair<List<UserVmVO>, Integer> searchForUserVMs(Criteria c, Account caller, Long domainId, boolean isRecursive, List<Long> permittedAccounts, boolean listAll, ListProjectResourcesCriteria listProjectResourcesCriteria, Map<String, String> tags);
 
     String getChecksum(Long hostId, String templatePath);
     

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2855a3d6/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index dbcbeb8..a2a548f 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -2996,7 +2996,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
     }
 
     @Override
-    public List<UserVmVO> searchForUserVMs(ListVMsCmd cmd) {
+    public Pair<List<? extends UserVm>, Integer> searchForUserVMs(ListVMsCmd cmd) {
         Account caller = UserContext.current().getCaller();
         List<Long> permittedAccounts = new ArrayList<Long>();
         String hypervisor = cmd.getHypervisor();
@@ -3045,11 +3045,13 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
         }
         c.addCriteria(Criteria.ISADMIN, _accountMgr.isAdmin(caller.getType()));
 
-        return searchForUserVMs(c, caller, domainId, isRecursive, permittedAccounts, listAll, listProjectResourcesCriteria, tags);
+        Pair<List<UserVmVO>, Integer> result = searchForUserVMs(c, caller, domainId, isRecursive,
+                permittedAccounts, listAll, listProjectResourcesCriteria, tags);
+        return new Pair<List<? extends UserVm>, Integer>(result.first(), result.second());
     }
 
     @Override
-    public List<UserVmVO> searchForUserVMs(Criteria c, Account caller, Long domainId, boolean isRecursive, 
+    public Pair<List<UserVmVO>, Integer> searchForUserVMs(Criteria c, Account caller, Long domainId, boolean isRecursive, 
             List<Long> permittedAccounts, boolean listAll, ListProjectResourcesCriteria listProjectResourcesCriteria, Map<String, String> tags) {
         Filter searchFilter = new Filter(UserVmVO.class, c.getOrderBy(), c.getAscending(), c.getOffset(), c.getLimit());
 
@@ -3240,7 +3242,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
                     }
                     sc.setParameters("hostIdIN", (Object[]) hostIds);
                 } else {
-                    return new ArrayList<UserVmVO>();
+                    return new Pair<List<UserVmVO>, Integer>(new ArrayList<UserVmVO>(), 0);
                 }
             }
         }
@@ -3248,8 +3250,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
         if (storageId != null) {
             sc.setJoinParameters("volumeSearch", "poolId", storageId);
         }
-        s_logger.debug("THE WHERE CLAUSE IS:" + sc.getWhereClause());
-        return _vmDao.search(sc, searchFilter);
+        
+        return _vmDao.searchAndCount(sc, searchFilter);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2855a3d6/server/test/com/cloud/user/MockAccountManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/user/MockAccountManagerImpl.java b/server/test/com/cloud/user/MockAccountManagerImpl.java
index 0d15cd7..08234fd 100644
--- a/server/test/com/cloud/user/MockAccountManagerImpl.java
+++ b/server/test/com/cloud/user/MockAccountManagerImpl.java
@@ -298,13 +298,13 @@ public class MockAccountManagerImpl implements Manager, AccountManager, AccountS
 	}
 
     @Override
-    public List<? extends Account> searchForAccounts(ListAccountsCmd cmd) {
+    public Pair<List<? extends Account>, Integer> searchForAccounts(ListAccountsCmd cmd) {
         // TODO Auto-generated method stub
         return null;
     }
 
     @Override
-    public List<? extends UserAccount> searchForUsers(ListUsersCmd cmd) throws PermissionDeniedException {
+    public Pair<List<? extends UserAccount>, Integer> searchForUsers(ListUsersCmd cmd) throws PermissionDeniedException {
         // TODO Auto-generated method stub
         return null;
     }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2855a3d6/server/test/com/cloud/user/MockDomainManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/user/MockDomainManagerImpl.java b/server/test/com/cloud/user/MockDomainManagerImpl.java
index e99e4d9..4266f35 100644
--- a/server/test/com/cloud/user/MockDomainManagerImpl.java
+++ b/server/test/com/cloud/user/MockDomainManagerImpl.java
@@ -29,6 +29,7 @@ import com.cloud.domain.Domain;
 import com.cloud.domain.DomainVO;
 import com.cloud.exception.PermissionDeniedException;
 import com.cloud.utils.component.Manager;
+import com.cloud.utils.Pair;
 
 @Local(value = { DomainManager.class })
 public class MockDomainManagerImpl implements  Manager, DomainManager {
@@ -58,14 +59,14 @@ public class MockDomainManagerImpl implements  Manager, DomainManager {
     }
 
     @Override
-    public List<? extends Domain> searchForDomains(ListDomainsCmd cmd)
+    public Pair<List<? extends Domain>, Integer> searchForDomains(ListDomainsCmd cmd)
             throws PermissionDeniedException {
         // TODO Auto-generated method stub
         return null;
     }
 
     @Override
-    public List<? extends Domain> searchForDomainChildren(
+    public Pair<List<? extends Domain>, Integer> searchForDomainChildren(
             ListDomainChildrenCmd cmd) throws PermissionDeniedException {
         // TODO Auto-generated method stub
         return null;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2855a3d6/server/test/com/cloud/vm/MockUserVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vm/MockUserVmManagerImpl.java b/server/test/com/cloud/vm/MockUserVmManagerImpl.java
index efc6916..35ee139 100644
--- a/server/test/com/cloud/vm/MockUserVmManagerImpl.java
+++ b/server/test/com/cloud/vm/MockUserVmManagerImpl.java
@@ -192,7 +192,7 @@ public class MockUserVmManagerImpl implements UserVmManager, UserVmService, Mana
     }
 
     @Override
-    public List<UserVmVO> searchForUserVMs(Criteria c, Account caller, Long domainId, boolean isRecursive, List<Long> permittedAccounts, boolean listAll, ListProjectResourcesCriteria listProjectResourcesCriteria, Map<String, String> tags) {
+    public Pair<List<UserVmVO>, Integer> searchForUserVMs(Criteria c, Account caller, Long domainId, boolean isRecursive, List<Long> permittedAccounts, boolean listAll, ListProjectResourcesCriteria listProjectResourcesCriteria, Map<String, String> tags) {
         // TODO Auto-generated method stub
         return null;
     }
@@ -401,7 +401,7 @@ public class MockUserVmManagerImpl implements UserVmManager, UserVmService, Mana
 	}
 
     @Override
-    public List<? extends UserVm> searchForUserVMs(ListVMsCmd cmd) {
+    public Pair<List<? extends UserVm>, Integer> searchForUserVMs(ListVMsCmd cmd) {
         // TODO Auto-generated method stub
         return null;
     }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2855a3d6/server/test/com/cloud/vpc/MockVpcManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/MockVpcManagerImpl.java b/server/test/com/cloud/vpc/MockVpcManagerImpl.java
index fc10a46..2269339 100644
--- a/server/test/com/cloud/vpc/MockVpcManagerImpl.java
+++ b/server/test/com/cloud/vpc/MockVpcManagerImpl.java
@@ -49,6 +49,7 @@ import com.cloud.network.vpc.VpcService;
 import com.cloud.offering.NetworkOffering;
 import com.cloud.user.Account;
 import com.cloud.user.User;
+import com.cloud.utils.Pair;
 import com.cloud.utils.component.ComponentLocator;
 import com.cloud.utils.component.Manager;
 import com.cloud.vm.DomainRouterVO;
@@ -244,7 +245,7 @@ public class MockVpcManagerImpl implements VpcManager, Manager{
      * @see com.cloud.network.vpc.VpcService#listPrivateGateway(com.cloud.api.commands.ListPrivateGatewaysCmd)
      */
     @Override
-    public List<PrivateGateway> listPrivateGateway(ListPrivateGatewaysCmd listPrivateGatewaysCmd) {
+    public Pair<List<PrivateGateway>, Integer> listPrivateGateway(ListPrivateGatewaysCmd listPrivateGatewaysCmd) {
         // TODO Auto-generated method stub
         return null;
     }
@@ -289,7 +290,7 @@ public class MockVpcManagerImpl implements VpcManager, Manager{
      * @see com.cloud.network.vpc.VpcService#listStaticRoutes(com.cloud.api.commands.ListStaticRoutesCmd)
      */
     @Override
-    public List<? extends StaticRoute> listStaticRoutes(ListStaticRoutesCmd cmd) {
+    public Pair<List<? extends StaticRoute>, Integer> listStaticRoutes(ListStaticRoutesCmd cmd) {
         // TODO Auto-generated method stub
         return null;
     }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2855a3d6/utils/src/com/cloud/utils/db/GenericDao.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/GenericDao.java b/utils/src/com/cloud/utils/db/GenericDao.java
index 3ab319e..f36c4d8 100755
--- a/utils/src/com/cloud/utils/db/GenericDao.java
+++ b/utils/src/com/cloud/utils/db/GenericDao.java
@@ -22,6 +22,8 @@ import java.util.Map;
 
 import javax.naming.ConfigurationException;
 
+import com.cloud.utils.Pair;
+
 /**
  * a uniform method for persisting and finding db entities.
  **/
@@ -260,4 +262,11 @@ public interface GenericDao<T, ID extends Serializable> {
      * @return
      */
     Class<T> getEntityBeanType();
+
+    /**
+     * @param sc
+     * @param filter
+     * @return
+     */
+    Pair<List<T>, Integer> searchAndCount(SearchCriteria<T> sc, Filter filter);
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2855a3d6/utils/src/com/cloud/utils/db/GenericDaoBase.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/GenericDaoBase.java b/utils/src/com/cloud/utils/db/GenericDaoBase.java
index 3df8374..8d5cb96 100755
--- a/utils/src/com/cloud/utils/db/GenericDaoBase.java
+++ b/utils/src/com/cloud/utils/db/GenericDaoBase.java
@@ -130,6 +130,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
     protected StringBuilder _discriminatorClause;
     protected Map<String, Object> _discriminatorValues;
     protected String _selectByIdSql;
+    protected String _count;
 
     protected Field _idField;
 
@@ -201,6 +202,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
 
         final SqlGenerator generator = new SqlGenerator(_entityBeanType);
         _partialSelectSql = generator.buildSelectSql(false);
+        _count = generator.buildCountSql();
         _partialQueryCacheSelectSql = generator.buildSelectSql(true);
         _embeddedFields = generator.getEmbeddedFields();
         _insertSqls = generator.buildInsertSqls();
@@ -1211,6 +1213,13 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
     public List<T> search(final SearchCriteria<T> sc, final Filter filter) {
         return search(sc, filter, null, false);
     }
+    
+    @Override @DB(txn=false)
+    public Pair<List<T>, Integer> searchAndCount(final SearchCriteria<T> sc, final Filter filter) {
+        List<T> objects = search(sc, filter, null, false);
+        Integer count = getCount(sc);
+        return new Pair<List<T>, Integer>(objects, count);
+    }
 
     @Override @DB(txn=false)
     public List<T> search(final SearchCriteria<T> sc, final Filter filter, final boolean enable_query_cache) {
@@ -1769,4 +1778,71 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
         factory.setCallback(0, sc);
         return sc;
     }
+
+    public Integer getCount(SearchCriteria<T> sc) {
+        String clause = sc != null ? sc.getWhereClause() : null;
+        if (clause != null && clause.length() == 0) {
+            clause = null;
+        }
+
+        final StringBuilder str = createCountSelect(sc, clause != null);
+        if (clause != null) {
+            str.append(clause);
+        }
+
+        Collection<JoinBuilder<SearchCriteria<?>>> joins = null;
+        if (sc != null) {
+            joins = sc.getJoins();
+            if (joins != null) {
+                addJoins(str, joins);
+            }
+        }
+
+        List<Object> groupByValues = addGroupBy(str, sc);
+        final Transaction txn = Transaction.currentTxn();
+        final String sql = str.toString();
+
+        PreparedStatement pstmt = null;
+        try {
+            pstmt = txn.prepareAutoCloseStatement(sql);
+            int i = 0;
+            if (clause != null) {
+                for (final Pair<Attribute, Object> value : sc.getValues()) {
+                    prepareAttribute(++i, pstmt, value.first(), value.second());
+                }
+            }
+
+            if (joins != null) {
+                i = addJoinAttributes(i, pstmt, joins);
+            }
+            
+            if (groupByValues != null) {
+                for (Object value : groupByValues) {
+                    pstmt.setObject(i++, value);
+                }
+            }
+
+            final ResultSet rs = pstmt.executeQuery();
+            while (rs.next()) {
+                return rs.getInt(1);
+            }
+            return 0;
+        } catch (final SQLException e) {
+            throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
+        } catch (final Throwable e) {
+            throw new CloudRuntimeException("Caught: " + pstmt, e);
+        }
+    }
+
+    @DB(txn=false)
+    protected StringBuilder createCountSelect(SearchCriteria<?> sc, final boolean whereClause) {
+        StringBuilder sql = new StringBuilder(_count);
+
+        if (!whereClause) {
+            sql.delete(sql.length() - (_discriminatorClause == null ? 6 : 4), sql.length());
+        }
+
+        return sql;
+    }
+    
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/2855a3d6/utils/src/com/cloud/utils/db/SqlGenerator.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/db/SqlGenerator.java b/utils/src/com/cloud/utils/db/SqlGenerator.java
index 3b2d8cd..e48fee5 100755
--- a/utils/src/com/cloud/utils/db/SqlGenerator.java
+++ b/utils/src/com/cloud/utils/db/SqlGenerator.java
@@ -659,4 +659,11 @@ public class SqlGenerator {
     public Field[] getEmbeddedFields() {
         return _embeddeds.toArray(new Field[_embeddeds.size()]);
     }
+
+    public String buildCountSql() {
+        StringBuilder sql = new StringBuilder();
+
+        return sql.append("SELECT COUNT(*) FROM ").append(buildTableReferences()).
+                append(" WHERE ").append(buildDiscriminatorClause().first()).toString();
+    }
 }