001: package liquibase.change;
002:
003: import liquibase.database.Database;
004: import liquibase.database.sql.AddForeignKeyConstraintStatement;
005: import liquibase.database.sql.SqlStatement;
006: import liquibase.database.structure.Column;
007: import liquibase.database.structure.DatabaseObject;
008: import liquibase.database.structure.ForeignKey;
009: import liquibase.database.structure.Table;
010: import liquibase.exception.UnsupportedChangeException;
011: import org.w3c.dom.Document;
012: import org.w3c.dom.Element;
013:
014: import java.util.HashSet;
015: import java.util.Set;
016:
017: /**
018: * Adds a foreign key constraint to an existing column.
019: */
020: public class AddForeignKeyConstraintChange extends AbstractChange {
021: private String baseTableSchemaName;
022: private String baseTableName;
023: private String baseColumnNames;
024:
025: private String referencedTableSchemaName;
026: private String referencedTableName;
027: private String referencedColumnNames;
028:
029: private String constraintName;
030:
031: private Boolean deferrable;
032: private Boolean initiallyDeferred;
033:
034: private Boolean deleteCascade;
035:
036: public AddForeignKeyConstraintChange() {
037: super ("addForeignKeyConstraint", "Add Foreign Key Constraint");
038: }
039:
040: public String getBaseTableSchemaName() {
041: return baseTableSchemaName;
042: }
043:
044: public void setBaseTableSchemaName(String baseTableSchemaName) {
045: this .baseTableSchemaName = baseTableSchemaName;
046: }
047:
048: public String getBaseTableName() {
049: return baseTableName;
050: }
051:
052: public void setBaseTableName(String baseTableName) {
053: this .baseTableName = baseTableName;
054: }
055:
056: public String getBaseColumnNames() {
057: return baseColumnNames;
058: }
059:
060: public void setBaseColumnNames(String baseColumnNames) {
061: this .baseColumnNames = baseColumnNames;
062: }
063:
064: public String getReferencedTableSchemaName() {
065: return referencedTableSchemaName;
066: }
067:
068: public void setReferencedTableSchemaName(
069: String referencedTableSchemaName) {
070: this .referencedTableSchemaName = referencedTableSchemaName;
071: }
072:
073: public String getReferencedTableName() {
074: return referencedTableName;
075: }
076:
077: public void setReferencedTableName(String referencedTableName) {
078: this .referencedTableName = referencedTableName;
079: }
080:
081: public String getReferencedColumnNames() {
082: return referencedColumnNames;
083: }
084:
085: public void setReferencedColumnNames(String referencedColumnNames) {
086: this .referencedColumnNames = referencedColumnNames;
087: }
088:
089: public String getConstraintName() {
090: return constraintName;
091: }
092:
093: public void setConstraintName(String constraintName) {
094: this .constraintName = constraintName;
095: }
096:
097: public Boolean getDeferrable() {
098: return deferrable;
099: }
100:
101: public void setDeferrable(Boolean deferrable) {
102: this .deferrable = deferrable;
103: }
104:
105: public Boolean getInitiallyDeferred() {
106: return initiallyDeferred;
107: }
108:
109: public void setInitiallyDeferred(Boolean initiallyDeferred) {
110: this .initiallyDeferred = initiallyDeferred;
111: }
112:
113: public Boolean getDeleteCascade() {
114: return deleteCascade;
115: }
116:
117: public void setDeleteCascade(Boolean deleteCascade) {
118: this .deleteCascade = deleteCascade;
119: }
120:
121: public SqlStatement[] generateStatements(Database database)
122: throws UnsupportedChangeException {
123: boolean deferrable = false;
124: if (getDeferrable() != null) {
125: deferrable = getDeferrable();
126: }
127:
128: boolean initiallyDeferred = false;
129: if (getInitiallyDeferred() != null) {
130: initiallyDeferred = getInitiallyDeferred();
131: }
132:
133: boolean deleteCascade = false;
134: if (getDeleteCascade() != null) {
135: deleteCascade = getDeleteCascade();
136: }
137:
138: return new SqlStatement[] { new AddForeignKeyConstraintStatement(
139: getConstraintName(),
140: getBaseTableSchemaName() == null ? database
141: .getDefaultSchemaName()
142: : getBaseTableSchemaName(), getBaseTableName(),
143: getBaseColumnNames(),
144: getReferencedTableSchemaName() == null ? database
145: .getDefaultSchemaName()
146: : getReferencedTableSchemaName(),
147: getReferencedTableName(), getReferencedColumnNames())
148: .setDeferrable(deferrable).setInitiallyDeferred(
149: initiallyDeferred).setDeleteCascade(
150: deleteCascade) };
151: }
152:
153: protected Change[] createInverses() {
154: DropForeignKeyConstraintChange inverse = new DropForeignKeyConstraintChange();
155: inverse.setBaseTableSchemaName(getBaseTableSchemaName());
156: inverse.setBaseTableName(getBaseTableName());
157: inverse.setConstraintName(getConstraintName());
158:
159: return new Change[] { inverse };
160: }
161:
162: public String getConfirmationMessage() {
163: return "Foreign key contraint added to " + getBaseTableName()
164: + " (" + getBaseColumnNames() + ")";
165: }
166:
167: public Element createNode(Document currentChangeLogFileDOM) {
168: Element node = currentChangeLogFileDOM
169: .createElement(getTagName());
170:
171: if (getBaseTableSchemaName() != null) {
172: node.setAttribute("baseTableSchemaName",
173: getBaseTableSchemaName());
174: }
175:
176: node.setAttribute("baseTableName", getBaseTableName());
177: node.setAttribute("baseColumnNames", getBaseColumnNames());
178: node.setAttribute("constraintName", getConstraintName());
179:
180: if (getReferencedTableSchemaName() != null) {
181: node.setAttribute("referencedTableSchemaName",
182: getReferencedTableSchemaName());
183: }
184: node.setAttribute("referencedTableName",
185: getReferencedTableName());
186: node.setAttribute("referencedColumnNames",
187: getReferencedColumnNames());
188:
189: if (getDeferrable() != null) {
190: node.setAttribute("deferrable", getDeferrable().toString());
191: }
192:
193: if (getInitiallyDeferred() != null) {
194: node.setAttribute("initiallyDeferred",
195: getInitiallyDeferred().toString());
196: }
197:
198: if (getDeleteCascade() != null) {
199: node.setAttribute("deleteCascade", getDeleteCascade()
200: .toString());
201: }
202: return node;
203: }
204:
205: public Set<DatabaseObject> getAffectedDatabaseObjects() {
206: Set<DatabaseObject> returnSet = new HashSet<DatabaseObject>();
207:
208: Table baseTable = new Table(getBaseTableName());
209: returnSet.add(baseTable);
210:
211: for (String columnName : getBaseColumnNames().split(",")) {
212: Column baseColumn = new Column();
213: baseColumn.setTable(baseTable);
214: baseColumn.setName(columnName.trim());
215:
216: returnSet.add(baseColumn);
217: }
218:
219: Table referencedTable = new Table(getReferencedTableName());
220: returnSet.add(referencedTable);
221:
222: for (String columnName : getReferencedColumnNames().split(",")) {
223: Column referencedColumn = new Column();
224: referencedColumn.setTable(baseTable);
225: referencedColumn.setName(columnName.trim());
226:
227: returnSet.add(referencedColumn);
228: }
229:
230: ForeignKey fk = new ForeignKey();
231: fk.setName(constraintName);
232: fk.setForeignKeyTable(baseTable);
233: fk.setForeignKeyColumns(baseColumnNames);
234: fk.setPrimaryKeyTable(referencedTable);
235: fk.setPrimaryKeyColumns(referencedColumnNames);
236: returnSet.add(fk);
237:
238: return returnSet;
239:
240: }
241:
242: }
|