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
.v33_34
;
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
;
19 import eu
.etaxonomy
.cdm
.database
.update
.CaseType
;
20 import eu
.etaxonomy
.cdm
.database
.update
.ISchemaUpdaterStep
;
21 import eu
.etaxonomy
.cdm
.database
.update
.SchemaUpdaterStepBase
;
28 public class UsernameConstraintUpdater
extends SchemaUpdaterStepBase
<UsernameConstraintUpdater
> implements ISchemaUpdaterStep
{
29 private static final Logger logger
= Logger
.getLogger(UsernameConstraintUpdater
.class);
31 public static final UsernameConstraintUpdater
NewInstance(String stepName
){
32 return new UsernameConstraintUpdater(stepName
);
36 protected UsernameConstraintUpdater(String stepName
) {
42 public Integer
invoke(ICdmDataSource datasource
, IProgressMonitor monitor
, CaseType caseType
) throws SQLException
{
43 //remove 2-fold constraint
44 removeExistingConstraint(datasource
, caseType
);
45 createUsernameConstraint(datasource
, caseType
);
46 createUuidConstraint(datasource
, caseType
);
50 private void createUuidConstraint(ICdmDataSource datasource
,
53 String updateQuery
= getCreateQuery(datasource
, caseType
, "@@UserAccount@@", "username_", "username");
54 datasource
.executeUpdate(updateQuery
);
55 } catch (SQLException e
) {
56 logger
.warn("Unique index for UserAccount.uuid could not be created");
60 private void createUsernameConstraint(ICdmDataSource datasource
,
63 String updateQuery
= getCreateQuery(datasource
, caseType
, "@@UserAccount@@", "username_", "username");
64 datasource
.executeUpdate(updateQuery
);
65 } catch (SQLException e
) {
66 logger
.warn("Unique index for username could not be created");
70 private String
getCreateQuery(ICdmDataSource datasource
, CaseType caseType
, String tableName
, String constraintName
, String columnName
) {
71 DatabaseTypeEnum type
= datasource
.getDatabaseType();
72 String indexName
= "_UniqueKey";
74 if (type
.equals(DatabaseTypeEnum
.MySQL
)){
75 updateQuery
= "ALTER TABLE @@"+ tableName
+ "@@ ADD UNIQUE INDEX " + constraintName
+ " ("+columnName
+");";
76 }else if (type
.equals(DatabaseTypeEnum
.H2
) || type
.equals(DatabaseTypeEnum
.PostgreSQL
) || type
.equals(DatabaseTypeEnum
.SqlServer2005
)){
77 updateQuery
= "CREATE UNIQUE INDEX " + constraintName
+ " ON "+tableName
+"(" + columnName
+ ")";
79 throw new IllegalArgumentException("Datasource type not supported: " + type
.getName());
81 updateQuery
= updateQuery
.replace("@indexName", indexName
);
82 caseType
.replaceTableNames("@@UserAccount@@");
87 private void removeExistingConstraint(ICdmDataSource datasource
, CaseType caseType
) {
89 DatabaseTypeEnum type
= datasource
.getDatabaseType();
90 String indexName
= "_UniqueKey";
92 if (type
.equals(DatabaseTypeEnum
.MySQL
)){
93 updateQuery
= "ALTER TABLE @@UserAccount@@ DROP INDEX @indexName";
94 }else if (type
.equals(DatabaseTypeEnum
.H2
)){
95 updateQuery
= "ALTER TABLE @@UserAccount@@ DROP CONSTRAINT IF EXISTS @indexName";
96 }else if (type
.equals(DatabaseTypeEnum
.PostgreSQL
)){
97 updateQuery
= "ALTER TABLE @@UserAccount@@ DROP CONSTRAINT @indexName";
98 }else if (type
.equals(DatabaseTypeEnum
.SqlServer2005
)){
100 throw new RuntimeException("Remove index not yet supported for SQLServer");
102 throw new IllegalArgumentException("Datasource type not supported: " + type
.getName());
104 updateQuery
= updateQuery
.replace("@indexName", indexName
);
105 updateQuery
= caseType
.replaceTableNames("@@UserAccount@@");
106 datasource
.executeUpdate(updateQuery
);
107 } catch (SQLException e
) {
108 logger
.warn("Old index could not be removed");
112 // private boolean checkExists(ICdmDataSource datasource) throws SQLException, DatabaseTypeNotSupportedException {
113 // DatabaseTypeEnum type = datasource.getDatabaseType();
114 // if (type.equals(DatabaseTypeEnum.MySQL)){
115 // String sql = "SELECT count(*) FROM information_schema.TABLE_CONSTRAINTS " +
116 // " WHERE table_name ='@tableName' AND CONSTRAINT_SCHEMA = '@dbName' AND CONSTRAINT_TYPE = 'UNIQUE' ";
117 // sql = sql.replace("@tableName", tableName);
118 // sql = sql.replace("@columnName", indexColumn);
119 // sql = sql.replace("@dbName", datasource.getDatabase());
120 // long count = (Long)datasource.getSingleValue(sql);
122 // }else if (type.equals(DatabaseTypeEnum.PostgreSQL)){
123 // logger.warn("checkExists not yet implemented for PostGreSQL" );
125 // }else if (type.equals(DatabaseTypeEnum.H2)){
126 // String indexName = getIndexName(datasource);
127 // return indexName != null;
135 // public String getUpdateQueryString(String tableName, ICdmDataSource datasource, IProgressMonitor monitor) throws DatabaseTypeNotSupportedException, SQLException {
136 // //NOTE: no caseType required here
137 // String updateQuery;
138 // DatabaseTypeEnum type = datasource.getDatabaseType();
139 // String indexName = getIndexName(datasource);
141 //// if (type.equals(DatabaseTypeEnum.SqlServer2005)){
142 // //MySQL allows both syntaxes
143 //// updateQuery = "ALTER TABLE @tableName ADD @columnName @columnType";
145 // if (type.equals(DatabaseTypeEnum.H2)){
146 // updateQuery = "ALTER TABLE @tableName DROP CONSTRAINT IF EXISTS @indexName";
147 // }else if (type.equals(DatabaseTypeEnum.PostgreSQL)){
148 //// updateQuery = "DROP INDEX IF EXISTS @indexName"; // does not work because index is used in the constraint
149 //// updateQuery = "ALTER TABLE @tableName DROP CONSTRAINT IF EXISTS @indexName"; //"if exists" does not work (version 8.4)
150 // updateQuery = "ALTER TABLE @tableName DROP CONSTRAINT @indexName";
151 // }else if (type.equals(DatabaseTypeEnum.MySQL)){
152 // updateQuery = "ALTER TABLE @tableName DROP INDEX @indexName";
154 // updateQuery = null;
155 // String warning = "Update step '" + this.getStepName() + "' is not supported by " + type.getName();
156 // monitor.warning(warning);
157 // throw new DatabaseTypeNotSupportedException(warning);
159 // updateQuery = updateQuery.replace("@tableName", tableName);
160 // updateQuery = updateQuery.replace("@indexName", indexName);
162 // return updateQuery;
166 // private String getIndexName(ICdmDataSource datasource) throws DatabaseTypeNotSupportedException, SQLException {
167 // String result = this.indexColumn;
168 // DatabaseTypeEnum type = datasource.getDatabaseType();
169 // if (type.equals(DatabaseTypeEnum.SqlServer2005)){
170 // throw new DatabaseTypeNotSupportedException(type.toString());
171 // }else if (type.equals(DatabaseTypeEnum.MySQL)){
172 // result = this.indexColumn;
173 // }else if (type.equals(DatabaseTypeEnum.H2) ){
174 //// String sql = "SELECT INDEX_NAME FROM INFORMATION_SCHEMA.INDEXES WHERE TABLE_NAME = @tableName AND INDEX_TYPE_NAME = 'UNIQUE INDEX'";
175 // String sql = "SELECT CONSTRAINT_NAME " +
176 // " FROM INFORMATION_SCHEMA.CONSTRAINTS "+
177 // " WHERE CONSTRAINT_CATALOG = '@dbName' AND "+
178 // " TABLE_NAME = '@tableName' AND CONSTRAINT_TYPE = 'UNIQUE' AND "+
179 // " COLUMN_LIST = '@columnName'";
180 // sql = sql.replace("@tableName", tableName.toUpperCase());
181 // sql = sql.replace("@columnName", indexColumn.toUpperCase());
182 // sql = sql.replace("@dbName", datasource.getDatabase().toUpperCase());
183 // String constraintName = (String)datasource.getSingleValue(sql);
184 // result = constraintName;
185 // }else if (type.equals(DatabaseTypeEnum.PostgreSQL)){
186 // //TODO do we need this cased?
187 // result = this.tableName + "_" + this.indexColumn + "_key";
189 // throw new DatabaseTypeNotSupportedException(type.toString());