1 package liquibase.change.core;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import liquibase.change.AbstractChange;
7 import liquibase.change.Change;
8 import liquibase.change.ChangeMetaData;
9 import liquibase.change.ColumnConfig;
10 import liquibase.database.Database;
11 import liquibase.database.core.DB2Database;
12 import liquibase.database.core.SQLiteDatabase;
13 import liquibase.database.core.SQLiteDatabase.AlterTableVisitor;
14 import liquibase.database.structure.Index;
15 import liquibase.statement.SqlStatement;
16 import liquibase.statement.core.ReorganizeTableStatement;
17 import liquibase.statement.core.SetNullableStatement;
18 import liquibase.statement.core.UpdateStatement;
19 import liquibase.util.StringUtils;
20
21
22
23
24 public class AddNotNullConstraintChange extends AbstractChange {
25 private String schemaName;
26 private String tableName;
27 private String columnName;
28 private String defaultNullValue;
29 private String columnDataType;
30
31 public AddNotNullConstraintChange() {
32 super("addNotNullConstraint", "Add Not-Null Constraint", ChangeMetaData.PRIORITY_DEFAULT);
33 }
34
35 public String getSchemaName() {
36 return schemaName;
37 }
38
39 public void setSchemaName(String schemaName) {
40 this.schemaName = StringUtils.trimToNull(schemaName);
41 }
42
43 public String getTableName() {
44 return tableName;
45 }
46
47 public void setTableName(String tableName) {
48 this.tableName = tableName;
49 }
50
51 public String getColumnName() {
52 return columnName;
53 }
54
55 public void setColumnName(String columnName) {
56 this.columnName = columnName;
57 }
58
59 public String getDefaultNullValue() {
60 return defaultNullValue;
61 }
62
63 public void setDefaultNullValue(String defaultNullValue) {
64 this.defaultNullValue = defaultNullValue;
65 }
66
67 public String getColumnDataType() {
68 return columnDataType;
69 }
70
71 public void setColumnDataType(String columnDataType) {
72 this.columnDataType = columnDataType;
73 }
74
75 @Override
76 public SqlStatement[] generateStatements(Database database) {
77
78
79
80
81
82
83 List<SqlStatement> statements = new ArrayList<SqlStatement>();
84 String schemaName = getSchemaName() == null ? database.getDefaultSchemaName() : getSchemaName();
85
86 if (defaultNullValue != null) {
87 statements.add(new UpdateStatement(schemaName, getTableName()).addNewColumnValue(getColumnName(),
88 getDefaultNullValue()).setWhereClause(getColumnName() + " IS NULL"));
89 }
90
91 statements
92 .add(new SetNullableStatement(schemaName, getTableName(), getColumnName(), getColumnDataType(), false));
93 if (database instanceof DB2Database) {
94 statements.add(new ReorganizeTableStatement(schemaName, getTableName()));
95 }
96
97 return statements.toArray(new SqlStatement[statements.size()]);
98 }
99
100 private SqlStatement[] generateStatementsForSQLiteDatabase(Database database) {
101
102
103
104
105
106 List<SqlStatement> statements = new ArrayList<SqlStatement>();
107
108 String schemaName = getSchemaName() == null ? database.getDefaultSchemaName() : getSchemaName();
109 if (defaultNullValue != null) {
110 statements.add(new UpdateStatement(schemaName, getTableName()).addNewColumnValue(getColumnName(),
111 getDefaultNullValue()).setWhereClause(getColumnName() + " IS NULL"));
112 }
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136 AlterTableVisitor rename_alter_visitor = new AlterTableVisitor() {
137 @Override
138 public ColumnConfig[] getColumnsToAdd() {
139 return new ColumnConfig[0];
140 }
141
142 @Override
143 public boolean copyThisColumn(ColumnConfig column) {
144 return true;
145 }
146
147 @Override
148 public boolean createThisColumn(ColumnConfig column) {
149 if (column.getName().equals(getColumnName())) {
150 column.getConstraints().setNullable(false);
151 }
152 return true;
153 }
154
155 @Override
156 public boolean createThisIndex(Index index) {
157 return true;
158 }
159 };
160
161 try {
162
163 statements.addAll(SQLiteDatabase.getAlterTableStatements(rename_alter_visitor, database, getSchemaName(),
164 getTableName()));
165 } catch (Exception e) {
166 e.printStackTrace();
167 }
168
169 return statements.toArray(new SqlStatement[statements.size()]);
170 }
171
172 @Override
173 protected Change[] createInverses() {
174 DropNotNullConstraintChange inverse = new DropNotNullConstraintChange();
175 inverse.setColumnName(getColumnName());
176 inverse.setSchemaName(getSchemaName());
177 inverse.setTableName(getTableName());
178 inverse.setColumnDataType(getColumnDataType());
179
180 return new Change[] { inverse };
181 }
182
183 @Override
184 public String getConfirmationMessage() {
185 return "Null constraint has been added to " + getTableName() + "." + getColumnName();
186 }
187 }