package liquibase.sqlgenerator.core;
import liquibase.database.Database;
import liquibase.database.core.*;
import liquibase.exception.ValidationErrors;
import liquibase.sql.Sql;
import liquibase.sql.UnparsedSql;
import liquibase.sqlgenerator.SqlGenerator;
import liquibase.sqlgenerator.SqlGeneratorChain;
import liquibase.statement.core.AddUniqueConstraintStatement;
import liquibase.structure.core.Column;
import liquibase.structure.core.Index;
import liquibase.structure.core.Table;
import liquibase.structure.core.UniqueConstraint;
import liquibase.util.StringUtils;
public class AddUniqueConstraintGenerator extends AbstractSqlGenerator<AddUniqueConstraintStatement> {
@Override
public boolean supports(AddUniqueConstraintStatement statement, Database database) {
return !(database instanceof SQLiteDatabase)
&& !(database instanceof SybaseDatabase)
&& !(database instanceof SybaseASADatabase)
&& !(database instanceof InformixDatabase)
;
}
@Override
public ValidationErrors validate(AddUniqueConstraintStatement addUniqueConstraintStatement, Database database, SqlGeneratorChain sqlGeneratorChain) {
ValidationErrors validationErrors = new ValidationErrors();
validationErrors.checkRequiredField("columnNames", addUniqueConstraintStatement.getColumnNames());
validationErrors.checkRequiredField("tableName", addUniqueConstraintStatement.getTableName());
if (!(database instanceof OracleDatabase)) {
validationErrors.checkDisallowedField("forIndexName", addUniqueConstraintStatement.getForIndexName(), database);
}
if (!(database instanceof MSSQLDatabase) && addUniqueConstraintStatement.isClustered()) {
validationErrors.checkDisallowedField("clustered", addUniqueConstraintStatement.isClustered(), database);
}
return validationErrors;
}
@Override
public Sql[] generateSql(AddUniqueConstraintStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain) {
String sql = null;
if (statement.getConstraintName() == null) {
sql = String.format("ALTER TABLE %s ADD UNIQUE" + (statement.isClustered() ? " CLUSTERED " : " ") + "(%s)"
, database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName())
, database.escapeColumnNameList(statement.getColumnNames())
);
} else {
sql = String.format("ALTER TABLE %s ADD CONSTRAINT %s UNIQUE" + (statement.isClustered() ? " CLUSTERED " : " ") + "(%s)"
, database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName())
, database.escapeConstraintName(statement.getConstraintName())
, database.escapeColumnNameList(statement.getColumnNames())
);
}
if (database instanceof OracleDatabase || database instanceof PostgresDatabase) {
if (statement.isDeferrable()) {
sql += " DEFERRABLE";
}
if (statement.isInitiallyDeferred()) {
sql += " INITIALLY DEFERRED";
}
if (statement.isDisabled()) {
sql += " DISABLE";
}
}
if (StringUtils.trimToNull(statement.getTablespace()) != null && database.supportsTablespaces()) {
if (database instanceof MSSQLDatabase) {
sql += " ON " + statement.getTablespace();
} else if (database instanceof DB2Database
|| database instanceof SybaseASADatabase
|| database instanceof InformixDatabase) {
; //not supported
} else {
sql += " USING INDEX TABLESPACE " + statement.getTablespace();
}
}
if (statement.getForIndexName() != null) {
sql += " USING INDEX " + database.escapeObjectName(statement.getForIndexCatalogName(), statement.getForIndexSchemaName(), statement.getForIndexName(), Index.class);
}
return new Sql[]{
new UnparsedSql(sql, getAffectedUniqueConstraint(statement))
};
}
protected UniqueConstraint getAffectedUniqueConstraint(AddUniqueConstraintStatement statement) {
UniqueConstraint uniqueConstraint = new UniqueConstraint()
.setName(statement.getConstraintName())
.setTable((Table) new Table().setName(statement.getTableName()).setSchema(statement.getCatalogName(), statement.getSchemaName()));
int i = 0;
for (Column column : Column.listFromNames(statement.getColumnNames())) {
uniqueConstraint.addColumn(i++, column);
}
return uniqueConstraint;
}
}