3 * Copyright (C) 2009 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
10 package eu
.etaxonomy
.cdm
.database
.update
;
12 import java
.sql
.SQLException
;
14 import org
.apache
.log4j
.Logger
;
16 import eu
.etaxonomy
.cdm
.common
.monitor
.IProgressMonitor
;
17 import eu
.etaxonomy
.cdm
.database
.DatabaseTypeEnum
;
18 import eu
.etaxonomy
.cdm
.database
.ICdmDataSource
;
25 public class ColumnAdder
extends SchemaUpdaterStepBase
<ColumnAdder
> implements ISchemaUpdaterStep
{
26 private static final Logger logger
= Logger
.getLogger(ColumnAdder
.class);
28 private String tableName
;
29 private String newColumnName
;
30 private String columnType
;
31 private boolean includeAudTable
;
32 private Object defaultValue
;
33 private boolean isNotNull
;
34 private String referencedTable
;
36 public static final ColumnAdder
NewIntegerInstance(String stepName
, String tableName
, String newColumnName
, boolean includeAudTable
, boolean notNull
, String referencedTable
){
37 return new ColumnAdder(stepName
, tableName
, newColumnName
, "int", includeAudTable
, null, notNull
, referencedTable
);
40 public static final ColumnAdder
NewTinyIntegerInstance(String stepName
, String tableName
, String newColumnName
, boolean includeAudTable
, boolean notNull
){
41 return new ColumnAdder(stepName
, tableName
, newColumnName
, "tinyint", includeAudTable
, null, notNull
, null);
44 public static final ColumnAdder
NewBooleanInstance(String stepName
, String tableName
, String newColumnName
, boolean includeAudTable
, Boolean defaultValue
){
45 return new ColumnAdder(stepName
, tableName
, newColumnName
, "bit", includeAudTable
, defaultValue
, false, null);
48 public static final ColumnAdder
NewStringInstance(String stepName
, String tableName
, String newColumnName
, boolean includeAudTable
){
49 return new ColumnAdder(stepName
, tableName
, newColumnName
, "nvarchar(255)", includeAudTable
, null, false, null);
52 public static final ColumnAdder
NewStringInstance(String stepName
, String tableName
, String newColumnName
, int length
, boolean includeAudTable
){
53 return new ColumnAdder(stepName
, tableName
, newColumnName
, "nvarchar("+length
+")", includeAudTable
, null, false, null);
56 public static final ColumnAdder
NewDateTimeInstance(String stepName
, String tableName
, String newColumnName
, boolean includeAudTable
){
57 return new ColumnAdder(stepName
, tableName
, newColumnName
, "datetime", includeAudTable
, null, false, null);
60 protected ColumnAdder(String stepName
, String tableName
, String newColumnName
, String columnType
, boolean includeAudTable
, Object defaultValue
, boolean notNull
, String referencedTable
) {
62 this.tableName
= tableName
;
63 this.newColumnName
= newColumnName
;
64 this.columnType
= columnType
;
65 this.includeAudTable
= includeAudTable
;
66 this.defaultValue
= defaultValue
;
67 this.isNotNull
= notNull
;
68 this.referencedTable
= referencedTable
;
73 * @see eu.etaxonomy.cdm.database.update.SchemaUpdaterStepBase#invoke(eu.etaxonomy.cdm.database.ICdmDataSource, eu.etaxonomy.cdm.common.IProgressMonitor)
76 public Integer
invoke(ICdmDataSource datasource
, IProgressMonitor monitor
) throws SQLException
{
77 boolean result
= true;
78 result
&= addColumn(tableName
, datasource
, monitor
);
81 result
&= addColumn(tableName
+ aud
, datasource
, monitor
);
83 return (result
== true )?
0 : null;
86 private boolean addColumn(String tableName
, ICdmDataSource datasource
, IProgressMonitor monitor
) {
87 boolean result
= true;
89 String updateQuery
= getUpdateQueryString(tableName
, datasource
, monitor
);
91 datasource
.executeUpdate(updateQuery
);
92 } catch (SQLException e
) {
97 if (defaultValue
instanceof Boolean
){
98 updateQuery
= "UPDATE @tableName SET @columnName = " + (defaultValue
== null ?
"null" : getBoolean((Boolean
) defaultValue
, datasource
));
99 updateQuery
= updateQuery
.replace("@tableName", tableName
);
100 updateQuery
= updateQuery
.replace("@columnName", newColumnName
);
102 datasource
.executeUpdate(updateQuery
);
103 } catch (SQLException e
) {
108 if (referencedTable
!= null){
109 result
&= TableCreator
.makeForeignKey(tableName
, datasource
, newColumnName
, referencedTable
);
113 } catch ( DatabaseTypeNotSupportedException e
) {
118 public String
getUpdateQueryString(String tableName
, ICdmDataSource datasource
, IProgressMonitor monitor
) throws DatabaseTypeNotSupportedException
{
120 DatabaseTypeEnum type
= datasource
.getDatabaseType();
121 String databaseColumnType
= getDatabaseColumnType(datasource
, this.columnType
);
123 if (type
.equals(DatabaseTypeEnum
.SqlServer2005
)){
124 //MySQL allows both syntaxes
125 updateQuery
= "ALTER TABLE @tableName ADD @columnName @columnType";
126 }else if (type
.equals(DatabaseTypeEnum
.H2
) || type
.equals(DatabaseTypeEnum
.PostgreSQL
) || type
.equals(DatabaseTypeEnum
.MySQL
)){
127 updateQuery
= "ALTER TABLE @tableName @addSeparator @columnName @columnType";
130 String warning
= "Update step '" + this.getStepName() + "' is not supported by " + type
.getName();
131 monitor
.warning(warning
);
132 throw new DatabaseTypeNotSupportedException(warning
);
135 updateQuery
+= " NOT NULL";
137 updateQuery
= updateQuery
.replace("@tableName", tableName
);
138 updateQuery
= updateQuery
.replace("@columnName", newColumnName
);
139 updateQuery
= updateQuery
.replace("@columnType", databaseColumnType
);
140 updateQuery
= updateQuery
.replace("@addSeparator", getAddColumnSeperator(datasource
));
145 private String
getDatabaseColumnType(ICdmDataSource datasource
, String columnType
) {
146 String result
= columnType
;
147 if (datasource
.getDatabaseType().equals(DatabaseTypeEnum
.PostgreSQL
)){
148 result
= result
.replace("nvarchar", "varchar");
154 public static String
getAddColumnSeperator(ICdmDataSource datasource
) throws DatabaseTypeNotSupportedException
{
155 DatabaseTypeEnum type
= datasource
.getDatabaseType();
156 if (type
.equals(DatabaseTypeEnum
.SqlServer2005
)){
158 }else if (type
.equals(DatabaseTypeEnum
.H2
) || type
.equals(DatabaseTypeEnum
.PostgreSQL
) || type
.equals(DatabaseTypeEnum
.MySQL
)){
159 return "ADD COLUMN ";
161 throw new DatabaseTypeNotSupportedException(datasource
.getName());
165 public String
getReferencedTable() {
166 return referencedTable
;
170 public String
getNewColumnName() {
171 return newColumnName
;