org.dashbuilder.dataprovider.sql.dialect.DefaultDialect Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.dashbuilder.dataprovider.sql.dialect;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.dashbuilder.dataprovider.sql.model.Column;
import org.dashbuilder.dataprovider.sql.model.Condition;
import org.dashbuilder.dataprovider.sql.model.CoreCondition;
import org.dashbuilder.dataprovider.sql.model.CreateTable;
import org.dashbuilder.dataprovider.sql.model.Delete;
import org.dashbuilder.dataprovider.sql.model.DynamicDateColumn;
import org.dashbuilder.dataprovider.sql.model.FixedDateColumn;
import org.dashbuilder.dataprovider.sql.model.FunctionColumn;
import org.dashbuilder.dataprovider.sql.model.Insert;
import org.dashbuilder.dataprovider.sql.model.LogicalCondition;
import org.dashbuilder.dataprovider.sql.model.SQLStatement;
import org.dashbuilder.dataprovider.sql.model.Select;
import org.dashbuilder.dataprovider.sql.model.SimpleColumn;
import org.dashbuilder.dataprovider.sql.model.SortColumn;
import org.dashbuilder.dataprovider.sql.model.Table;
import org.dashbuilder.dataset.ColumnType;
import org.dashbuilder.dataset.filter.CoreFunctionType;
import org.dashbuilder.dataset.filter.LogicalExprType;
import org.dashbuilder.dataset.group.AggregateFunctionType;
import org.dashbuilder.dataset.group.DateIntervalType;
import org.dashbuilder.dataset.sort.SortOrder;
import static org.dashbuilder.dataprovider.sql.SQLFactory.*;
public class DefaultDialect implements Dialect {
private static final String AND = " AND ";
@Override
public String[] getExcludedColumns() {
return new String[] {};
}
@Override
public String getColumnSQL(Column column) {
if (column instanceof FunctionColumn) {
return getFunctionColumnSQL((FunctionColumn) column);
}
else if (column instanceof SortColumn) {
return getSortColumnSQL((SortColumn) column);
}
else if (column instanceof DynamicDateColumn) {
return getDynamicDateColumnSQL((DynamicDateColumn) column);
}
else if (column instanceof FixedDateColumn) {
return getFixedDateColumnSQL((FixedDateColumn) column);
}
else if (column instanceof SimpleColumn) {
return getSimpleColumnSQL((SimpleColumn) column);
}
else {
return getColumnNameSQL(column.getName());
}
}
@Override
public String getColumnTypeSQL(Column column) {
switch (column.getType()) {
case NUMBER: {
return "NUMERIC(28,2)";
}
case DATE: {
return "TIMESTAMP";
}
default: {
return "VARCHAR(" + column.getLength() + ")";
}
}
}
@Override
public String convertToString(Object value) {
try {
return value == null ? null : (String) value;
} catch (ClassCastException e) {
return value.toString();
}
}
@Override
public Double convertToDouble(Object value) {
try {
return value == null ? null : ((Number) value).doubleValue();
} catch (ClassCastException e) {
return Double.parseDouble(value.toString());
}
}
@Override
public Date convertToDate(Object value) {
try {
return value == null ? null : (Date) value;
} catch (ClassCastException e) {
throw new IllegalArgumentException("Not a java.util.Date: " + value + " (" + value.getClass().getName() + ")");
}
}
@Override
public String getTableSQL(SQLStatement> stmt) {
Table table = stmt.getTable();
String name = getTableNameSQL(table.getName());
if (StringUtils.isBlank(table.getSchema())) {
return name;
} else{
return getSchemaNameSQL(table.getSchema()) + "." + name;
}
}
@Override
public String getTableNameSQL(String name) {
return name;
}
@Override
public String getSchemaNameSQL(String name) {
return name;
}
@Override
public String getSimpleColumnSQL(SimpleColumn column) {
String result = getColumnNameSQL(column.getName());
if (column.getFunctionType() != null) {
result = getColumnFunctionSQL(result, column.getFunctionType());
}
return result;
}
@Override
public String getFunctionColumnSQL(FunctionColumn column) {
if (FunctionColumn.LOWER.equals(column.getFunction())) {
return getLowerFunctionSQL(column.getColumns()[0]);
}
if (FunctionColumn.CONCAT.equals(column.getFunction())) {
return getConcatFunctionSQL(column.getColumns());
}
if (FunctionColumn.YEAR.equals(column.getFunction())) {
return getDatePartFunctionSQL("YEAR", column.getColumns()[0]);
}
if (FunctionColumn.MONTH.equals(column.getFunction())) {
return getDatePartFunctionSQL("MONTH", column.getColumns()[0]);
}
if (FunctionColumn.DAY.equals(column.getFunction())) {
return getDatePartFunctionSQL("DAY", column.getColumns()[0]);
}
if (FunctionColumn.HOUR.equals(column.getFunction())) {
return getDatePartFunctionSQL("HOUR", column.getColumns()[0]);
}
if (FunctionColumn.MINUTE.equals(column.getFunction())) {
return getDatePartFunctionSQL("MINUTE", column.getColumns()[0]);
}
if (FunctionColumn.SECOND.equals(column.getFunction())) {
return getDatePartFunctionSQL("SECOND", column.getColumns()[0]);
}
throw new IllegalArgumentException("Column function not supported: " + column.getFunction());
}
@Override
public String getLowerFunctionSQL(Column column) {
String columnSQL = getColumnSQL(column);
return "LOWER(" + columnSQL + ")";
}
@Override
public String getConcatFunctionSQL(Column[] columns) {
return getConcatFunctionSQL(columns, "(", ")", " || ");
}
public String getConcatFunctionSQL(Column[] columns, String begin, String end, String separator) {
StringBuilder out = new StringBuilder();
out.append(begin);
for (int i = 0; i < columns.length; i++) {
if (i > 0) out.append(separator);
Column column = columns[i];
ColumnType type = column.getType();
if (ColumnType.LABEL.equals(type) || ColumnType.TEXT.equals(type)) {
out.append("'").append(column.getName()).append("'");
} else {
// Cast needed
out.append(getColumnCastSQL(column));
}
}
out.append(end);
return out.toString();
}
public String getColumnCastSQL(Column column) {
String columnSQL = getColumnSQL(column);
return "CAST(" + columnSQL + " AS VARCHAR)";
}
@Override
public String getDatePartFunctionSQL(String part, Column column) {
String columnSQL = getColumnSQL(column);
return "EXTRACT(" + part + " FROM " + columnSQL + ")";
}
@Override
public String getSortColumnSQL(SortColumn sortColumn) {
Column column = sortColumn.getSource();
String columnSQL = getColumnSQL(column);
// Always order by the alias (if any)
if (!StringUtils.isBlank(column.getAlias())) {
columnSQL = getAliasForStatementSQL(column.getAlias());
}
return columnSQL + " " + getSortOrderSQL(sortColumn.getOrder());
}
@Override
public String getSortOrderSQL(SortOrder order) {
if (SortOrder.ASCENDING.equals(order)) {
return "ASC";
}
if (SortOrder.DESCENDING.equals(order)) {
return "DESC";
}
throw new IllegalArgumentException("Sort order not supported: " + order);
}
/**
* The text conversion of a date column is very DB specific.
* A mechanism combining concat and extract functions is used by default.
* Depending on the DB dialect a more polished approach can be used.
* For instance,
* - In Oracle and Postgres the 'to_char' function is used.
* - In Mysql, 'date_format'
* - In H2, the 'to_char' function is not used as it's only available since version 1.3.175 and we do need to support older versions.
*
*/
@Override
public String getDynamicDateColumnSQL(DynamicDateColumn column) {
Column dateColumn = toChar(column);
return getColumnSQL(dateColumn);
}
public Column toChar(DynamicDateColumn column) {
Column target = column(column.getName());
DateIntervalType type = column.getDateType();
Column SEPARATOR_DATE = column("-", ColumnType.TEXT, 3);
Column SEPARATOR_EMPTY = column(" ", ColumnType.TEXT, 3);
Column SEPARATOR_TIME = column(":", ColumnType.TEXT, 3);
if (DateIntervalType.SECOND.equals(type)) {
return concat(target.year(), SEPARATOR_DATE,
target.month(), SEPARATOR_DATE,
target.day(), SEPARATOR_EMPTY,
target.hour(), SEPARATOR_TIME,
target.minute(), SEPARATOR_TIME,
target.second());
}
if (DateIntervalType.MINUTE.equals(type)) {
return concat(target.year(), SEPARATOR_DATE,
target.month(), SEPARATOR_DATE,
target.day(), SEPARATOR_EMPTY,
target.hour(), SEPARATOR_TIME,
target.minute());
}
if (DateIntervalType.HOUR.equals(type)) {
return concat(target.year(), SEPARATOR_DATE,
target.month(), SEPARATOR_DATE,
target.day(), SEPARATOR_EMPTY,
target.hour());
}
if (DateIntervalType.DAY.equals(type) || DateIntervalType.WEEK.equals(type)) {
return concat(target.year(), SEPARATOR_DATE,
target.month(), SEPARATOR_DATE,
target.day());
}
if (DateIntervalType.MONTH.equals(type)
|| DateIntervalType.QUARTER.equals(type)) {
return concat(target.year(), SEPARATOR_DATE,
target.month());
}
if (DateIntervalType.YEAR.equals(type)
|| DateIntervalType.DECADE.equals(type)
|| DateIntervalType.CENTURY.equals(type)
|| DateIntervalType.MILLENIUM.equals(type)) {
return target.year();
}
throw new IllegalArgumentException("Group '" + target.getName() +
"' by the given date interval type is not supported: " + type);
}
@Override
public String getFixedDateColumnSQL(FixedDateColumn column) {
Column target = column(column.getName());
DateIntervalType type = column.getDateType();
if (DateIntervalType.SECOND.equals(type)) {
return getColumnSQL(target.second());
}
if (DateIntervalType.MINUTE.equals(type)) {
return getColumnSQL(target.minute());
}
if (DateIntervalType.HOUR.equals(type)) {
return getColumnSQL(target.hour());
}
if (DateIntervalType.DAY_OF_WEEK.equals(type)) {
return getColumnSQL(target.day());
}
if (DateIntervalType.MONTH.equals(type)) {
return getColumnSQL(target.month());
}
if (DateIntervalType.QUARTER.equals(type)) {
// Emulated using month and converted to quarter during the data set post-processing
return getColumnSQL(target.month());
}
throw new IllegalArgumentException("Interval size '" + type + "' not supported for " +
"fixed date intervals. The only supported sizes are: " +
StringUtils.join(DateIntervalType.FIXED_INTERVALS_SUPPORTED, ","));
}
@Override
public String getColumnNameSQL(String name) {
return name;
}
@Override
public String getColumnNameQuotedSQL(String name) {
return "\"" + name + "\"";
}
@Override
public String getAliasForColumnSQL(String alias) {
return "\"" + alias + "\"";
}
@Override
public String getAliasForStatementSQL(String alias) {
return "\"" + alias + "\"";
}
@Override
public String getConditionSQL(Condition condition) {
if (condition instanceof CoreCondition) {
return getCoreConditionSQL((CoreCondition) condition);
}
if (condition instanceof LogicalCondition) {
return getLogicalConditionSQL((LogicalCondition) condition);
}
throw new IllegalArgumentException("Condition type not supported: " + condition);
}
@Override
public String getCoreConditionSQL(CoreCondition condition) {
String columnSQL = getColumnSQL(condition.getColumn());
CoreFunctionType type = condition.getFunction();
Object[] params = condition.getParameters();
if (CoreFunctionType.IS_NULL.equals(type)) {
return getIsNullConditionSQL(columnSQL);
}
if (CoreFunctionType.NOT_NULL.equals(type)) {
return getNotNullConditionSQL(columnSQL);
}
if (CoreFunctionType.EQUALS_TO.equals(type)) {
return getIsEqualsToConditionSQL(columnSQL, params[0]);
}
if (CoreFunctionType.NOT_EQUALS_TO.equals(type)) {
return getNotEqualsToConditionSQL(columnSQL, params[0]);
}
if (CoreFunctionType.NOT_EQUALS_TO.equals(type)) {
return getNotEqualsToConditionSQL(columnSQL, params[0]);
}
if (CoreFunctionType.LIKE_TO.equals(type)) {
return getLikeToConditionSQL(columnSQL, params[0]);
}
if (CoreFunctionType.GREATER_THAN.equals(type)) {
return getGreaterThanConditionSQL(columnSQL, params[0]);
}
if (CoreFunctionType.GREATER_OR_EQUALS_TO.equals(type)) {
return getGreaterOrEqualsConditionSQL(columnSQL, params[0]);
}
if (CoreFunctionType.LOWER_THAN.equals(type)) {
return getLowerThanConditionSQL(columnSQL, params[0]);
}
if (CoreFunctionType.LOWER_OR_EQUALS_TO.equals(type)) {
return getLowerOrEqualsConditionSQL(columnSQL, params[0]);
}
if (CoreFunctionType.BETWEEN.equals(type)) {
return getBetweenConditionSQL(columnSQL, params[0], params[1]);
}
if (CoreFunctionType.IN.equals(type)) {
return getInConditionSQL(columnSQL, params[0]);
}
if (CoreFunctionType.NOT_IN.equals(type)) {
return getNotInConditionSQL(columnSQL, params[0]);
}
throw new IllegalArgumentException("Core condition type not supported: " + type);
}
@Override
public String getNotNullConditionSQL(String column) {
return column + " IS NOT NULL";
}
@Override
public String getIsNullConditionSQL(String column) {
return column + " IS NULL";
}
@Override
public String getIsEqualsToConditionSQL(String column, Object param) {
if (param == null) {
return getIsNullConditionSQL(column);
} else {
String paramStr = getParameterSQL(param);
return column + " = " + paramStr;
}
}
@Override
public String getNotEqualsToConditionSQL(String column, Object param) {
if (param == null) {
return getNotNullConditionSQL(column);
} else {
String paramStr = getParameterSQL(param);
return column + " <> " + paramStr;
}
}
@Override
public String getLikeToConditionSQL(String column, Object param) {
String paramStr = getParameterSQL(param);
return column + " LIKE " + paramStr;
}
@Override
public String getGreaterThanConditionSQL(String column, Object param) {
String paramStr = getParameterSQL(param);
return column + " > " + paramStr;
}
@Override
public String getGreaterOrEqualsConditionSQL(String column, Object param) {
String paramStr = getParameterSQL(param);
return column + " >= " + paramStr;
}
@Override
public String getLowerThanConditionSQL(String column, Object param) {
String paramStr = getParameterSQL(param);
return column + " < " + paramStr;
}
@Override
public String getLowerOrEqualsConditionSQL(String column, Object param) {
String paramStr = getParameterSQL(param);
return column + " <= " + paramStr;
}
@Override
public String getBetweenConditionSQL(String column, Object from, Object to) {
String fromStr = getParameterSQL(from);
String toStr = getParameterSQL(to);
return column + " BETWEEN " + fromStr + AND + toStr;
}
@Override
public String getInConditionSQL(String column, Object param) {
StringBuilder inStatement = new StringBuilder();
inStatement.append(column);
inStatement.append(" IN (");
for (Object p : (Collection>) param) {
inStatement.append(getParameterSQL(p) + ",");
}
inStatement.deleteCharAt(inStatement.length()-1);
inStatement.append(")");
return inStatement.toString();
}
@Override
public String getNotInConditionSQL(String column, Object param) {
StringBuilder inStatement = new StringBuilder();
inStatement.append(column);
inStatement.append(" NOT IN (");
for (Object p : (Collection>) param) {
inStatement.append(getParameterSQL(p) + ",");
}
inStatement.deleteCharAt(inStatement.length()-1);
inStatement.append(")");
return inStatement.toString();
}
@Override
public String getParameterSQL(Object param) {
if (param == null) {
return "null";
}
if (param instanceof Number) {
return getNumberParameterSQL((Number) param);
}
if (param instanceof Date) {
return getDateParameterSQL((Date) param);
}
return getStringParameterSQL(param.toString());
}
@Override
public String getNumberParameterSQL(Number param) {
return param.toString();
}
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
@Override
public String getDateParameterSQL(Date param) {
// timestamp '2015-08-24 13:14:36.615'
return "TIMESTAMP '" + dateFormat.format(param) + "'";
}
@Override
public String getStringParameterSQL(String param) {
// DASHBUILDE-113: SQL Injection on data set lookup filters
String escapedParam = param.replaceAll("'", "''");
return "'" + escapedParam + "'";
}
@Override
public String getLogicalConditionSQL(LogicalCondition condition) {
LogicalExprType type = condition.getType();
Condition[] conditions = condition.getConditions();
if (LogicalExprType.NOT.equals(type)) {
return getNotExprConditionSQL(conditions[0]);
}
if (LogicalExprType.AND.equals(type)) {
return getAndExprConditionSQL(conditions);
}
if (LogicalExprType.OR.equals(type)) {
return getOrExprConditionSQL(conditions);
}
throw new IllegalArgumentException("Logical condition type not supported: " + type);
}
@Override
public String getNotExprConditionSQL(Condition condition) {
String conditionSQL = getConditionSQL(condition);
return "NOT(" + conditionSQL + ")";
}
@Override
public String getAndExprConditionSQL(Condition[] conditions) {
return _getLogicalExprConditionSQL(conditions, "AND");
}
@Override
public String getOrExprConditionSQL(Condition[] conditions) {
return _getLogicalExprConditionSQL(conditions, "OR");
}
protected String _getLogicalExprConditionSQL(Condition[] conditions, String op) {
StringBuilder out = new StringBuilder();
out.append("(");
for (int i = 0; i < conditions.length; i++) {
Condition condition = conditions[i];
String conditionSQL = getConditionSQL(condition);
if (i > 0) {
out.append(" ").append(op).append(" ");
}
out.append(conditionSQL);
}
out.append(")");
return out.toString();
}
@Override
public String getColumnFunctionSQL(String column, AggregateFunctionType function) {
switch (function) {
case SUM: {
return "SUM(" + column + ")";
}
case MAX: {
return "MAX(" + column + ")";
}
case MIN: {
return "MIN(" + column + ")";
}
case AVERAGE: {
return "AVG(" + column + ")";
}
case COUNT: {
return "COUNT(" + column + ")";
}
case DISTINCT: {
return "COUNT(DISTINCT " + column + ")";
}
default: {
throw new IllegalArgumentException("Function type not valid: " + function);
}
}
}
@Override
public String getCountQuerySQL(Select select) {
List sortColumns = new ArrayList();
sortColumns.addAll(select.getOrderBys());
try {
// Remove ORDER BY for better performance
select.getOrderBys().clear();
return "SELECT "
+ getColumnFunctionSQL("*", AggregateFunctionType.COUNT)
+ " FROM (" + select.getSQL() + ") "
+ getAliasForColumnSQL("dbSQL");
} finally {
select.orderBy(sortColumns);
}
}
@Override
public String getSQL(CreateTable create) {
StringBuilder sql = new StringBuilder("CREATE TABLE ");
List pkeys = new ArrayList();
String tname = getTableSQL(create);
sql.append(tname);
// Columns
boolean first = true;
sql.append(" (\n");
for (Column column : create.getColumns()) {
if (!first) {
sql.append(",\n");
}
String name = getColumnNameSQL(column.getName());
String type = getColumnTypeSQL(column);
sql.append(" ").append(name).append(" ").append(type);
if (create.getPrimaryKeys().contains(column)) {
sql.append(" NOT NULL");
pkeys.add(name);
}
first = false;
}
if (!create.getPrimaryKeys().isEmpty()) {
sql.append(",\n");
sql.append(" PRIMARY KEY(");
sql.append(StringUtils.join(pkeys, ","));
sql.append(")\n");
}
sql.append(")");
return sql.toString();
}
@Override
public String getSQL(Select select) {
// Select clause
StringBuilder sql = new StringBuilder();
String selectClause = getSelectSQL(select);
sql.append(selectClause);
// From clause (inner SQL or table)
sql.append(" ").append(getFromSQL(select));
// Where clauses
List wheres = select.getWheres();
if (!wheres.isEmpty()) {
sql.append(" ").append(getWhereSQL(select));
}
// Group by
List groupBys = select.getGroupBys();
if (!groupBys.isEmpty()) {
sql.append(" ").append(getGroupBySQL(select));
}
// Order by
List orderBys = select.getOrderBys();
if (!orderBys.isEmpty()) {
sql.append(" ").append(getOrderBySQL(select));
}
// Limits
int limit = select.getLimit();
int offset = select.getOffset();
if (limit > 0 || offset > 0) {
String limitSql = getOffsetLimitSQL(select);
if (!StringUtils.isBlank(limitSql)) {
sql.append(limitSql);
}
}
return sql.toString();
}
@Override
public String getSQL(Insert insert) {
// Insert clause
StringBuilder sql = new StringBuilder();
String insertClause = getInsertStatement(insert);
sql.append(insertClause);
// Table
sql.append(" ").append(getTableSQL(insert));
// Columns
boolean first = true;
sql.append(" (");
for (Column column : insert.getColumns()) {
if (!first) {
sql.append(",");
}
String str = getColumnSQL(column);
sql.append(str);
first = false;
}
sql.append(")");
// Values
first = true;
sql.append(" VALUES (");
for (Object value : insert.getValues()) {
if (!first) {
sql.append(",");
}
String str = getParameterSQL(value);
sql.append(str);
first = false;
}
sql.append(")");
return sql.toString();
}
@Override
public String getSQL(Delete delete) {
// Delete clause
StringBuilder sql = new StringBuilder();
String deleteClause = getDeleteStatement(delete);
sql.append(deleteClause);
// From clause
sql.append(" ").append(getTableSQL(delete));
// Where clauses
List wheres = delete.getWheres();
if (!wheres.isEmpty()) {
sql.append(" ").append(getWhereSQL(delete));
}
return sql.toString();
}
@Override
public String getSelectSQL(Select select) {
StringBuilder clause = new StringBuilder();
clause.append(getSelectStatement(select));
clause.append(" ");
if (select.getColumns().isEmpty()) {
clause.append("*");
} else {
boolean first = true;
for (Column column : select.getColumns()) {
if (!first) {
clause.append(", ");
}
String str = getColumnSQL(column);
boolean aliasNonEmpty = !StringUtils.isBlank(column.getAlias());
boolean isSimpleColumn = (column instanceof SimpleColumn) && !str.equals(getColumnNameSQL(column.getAlias()));
if (aliasNonEmpty && (allowAliasInStatements() || isSimpleColumn)) {
str += " " + getAliasForColumnSQL(column.getAlias());
}
clause.append(str);
first = false;
}
}
return clause.toString();
}
@Override
public String getFromSQL(Select select) {
String fromSelect = select.getFromSelect();
Table fromTable = select.getFromTable();
String from = getFromStatement(select);
if (fromSelect != null) {
String alias = getAliasForColumnSQL("dbSQL");
return from + " (" + fromSelect + ") " + alias;
}
else if (fromTable != null ){
String table = getTableSQL(select);
return from + " " + table;
}
return "";
}
@Override
public String getWhereSQL(Select select) {
StringBuilder sql = new StringBuilder();
List wheres = select.getWheres();
boolean first = true;
for (Condition condition : wheres) {
if (first) {
sql.append(getWhereStatement(select)).append(" ");
} else {
sql.append(AND);
}
String str = getConditionSQL(condition);
sql.append(str);
first = false;
}
return sql.toString();
}
@Override
public String getWhereSQL(Delete delete) {
StringBuilder sql = new StringBuilder();
List wheres = delete.getWheres();
boolean first = true;
for (Condition condition : wheres) {
if (first) {
sql.append(getWhereStatement(delete)).append(" ");
} else {
sql.append(AND);
}
String str = getConditionSQL(condition);
sql.append(str);
first = false;
}
return sql.toString();
}
@Override
public String getGroupBySQL(Select select) {
StringBuilder sql = new StringBuilder();
List groupBys = select.getGroupBys();
boolean first = true;
for (Column column : groupBys) {
if (first) {
sql.append(getGroupByStatement(select)).append(" ");
} else {
sql.append(", ");
}
Column aliasColumn = allowAliasInStatements() ? getAliasStatement(select, column) : null;
sql.append(aliasColumn != null ? getAliasForStatementSQL(aliasColumn.getAlias()) : getColumnSQL(column));
first = false;
}
return sql.toString();
}
@Override
public String getOrderBySQL(Select select) {
StringBuilder sql = new StringBuilder();
List orderBys = select.getOrderBys();
boolean first = true;
for (SortColumn column : orderBys) {
if (first) {
sql.append(getOrderByStatement(select)).append(" ");
} else {
sql.append(", ");
}
Column aliasColumn = allowAliasInStatements() ? getAliasStatement(select, column.getSource()) : null;
if (aliasColumn != null) {
column = new SortColumn(aliasColumn, column.getOrder());
}
String str = getSortColumnSQL(column);
sql.append(str);
first = false;
}
return sql.toString();
}
@Override
public String getOffsetLimitSQL(Select select) {
int offset = select.getOffset();
int limit = select.getLimit();
StringBuilder out = new StringBuilder();
if (limit > 0) out.append(" LIMIT ").append(limit);
if (offset > 0) out.append(" OFFSET ").append(offset);
return out.toString();
}
@Override
public String getSelectStatement(Select select) {
return "SELECT";
}
@Override
public String getInsertStatement(Insert insert) {
return "INSERT INTO";
}
@Override
public String getDeleteStatement(Delete delete) {
return "DELETE FROM";
}
@Override
public String getFromStatement(Select select) {
return "FROM";
}
@Override
public String getWhereStatement(Select select) {
return "WHERE";
}
@Override
public String getWhereStatement(Delete delete) {
return "WHERE";
}
@Override
public String getGroupByStatement(Select select) {
return "GROUP BY";
}
@Override
public String getOrderByStatement(Select select) {
return "ORDER BY";
}
// Helper methods
protected Object invokeMethod(Object o, String methodName, Object[] params) {
Method methods[] = o.getClass().getMethods();
for (int i = 0; i < methods.length; ++i) {
if (methodName.equals(methods[i].getName())) {
try {
methods[i].setAccessible(true);
return methods[i].invoke(o, params);
}
catch (IllegalAccessException ex) {
return null;
}
catch (InvocationTargetException ite) {
return null;
}
}
}
return null;
}
public boolean areEquals(Column column1, Column column2) {
if (!column1.getName().equals(column2.getName())) {
return false;
}
if (!column1.getClass().getName().equals(column2.getClass().getName())) {
return false;
}
if (column1 instanceof DynamicDateColumn) {
DynamicDateColumn dd1 = (DynamicDateColumn) column1;
DynamicDateColumn dd2 = (DynamicDateColumn) column2;
if (!dd1.getDateType().equals(dd2.getDateType())) {
return false;
}
}
if (column1 instanceof FixedDateColumn) {
FixedDateColumn fd1 = (FixedDateColumn) column1;
FixedDateColumn fd2 = (FixedDateColumn) column2;
if (!fd1.getDateType().equals(fd2.getDateType())) {
return false;
}
}
return true;
}
public boolean allowAliasInStatements() {
return false;
}
public Column getAliasStatement(Select select, Column target) {
for (Column column : select.getColumns()) {
if (!(column instanceof SimpleColumn) &&
!StringUtils.isBlank(column.getAlias()) &&
areEquals(column, target)) {
return column;
}
}
return null;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy