001: package liquibase.change;
002:
003: import liquibase.ChangeSet;
004: import liquibase.FileOpener;
005: import liquibase.database.Database;
006: import liquibase.database.sql.SqlStatement;
007: import liquibase.database.structure.DatabaseObject;
008: import liquibase.exception.*;
009: import org.w3c.dom.Document;
010: import org.w3c.dom.Element;
011:
012: import java.io.IOException;
013: import java.io.Writer;
014: import java.util.Set;
015:
016: /**
017: * Interface all changes (refactorings) implement.
018: * <p>
019: * <b>How changes are constructed and run when reading changelogs:</b>
020: * <ol>
021: * <li>As the changelog handler gets to each element inside a changeSet, it passes the tag name to liquibase.change.ChangeFactory
022: * which looks through all the registered changes until it finds one with matching specified tag name</li>
023: * <li>The ChangeFactory then constructs a new instance of the change</li>
024: * <li>For each attribute in the XML node, reflection is used to call a corresponding set* method on the change class</li>
025: * <li>The correct generateStatements(*) method is called for the current database</li>
026: * </ol>
027: * <p>
028: * <b>To implement a new change:</b>
029: * <ol>
030: * <li>Create a new class that implements Change (normally extend AbstractChange)</li>
031: * <li>Implement the abstract generateStatements(*) methods which return the correct SQL calls for each database</li>
032: * <li>Implement the createMessage() method to create a descriptive message for logs and dialogs
033: * <li>Implement the createNode() method to generate an XML element based on the values in this change</li>
034: * <li>Add the new class to the liquibase.change.ChangeFactory</li>
035: * </ol>
036: * <p><b>Implementing automatic rollback support</b><br><br>
037: * The easiest way to allow automatic rollback support is by overriding the createInverses() method.
038: * If there are no corresponding inverse changes, you can override the generateRollbackStatements(*) and canRollBack() methods.
039: * <p>
040: * <b>Notes for generated SQL:</b><br>
041: * Because migration and rollback scripts can be generated for execution at a different time, or against a different database,
042: * changes you implement cannot directly reference data in the database. For example, you cannot implement a change that selects
043: * 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
044: * exist and/or new rows may have been added.
045: * <p>
046: * We chose the name "change" over "refactoring" because changes will sometimes change functionality whereas true refactoring will not.
047: *
048: * @see ChangeFactory
049: * @see Database
050: */
051: public interface Change {
052:
053: /**
054: * Returns the name of this change
055: *
056: * @return the name of the change
057: */
058: public String getChangeName();
059:
060: /**
061: * Returns the tag name of this change
062: *
063: * @return the tag name of the change
064: */
065: public String getTagName();
066:
067: /**
068: * Executes the statements in this change against the database passed in the argument
069: *
070: * @param database the reference to the target {@link Database}
071: * to which the statements are executed
072: * @throws JDBCException if there were problems executing the statements
073: * @throws UnsupportedChangeException if this change is not supported by the {@link Database} passed as argument
074: */
075: public void executeStatements(Database database)
076: throws JDBCException, UnsupportedChangeException;
077:
078: /**
079: * Outputs the SQL statements generated by this change
080: *
081: * @param database the target {@link Database} associated to this change's statements
082: * @param writer the target {@link Writer} to which the statements are <i>appended</i>
083: * @throws IOException if there were problems appending the statements to the writer
084: * @throws UnsupportedChangeException if this change is not supported by the {@link Database} passed as argument
085: */
086: public void saveStatements(Database database, Writer writer)
087: throws IOException, UnsupportedChangeException,
088: StatementNotSupportedOnDatabaseException;
089:
090: /**
091: * Rolls back the statements in this change against the {@link Database} passed as argument
092: *
093: * @param database the target {@link Database} associated to this change's rollback statements
094: * @throws JDBCException if there were problems executing the rollback statements
095: * @throws UnsupportedChangeException if this change is not supported by the {@link Database} passed as argument
096: * @throws RollbackImpossibleException if rollback is not supported for this change
097: */
098: public void executeRollbackStatements(Database database)
099: throws JDBCException, UnsupportedChangeException,
100: RollbackImpossibleException;
101:
102: /**
103: * Outputs the statements necessary to roll back this change
104: *
105: * @param database the target {@link Database} associated to this change's rollback statements
106: * @param writer writer the target {@link Writer} to which the rollback statements are <i>appended</i>
107: * @throws IOException if there were problems appending the rollback statements to the writer
108: * @throws UnsupportedChangeException if this change is not supported by the {@link Database} passed as argument
109: * @throws RollbackImpossibleException if rollback is not supported for this change
110: */
111: public void saveRollbackStatement(Database database, Writer writer)
112: throws IOException, UnsupportedChangeException,
113: RollbackImpossibleException,
114: StatementNotSupportedOnDatabaseException;
115:
116: /**
117: * Generates the SQL statements required to run the change
118: *
119: * @param database databasethe target {@link Database} associated to this change's statements
120: * @return an array of {@link String}s with the statements
121: * @throws UnsupportedChangeException if this change is not supported by the {@link Database} passed as argument
122: */
123: public SqlStatement[] generateStatements(Database database)
124: throws UnsupportedChangeException;
125:
126: /**
127: * Generates the SQL statements required to roll back the change
128: *
129: * @param database database databasethe target {@link Database} associated to this change's rollback statements
130: * @return an array of {@link String}s with the rollback statements
131: * @throws UnsupportedChangeException if this change is not supported by the {@link Database} passed as argument
132: * @throws RollbackImpossibleException if rollback is not supported for this change
133: */
134: public SqlStatement[] generateRollbackStatements(Database database)
135: throws UnsupportedChangeException,
136: RollbackImpossibleException;
137:
138: /**
139: * Can this change be rolled back
140: *
141: * @return <i>true</i> if rollback is supported, <i>false</i> otherwise
142: */
143: public boolean canRollBack();
144:
145: /**
146: * Confirmation message to be displayed after the change is executed
147: *
148: * @return a {@link String} containing the message after the change is executed
149: */
150: public String getConfirmationMessage();
151:
152: /**
153: * Creates an XML element (of type {@link Element}) of the change object, and adds it
154: * to the {@link Document} object passed as argument
155: *
156: * @param currentChangeLogDOM the current {@link Document} where this element is being added
157: * @return the {@link Element} object created
158: */
159: public Element createNode(Document currentChangeLogDOM);
160:
161: /**
162: * Calculates the MD5 hash for the string representation of the XML element
163: * of this change
164: *
165: * @return the MD5 hash
166: */
167: public String getMD5Sum();
168:
169: /**
170: * Sets the fileOpener that should be used for any file loading and resource
171: * finding for files that are provided by the user.
172: */
173: public void setFileOpener(FileOpener fileOpener);
174:
175: /**
176: * This method will be called after the no arg constructor and all of the
177: * properties have been set to allow the task to do any heavy tasks or
178: * more importantly generate any exceptions to report to the user about
179: * the settings provided.
180: *
181: */
182: public void setUp() throws SetupException;
183:
184: public Set<DatabaseObject> getAffectedDatabaseObjects();
185:
186: public ChangeSet getChangeSet();
187:
188: public void setChangeSet(ChangeSet changeSet);
189: }
|