package liquibase.ext.oracle.preconditions; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import liquibase.changelog.ChangeSet; import liquibase.changelog.DatabaseChangeLog; import liquibase.database.Database; import liquibase.database.jvm.JdbcConnection; import liquibase.exception.DatabaseException; import liquibase.exception.PreconditionErrorException; import liquibase.exception.PreconditionFailedException; import liquibase.exception.ValidationErrors; import liquibase.exception.Warnings; import liquibase.precondition.Precondition; import liquibase.util.StringUtils; public class OraclePrimaryKeyExistsPrecondition extends OraclePrecondition { private String primaryKeyName; private String tableName; public String getTableName() { return tableName; } public void setTableName( String tableName ) { this.tableName = tableName; } public String getName() { return "oraclePrimaryKeyExists"; } public String getPrimaryKeyName() { return primaryKeyName; } public void setPrimaryKeyName( String constraintName ) { this.primaryKeyName = constraintName; } public Warnings warn( Database database ) { return new Warnings(); } public ValidationErrors validate( Database database ) { return new ValidationErrors(); } public void check( Database database, DatabaseChangeLog changeLog, ChangeSet changeSet ) throws PreconditionFailedException, PreconditionErrorException { JdbcConnection connection = (JdbcConnection) database.getConnection(); PreparedStatement ps = null; ResultSet rs = null; try { /* THE CONSTRAINT_TYPE will tell you what type of constraint it is R - Referential key ( foreign key) U - Unique key P - Primary key C - Check constraint */ final String sql = "select constraint_name from all_constraints where table_name = upper(?) and upper(owner) = upper(?) and constraint_type = 'P'"; ps = connection.prepareStatement( sql ); ps.setString( 1, getTableName() ); ps.setString( 2, database.getLiquibaseSchemaName() ); rs = ps.executeQuery(); if ( !rs.next() ) { throw new PreconditionFailedException( String.format( "The primary key '%s' was not found on the table '%s.%s'.", getPrimaryKeyName(), database.getLiquibaseSchemaName(), getTableName() ), changeLog, this ); } else { String name = rs.getString( 1 ); if ( getPrimaryKeyName() != null && getPrimaryKeyName().length() > 0 ) { // check the name is the same, otherwise presume we are fine. if ( ! name.equalsIgnoreCase( getPrimaryKeyName() ) ) { throw new PreconditionFailedException( String.format( "The primary key '%s' was not found on the table '%s.%s'.", getPrimaryKeyName(), database.getLiquibaseSchemaName(), getTableName() ), changeLog, this ); } } } } catch ( SQLException e ) { throw new PreconditionErrorException( e, changeLog, this ); } catch ( DatabaseException e ) { throw new PreconditionErrorException( e, changeLog, this ); } finally { closeSilently( rs ); closeSilently( ps ); } } }