package gov.nysenate.openleg.dao.base;
import com.google.common.collect.ImmutableMap;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.text.StrSubstitutor;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Common utility methods to be used by enums/classes that store sql queries.
*/
public abstract class SqlQueryUtils
{
/**
* Replaces the ${schema} placeholder in the given sql String with the given schema name.
* This is mainly used for queries where the schema name can be user defined, e.g. the environment schema.
*
* @param sql String - A string that contains the ${schema} placeholders.
* @param schema String - The name of the database schema
* @return String
*/
public static String getSqlWithSchema(String sql, String schema) {
Map<String, String> replaceMap = new HashMap<>();
replaceMap.put("schema", schema);
return new StrSubstitutor(replaceMap).replace(sql);
}
/**
* Adds support for a search schema as well.
*/
public static String getSqlWithSchema(String sql, String dataSchema, String searchSchema) {
Map<String, String> replaceMap = new HashMap<>();
replaceMap.put("schema", dataSchema);
replaceMap.put("search_schema", searchSchema);
return new StrSubstitutor(replaceMap).replace(sql);
}
/**
* Overloaded to add LIMIT clause to getSqlWithSchema(sql, schema) output.
*/
public static String getSqlWithSchema(String sql, String schema, LimitOffset limitOffset) {
return getSqlWithSchema(sql, schema) + getLimitOffsetClause(limitOffset);
}
/**
* Overloaded to add LIMIT clause to getSqlWithSchema(sql, dataSchema, searchSchema) output.
*/
public static String getSqlWithSchema(String sql, String dataSchema, String searchSchema, LimitOffset limitOffset) {
return getSqlWithSchema(sql, dataSchema, searchSchema) + getLimitOffsetClause(limitOffset);
}
/**
* Overloaded to add LIMIT AND ORDER BY clause to getSqlWithSchema(sql, schema) output.
*/
public static String getSqlWithSchema(String sql, String schema, OrderBy orderBy, LimitOffset limitOffset) {
return getSqlWithSchema(sql, schema) + getOrderByClause(orderBy) + getLimitOffsetClause(limitOffset);
}
/**
* Overloaded to add LIMIT AND ORDER BY clause to getSqlWithSchema(sql, dataSchema, searchSchema) output.
*/
public static String getSqlWithSchema(String sql, String dataSchema, String searchSchema, OrderBy orderBy,
LimitOffset limitOffset) {
return getSqlWithSchema(sql, dataSchema, searchSchema) + getOrderByClause(orderBy) + getLimitOffsetClause(limitOffset);
}
/**
* Returns a LIMIT OFFSET sql clause using the supplied LimitOffset instance.
* If neither the limit nor the offset is set an empty string will be returned.
*
* @param limitOffset LimitOffset
* @return String
*/
public static String getLimitOffsetClause(LimitOffset limitOffset) {
String clause = "";
if (limitOffset != null) {
if (limitOffset.hasLimit()) {
clause = String.format(" LIMIT %d", limitOffset.getLimit());
}
if (limitOffset.hasOffset()) {
clause += String.format(" OFFSET %d", limitOffset.getOffsetStart() - 1);
}
}
return clause;
}
/**
* Returns an ORDER BY sql clause using the supplied orderBy clause. Supports
* multiple column orderings as specified in the OrderBy instance.
*
* @param orderBy OrderBy
* @return String
*/
public static String getOrderByClause(OrderBy orderBy) {
String clause = "";
if (orderBy != null) {
ImmutableMap<String, SortOrder> sortColumns = orderBy.getSortColumns();
List<String> orderClauses = sortColumns.keySet().stream()
.filter(column -> !sortColumns.get(column).equals(SortOrder.NONE))
.map(column -> column + " " + sortColumns.get(column).name())
.collect(Collectors.toList());
if (!orderClauses.isEmpty()) {
clause += " ORDER BY " + StringUtils.join(orderClauses, ", ");
}
}
return clause;
}
}