minor
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / database / update / ColumnAdder.java
index f7778d54f6cb3de0c5876f219c36c62d2c4eebbe..29ed2159624e3e73dc66fa5812fc1a11811a197c 100644 (file)
@@ -13,7 +13,7 @@ import java.sql.SQLException;
 \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
@@ -22,59 +22,153 @@ import eu.etaxonomy.cdm.database.ICdmDataSource;
  * @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 newColumnName;\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 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, false, null);\r
+       }\r
+       \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 NewIntegerInstance(String stepName, String tableName, String newColumnName, boolean includeAudTable){\r
-               return new ColumnAdder(stepName, tableName, newColumnName, "int", includeAudTable);\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) {\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
-               return true;\r
+               updateQuery = updateQuery.replace("@columnType", databaseColumnType);\r
+               updateQuery = updateQuery.replace("@addSeparator", getAddColumnSeperator(datasource));\r
+               \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 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