package liquibase.change;
import java.util.Set;
import liquibase.changelog.ChangeLogParameters;
import liquibase.changelog.ChangeSet;
import liquibase.database.Database;
import liquibase.database.structure.DatabaseObject;
import liquibase.exception.RollbackImpossibleException;
import liquibase.exception.SetupException;
import liquibase.exception.UnsupportedChangeException;
import liquibase.exception.ValidationErrors;
import liquibase.exception.Warnings;
import liquibase.resource.ResourceAccessor;
import liquibase.statement.SqlStatement;
/**
* Interface all changes (refactorings) implement.
* <p/>
* <b>How changes are constructed and run when reading changelogs:</b>
* <ol>
* <li>As the changelog handler gets to each element inside a changeSet, it passes the tag name to liquibase.change.ChangeFactory
* which looks through all the registered changes until it finds one with matching specified tag name</li>
* <li>The ChangeFactory then constructs a new instance of the change</li>
* <li>For each attribute in the XML node, reflection is used to call a corresponding set* method on the change class</li>
* <li>The correct generateStatements(*) method is called for the current database</li>
* </ol>
* <p/>
* <b>To implement a new change:</b>
* <ol>
* <li>Create a new class that implements Change (normally extend AbstractChange)</li>
* <li>Implement the abstract generateStatements(*) methods which return the correct SQL calls for each database</li>
* <li>Implement the createMessage() method to create a descriptive message for logs and dialogs
* <li>Implement the createNode() method to generate an XML element based on the values in this change</li>
* <li>Add the new class to the liquibase.change.ChangeFactory</li>
* </ol>
* <p><b>Implementing automatic rollback support</b><br><br>
* The easiest way to allow automatic rollback support is by overriding the createInverses() method.
* If there are no corresponding inverse changes, you can override the generateRollbackStatements(*) and canRollBack() methods.
* <p/>
* <b>Notes for generated SQL:</b><br>
* Because migration and rollback scripts can be generated for execution at a different time, or against a different database,
* changes you implement cannot directly reference data in the database. For example, you cannot implement a change that selects
* all rows from a database and modifies them based on the primary keys you find because when the SQL is actually run, those rows may not longer
* exist and/or new rows may have been added.
* <p/>
* We chose the name "change" over "refactoring" because changes will sometimes change functionality whereas true refactoring will not.
*
* @see ChangeFactory
* @see Database
*/
public interface Change {
public ChangeMetaData getChangeMetaData();
public ChangeSet getChangeSet();
public void setChangeSet(ChangeSet changeSet);
/**
* Sets the fileOpener that should be used for any file loading and resource
* finding for files that are provided by the user.
*/
public void setResourceAccessor(ResourceAccessor resourceAccessor);
/**
* This method will be called after the no arg constructor and all of the
* properties have been set to allow the task to do any heavy tasks or
* more importantly generate any exceptions to report to the user about
* the settings provided.
*/
public void init() throws SetupException;
boolean supports(Database database);
public Warnings warn(Database database);
public ValidationErrors validate(Database database);
public Set<DatabaseObject> getAffectedDatabaseObjects(Database database);
/**
* Calculates the checksum (currently MD5 hash) for the current configuration of this change.
*/
public CheckSum generateCheckSum();
/**
* @return Confirmation message to be displayed after the change is executed
*/
public String getConfirmationMessage();
/**
* Generates the SQL statements required to run the change
*
* @param database databasethe target {@link liquibase.database.Database} associated to this change's statements
* @return an array of {@link String}s with the statements
*/
public SqlStatement[] generateStatements(Database database);
/**
* Can this change be rolled back
*
* @return <i>true</i> if rollback is supported, <i>false</i> otherwise
* @param database
*/
public boolean supportsRollback(Database database);
/**
* Generates the SQL statements required to roll back the change
*
* @param database database databasethe target {@link Database} associated to this change's rollback statements
* @return an array of {@link String}s with the rollback statements
* @throws UnsupportedChangeException if this change is not supported by the {@link Database} passed as argument
* @throws RollbackImpossibleException if rollback is not supported for this change
*/
public SqlStatement[] generateRollbackStatements(Database database) throws UnsupportedChangeException, RollbackImpossibleException;
/**
* Does this change require access to the database metadata? If true, the change cannot be used in an updateSql-style command.
*/
public boolean requiresUpdatedDatabaseMetadata(Database database);
/**
* @param changeLogParameters
*/
public void setChangeLogParameters(ChangeLogParameters changeLogParameters);
}