package org.pegadi.sqlsearch; import org.apache.commons.lang.NotImplementedException; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.util.List; @Component public class DataSourceBasedLimitResultsUtil { private String databaseDriverName; public DataSourceBasedLimitResultsUtil(@Value("${server.db.driver}") String databaseDriverName) { this.databaseDriverName = databaseDriverName; } /** * @param searchTerm to decorate * @param numberOfRows to limit * @param offset rowoffset * @return the given SearchTerm decorated with limit and offset clause based on the database driver in use. * @throws NotImplementedException if handling for the database driver is implemented. */ public SearchTerm createLimitClauseToSearchTerm(SearchTerm searchTerm, int numberOfRows, int offset){ return new LimitedClauseSearchTerm(searchTerm, numberOfRows, offset); } /** * @param searchTerm to decorate * @param numberOfRows to limit * @return the given SearchTerm decorated with limit clause based on the database driver in use. * @throws NotImplementedException if handling for the database driver is implemented. */ public SearchTerm createLimitClauseToSearchTerm(SearchTerm searchTerm, int numberOfRows){ return new LimitedClauseSearchTerm(searchTerm, numberOfRows); } private String addLimitRows(String originalQuery, int numberOfRows){ if (databaseDriverName.contains("mysql")) { return originalQuery + " limit " + numberOfRows; } else if (databaseDriverName.contains("derby")){ return originalQuery + " fetch first " + numberOfRows + " rows only"; } else if (databaseDriverName.contains("hsqldb")) { return originalQuery + " limit " + numberOfRows; } else { throw new NotImplementedException("Could not add limit clause, sqldriver " + databaseDriverName + " is unknown"); } } private String addLimitRows(String originalQuery, int numberOfRows, int offset){ if (databaseDriverName.contains("mysql")) { return originalQuery + " limit " + offset + "," + numberOfRows; } else if (databaseDriverName.contains("derby")) { return originalQuery + " offset " + offset + " fetch next " + numberOfRows + " rows only"; } else if (databaseDriverName.contains("hsqldb")) { return originalQuery + " limit " + numberOfRows + " " + offset; } else { throw new NotImplementedException("Could not add limit clause, sqldriver " + databaseDriverName + " is unknown"); } } private class LimitedClauseSearchTerm extends SearchTerm { private final SearchTerm searchTerm; private final int numberOfRows; private final int offset; protected LimitedClauseSearchTerm(SearchTerm searchTerm, int numberOfRows) { this(searchTerm, numberOfRows, 0); } protected LimitedClauseSearchTerm(SearchTerm searchTerm, int numberOfRows, int offset) { super(); this.searchTerm = searchTerm; this.numberOfRows = numberOfRows; this.offset = offset; } @Override public String whereClause() { return searchTerm.whereClause(); } @Override public List<String> getTables() { return searchTerm.getTables(); } @Override public List<String> getIgnoreTables() { return searchTerm.getIgnoreTables(); } @Override public String getQuery(String selectString) { if (offset == 0) { return addLimitRows(searchTerm.getQuery(selectString), numberOfRows); } else { return addLimitRows(searchTerm.getQuery(selectString), numberOfRows, offset); } } @Override public void setSelectDistinct(boolean selectDistinct) { searchTerm.setSelectDistinct(selectDistinct); } } }