package liquibase.sqlgenerator.core; import liquibase.change.ColumnConfig; import liquibase.database.Database; import liquibase.database.core.*; import liquibase.exception.UnexpectedLiquibaseException; import liquibase.exception.ValidationErrors; import liquibase.sql.Sql; import liquibase.sql.UnparsedSql; import liquibase.sqlgenerator.SqlGeneratorChain; import liquibase.statement.core.SelectFromDatabaseChangeLogStatement; import liquibase.util.StringUtils; import java.util.Arrays; import java.util.Iterator; import java.util.List; public class SelectFromDatabaseChangeLogGenerator extends AbstractSqlGenerator<SelectFromDatabaseChangeLogStatement> { @Override public ValidationErrors validate(SelectFromDatabaseChangeLogStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain) { ValidationErrors errors = new ValidationErrors(); errors.checkRequiredField("columnToSelect", statement.getColumnsToSelect()); return errors; } @Override public Sql[] generateSql(SelectFromDatabaseChangeLogStatement statement, final Database database, SqlGeneratorChain sqlGeneratorChain) { List<ColumnConfig> columnsToSelect = Arrays.asList(statement.getColumnsToSelect()); String sql = "SELECT " + (database instanceof MSSQLDatabase && statement.getLimit() != null ? "TOP "+statement.getLimit()+" " : "") + StringUtils.join(columnsToSelect, ",", new StringUtils.StringUtilsFormatter<ColumnConfig>() { @Override public String toString(ColumnConfig column) { if (column.getComputed() != null && column.getComputed()) { return column.getName(); } else { return database.escapeColumnName(null, null, null, column.getName()); } } }).toUpperCase() + " FROM " + database.escapeTableName(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), database.getDatabaseChangeLogTableName()); SelectFromDatabaseChangeLogStatement.WhereClause whereClause = statement.getWhereClause(); if (whereClause != null) { if (whereClause instanceof SelectFromDatabaseChangeLogStatement.ByTag) { sql += " WHERE "+database.escapeColumnName(null, null, null, "TAG")+"='" + ((SelectFromDatabaseChangeLogStatement.ByTag) whereClause).getTagName() + "'"; } else if (whereClause instanceof SelectFromDatabaseChangeLogStatement.ByNotNullCheckSum) { sql += " WHERE "+database.escapeColumnName(null, null, null, "MD5SUM")+" IS NOT NULL"; } else { throw new UnexpectedLiquibaseException("Unknown where clause type: " + whereClause.getClass().getName()); } } if (statement.getOrderByColumns() != null && statement.getOrderByColumns().length > 0) { sql += " ORDER BY "; Iterator<String> orderBy = Arrays.asList(statement.getOrderByColumns()).iterator(); while (orderBy.hasNext()) { String orderColumn = orderBy.next(); String[] orderColumnData = orderColumn.split(" "); sql += database.escapeColumnName(null, null, null, orderColumnData[0]); if (orderColumnData.length == 2) { sql += " "; sql += orderColumnData[1].toUpperCase(); } if (orderBy.hasNext()) { sql += ", "; } } } if (statement.getLimit() != null) { if (database instanceof OracleDatabase) { if (whereClause == null) { sql += " WHERE ROWNUM="+statement.getLimit(); } else { sql += " AND ROWNUM="+statement.getLimit(); } } else if (database instanceof MySQLDatabase || database instanceof PostgresDatabase) { sql += " LIMIT "+statement.getLimit(); } else if (database instanceof DB2Database) { sql += " FETCH FIRST "+statement.getLimit()+" ROWS ONLY"; } } return new Sql[]{ new UnparsedSql(sql) }; } }