001: package liquibase.database.sql;
002:
003: import liquibase.database.*;
004: import liquibase.exception.StatementNotSupportedOnDatabaseException;
005:
006: import java.util.Arrays;
007: import java.util.HashSet;
008: import java.util.Set;
009:
010: public class AddColumnStatement implements SqlStatement {
011:
012: private String schemaName;
013: private String tableName;
014: private String columnName;
015: private String columnType;
016: private Object defaultValue;
017: private Set<ColumnConstraint> constraints = new HashSet<ColumnConstraint>();
018:
019: public AddColumnStatement(String schemaName, String tableName,
020: String columnName, String columnType, Object defaultValue,
021: ColumnConstraint... constraints) {
022: this .schemaName = schemaName;
023: this .tableName = tableName;
024: this .columnName = columnName;
025: this .columnType = columnType;
026: this .defaultValue = defaultValue;
027: if (constraints != null) {
028: this .constraints.addAll(Arrays.asList(constraints));
029: }
030: }
031:
032: public String getSchemaName() {
033: return schemaName;
034: }
035:
036: public String getTableName() {
037: return tableName;
038: }
039:
040: public String getColumnName() {
041: return columnName;
042: }
043:
044: public String getColumnType() {
045: return columnType;
046: }
047:
048: public Set<ColumnConstraint> getConstraints() {
049: return constraints;
050: }
051:
052: public String getSqlStatement(Database database)
053: throws StatementNotSupportedOnDatabaseException {
054: if (isPrimaryKey()
055: && (database instanceof CacheDatabase
056: || database instanceof H2Database
057: || database instanceof DB2Database || database instanceof DerbyDatabase)) {
058: throw new StatementNotSupportedOnDatabaseException(
059: "Adding primary key columns is not supported",
060: this , database);
061: }
062:
063: String alterTable = "ALTER TABLE "
064: + database.escapeTableName(getSchemaName(),
065: getTableName())
066: + " ADD "
067: + database.escapeColumnName(getColumnName())
068: + " "
069: + database.getColumnType(getColumnType(),
070: isAutoIncrement());
071:
072: if (defaultClauseBeforeNotNull(database)) {
073: alterTable += getDefaultClause(database);
074: }
075:
076: if (primaryKeyBeforeNotNull(database)) {
077: if (isPrimaryKey()) {
078: alterTable += " PRIMARY KEY";
079: }
080: }
081:
082: if (isAutoIncrement()) {
083: alterTable += " " + database.getAutoIncrementClause();
084: }
085:
086: if (!isNullable()) {
087: alterTable += " NOT NULL";
088: } else {
089: if (database instanceof SybaseDatabase) {
090: alterTable += " NULL";
091: }
092: }
093:
094: if (!primaryKeyBeforeNotNull(database)) {
095: if (isPrimaryKey()) {
096: alterTable += " PRIMARY KEY";
097: }
098: }
099:
100: if (!defaultClauseBeforeNotNull(database)) {
101: alterTable += getDefaultClause(database);
102: }
103:
104: return alterTable;
105: }
106:
107: private boolean primaryKeyBeforeNotNull(Database database) {
108: return !(database instanceof HsqlDatabase);
109: }
110:
111: private boolean isAutoIncrement() {
112: for (ColumnConstraint constraint : getConstraints()) {
113: if (constraint instanceof AutoIncrementConstraint) {
114: return true;
115: }
116: }
117: return false;
118: }
119:
120: public boolean isPrimaryKey() {
121: for (ColumnConstraint constraint : getConstraints()) {
122: if (constraint instanceof PrimaryKeyConstraint) {
123: return true;
124: }
125: }
126: return false;
127: }
128:
129: public String getEndDelimiter(Database database) {
130: return ";";
131: }
132:
133: public boolean supportsDatabase(Database database) {
134: return true;
135: }
136:
137: private boolean defaultClauseBeforeNotNull(Database database) {
138: return database instanceof OracleDatabase
139: || database instanceof HsqlDatabase
140: || database instanceof DerbyDatabase
141: || database instanceof DB2Database
142: || database instanceof FirebirdDatabase;
143: }
144:
145: private String getDefaultClause(Database database) {
146: String clause = "";
147: if (getDefaultValue() != null) {
148: if (database instanceof MSSQLDatabase) {
149: clause += " CONSTRAINT "
150: + ((MSSQLDatabase) database)
151: .generateDefaultConstraintName(
152: tableName, getColumnName());
153: }
154: clause += " DEFAULT "
155: + database
156: .convertJavaObjectToString(getDefaultValue());
157: }
158: return clause;
159: }
160:
161: public boolean isNullable() {
162: if (isPrimaryKey()) {
163: return false;
164: }
165: for (ColumnConstraint constraint : getConstraints()) {
166: if (constraint instanceof NotNullConstraint) {
167: return false;
168: }
169: }
170: return true;
171: }
172:
173: public Object getDefaultValue() {
174: return defaultValue;
175: }
176: }
|