From 20bcd8bd6c43845a8c49837a04cb1d526a190624 Mon Sep 17 00:00:00 2001 From: Anuruddha Premalal Date: Tue, 30 Apr 2013 09:01:41 +0530 Subject: [PATCH] update pagination methods to utilize search and order the results. optimized data fetching. --- .../client/api/ClientsApiResource.java | 36 ++++++++++++-- .../service/ClientReadPlatformService.java | 2 +- .../ClientReadPlatformServiceImpl.java | 49 +++++++++---------- .../portfolio/pagination/Page.java | 15 +++--- .../pagination/PaginationHelper.java | 45 ++++------------- 5 files changed, 73 insertions(+), 74 deletions(-) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientsApiResource.java index 9fa8a555e..a1d86a75b 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientsApiResource.java @@ -15,6 +15,7 @@ import java.util.Set; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; +import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; @@ -126,15 +127,42 @@ public class ClientsApiResource { return this.toApiJsonSerializer.serialize(settings, clientData, ClientApiConstants.CLIENT_RESPONSE_DATA_PARAMETERS); } + @GET + @Path("/paginatedandsorted") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveAllPaginatedAndSorted(@Context final UriInfo uriInfo, @QueryParam("sqlSearch") final String sqlSearch, + @QueryParam("officeId") final Long officeId, @QueryParam("externalId") final String externalId, + @QueryParam("displayName") final String displayName, @QueryParam("firstName") final String firstname, + @QueryParam("lastName") final String lastname, @QueryParam("underHierarchy") final String hierarchy, + @DefaultValue("0") @QueryParam("offset") final int offset, @DefaultValue("200") @QueryParam("limit") final int limit, + @QueryParam("orderBy") final String orderBy, @QueryParam("sortOrder") final String sortOrder) throws SQLException { + + context.authenticatedUser().validateHasReadPermission(ClientApiConstants.CLIENT_RESOURCE_NAME); + + final SearchParameters searchParameters = SearchParameters.forClients(sqlSearch, officeId, externalId, displayName, firstname, + lastname, hierarchy); + Page clientData = this.clientReadPlatformService.retrieveAllPaginatedAndSorted(searchParameters, offset, limit, orderBy, sortOrder); + return this.toApiJsonSerializer.serialize(clientData); + } + + @GET @Path("/paginated") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String retrievePaginated(@QueryParam("pageNo") final int pageNo, @QueryParam("pageSize") final int pageSize, - @Context final UriInfo uriInfo) throws SQLException { + public String retrieveAllPaginated(@Context final UriInfo uriInfo, @QueryParam("sqlSearch") final String sqlSearch, + @QueryParam("officeId") final Long officeId, @QueryParam("externalId") final String externalId, + @QueryParam("displayName") final String displayName, @QueryParam("firstName") final String firstname, + @QueryParam("lastName") final String lastname, @QueryParam("underHierarchy") final String hierarchy, + @DefaultValue("0") @QueryParam("offset") final int offset, @DefaultValue("200") @QueryParam("limit") final int limit) + throws SQLException { context.authenticatedUser().validateHasReadPermission(ClientApiConstants.CLIENT_RESOURCE_NAME); - Page clientData = this.clientReadPlatformService.retrievePaginated(pageNo, pageSize); - return clientData.toString(); + + final SearchParameters searchParameters = SearchParameters.forClients(sqlSearch, officeId, externalId, displayName, firstname, + lastname, hierarchy); + Page clientData = this.clientReadPlatformService.retrieveAllPaginatedAndSorted(searchParameters, offset, limit, null, null); + return this.toApiJsonSerializer.serialize(clientData); } @POST diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformService.java index 690a694d7..32aac3e9e 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformService.java @@ -19,7 +19,7 @@ public interface ClientReadPlatformService { Collection retrieveAll(SearchParameters searchParameters); - Page retrievePaginated(int pageNo, int pageSize); + Page retrieveAllPaginatedAndSorted(SearchParameters searchParameters, int pageNo, int pageSize, String sortBy, String sortOrder); ClientData retrieveOne(Long clientId); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java index f44babc81..883324867 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java @@ -36,7 +36,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.core.simple.ParameterizedRowMapper; import org.springframework.stereotype.Service; @Service @@ -91,32 +90,30 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService } @Override - public Page retrievePaginated(final int pageNo, final int pageSize) { + public Page retrieveAllPaginatedAndSorted(final SearchParameters searchParameters, final int offset, final int limit, + final String orderby, final String sortOrder) { + + final AppUser currentUser = context.authenticatedUser(); + final String hierarchy = currentUser.getOffice().getHierarchy(); + final String hierarchySearchString = hierarchy + "%"; + + String sql = "select SQL_CALC_FOUND_ROWS " + this.clientMapper.schema() + " where o.hierarchy like ?"; + + final String extraCriteria = buildSqlStringFromClientCriteria(searchParameters); + + if (StringUtils.isNotBlank(extraCriteria)) sql += " and (" + extraCriteria + ")"; + + if (orderby != null && sortOrder != null) { + if (!orderby.equalsIgnoreCase("") && !sortOrder.equalsIgnoreCase("")) { + sql += " order by " + orderby + " " + sortOrder; + } + } else + sql += " order by c.display_name ASC, c.account_no ASC"; + PaginationHelper ph = new PaginationHelper(); - return ph.fetchPage(jdbcTemplate, "SELECT count(*) FROM m_client ORDER BY firstname", "SELECT * FROM m_client ORDER BY firstname", - null, pageNo, pageSize, new ParameterizedRowMapper() { - - @Override - public ClientData mapRow(ResultSet rs, int rowNum) throws SQLException { - final String accountNo = rs.getString("account_no"); - final EnumOptionData status = null; - final Long officeId = JdbcSupport.getLong(rs, "office_id"); - final Long id = JdbcSupport.getLong(rs, "id"); - final String firstname = rs.getString("firstname"); - final String middlename = rs.getString("middlename"); - final String lastname = rs.getString("lastname"); - final String fullname = rs.getString("fullname"); - final String displayName = rs.getString("display_name"); - final String externalId = rs.getString("external_Id"); - final LocalDate activationDate = JdbcSupport.getLocalDate(rs, "activation_date"); - final String imageKey = rs.getString("image_key"); - final String officeName = null; - - return ClientData.instance(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, - displayName, externalId, activationDate, imageKey); - } - }); - + String sqlCountRows = "SELECT FOUND_ROWS()"; + String sqlFetchRows = sql + " LIMIT " + limit + " OFFSET " + offset; + return ph.fetchPage(jdbcTemplate, sqlCountRows, sqlFetchRows, new Object[] { hierarchySearchString }, offset, limit, clientMapper); } private String buildSqlStringFromClientCriteria(final SearchParameters searchParameters) { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/pagination/Page.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/pagination/Page.java index 27177d6d9..9050e578b 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/pagination/Page.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/pagination/Page.java @@ -8,17 +8,13 @@ import com.google.gson.Gson; public class Page { private int pageNumber; - private int pagesAvailable; + private int totalFilteredRecords; private List pageItems = new ArrayList(); public void setPageNumber(int pageNumber) { this.pageNumber = pageNumber; } - public void setPagesAvailable(int pagesAvailable) { - this.pagesAvailable = pagesAvailable; - } - public void setPageItems(List pageItems) { this.pageItems = pageItems; } @@ -26,9 +22,14 @@ public class Page { public int getPageNumber() { return pageNumber; } + + public int getTotalFilteredRecords() { + return this.totalFilteredRecords; + } - public int getPagesAvailable() { - return pagesAvailable; + + public void setTotalFilteredRecords(int totalFilteredRecords) { + this.totalFilteredRecords = totalFilteredRecords; } public List getPageItems() { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/pagination/PaginationHelper.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/pagination/PaginationHelper.java index 2a56a12bc..bfe7875fc 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/pagination/PaginationHelper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/pagination/PaginationHelper.java @@ -1,50 +1,23 @@ package org.mifosplatform.portfolio.pagination; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.List; - -import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.ResultSetExtractor; -import org.springframework.jdbc.core.simple.ParameterizedRowMapper; +import org.springframework.jdbc.core.RowMapper; public class PaginationHelper { public Page fetchPage(final JdbcTemplate jt, final String sqlCountRows, final String sqlFetchRows, final Object args[], - final int pageNo, final int pageSize, final ParameterizedRowMapper rowMapper) { + final int offset, final int limit, final RowMapper rowMapper) { + + final Page page = new Page(); + + page.getPageItems().addAll(jt.query(sqlFetchRows, args, rowMapper)); // determine how many rows are available - final int rowCount = jt.queryForInt(sqlCountRows, args); + final int totalFilteredRecords = jt.queryForInt(sqlCountRows); - // calculate the number of pages - int pageCount = rowCount / pageSize; - if (rowCount > pageSize * pageCount) { - pageCount++; - } + page.setPageNumber(offset);//TODO will change to suit limit & offset + page.setTotalFilteredRecords(totalFilteredRecords); - // create the page object - final Page page = new Page(); - page.setPageNumber(pageNo); - page.setPagesAvailable(pageCount); - - // fetch a single page of results - final int startRow = (pageNo - 1) * pageSize; - jt.query(sqlFetchRows, new ResultSetExtractor() { - - @Override - public E extractData(ResultSet rs) throws SQLException, DataAccessException { - final List pageItems = page.getPageItems(); - int currentRow = 0; - while (rs.next() && currentRow < startRow + pageSize) { - if (currentRow >= startRow) { - pageItems.add(rowMapper.mapRow(rs, currentRow)); - } - currentRow++; - } - return (E) page; - } - }); return page; }