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.v33_34;
10

    
11
import java.sql.ResultSet;
12
import java.sql.SQLException;
13
import java.util.HashSet;
14
import java.util.Set;
15

    
16
import org.apache.log4j.Logger;
17

    
18
import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
19
import eu.etaxonomy.cdm.database.DatabaseTypeEnum;
20
import eu.etaxonomy.cdm.database.ICdmDataSource;
21
import eu.etaxonomy.cdm.database.update.CaseType;
22
import eu.etaxonomy.cdm.database.update.ISchemaUpdaterStep;
23
import eu.etaxonomy.cdm.database.update.SchemaUpdaterStepBase;
24

    
25
/**
26
 * @author a.mueller
27
 * @date 16.09.2010
28
 *
29
 */
30
public class UsernameConstraintUpdater extends SchemaUpdaterStepBase<UsernameConstraintUpdater> implements ISchemaUpdaterStep {
31
	private static final Logger logger = Logger.getLogger(UsernameConstraintUpdater.class);
32
	
33
	private String tableName;
34
	
35
	private String columnName;
36
	
37
	public static final UsernameConstraintUpdater NewInstance(String stepName, String tableName, String columnName){
38
		return new UsernameConstraintUpdater(stepName, tableName, columnName);
39
	}
40

    
41
	
42
	protected UsernameConstraintUpdater(String stepName, String tableName, String columnName) {
43
		super(stepName);
44
		this.tableName = tableName;
45
		this.columnName = columnName;
46
	}
47
	
48

    
49
	@Override
50
	public Integer invoke(ICdmDataSource datasource, IProgressMonitor monitor, CaseType caseType) throws SQLException {
51
		//remove 2-fold constraint
52
		boolean result = removeDuplicates(datasource, caseType);
53
		result &= removeExistingConstraint(datasource, caseType);
54
		result &= createColumnConstraint(datasource, caseType);
55
		result &= createUuidConstraint(datasource, caseType);
56
		return result ? 1 : null;
57
	}
58
	
59
	private boolean removeDuplicates(ICdmDataSource datasource, CaseType caseType) {
60
		try {
61
			Set<String> existing = new HashSet<String>();
62
			String sql = " SELECT id, columnName as uniquecol FROM tableName ";
63
			sql = sql.replace("columnName", columnName).replace("tableName", caseType.transformTo(tableName));
64
			ResultSet rs = datasource.executeQuery(sql);
65
			while (rs.next()){
66
				int id = rs.getInt("id");
67
				String key = rs.getString("uniquecol");
68
				while (key == null || existing.contains(key.toLowerCase())){
69
					key = key == null ? "_" : key + "_"; 
70
					String sqlUpdate = "UPDATE tableName SET columnName = '" + key + "' WHERE id = " + id;
71
					sqlUpdate = sqlUpdate.replace("columnName", columnName).replace("tableName", caseType.transformTo(tableName));
72
					datasource.executeUpdate(sqlUpdate);
73
				}
74
				existing.add(key.toLowerCase());
75
			}
76
			return true;
77
		} catch (SQLException e) {
78
			e.printStackTrace();
79
			return false;
80
		}
81
	}
82

    
83

    
84
	private boolean createUuidConstraint(ICdmDataSource datasource, CaseType caseType) {
85
		try {
86
			String updateQuery = getCreateQuery(datasource, caseType, tableName, tableName + "_UniqueKey", "uuid");
87
			datasource.executeUpdate(updateQuery);
88
			return true;
89
		} catch (Exception e) {
90
			logger.warn("Unique index for " + tableName + ".uuid could not be created");
91
			return false;
92
		}
93
	}
94
	
95
	private boolean createColumnConstraint(ICdmDataSource datasource, CaseType caseType) {
96
		try {
97
			String updateQuery = getCreateQuery(datasource, caseType, tableName, columnName + "_", columnName);
98
			datasource.executeUpdate(updateQuery);
99
			return true;
100
		} catch (Exception e) {
101
			logger.warn("Unique index for username could not be created");
102
			return false;
103
		}
104
	}
105
	
106
	private String getCreateQuery(ICdmDataSource datasource, CaseType caseType, String tableName, String constraintName, String columnName) {
107
			DatabaseTypeEnum type = datasource.getDatabaseType();
108
			String indexName = "_UniqueKey";
109
			String updateQuery;
110
			if (type.equals(DatabaseTypeEnum.MySQL)){
111
				//Maybe MySQL also works with the below syntax. Did not check yet.
112
				updateQuery = "ALTER TABLE @@"+ tableName + "@@ ADD UNIQUE INDEX " + constraintName + " ("+columnName+");";
113
			}else if (type.equals(DatabaseTypeEnum.H2) || type.equals(DatabaseTypeEnum.PostgreSQL) || type.equals(DatabaseTypeEnum.SqlServer2005)){
114
				updateQuery = "CREATE UNIQUE INDEX " + constraintName + " ON "+tableName+"(" + columnName + ")";
115
			}else{
116
				throw new IllegalArgumentException("Datasource type not supported: " + type.getName());
117
			}
118
			updateQuery = updateQuery.replace("@indexName", indexName);
119
			updateQuery = caseType.replaceTableNames(updateQuery);
120
			return updateQuery;
121
	}
122

    
123
	private boolean removeExistingConstraint(ICdmDataSource datasource, CaseType caseType) {
124
		try {
125
			DatabaseTypeEnum type = datasource.getDatabaseType();
126
			String indexName = "_UniqueKey";
127
			String updateQuery = makeRemoveConstraintUpdateQuery(caseType, type, indexName);
128
			try {
129
				datasource.executeUpdate(updateQuery);
130
			} catch (Exception e) {
131
				indexName = "uuid";
132
				updateQuery = makeRemoveConstraintUpdateQuery(caseType, type, indexName);
133
				datasource.executeUpdate(updateQuery);
134
			}
135
			return true;
136
		} catch (Exception e) {
137
			logger.warn("Old index could not be removed");
138
			return false;
139
		}
140
	}
141

    
142

    
143
	/**
144
	 * @param caseType
145
	 * @param type
146
	 * @param indexName
147
	 * @param updateQuery
148
	 * @return
149
	 */
150
	private String makeRemoveConstraintUpdateQuery(CaseType caseType,
151
			DatabaseTypeEnum type, String indexName) {
152
		String updateQuery;
153
		if (type.equals(DatabaseTypeEnum.MySQL)){
154
			updateQuery = "ALTER TABLE @@" + tableName + "@@ DROP INDEX @indexName";
155
		}else if (type.equals(DatabaseTypeEnum.H2)){
156
			updateQuery = "ALTER TABLE @@" + tableName + "@@ DROP CONSTRAINT IF EXISTS @indexName";
157
		}else if (type.equals(DatabaseTypeEnum.PostgreSQL)){
158
			updateQuery = "ALTER TABLE @@" + tableName + "@@ DROP CONSTRAINT @indexName";
159
		}else if (type.equals(DatabaseTypeEnum.SqlServer2005)){
160
			//TODO
161
			throw new RuntimeException("Remove index not yet supported for SQLServer");
162
		}else{
163
			throw new IllegalArgumentException("Datasource type not supported: " + type.getName());
164
		}
165
		updateQuery = updateQuery.replace("@indexName", indexName);
166
		updateQuery = caseType.replaceTableNames(updateQuery);
167
		return updateQuery;
168
	}
169
}
(4-4/4)