001: package liquibase.database.sql;
002:
003: import liquibase.database.DB2Database;
004: import liquibase.database.Database;
005: import liquibase.database.MSSQLDatabase;
006: import liquibase.database.SybaseDatabase;
007: import liquibase.util.StringUtils;
008:
009: import java.util.*;
010:
011: public class CreateTableStatement implements SqlStatement {
012: private String schemaName;
013: private String tableName;
014: private String tablespace;
015: private List<String> columns = new ArrayList<String>();
016: private Set<String> autoIncrementColumns = new HashSet<String>();
017: private Map<String, String> columnTypes = new HashMap<String, String>();
018: private Map<String, String> defaultValues = new HashMap<String, String>();
019:
020: private PrimaryKeyConstraint primaryKeyConstraint;
021: private Set<String> notNullColumns = new HashSet<String>();
022: private Set<ForeignKeyConstraint> foreignKeyConstraints = new HashSet<ForeignKeyConstraint>();
023: private Set<UniqueConstraint> uniqueConstraints = new HashSet<UniqueConstraint>();
024:
025: public CreateTableStatement(String schemaName, String tableName) {
026: this .schemaName = schemaName;
027: this .tableName = tableName;
028: }
029:
030: public String getSchemaName() {
031: return schemaName;
032: }
033:
034: public String getTableName() {
035: return tableName;
036: }
037:
038: public List<String> getColumns() {
039: return columns;
040: }
041:
042: public String getTablespace() {
043: return tablespace;
044: }
045:
046: public CreateTableStatement setTablespace(String tablespace) {
047: this .tablespace = tablespace;
048: return this ;
049: }
050:
051: public PrimaryKeyConstraint getPrimaryKeyConstraint() {
052: return primaryKeyConstraint;
053: }
054:
055: public Set<ForeignKeyConstraint> getForeignKeyConstraints() {
056: return foreignKeyConstraints;
057: }
058:
059: public Set<UniqueConstraint> getUniqueConstraints() {
060: return uniqueConstraints;
061: }
062:
063: public Set<String> getNotNullColumns() {
064: return notNullColumns;
065: }
066:
067: public CreateTableStatement addPrimaryKeyColumn(String columnName,
068: String columnType, ColumnConstraint... constraints) {
069: // String pkName = "PK_" + getTableName().toUpperCase();
070: //// if (pkName.length() > 18) {
071: //// pkName = pkName.substring(0, 17);
072: //// }
073: PrimaryKeyConstraint pkConstraint = new PrimaryKeyConstraint(
074: null);
075: pkConstraint.addColumns(columnName);
076:
077: List<ColumnConstraint> allConstraints = new ArrayList<ColumnConstraint>();
078: allConstraints.addAll(Arrays.asList(constraints));
079: allConstraints.add(new NotNullConstraint(columnName));
080: allConstraints.add(pkConstraint);
081:
082: addColumn(columnName, columnType, allConstraints
083: .toArray(new ColumnConstraint[allConstraints.size()]));
084:
085: return this ;
086: }
087:
088: public CreateTableStatement addColumn(String columnName,
089: String columnType) {
090: return addColumn(columnName, columnType, null,
091: new ColumnConstraint[0]);
092: }
093:
094: public CreateTableStatement addColumn(String columnName,
095: String columnType, String defaultValue) {
096: return addColumn(columnName, columnType, defaultValue,
097: new ColumnConstraint[0]);
098: }
099:
100: public CreateTableStatement addColumn(String columnName,
101: String columnType, ColumnConstraint... constraints) {
102: return addColumn(columnName, columnType, null, constraints);
103: }
104:
105: public boolean supportsDatabase(Database database) {
106: return true;
107: }
108:
109: public CreateTableStatement addColumn(String columnName,
110: String columnType, String defaultValue,
111: ColumnConstraint... constraints) {
112: this .getColumns().add(columnName);
113: this .columnTypes.put(columnName, columnType);
114: if (defaultValue != null) {
115: defaultValues.put(columnName, defaultValue);
116: }
117: if (constraints != null) {
118: for (ColumnConstraint constraint : constraints) {
119: if (constraint instanceof PrimaryKeyConstraint) {
120: if (this .getPrimaryKeyConstraint() == null) {
121: this .primaryKeyConstraint = (PrimaryKeyConstraint) constraint;
122: } else {
123: for (String column : ((PrimaryKeyConstraint) constraint)
124: .getColumns()) {
125: this .getPrimaryKeyConstraint().addColumns(
126: column);
127: }
128: }
129: } else if (constraint instanceof NotNullConstraint) {
130: ((NotNullConstraint) constraint)
131: .setColumnName(columnName);
132: getNotNullColumns().add(columnName);
133: } else if (constraint instanceof ForeignKeyConstraint) {
134: ((ForeignKeyConstraint) constraint)
135: .setColumn(columnName);
136: getForeignKeyConstraints().add(
137: ((ForeignKeyConstraint) constraint));
138: } else if (constraint instanceof UniqueConstraint) {
139: ((UniqueConstraint) constraint)
140: .addColumns(columnName);
141: getUniqueConstraints().add(
142: ((UniqueConstraint) constraint));
143: } else if (constraint instanceof AutoIncrementConstraint) {
144: autoIncrementColumns.add(columnName);
145: } else {
146: throw new RuntimeException(
147: "Unknown constraint type: "
148: + constraint.getClass().getName());
149: }
150: }
151: }
152:
153: return this ;
154: }
155:
156: public String getSqlStatement(Database database) {
157: // StringBuffer fkConstraints = new StringBuffer();
158:
159: StringBuffer buffer = new StringBuffer();
160: buffer.append("CREATE TABLE ").append(
161: database.escapeTableName(getSchemaName(),
162: getTableName())).append(" ");
163: buffer.append("(");
164: Iterator<String> columnIterator = getColumns().iterator();
165: while (columnIterator.hasNext()) {
166: String column = columnIterator.next();
167: boolean isAutoIncrement = autoIncrementColumns
168: .contains(column);
169:
170: buffer.append(database.escapeColumnName(column));
171: buffer.append(" ").append(
172: database.getColumnType(columnTypes.get(column),
173: isAutoIncrement));
174:
175: if (getDefaultValue(column) != null) {
176: if (database instanceof MSSQLDatabase) {
177: buffer.append(" CONSTRAINT ").append(
178: ((MSSQLDatabase) database)
179: .generateDefaultConstraintName(
180: tableName, column));
181: }
182: buffer.append(" DEFAULT ");
183: buffer.append(getDefaultValue(column));
184: }
185:
186: if (isAutoIncrement) {
187: buffer.append(" ").append(
188: database.getAutoIncrementClause()).append(" ");
189: }
190:
191: if (getNotNullColumns().contains(column)) {
192: buffer.append(" NOT NULL");
193: } else {
194: if (database instanceof SybaseDatabase) {
195: buffer.append(" NULL");
196: }
197: }
198:
199: if (columnIterator.hasNext()) {
200: buffer.append(", ");
201: }
202: }
203:
204: buffer.append(",");
205:
206: if (getPrimaryKeyConstraint() != null
207: && getPrimaryKeyConstraint().getColumns().size() > 0) {
208: String pkName = StringUtils
209: .trimToNull(getPrimaryKeyConstraint()
210: .getConstraintName());
211: if (pkName == null) {
212: pkName = database
213: .generatePrimaryKeyName(getTableName());
214: }
215: buffer.append(" CONSTRAINT ");
216: buffer.append(pkName);
217: buffer.append(" PRIMARY KEY (");
218: buffer.append(database
219: .escapeColumnNameList(StringUtils.join(
220: getPrimaryKeyConstraint().getColumns(),
221: ", ")));
222: buffer.append(")");
223: buffer.append(",");
224: }
225:
226: for (ForeignKeyConstraint fkConstraint : getForeignKeyConstraints()) {
227: buffer.append(" CONSTRAINT ").append(
228: fkConstraint.getForeignKeyName()).append(
229: " FOREIGN KEY (")
230: .append(
231: database.escapeColumnName(fkConstraint
232: .getColumn())).append(
233: ") REFERENCES ").append(
234: fkConstraint.getReferences());
235:
236: if (fkConstraint.isDeleteCascade()) {
237: buffer.append(" ON DELETE CASCADE");
238: }
239:
240: if (fkConstraint.isInitiallyDeferred()) {
241: buffer.append(" INITIALLY DEFERRED");
242: }
243: if (fkConstraint.isDeferrable()) {
244: buffer.append(" DEFERRABLE");
245: }
246: buffer.append(",");
247: }
248:
249: for (UniqueConstraint uniqueConstraint : getUniqueConstraints()) {
250: if (uniqueConstraint.getConstraintName() != null) {
251: buffer.append(" CONSTRAINT ");
252: buffer.append(uniqueConstraint.getConstraintName());
253: }
254: buffer.append(" UNIQUE (");
255: buffer.append(database.escapeColumnNameList(StringUtils
256: .join(uniqueConstraint.getColumns(), ", ")));
257: buffer.append("),");
258: }
259:
260: // if (constraints != null && constraints.getCheck() != null) {
261: // buffer.append(constraints.getCheck()).append(" ");
262: // }
263: // }
264:
265: String sql = buffer.toString().replaceFirst(",\\s*$", "") + ")";
266:
267: // if (StringUtils.trimToNull(tablespace) != null && database.supportsTablespaces()) {
268: // if (database instanceof MSSQLDatabase) {
269: // buffer.append(" ON ").append(tablespace);
270: // } else if (database instanceof DB2Database) {
271: // buffer.append(" IN ").append(tablespace);
272: // } else {
273: // buffer.append(" TABLESPACE ").append(tablespace);
274: // }
275: // }
276:
277: if (getTablespace() != null && database.supportsTablespaces()) {
278: if (database instanceof MSSQLDatabase) {
279: sql += " ON " + getTablespace();
280: } else if (database instanceof DB2Database) {
281: sql += " IN " + getTablespace();
282: } else {
283: sql += " TABLESPACE " + getTablespace();
284: }
285: }
286: return sql;
287: }
288:
289: public String getDefaultValue(String column) {
290: return defaultValues.get(column);
291: }
292:
293: public String getEndDelimiter(Database database) {
294: return ";";
295: }
296:
297: public CreateTableStatement addColumnConstraint(
298: NotNullConstraint notNullConstraint) {
299: getNotNullColumns().add(notNullConstraint.getColumnName());
300: return this ;
301: }
302:
303: public CreateTableStatement addColumnConstraint(
304: ForeignKeyConstraint fkConstraint) {
305: getForeignKeyConstraints().add(fkConstraint);
306: return this ;
307: }
308:
309: public CreateTableStatement addColumnConstraint(
310: UniqueConstraint uniqueConstraint) {
311: getUniqueConstraints().add(uniqueConstraint);
312: return this ;
313: }
314:
315: public CreateTableStatement addColumnConstraint(
316: AutoIncrementConstraint autoIncrementConstraint) {
317: autoIncrementColumns.add(autoIncrementConstraint
318: .getColumnName());
319: return this;
320: }
321: }
|