update pagination methods to utilize search and order the results.

optimized data fetching.
This commit is contained in:
Anuruddha Premalal
2013-05-01 16:53:24 +05:30
parent 7476d9775b
commit 20bcd8bd6c
5 changed files with 73 additions and 74 deletions
@@ -15,6 +15,7 @@ import java.util.Set;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE; import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET; import javax.ws.rs.GET;
import javax.ws.rs.POST; import javax.ws.rs.POST;
import javax.ws.rs.PUT; import javax.ws.rs.PUT;
@@ -126,15 +127,42 @@ public class ClientsApiResource {
return this.toApiJsonSerializer.serialize(settings, clientData, ClientApiConstants.CLIENT_RESPONSE_DATA_PARAMETERS); 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> clientData = this.clientReadPlatformService.retrieveAllPaginatedAndSorted(searchParameters, offset, limit, orderBy, sortOrder);
return this.toApiJsonSerializer.serialize(clientData);
}
@GET @GET
@Path("/paginated") @Path("/paginated")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String retrievePaginated(@QueryParam("pageNo") final int pageNo, @QueryParam("pageSize") final int pageSize, public String retrieveAllPaginated(@Context final UriInfo uriInfo, @QueryParam("sqlSearch") final String sqlSearch,
@Context final UriInfo uriInfo) throws SQLException { @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); context.authenticatedUser().validateHasReadPermission(ClientApiConstants.CLIENT_RESOURCE_NAME);
Page<ClientData> clientData = this.clientReadPlatformService.retrievePaginated(pageNo, pageSize);
return clientData.toString(); final SearchParameters searchParameters = SearchParameters.forClients(sqlSearch, officeId, externalId, displayName, firstname,
lastname, hierarchy);
Page<ClientData> clientData = this.clientReadPlatformService.retrieveAllPaginatedAndSorted(searchParameters, offset, limit, null, null);
return this.toApiJsonSerializer.serialize(clientData);
} }
@POST @POST
@@ -19,7 +19,7 @@ public interface ClientReadPlatformService {
Collection<ClientData> retrieveAll(SearchParameters searchParameters); Collection<ClientData> retrieveAll(SearchParameters searchParameters);
Page<ClientData> retrievePaginated(int pageNo, int pageSize); Page<ClientData> retrieveAllPaginatedAndSorted(SearchParameters searchParameters, int pageNo, int pageSize, String sortBy, String sortOrder);
ClientData retrieveOne(Long clientId); ClientData retrieveOne(Long clientId);
@@ -36,7 +36,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@Service @Service
@@ -91,32 +90,30 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
} }
@Override @Override
public Page<ClientData> retrievePaginated(final int pageNo, final int pageSize) { public Page<ClientData> 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<ClientData> ph = new PaginationHelper<ClientData>(); PaginationHelper<ClientData> ph = new PaginationHelper<ClientData>();
return ph.fetchPage(jdbcTemplate, "SELECT count(*) FROM m_client ORDER BY firstname", "SELECT * FROM m_client ORDER BY firstname", String sqlCountRows = "SELECT FOUND_ROWS()";
null, pageNo, pageSize, new ParameterizedRowMapper<ClientData>() { String sqlFetchRows = sql + " LIMIT " + limit + " OFFSET " + offset;
return ph.fetchPage(jdbcTemplate, sqlCountRows, sqlFetchRows, new Object[] { hierarchySearchString }, offset, limit, clientMapper);
@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);
}
});
} }
private String buildSqlStringFromClientCriteria(final SearchParameters searchParameters) { private String buildSqlStringFromClientCriteria(final SearchParameters searchParameters) {
@@ -8,17 +8,13 @@ import com.google.gson.Gson;
public class Page<E> { public class Page<E> {
private int pageNumber; private int pageNumber;
private int pagesAvailable; private int totalFilteredRecords;
private List<E> pageItems = new ArrayList<E>(); private List<E> pageItems = new ArrayList<E>();
public void setPageNumber(int pageNumber) { public void setPageNumber(int pageNumber) {
this.pageNumber = pageNumber; this.pageNumber = pageNumber;
} }
public void setPagesAvailable(int pagesAvailable) {
this.pagesAvailable = pagesAvailable;
}
public void setPageItems(List<E> pageItems) { public void setPageItems(List<E> pageItems) {
this.pageItems = pageItems; this.pageItems = pageItems;
} }
@@ -26,9 +22,14 @@ public class Page<E> {
public int getPageNumber() { public int getPageNumber() {
return pageNumber; return pageNumber;
} }
public int getTotalFilteredRecords() {
return this.totalFilteredRecords;
}
public int getPagesAvailable() {
return pagesAvailable; public void setTotalFilteredRecords(int totalFilteredRecords) {
this.totalFilteredRecords = totalFilteredRecords;
} }
public List<E> getPageItems() { public List<E> getPageItems() {
@@ -1,50 +1,23 @@
package org.mifosplatform.portfolio.pagination; 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.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor; import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
public class PaginationHelper<E> { public class PaginationHelper<E> {
public Page<E> fetchPage(final JdbcTemplate jt, final String sqlCountRows, final String sqlFetchRows, final Object args[], public Page<E> fetchPage(final JdbcTemplate jt, final String sqlCountRows, final String sqlFetchRows, final Object args[],
final int pageNo, final int pageSize, final ParameterizedRowMapper<E> rowMapper) { final int offset, final int limit, final RowMapper<E> rowMapper) {
final Page<E> page = new Page<E>();
page.getPageItems().addAll(jt.query(sqlFetchRows, args, rowMapper));
// determine how many rows are available // determine how many rows are available
final int rowCount = jt.queryForInt(sqlCountRows, args); final int totalFilteredRecords = jt.queryForInt(sqlCountRows);
// calculate the number of pages page.setPageNumber(offset);//TODO will change to suit limit & offset
int pageCount = rowCount / pageSize; page.setTotalFilteredRecords(totalFilteredRecords);
if (rowCount > pageSize * pageCount) {
pageCount++;
}
// create the page object
final Page<E> page = new Page<E>();
page.setPageNumber(pageNo);
page.setPagesAvailable(pageCount);
// fetch a single page of results
final int startRow = (pageNo - 1) * pageSize;
jt.query(sqlFetchRows, new ResultSetExtractor<E>() {
@Override
public E extractData(ResultSet rs) throws SQLException, DataAccessException {
final List<E> 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; return page;
} }