\r
import org.apache.log4j.Logger;\r
\r
-import eu.etaxonomy.cdm.common.IProgressMonitor;\r
+import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;\r
import eu.etaxonomy.cdm.database.DatabaseTypeEnum;\r
import eu.etaxonomy.cdm.database.ICdmDataSource;\r
\r
* @date 16.09.2010\r
*\r
*/\r
-public class ColumnAdder extends SchemaUpdaterStepBase implements ISchemaUpdaterStep {\r
- @SuppressWarnings("unused")\r
+public class ColumnAdder extends SchemaUpdaterStepBase<ColumnAdder> implements ISchemaUpdaterStep {\r
private static final Logger logger = Logger.getLogger(ColumnAdder.class);\r
\r
private String tableName;\r
private String columnType;\r
private boolean includeAudTable;\r
private Object defaultValue;\r
+ private boolean isNotNull;\r
+ private String referencedTable;\r
+\r
+ public static final ColumnAdder NewIntegerInstance(String stepName, String tableName, String newColumnName, boolean includeAudTable, boolean notNull, String referencedTable){\r
+ return new ColumnAdder(stepName, tableName, newColumnName, "int", includeAudTable, null, notNull, referencedTable);\r
+ }\r
\r
- public static final ColumnAdder NewIntegerInstance(String stepName, String tableName, String newColumnName, boolean includeAudTable){\r
- return new ColumnAdder(stepName, tableName, newColumnName, "int", includeAudTable, null);\r
+ public static final ColumnAdder NewTinyIntegerInstance(String stepName, String tableName, String newColumnName, boolean includeAudTable, boolean notNull){\r
+ return new ColumnAdder(stepName, tableName, newColumnName, "tinyint", includeAudTable, null, notNull, null);\r
}\r
\r
public static final ColumnAdder NewBooleanInstance(String stepName, String tableName, String newColumnName, boolean includeAudTable, Boolean defaultValue){\r
- return new ColumnAdder(stepName, tableName, newColumnName, "bit", includeAudTable, defaultValue);\r
+ return new ColumnAdder(stepName, tableName, newColumnName, "bit", includeAudTable, defaultValue, false, null);\r
}\r
\r
- protected ColumnAdder(String stepName, String tableName, String newColumnName, String columnType, boolean includeAudTable, Object defaultValue) {\r
+ public static final ColumnAdder NewStringInstance(String stepName, String tableName, String newColumnName, boolean includeAudTable){\r
+ return new ColumnAdder(stepName, tableName, newColumnName, "nvarchar(255)", includeAudTable, null, false, null);\r
+ }\r
+\r
+ public static final ColumnAdder NewStringInstance(String stepName, String tableName, String newColumnName, int length, boolean includeAudTable){\r
+ return new ColumnAdder(stepName, tableName, newColumnName, "nvarchar("+length+")", includeAudTable, null, false, null);\r
+ }\r
+ \r
+ public static final ColumnAdder NewDateTimeInstance(String stepName, String tableName, String newColumnName, boolean includeAudTable){\r
+ return new ColumnAdder(stepName, tableName, newColumnName, "datetime", includeAudTable, null, false, null);\r
+ }\r
+ \r
+ protected ColumnAdder(String stepName, String tableName, String newColumnName, String columnType, boolean includeAudTable, Object defaultValue, boolean notNull, String referencedTable) {\r
super(stepName);\r
this.tableName = tableName;\r
this.newColumnName = newColumnName;\r
this.columnType = columnType;\r
this.includeAudTable = includeAudTable;\r
this.defaultValue = defaultValue;\r
+ this.isNotNull = notNull;\r
+ this.referencedTable = referencedTable;\r
}\r
\r
+\r
/* (non-Javadoc)\r
* @see eu.etaxonomy.cdm.database.update.SchemaUpdaterStepBase#invoke(eu.etaxonomy.cdm.database.ICdmDataSource, eu.etaxonomy.cdm.common.IProgressMonitor)\r
*/\r
@Override\r
public Integer invoke(ICdmDataSource datasource, IProgressMonitor monitor) throws SQLException {\r
boolean result = true;\r
- result &= addColumn(tableName, newColumnName, columnType, datasource, monitor);\r
+ result &= addColumn(tableName, datasource, monitor);\r
if (includeAudTable){\r
String aud = "_AUD";\r
- result &= addColumn(tableName + aud, newColumnName, columnType, datasource, monitor);\r
+ result &= addColumn(tableName + aud, datasource, monitor);\r
}\r
return (result == true )? 0 : null;\r
}\r
\r
- private boolean addColumn(String tableName, String newColumnName, String columnType, ICdmDataSource datasource, IProgressMonitor monitor) {\r
- DatabaseTypeEnum type = datasource.getDatabaseType();\r
+ private boolean addColumn(String tableName, ICdmDataSource datasource, IProgressMonitor monitor) {\r
+ boolean result = true;\r
+ try {\r
+ String updateQuery = getUpdateQueryString(tableName, datasource, monitor);\r
+ try {\r
+ datasource.executeUpdate(updateQuery);\r
+ } catch (SQLException e) {\r
+ logger.error(e);\r
+ result = false;\r
+ }\r
+ \r
+ if (defaultValue instanceof Boolean){\r
+ updateQuery = "UPDATE @tableName SET @columnName = " + (defaultValue == null ? "null" : getBoolean((Boolean) defaultValue, datasource));\r
+ updateQuery = updateQuery.replace("@tableName", tableName);\r
+ updateQuery = updateQuery.replace("@columnName", newColumnName);\r
+ try {\r
+ datasource.executeUpdate(updateQuery);\r
+ } catch (SQLException e) {\r
+ logger.error(e);\r
+ result = false;\r
+ }\r
+ }\r
+ if (referencedTable != null){\r
+ result &= TableCreator.makeForeignKey(tableName, datasource, newColumnName, referencedTable);\r
+ }\r
+ \r
+ return result;\r
+ } catch ( DatabaseTypeNotSupportedException e) {\r
+ return false;\r
+ }\r
+ }\r
+\r
+ public String getUpdateQueryString(String tableName, ICdmDataSource datasource, IProgressMonitor monitor) throws DatabaseTypeNotSupportedException {\r
String updateQuery;\r
+ DatabaseTypeEnum type = datasource.getDatabaseType();\r
+ String databaseColumnType = getDatabaseColumnType(datasource, this.columnType);\r
+\r
if (type.equals(DatabaseTypeEnum.SqlServer2005)){\r
//MySQL allows both syntaxes\r
updateQuery = "ALTER TABLE @tableName ADD @columnName @columnType";\r
}else if (type.equals(DatabaseTypeEnum.H2) || type.equals(DatabaseTypeEnum.PostgreSQL) || type.equals(DatabaseTypeEnum.MySQL)){\r
- updateQuery = "ALTER TABLE @tableName ADD COLUMN @columnName @columnType";\r
+ updateQuery = "ALTER TABLE @tableName @addSeparator @columnName @columnType";\r
}else{\r
updateQuery = null;\r
- monitor.warning("Update step '" + this.getStepName() + "' is not supported by " + type.getName());\r
- return false;\r
+ String warning = "Update step '" + this.getStepName() + "' is not supported by " + type.getName();\r
+ monitor.warning(warning);\r
+ throw new DatabaseTypeNotSupportedException(warning);\r
+ }\r
+ if (isNotNull){\r
+ updateQuery += " NOT NULL";\r
}\r
updateQuery = updateQuery.replace("@tableName", tableName);\r
updateQuery = updateQuery.replace("@columnName", newColumnName);\r
- updateQuery = updateQuery.replace("@columnType", columnType);\r
- datasource.executeUpdate(updateQuery);\r
+ updateQuery = updateQuery.replace("@columnType", databaseColumnType);\r
+ updateQuery = updateQuery.replace("@addSeparator", getAddColumnSeperator(datasource));\r
\r
- if (defaultValue instanceof Boolean){\r
- updateQuery = "UPADTE @tableName SET @columnName = " + defaultValue == null ? "null" : getBoolean((Boolean) defaultValue, datasource);\r
- updateQuery = updateQuery.replace("@tableName", tableName);\r
- updateQuery = updateQuery.replace("@columnName", newColumnName);\r
- datasource.executeUpdate(updateQuery);\r
+ return updateQuery;\r
+ }\r
+\r
+ private String getDatabaseColumnType(ICdmDataSource datasource, String columnType) {\r
+ String result = columnType;\r
+ if (datasource.getDatabaseType().equals(DatabaseTypeEnum.PostgreSQL)){\r
+ result = result.replace("nvarchar", "varchar");\r
}\r
- return true;\r
+ return result;\r
+ }\r
+ \r
+\r
+ public static String getAddColumnSeperator(ICdmDataSource datasource) throws DatabaseTypeNotSupportedException {\r
+ DatabaseTypeEnum type = datasource.getDatabaseType();\r
+ if (type.equals(DatabaseTypeEnum.SqlServer2005)){\r
+ return "ADD ";\r
+ }else if (type.equals(DatabaseTypeEnum.H2) || type.equals(DatabaseTypeEnum.PostgreSQL) || type.equals(DatabaseTypeEnum.MySQL)){\r
+ return "ADD COLUMN ";\r
+ }else{\r
+ throw new DatabaseTypeNotSupportedException(datasource.getName());\r
+ }\r
+ }\r
+\r
+ public String getReferencedTable() {\r
+ return referencedTable;\r
+ }\r
+ \r
+\r
+ public String getNewColumnName() {\r
+ return newColumnName;\r
}\r
\r
}\r