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 org
.apache
.log4j
.Logger
;
14 import eu
.etaxonomy
.cdm
.common
.monitor
.IProgressMonitor
;
15 import eu
.etaxonomy
.cdm
.database
.DatabaseTypeEnum
;
16 import eu
.etaxonomy
.cdm
.database
.ICdmDataSource
;
23 public class ColumnTypeChanger
extends AuditedSchemaUpdaterStepBase
<ColumnTypeChanger
> implements ISchemaUpdaterStep
{
24 private static final Logger logger
= Logger
.getLogger(ColumnTypeChanger
.class);
26 private String columnName
;
27 private String newColumnType
;
28 private Object defaultValue
;
29 private boolean isNotNull
;
30 private String referencedTable
;
33 public static final ColumnTypeChanger
NewStringSizeInstance(String stepName
, String tableName
, String columnName
, int newSize
, boolean includeAudTable
){
34 return new ColumnTypeChanger(stepName
, tableName
, columnName
, "nvarchar("+newSize
+")", includeAudTable
, null, false, null);
37 public static final ColumnTypeChanger
NewClobInstance(String stepName
, String tableName
, String columnName
, boolean includeAudTable
){
38 return new ColumnTypeChanger(stepName
, tableName
, columnName
, "clob", includeAudTable
, null, false, null);
41 public static final ColumnTypeChanger
NewInt2DoubleInstance(String stepName
, String tableName
, String columnName
, boolean includeAudTable
){
42 return new ColumnTypeChanger(stepName
, tableName
, columnName
, "double", includeAudTable
, null, false, null);
45 public static final ColumnTypeChanger
NewInt2StringInstance(String stepName
, String tableName
, String columnName
, int size
, boolean includeAudTable
, Integer defaultValue
, boolean notNull
){
46 return new ColumnTypeChanger(stepName
, tableName
, columnName
, "nvarchar("+size
+")", includeAudTable
, defaultValue
, notNull
, null);
50 protected ColumnTypeChanger(String stepName
, String tableName
, String columnName
, String newColumnType
, boolean includeAudTable
, Object defaultValue
, boolean notNull
, String referencedTable
) {
52 this.tableName
= tableName
;
53 this.columnName
= columnName
;
54 this.newColumnType
= newColumnType
;
55 this.includeAudTable
= includeAudTable
;
56 this.defaultValue
= defaultValue
;
57 this.isNotNull
= notNull
;
58 this.referencedTable
= referencedTable
;
62 protected boolean invokeOnTable(String tableName
, ICdmDataSource datasource
, IProgressMonitor monitor
) {
63 boolean result
= true;
68 updateQuery
= getNotNullUpdateQuery(tableName
, datasource
, monitor
);
69 datasource
.executeUpdate(updateQuery
);
72 updateQuery
= getUpdateQueryString(tableName
, datasource
, monitor
);
73 datasource
.executeUpdate(updateQuery
);
75 if (defaultValue
instanceof Boolean
){
76 updateQuery
= "UPDATE @tableName SET @columnName = " + (defaultValue
== null ?
"null" : getBoolean((Boolean
) defaultValue
, datasource
));
77 updateQuery
= updateQuery
.replace("@tableName", tableName
);
78 updateQuery
= updateQuery
.replace("@columnName", columnName
);
79 datasource
.executeUpdate(updateQuery
);
81 if (referencedTable
!= null){
82 result
&= TableCreator
.makeForeignKey(tableName
, datasource
, columnName
, referencedTable
);
86 } catch ( Exception e
) {
87 monitor
.warning(e
.getMessage(), e
);
93 private String
getNotNullUpdateQuery(String tableName
, ICdmDataSource datasource
, IProgressMonitor monitor
) {
94 String query
= " UPDATE %s SET %s = %S WHERE %s IS NULL ";
95 String defaultValueStr
= String
.valueOf(this.defaultValue
);
96 if (this.defaultValue
instanceof Integer
){
99 defaultValueStr
= "'" + defaultValueStr
+ "'";
101 query
= String
.format(query
, tableName
, this.columnName
, defaultValueStr
, this.columnName
);
105 public String
getUpdateQueryString(String tableName
, ICdmDataSource datasource
, IProgressMonitor monitor
) throws DatabaseTypeNotSupportedException
{
107 DatabaseTypeEnum type
= datasource
.getDatabaseType();
108 String databaseColumnType
= getDatabaseColumnType(datasource
, this.newColumnType
);
110 if (type
.equals(DatabaseTypeEnum
.SqlServer2005
)){
111 //MySQL allows both syntaxes
112 updateQuery
= "ALTER TABLE @tableName ALTER COLUMN @columnName @columnType";
113 }else if (type
.equals(DatabaseTypeEnum
.H2
)){
114 updateQuery
= "ALTER TABLE @tableName ALTER COLUMN @columnName @columnType";
115 }else if (type
.equals(DatabaseTypeEnum
.PostgreSQL
)){
116 updateQuery
= "ALTER TABLE @tableName ALTER COLUMN @columnName TYPE @columnType";
117 }else if (type
.equals(DatabaseTypeEnum
.MySQL
)){
118 updateQuery
= "ALTER TABLE @tableName MODIFY COLUMN @columnName @columnType";
121 String warning
= "Update step '" + this.getStepName() + "' is not supported by " + type
.getName();
122 monitor
.warning(warning
);
123 throw new DatabaseTypeNotSupportedException(warning
);
126 updateQuery
+= " NOT NULL";
128 updateQuery
= updateQuery
.replace("@tableName", tableName
);
129 updateQuery
= updateQuery
.replace("@columnName", columnName
);
130 updateQuery
= updateQuery
.replace("@columnType", databaseColumnType
);
131 // updateQuery = updateQuery.replace("@addSeparator", getAddColumnSeperator(datasource));
136 private String
getDatabaseColumnType(ICdmDataSource datasource
, String columnType
) {
137 return ColumnAdder
.getDatabaseColumnType(datasource
, columnType
);
140 public String
getReferencedTable() {
141 return referencedTable
;
144 // public String getNewColumnName() {
145 // return columnName;