package liquibase.sqlgenerator.core;
import liquibase.database.Database;
import liquibase.database.core.*;
import liquibase.exception.DatabaseException;
import liquibase.exception.ValidationErrors;
import liquibase.sql.Sql;
import liquibase.sql.UnparsedSql;
import liquibase.sqlgenerator.SqlGeneratorChain;
import liquibase.statement.core.DropPrimaryKeyStatement;
import liquibase.structure.core.PrimaryKey;
import liquibase.structure.core.Table;
import liquibase.structure.core.Schema;
public class DropPrimaryKeyGenerator extends AbstractSqlGenerator<DropPrimaryKeyStatement> {
@Override
public boolean supports(DropPrimaryKeyStatement statement, Database database) {
return (!(database instanceof SQLiteDatabase));
}
@Override
public ValidationErrors validate(DropPrimaryKeyStatement dropPrimaryKeyStatement, Database database, SqlGeneratorChain sqlGeneratorChain) {
ValidationErrors validationErrors = new ValidationErrors();
validationErrors.checkRequiredField("tableName", dropPrimaryKeyStatement.getTableName());
if (database instanceof FirebirdDatabase || database instanceof InformixDatabase) {
validationErrors.checkRequiredField("constraintName", dropPrimaryKeyStatement.getConstraintName());
}
return validationErrors;
}
@Override
public Sql[] generateSql(DropPrimaryKeyStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain) {
String sql;
if (database instanceof MSSQLDatabase) {
String escapedTableName = database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName());
if (statement.getConstraintName() == null) {
boolean sql2005OrLater = true;
try {
sql2005OrLater = database.getDatabaseMajorVersion() >= 9;
} catch (DatabaseException e) {
// Assume SQL Server 2005 or later
}
if (sql2005OrLater) {
// SQL Server 2005 or later
sql =
"DECLARE @sql [nvarchar](MAX)\r\n" +
"SELECT @sql = N'ALTER TABLE " + database.escapeStringForDatabase(escapedTableName) + " DROP CONSTRAINT ' + QUOTENAME([kc].[name]) " +
"FROM [sys].[key_constraints] AS [kc] " +
"WHERE [kc].[parent_object_id] = OBJECT_ID(N'" + database.escapeStringForDatabase(escapedTableName) + "') " +
"AND [kc].[type] = 'PK'\r\n" +
"EXEC sp_executesql @sql";
} else {
// SQL Server 2000
sql =
"DECLARE @sql [nvarchar](4000)\r\n" +
"SELECT @sql = N'ALTER TABLE " + database.escapeStringForDatabase(escapedTableName) + " DROP CONSTRAINT ' + QUOTENAME([kc].[name]) " +
"FROM [dbo].[sysobjects] AS [kc] " +
"WHERE [kc].[parent_obj] = OBJECT_ID(N'" + database.escapeStringForDatabase(escapedTableName) + "') " +
"AND [kc].[xtype] = 'PK'\r\n" +
"EXEC sp_executesql @sql";
}
} else {
sql = "ALTER TABLE " + escapedTableName + " DROP CONSTRAINT " + database.escapeConstraintName(statement.getConstraintName());
}
} else if (database instanceof PostgresDatabase) {
if (statement.getConstraintName() == null) {
String schemaName = statement.getSchemaName() != null ? statement.getSchemaName() : database.getDefaultSchemaName();
schemaName = database.correctObjectName(schemaName, Schema.class);
String tableName = database.correctObjectName(statement.getTableName(), Table.class);
sql = String.format(""
+ "DO $$ DECLARE constraint_name varchar;\n"
+ "BEGIN\n"
+ " SELECT tc.CONSTRAINT_NAME into strict constraint_name\n"
+ " FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc\n"
+ " WHERE CONSTRAINT_TYPE = 'PRIMARY KEY'\n"
+ " AND TABLE_NAME = '%2$s' AND TABLE_SCHEMA = '%1$s';\n"
+ " EXECUTE 'alter table %1$s.%2$s drop constraint ' || constraint_name;\n"
+ "END $$;"
, schemaName, tableName);
} else {
sql = "ALTER TABLE " + database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName()) + " DROP CONSTRAINT " + database.escapeConstraintName(statement.getConstraintName());
}
} else if (database instanceof FirebirdDatabase) {
sql = "ALTER TABLE " + database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName()) + " DROP CONSTRAINT "+database.escapeConstraintName(statement.getConstraintName());
} else if (database instanceof OracleDatabase) {
sql = "ALTER TABLE " + database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName()) + " DROP PRIMARY KEY";
if (statement.getDropIndex() == null || statement.getDropIndex()) {
sql += " DROP INDEX";
} else {
sql += " KEEP INDEX";
}
} else if (database instanceof InformixDatabase) {
sql = "ALTER TABLE " + database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName()) + " DROP CONSTRAINT " + database.escapeConstraintName(statement.getConstraintName());
} else if (database instanceof SybaseDatabase) {
String escapedTableName = database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName());
String escapedConstraintName = database.escapeConstraintName(statement.getConstraintName());
sql = "ALTER TABLE " + escapedTableName + " DROP CONSTRAINT " + escapedConstraintName;
} else {
sql = "ALTER TABLE " + database.escapeTableName(statement.getCatalogName(), statement.getSchemaName(), statement.getTableName()) + " DROP PRIMARY KEY";
}
return new Sql[] {
new UnparsedSql(sql, getAffectedPrimaryKey(statement))
};
}
protected PrimaryKey getAffectedPrimaryKey(DropPrimaryKeyStatement statement) {
return new PrimaryKey().setName(statement.getConstraintName()).setTable((Table) new Table().setName(statement.getTableName()).setSchema(statement.getCatalogName(), statement.getSchemaName()));
}
}