001    package liquibase.sqlgenerator.core;
002    
003    import liquibase.database.Database;
004    import liquibase.database.core.FirebirdDatabase;
005    import liquibase.database.core.InformixDatabase;
006    import liquibase.database.core.MSSQLDatabase;
007    import liquibase.database.core.OracleDatabase;
008    import liquibase.database.core.PostgresDatabase;
009    import liquibase.database.core.SQLiteDatabase;
010    import liquibase.exception.ValidationErrors;
011    import liquibase.sql.Sql;
012    import liquibase.sql.UnparsedSql;
013    import liquibase.sqlgenerator.SqlGeneratorChain;
014    import liquibase.statement.core.DropPrimaryKeyStatement;
015    
016    public class DropPrimaryKeyGenerator extends AbstractSqlGenerator<DropPrimaryKeyStatement> {
017    
018        @Override
019        public boolean supports(DropPrimaryKeyStatement statement, Database database) {
020            return (!(database instanceof SQLiteDatabase));
021        }
022    
023        @Override
024        public ValidationErrors validate(DropPrimaryKeyStatement dropPrimaryKeyStatement, Database database,
025                SqlGeneratorChain sqlGeneratorChain) {
026            ValidationErrors validationErrors = new ValidationErrors();
027            validationErrors.checkRequiredField("tableName", dropPrimaryKeyStatement.getTableName());
028    
029            if (database instanceof FirebirdDatabase || database instanceof InformixDatabase) {
030                validationErrors.checkRequiredField("constraintName", dropPrimaryKeyStatement.getConstraintName());
031            }
032    
033            return validationErrors;
034        }
035    
036        @Override
037        public Sql[] generateSql(DropPrimaryKeyStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain) {
038            String sql;
039    
040            if (database instanceof MSSQLDatabase) {
041                if (statement.getConstraintName() == null) {
042                    StringBuilder query = new StringBuilder();
043                    query.append("DECLARE @pkname nvarchar(255)");
044                    query.append("\n");
045                    query.append("DECLARE @sql nvarchar(2048)");
046                    query.append("\n");
047                    query.append("select @pkname=i.name from sysindexes i");
048                    query.append(" join sysobjects o ON i.id = o.id");
049                    query.append(" join sysobjects pk ON i.name = pk.name AND pk.parent_obj = i.id AND pk.xtype = 'PK'");
050                    query.append(" join sysindexkeys ik on i.id = ik.id AND i.indid = ik.indid");
051                    query.append(" join syscolumns c ON ik.id = c.id AND ik.colid = c.colid");
052                    query.append(" where o.name = '").append(statement.getTableName()).append("'");
053                    query.append("\n");
054                    query.append("set @sql='alter table ")
055                            .append(database.escapeTableName(statement.getSchemaName(), statement.getTableName()))
056                            .append(" drop constraint ' + @pkname");
057                    query.append("\n");
058                    query.append("exec(@sql)");
059                    query.append("\n");
060                    sql = query.toString();
061                } else {
062                    sql = "ALTER TABLE " + database.escapeTableName(statement.getSchemaName(), statement.getTableName())
063                            + " DROP CONSTRAINT " + database.escapeConstraintName(statement.getConstraintName());
064                }
065            } else if (database instanceof PostgresDatabase) {
066                if (statement.getConstraintName() == null) {
067                    StringBuilder query = new StringBuilder();
068                    query.append("create or replace function __liquibase_drop_pk(tableName text) returns void as $$");
069                    query.append(" declare");
070                    query.append(" pkname text;");
071                    query.append(" sql text;");
072                    query.append(" begin");
073                    query.append(" pkname = c.conname");
074                    query.append(" from pg_class r, pg_constraint c");
075                    query.append(" where r.oid = c.conrelid");
076                    query.append(" and contype = 'p'");
077                    query.append(" and relname ilike tableName;");
078                    query.append(" sql = 'alter table ' || tableName || ' drop constraint ' || pkname;");
079                    query.append(" execute sql;");
080                    query.append(" end;");
081                    query.append(" $$ language plpgsql;");
082                    query.append(" select __liquibase_drop_pk('").append(statement.getTableName()).append("');");
083                    query.append(" drop function __liquibase_drop_pk(tableName text);");
084                    sql = query.toString();
085                } else {
086                    sql = "ALTER TABLE " + database.escapeTableName(statement.getSchemaName(), statement.getTableName())
087                            + " DROP CONSTRAINT " + database.escapeConstraintName(statement.getConstraintName());
088                }
089            } else if (database instanceof FirebirdDatabase) {
090                sql = "ALTER TABLE " + database.escapeTableName(statement.getSchemaName(), statement.getTableName())
091                        + " DROP CONSTRAINT " + database.escapeConstraintName(statement.getConstraintName());
092            } else if (database instanceof OracleDatabase) {
093                sql = "ALTER TABLE " + database.escapeTableName(statement.getSchemaName(), statement.getTableName())
094                        + " DROP PRIMARY KEY DROP INDEX";
095            } else if (database instanceof InformixDatabase) {
096                sql = "ALTER TABLE " + database.escapeTableName(statement.getSchemaName(), statement.getTableName())
097                        + " DROP CONSTRAINT " + database.escapeConstraintName(statement.getConstraintName());
098            } else {
099                sql = "ALTER TABLE " + database.escapeTableName(statement.getSchemaName(), statement.getTableName())
100                        + " DROP PRIMARY KEY";
101            }
102    
103            return new Sql[] { new UnparsedSql(sql) };
104        }
105    }