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);
}
}
}