Project

General

Profile

Download (6.28 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2009 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.database.update;
10

    
11
import org.apache.log4j.Logger;
12

    
13
import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
14
import eu.etaxonomy.cdm.database.DatabaseTypeEnum;
15
import eu.etaxonomy.cdm.database.ICdmDataSource;
16

    
17
/**
18
 * @author a.mueller
19
 * @since 16.09.2010
20
 *
21
 */
22
public class ColumnTypeChanger
23
        extends AuditedSchemaUpdaterStepBase {
24

    
25
    private static final Logger logger = Logger.getLogger(ColumnTypeChanger.class);
26

    
27
	private final String columnName;
28
	private final String newColumnType;
29
	private final Object defaultValue;
30
	private final boolean isNotNull;
31
	private final String referencedTable;
32

    
33

    
34
	public static final ColumnTypeChanger NewStringSizeInstance(String stepName, String tableName, String columnName, int newSize, boolean includeAudTable){
35
		return new ColumnTypeChanger(stepName, tableName, columnName, "nvarchar("+newSize+")", includeAudTable, null, false, null);
36
	}
37

    
38
	public static final ColumnTypeChanger NewClobInstance(String stepName, String tableName, String columnName, boolean includeAudTable){
39
		return new ColumnTypeChanger(stepName, tableName, columnName, "clob", includeAudTable, null, false, null);
40
	}
41

    
42
	public static final ColumnTypeChanger NewInt2DoubleInstance(String stepName, String tableName, String columnName, boolean includeAudTable){
43
		return new ColumnTypeChanger(stepName, tableName, columnName, "double", includeAudTable, null, false, null);
44
	}
45

    
46
	public static final ColumnTypeChanger NewInt2StringInstance(String stepName, String tableName, String columnName, int size, boolean includeAudTable, Integer defaultValue, boolean notNull){
47
		return new ColumnTypeChanger(stepName, tableName, columnName, "nvarchar("+size+")", includeAudTable, defaultValue, notNull, null);
48
	}
49

    
50
//	public static final ColumnTypeChanger NewChangeAllowNullOnStringChanger(){
51
//
52
//	}
53

    
54

    
55
	protected ColumnTypeChanger(String stepName, String tableName, String columnName, String newColumnType, boolean includeAudTable, Object defaultValue, boolean notNull, String referencedTable) {
56
		super(stepName, tableName, includeAudTable);
57
		this.columnName = columnName;
58
		this.newColumnType = newColumnType;
59
		this.defaultValue = defaultValue;
60
		this.isNotNull = notNull;
61
		this.referencedTable = referencedTable;
62
	}
63

    
64
    @Override
65
    protected void invokeOnTable(String tableName, ICdmDataSource datasource,
66
            IProgressMonitor monitor, CaseType caseType, SchemaUpdateResult result) {
67
        try {
68

    
69
			String updateQuery;
70
			if (this.isNotNull){
71
				updateQuery = getNotNullUpdateQuery(tableName);
72
				datasource.executeUpdate(updateQuery);
73
			}
74

    
75
			updateQuery = getUpdateQueryString(tableName, datasource, monitor);
76
			datasource.executeUpdate(updateQuery);
77

    
78
			if (defaultValue instanceof Boolean){
79
				updateQuery = "UPDATE @tableName SET @columnName = " + (defaultValue == null ? "null" : getBoolean((Boolean) defaultValue, datasource));
80
				updateQuery = updateQuery.replace("@tableName", tableName);
81
				updateQuery = updateQuery.replace("@columnName", columnName);
82
				datasource.executeUpdate(updateQuery);
83
			}
84
			if (referencedTable != null){
85
				TableCreator.makeForeignKey(tableName, datasource, monitor, columnName, referencedTable, caseType, result);
86
			}
87

    
88
			return;
89
		} catch ( Exception e) {
90
		    String message = "Unhandled exception when trying to change column type for " +
91
                    columnName + " for table " +  tableName;
92
            monitor.warning(message, e);
93
            logger.error(e);
94
            result.addException(e, message, getStepName());
95
            return;
96
		}
97
	}
98

    
99
	private String getNotNullUpdateQuery(String tableName) {
100
		String query = " UPDATE %s SET %s = %S WHERE %s IS NULL ";
101
		String defaultValueStr = String.valueOf(this.defaultValue);
102
		if (this.defaultValue instanceof Integer){
103
			//OK
104
		}else{
105
			defaultValueStr = "'" + defaultValueStr + "'";
106
		}
107
		query = String.format(query, tableName, this.columnName, defaultValueStr, this.columnName);
108
		return query;
109
	}
110

    
111
	public String getUpdateQueryString(String tableName, ICdmDataSource datasource, IProgressMonitor monitor) throws DatabaseTypeNotSupportedException {
112
		String updateQuery;
113
		DatabaseTypeEnum type = datasource.getDatabaseType();
114
		String databaseColumnType = getDatabaseColumnType(datasource, this.newColumnType);
115

    
116
		if (type.equals(DatabaseTypeEnum.SqlServer2005)){
117
			//MySQL allows both syntaxes
118
			updateQuery = "ALTER TABLE @tableName ALTER COLUMN @columnName @columnType";
119
		}else if (type.equals(DatabaseTypeEnum.H2)){
120
			updateQuery = "ALTER TABLE @tableName ALTER COLUMN @columnName @columnType";
121
		}else if (type.equals(DatabaseTypeEnum.PostgreSQL)){
122
			updateQuery = "ALTER TABLE @tableName ALTER COLUMN @columnName TYPE @columnType";
123
		}else if (type.equals(DatabaseTypeEnum.MySQL)){
124
			updateQuery = "ALTER TABLE @tableName MODIFY COLUMN @columnName @columnType";
125
		}else{
126
			updateQuery = null;
127
			String warning = "Update step '" + this.getStepName() + "' is not supported by " + type.getName();
128
			monitor.warning(warning);
129
			throw new DatabaseTypeNotSupportedException(warning);
130
		}
131
		if (isNotNull){
132
			if (datasource.getDatabaseType().equals(DatabaseTypeEnum.PostgreSQL)){
133
				logger.warn("NOT NULL not implementd for POSTGRES");
134
			}else{
135
				updateQuery += " NOT NULL";
136
			}
137
		} else{
138
			if (! datasource.getDatabaseType().equals(DatabaseTypeEnum.PostgreSQL)){
139
				updateQuery += " NULL ";
140
			}
141
		}
142
		updateQuery = updateQuery.replace("@tableName", tableName);
143
		updateQuery = updateQuery.replace("@columnName", columnName);
144
		updateQuery = updateQuery.replace("@columnType", databaseColumnType);
145
//		updateQuery = updateQuery.replace("@addSeparator", getAddColumnSeperator(datasource));
146

    
147
		return updateQuery;
148
	}
149

    
150
	private String getDatabaseColumnType(ICdmDataSource datasource, String columnType) {
151
		return ColumnAdder.getDatabaseColumnType(datasource, columnType);
152
	}
153

    
154
	public String getReferencedTable() {
155
		return referencedTable;
156
	}
157
//
158
//	public String getNewColumnName() {
159
//		return columnName;
160
//	}
161

    
162
}
(9-9/35)