Project

General

Profile

Download (20.1 KB) Statistics
| Branch: | Tag: | Revision:
1 1d36aa54 Andreas Müller
// $Id$
2
/**
3
* Copyright (C) 2009 EDIT
4 7d7355ba Andreas M��ller
* European Distributed Institute of Taxonomy
5 1d36aa54 Andreas Müller
* http://www.e-taxonomy.eu
6 7d7355ba Andreas M��ller
*
7 1d36aa54 Andreas Müller
* 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.
9
*/
10
package eu.etaxonomy.cdm.database.update;
11
12
import java.sql.SQLException;
13
import java.util.ArrayList;
14
import java.util.Arrays;
15
import java.util.List;
16
17
import org.apache.commons.lang.StringUtils;
18
import org.apache.log4j.Logger;
19
20 0f9d4e5a Andreas Müller
import eu.etaxonomy.cdm.common.CdmUtils;
21 bd1d3bee Andreas Müller
import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
22 1d36aa54 Andreas Müller
import eu.etaxonomy.cdm.database.DatabaseTypeEnum;
23
import eu.etaxonomy.cdm.database.ICdmDataSource;
24
25
/**
26
 * @author a.mueller
27
 * @date 16.09.2010
28
 *
29
 */
30 9692864e Andreas Müller
public class TableCreator extends AuditedSchemaUpdaterStepBase<TableCreator> implements ISchemaUpdaterStep {
31 1d36aa54 Andreas Müller
	private static final Logger logger = Logger.getLogger(TableCreator.class);
32 7d7355ba Andreas M��ller
33 1d36aa54 Andreas Müller
	private static final boolean SORT_INDEX = true;
34 7d7355ba Andreas M��ller
35
	private final List<String> columnNames;
36
	private final List<String> columnTypes;
37
	private final List<Object> defaultValues;
38
	private final List<Boolean> isNotNull;
39
	private final List<String> referencedTables;
40
	private final boolean includeCdmBaseAttributes;
41
	private final boolean includeIdentifiableEntity;
42
	private final boolean includeAnnotatableEntity;
43 5a479f39 Andreas Müller
	private boolean includeEventBase;
44 7d7355ba Andreas M��ller
	private final boolean excludeVersionableAttributes;
45 1d36aa54 Andreas Müller
	protected List<ColumnAdder> columnAdders = new ArrayList<ColumnAdder>();
46
	protected List<ISchemaUpdaterStep> mnTablesStepList = new ArrayList<ISchemaUpdaterStep>();
47
	private String primaryKeyParams;
48
	private String primaryKeyParams_AUD;
49
	private String uniqueParams;
50
	private String uniqueParams_AUD;
51
52 7d7355ba Andreas M��ller
53 1d36aa54 Andreas Müller
//	public static final TableCreator NewInstance(String stepName, String tableName, List<String> columnNames, List<String> columnTypes, List<Object> defaultValues, List<Boolean> isNull, boolean includeAudTable){
54
	public static final TableCreator NewInstance(String stepName, String tableName, List<String> columnNames, List<String> columnTypes, boolean includeAudTable, boolean includeCdmBaseAttributes){
55 3b38a94c Andreas Müller
		return new TableCreator(stepName, tableName, columnNames, columnTypes, null, null, null, includeAudTable, includeCdmBaseAttributes, false, false, false);
56 1d36aa54 Andreas Müller
	}
57 7d7355ba Andreas M��ller
58 1d36aa54 Andreas Müller
	public static final TableCreator NewInstance(String stepName, String tableName, String[] columnNames, String[] columnTypes, String[] referencedTables, boolean includeAudTable, boolean includeCdmBaseAttributes){
59 3b38a94c Andreas Müller
		return new TableCreator(stepName, tableName, Arrays.asList(columnNames), Arrays.asList(columnTypes), null, null, Arrays.asList(referencedTables), includeAudTable, includeCdmBaseAttributes, false, false, false);
60
	}
61 7d7355ba Andreas M��ller
62 782d9cc1 Andreas Müller
	public static final TableCreator NewNonVersionableInstance(String stepName, String tableName, String[] columnNames, String[] columnTypes, String[] referencedTables){
63
		return new TableCreator(stepName, tableName, Arrays.asList(columnNames), Arrays.asList(columnTypes), null, null, Arrays.asList(referencedTables), false, true, false, false, true);
64
	}
65 7d7355ba Andreas M��ller
66 782d9cc1 Andreas Müller
	public static final TableCreator NewVersionableInstance(String stepName, String tableName, String[] columnNames, String[] columnTypes, String[] referencedTables, boolean includeAudTable){
67
		return new TableCreator(stepName, tableName, Arrays.asList(columnNames), Arrays.asList(columnTypes), null, null, Arrays.asList(referencedTables), includeAudTable, true, false, false, false);
68 5a479f39 Andreas Müller
	}
69 7d7355ba Andreas M��ller
70 5a479f39 Andreas Müller
	public static final TableCreator NewAnnotatableInstance(String stepName, String tableName, String[] columnNames, String[] columnTypes, String[] referencedTables, boolean includeAudTable){
71 3b38a94c Andreas Müller
		return new TableCreator(stepName, tableName, Arrays.asList(columnNames), Arrays.asList(columnTypes), null, null, Arrays.asList(referencedTables), includeAudTable, true, true, false, false);
72 5a479f39 Andreas Müller
	}
73 7d7355ba Andreas M��ller
74 5a479f39 Andreas Müller
	public static final TableCreator NewEventInstance(String stepName, String tableName, String[] columnNames, String[] columnTypes, String[] referencedTables, boolean includeAudTable){
75 3b38a94c Andreas Müller
		TableCreator result = new TableCreator(stepName, tableName, Arrays.asList(columnNames), Arrays.asList(columnTypes), null, null, Arrays.asList(referencedTables), includeAudTable, true, true, false, false);
76 5a479f39 Andreas Müller
		result.includeEventBase = true;
77
		return result;
78 1d36aa54 Andreas Müller
	}
79 7d7355ba Andreas M��ller
80 1d36aa54 Andreas Müller
	public static final TableCreator NewIdentifiableInstance(String stepName, String tableName, String[] columnNames, String[] columnTypes, String[] referencedTables, boolean includeAudTable){
81 3b38a94c Andreas Müller
		return new TableCreator(stepName, tableName, Arrays.asList(columnNames), Arrays.asList(columnTypes), null, null, Arrays.asList(referencedTables), includeAudTable, true, true, true, false);
82 1d36aa54 Andreas Müller
	}
83 7d7355ba Andreas M��ller
84
	protected TableCreator(String stepName, String tableName, List<String> columnNames, List<String> columnTypes, List<Object> defaultValues, List<Boolean> isNotNull, List<String> referencedTables,
85 3b38a94c Andreas Müller
			boolean includeAudTable, boolean includeCdmBaseAttributes, boolean includeAnnotatableEntity, boolean includeIdentifiableEntity, boolean excludeVersionableAttributes) {
86 7d7355ba Andreas M��ller
		super(stepName, tableName, includeAudTable);
87 1d36aa54 Andreas Müller
		this.columnNames = columnNames;
88
		this.columnTypes = columnTypes;
89
		this.defaultValues = defaultValues;
90
		this.isNotNull = isNotNull;
91
		this.referencedTables = referencedTables;
92
		this.includeCdmBaseAttributes = includeCdmBaseAttributes;
93 5a479f39 Andreas Müller
		this.includeAnnotatableEntity = includeAnnotatableEntity;
94 1d36aa54 Andreas Müller
		this.includeIdentifiableEntity = includeIdentifiableEntity;
95 3b38a94c Andreas Müller
		this.excludeVersionableAttributes = excludeVersionableAttributes;
96 1d36aa54 Andreas Müller
		makeColumnAdders();
97 ef081a36 Andreas Müller
		makeMnTables(mnTablesStepList, this.tableName, this.includeAnnotatableEntity, this.includeIdentifiableEntity);
98 1d36aa54 Andreas Müller
	}
99
100
101 0f9d4e5a Andreas Müller
	@Override
102
	public List<ISchemaUpdaterStep> getInnerSteps() {
103
		return mnTablesStepList;
104
	}
105
106
	/**
107
	 * Fills the {@link #columnAdders} list.
108
	 */
109 1d36aa54 Andreas Müller
	private void makeColumnAdders() {
110
		if (columnNames.size() != columnTypes.size()){
111
			throw new RuntimeException ("ColumnNames and columnTypes must be of same size. Step: " + getStepName());
112
		}
113 7d7355ba Andreas M��ller
114 54e8de3a Andreas Müller
		try {
115
			for (int i = 0; i < columnNames.size(); i++){
116
				boolean isNotNull = this.isNotNull == null ? false : this.isNotNull.get(i);
117
				if ("integer".equals(columnTypes.get(i)) || "int".equals(columnTypes.get(i))){
118
					String referencedTable = (this.referencedTables == null) ?  null : this.referencedTables.get(i);
119
					ColumnAdder adder = ColumnAdder.NewIntegerInstance(this.getStepName(), this.tableName, this.columnNames.get(i), includeAudTable, isNotNull, referencedTable);
120
					this.columnAdders.add(adder);
121
				}else if ("boolean".equals(columnTypes.get(i)) || "bit".equals(columnTypes.get(i))){
122
					String defaultValue = this.defaultValues == null ? null : this.defaultValues.get(i).toString();
123
					ColumnAdder adder = ColumnAdder.NewBooleanInstance(getStepName(), this.tableName,  this.columnNames.get(i), includeAudTable, Boolean.valueOf(defaultValue));
124
					this.columnAdders.add(adder);
125
				}else if (columnTypes.get(i).startsWith("string")){
126
					Integer length = Integer.valueOf(columnTypes.get(i).substring("string_".length()));
127
					ColumnAdder adder = ColumnAdder.NewStringInstance(this.getStepName(), this.tableName, this.columnNames.get(i), length, includeAudTable);
128
					this.columnAdders.add(adder);
129 395ccc97 Andreas Müller
				}else if (columnTypes.get(i).startsWith("clob")){
130
					ColumnAdder adder = ColumnAdder.NewClobInstance(this.getStepName(), this.tableName, this.columnNames.get(i), includeAudTable);
131
					this.columnAdders.add(adder);
132 54e8de3a Andreas Müller
				}else if ("tinyint".equals(columnTypes.get(i)) ){
133
					ColumnAdder adder = ColumnAdder.NewTinyIntegerInstance(this.getStepName(), this.tableName, this.columnNames.get(i), includeAudTable, isNotNull);
134
					this.columnAdders.add(adder);
135 323da513 Andreas Müller
				}else if ("datetime".equals(columnTypes.get(i)) ){
136
					ColumnAdder adder = ColumnAdder.NewDateTimeInstance(this.getStepName(), this.tableName, this.columnNames.get(i), includeAudTable, isNotNull);
137
					this.columnAdders.add(adder);
138 54e8de3a Andreas Müller
				}else if ("double".equals(columnTypes.get(i)) ){
139
					ColumnAdder adder = ColumnAdder.NewDoubleInstance(this.getStepName(), this.tableName, this.columnNames.get(i), includeAudTable, isNotNull);
140
					this.columnAdders.add(adder);
141 323da513 Andreas Müller
				}else{
142
					throw new RuntimeException("Column type " + columnTypes.get(i) + " not yet supported");
143 54e8de3a Andreas Müller
				}
144 1d36aa54 Andreas Müller
			}
145 54e8de3a Andreas Müller
		} catch (Exception e) {
146
			throw new RuntimeException(e);
147 1d36aa54 Andreas Müller
		}
148
	}
149 7d7355ba Andreas M��ller
150 0f9d4e5a Andreas Müller
	/**
151
	 * fills the mnTablesStepList
152 7d7355ba Andreas M��ller
	 * @param mnTablesStepList, String tableName
153 0f9d4e5a Andreas Müller
	 */
154 ef081a36 Andreas Müller
	public static void makeMnTables(List<ISchemaUpdaterStep> mnTablesStepList, String tableName, boolean includeAnnotatable, boolean includeIdentifiable) {
155 0f9d4e5a Andreas Müller
		TableCreator tableCreator;
156 ef081a36 Andreas Müller
		String stepName;
157 7d7355ba Andreas M��ller
158 ef081a36 Andreas Müller
		if (includeAnnotatable){
159 0f9d4e5a Andreas Müller
			//annotations
160
			stepName= "Add @tableName annotations";
161 ef081a36 Andreas Müller
			stepName = stepName.replace("@tableName", tableName);
162
			tableCreator = MnTableCreator.NewMnInstance(stepName, tableName, "Annotation", SchemaUpdaterBase.INCLUDE_AUDIT);
163 0f9d4e5a Andreas Müller
			mnTablesStepList.add(tableCreator);
164 1d36aa54 Andreas Müller
165 0f9d4e5a Andreas Müller
			//marker
166
			stepName= "Add @tableName marker";
167 ef081a36 Andreas Müller
			stepName = stepName.replace("@tableName", tableName);
168
			tableCreator = MnTableCreator.NewMnInstance(stepName, tableName, "Marker", SchemaUpdaterBase.INCLUDE_AUDIT);
169 0f9d4e5a Andreas Müller
			mnTablesStepList.add(tableCreator);
170 7d7355ba Andreas M��ller
171 0f9d4e5a Andreas Müller
		}
172 7d7355ba Andreas M��ller
173 ef081a36 Andreas Müller
		if (includeIdentifiable){
174 1d36aa54 Andreas Müller
175 0f9d4e5a Andreas Müller
			//credits
176
			stepName= "Add @tableName credits";
177 ef081a36 Andreas Müller
			stepName = stepName.replace("@tableName", tableName);
178
			tableCreator = MnTableCreator.NewMnInstance(stepName, tableName, null, "Credit", null, SchemaUpdaterBase.INCLUDE_AUDIT, SORT_INDEX, false);
179
			mnTablesStepList.add(tableCreator);
180 7d7355ba Andreas M��ller
181
182 ef081a36 Andreas Müller
			//identifier
183
			stepName= "Add @tableName identifiers";
184
			stepName = stepName.replace("@tableName", tableName);
185
			tableCreator = MnTableCreator.NewMnInstance(stepName, tableName, null, "Identifier", null, SchemaUpdaterBase.INCLUDE_AUDIT, SORT_INDEX, false);
186 0f9d4e5a Andreas Müller
			mnTablesStepList.add(tableCreator);
187 ef081a36 Andreas Müller
188 7d7355ba Andreas M��ller
189 0f9d4e5a Andreas Müller
			//extensions
190
			stepName= "Add @tableName extensions";
191 ef081a36 Andreas Müller
			stepName = stepName.replace("@tableName", tableName);
192
			tableCreator = MnTableCreator.NewMnInstance(stepName, tableName, "Extension", SchemaUpdaterBase.INCLUDE_AUDIT);
193 0f9d4e5a Andreas Müller
			mnTablesStepList.add(tableCreator);
194 7d7355ba Andreas M��ller
195 0f9d4e5a Andreas Müller
			//OriginalSourceBase
196
			stepName= "Add @tableName sources";
197 ef081a36 Andreas Müller
			stepName = stepName.replace("@tableName", tableName);
198
			tableCreator = MnTableCreator.NewMnInstance(stepName, tableName, null, "OriginalSourceBase", "sources", SchemaUpdaterBase.INCLUDE_AUDIT, false, true);
199 0f9d4e5a Andreas Müller
			mnTablesStepList.add(tableCreator);
200
201
			//Rights
202
			stepName= "Add @tableName rights";
203 ef081a36 Andreas Müller
			stepName = stepName.replace("@tableName", tableName);
204
			tableCreator = MnTableCreator.NewMnInstance(stepName, tableName, "Rights", SchemaUpdaterBase.INCLUDE_AUDIT);
205 0f9d4e5a Andreas Müller
			mnTablesStepList.add(tableCreator);
206 1d36aa54 Andreas Müller
		}
207
	}
208
209 0f9d4e5a Andreas Müller
210 9692864e Andreas Müller
	@Override
211 7747019c Andreas Müller
	protected boolean invokeOnTable(String tableName, ICdmDataSource datasource, IProgressMonitor monitor, CaseType caseType)  {
212 e4468df7 Andreas Müller
		try {
213 9692864e Andreas Müller
			boolean result = true;
214 0f9d4e5a Andreas Müller
			//CREATE
215 9692864e Andreas Müller
			String updateQuery = "CREATE TABLE @tableName (";
216 0f9d4e5a Andreas Müller
			//AUDIT
217 9692864e Andreas Müller
			if (isAuditing){
218 80a43971 Katja Luther
				updateQuery += " REV integer not null, revtype " + ColumnAdder.getDatabaseColumnType(datasource, "tinyint") + ", ";
219 9692864e Andreas Müller
			}
220 0f9d4e5a Andreas Müller
			//CdmBase
221 9692864e Andreas Müller
			if (includeCdmBaseAttributes){
222 80a43971 Katja Luther
					updateQuery += " id integer NOT NULL,"
223
						+ " created " + ColumnAdder.getDatabaseColumnType(datasource, "datetime") + ", "
224 0a345e59 Andreas Müller
						+ " uuid varchar(36) NOT NULL,"
225 3b38a94c Andreas Müller
						+ (excludeVersionableAttributes? "" : " updated " + ColumnAdder.getDatabaseColumnType(datasource, "datetime") + ", ")
226 9692864e Andreas Müller
						+ " createdby_id integer,"
227 3b38a94c Andreas Müller
						+ (excludeVersionableAttributes ? "" : " updatedby_id integer, ");
228 9692864e Andreas Müller
			}
229 0f9d4e5a Andreas Müller
			//EventBase
230 9692864e Andreas Müller
			if (this.includeEventBase){
231
				updateQuery += "timeperiod_start varchar(255), timeperiod_end varchar(255), timeperiod_freetext varchar(255), actor_id int, description varchar(255),";
232
			}
233 0f9d4e5a Andreas Müller
			//Identifiable
234 9692864e Andreas Müller
			if (this.includeIdentifiableEntity){
235
				updateQuery += "lsid_authority varchar(255), lsid_lsid varchar(255), lsid_namespace varchar(255), lsid_object varchar(255), lsid_revision varchar(255), protectedtitlecache bit not null, titleCache varchar(255),";
236
			}
237 0f9d4e5a Andreas Müller
			//specific columns
238 9692864e Andreas Müller
			updateQuery += 	getColumnsSql(tableName, datasource, monitor);
239 7d7355ba Andreas M��ller
240 0f9d4e5a Andreas Müller
			//primary and unique keys
241 9692864e Andreas Müller
			String primaryKeySql = primaryKey(isAuditing)==null ? "" : "primary key (" + primaryKey(isAuditing) + "),";
242
			String uniqueSql = unique(isAuditing)== null ? "" : "unique(" + unique(isAuditing) + "),";
243
			updateQuery += primaryKeySql + uniqueSql;
244 7d7355ba Andreas M��ller
245 0f9d4e5a Andreas Müller
			//finalize
246
			updateQuery = StringUtils.chomp(updateQuery.trim(), ",") + ")";
247 7d7355ba Andreas M��ller
248 0f9d4e5a Andreas Müller
			//replace
249 9692864e Andreas Müller
			updateQuery = updateQuery.replace("@tableName", tableName);
250 7d7355ba Andreas M��ller
251 0f9d4e5a Andreas Müller
			//append datasource specific string
252
			updateQuery += datasource.getDatabaseType().getHibernateDialect().getTableTypeString();
253
			logger.debug("UPDATE Query: " + updateQuery);
254 7d7355ba Andreas M��ller
255 0f9d4e5a Andreas Müller
			//execute
256 e4468df7 Andreas Müller
			datasource.executeUpdate(updateQuery);
257 7d7355ba Andreas M��ller
258 0f9d4e5a Andreas Müller
			//Foreign Keys
259 7747019c Andreas Müller
			result &= createForeignKeys(tableName, isAuditing, datasource, monitor, caseType);
260 7d7355ba Andreas M��ller
261 9692864e Andreas Müller
			return result;
262
		} catch (Exception e) {
263
			monitor.warning(e.getMessage(), e);
264 e4468df7 Andreas Müller
			logger.error(e);
265 9692864e Andreas Müller
			return false;
266 e4468df7 Andreas Müller
		}
267 1d36aa54 Andreas Müller
	}
268
269
270 0f9d4e5a Andreas Müller
	/**
271
	 * Returns the sql part for the {@link #columnAdders} columns.
272
	 * This is done by reusing the same method in the ColumnAdder class and removing all the prefixes like 'ADD COLUMN'
273
	 */
274
	private String getColumnsSql(String tableName, ICdmDataSource datasource, IProgressMonitor monitor) throws DatabaseTypeNotSupportedException {
275
		String result = "";
276
		for (ColumnAdder adder : this.columnAdders){
277
			String singleAdderSQL = adder.getUpdateQueryString(tableName, datasource, monitor) + ", ";
278 7d7355ba Andreas M��ller
279 0f9d4e5a Andreas Müller
			String[] split = singleAdderSQL.split(ColumnAdder.getAddColumnSeperator(datasource));
280
			result += split[1];
281 1d36aa54 Andreas Müller
		}
282 0f9d4e5a Andreas Müller
		return result;
283 1d36aa54 Andreas Müller
	}
284 0f9d4e5a Andreas Müller
285 7d7355ba Andreas M��ller
286 7747019c Andreas Müller
	private boolean createForeignKeys(String tableName, boolean isAudit, ICdmDataSource datasource, IProgressMonitor monitor, CaseType caseType) throws SQLException {
287 e4468df7 Andreas Müller
		boolean result = true;
288 1d36aa54 Andreas Müller
		if (includeCdmBaseAttributes){
289 a50d65cd Andreas Müller
			if (! this.excludeVersionableAttributes){
290
				String attribute = "updatedby";
291
				String referencedTable = "UserAccount";
292
				result &= makeForeignKey(tableName, datasource, monitor, attribute, referencedTable, caseType);
293
			}
294 7d7355ba Andreas M��ller
295 a50d65cd Andreas Müller
			String attribute = "createdby";
296
			String referencedTable = "UserAccount";
297 7d7355ba Andreas M��ller
			result &= makeForeignKey(tableName, datasource, monitor, attribute, referencedTable, caseType);
298
299 1d36aa54 Andreas Müller
		}
300
		if (isAudit){
301
			String attribute = "REV";
302
			String referencedTable = "AuditEvent";
303 7747019c Andreas Müller
			result &= makeForeignKey(tableName, datasource, monitor, attribute, referencedTable, caseType);
304 0f9d4e5a Andreas Müller
		}
305
		if (this.includeEventBase){
306
			String attribute = "actor_id";
307
			String referencedTable = "AgentBase";
308 7747019c Andreas Müller
			result &= makeForeignKey(tableName, datasource, monitor, attribute, referencedTable, caseType);
309 1d36aa54 Andreas Müller
		}
310
		for (ColumnAdder adder : this.columnAdders){
311
			if (adder.getReferencedTable() != null){
312 7d7355ba Andreas M��ller
				result &= makeForeignKey(tableName, datasource, monitor, adder.getNewColumnName(), adder.getReferencedTable(), caseType);
313 1d36aa54 Andreas Müller
			}
314
		}
315 e4468df7 Andreas Müller
		return result;
316 1d36aa54 Andreas Müller
	}
317
318 7747019c Andreas Müller
	public static boolean makeForeignKey(String tableName, ICdmDataSource datasource, IProgressMonitor monitor, String attribute, String referencedTable, CaseType caseType) throws SQLException {
319 e4468df7 Andreas Müller
		boolean result = true;
320 7d7355ba Andreas M��ller
321 7747019c Andreas Müller
		referencedTable = caseType.transformTo(referencedTable);
322 7d7355ba Andreas M��ller
323 0f9d4e5a Andreas Müller
		if (supportsForeignKeys(datasource, monitor, tableName, referencedTable)){
324
			String index = "FK@tableName_@attribute";
325
			index = index.replace("@tableName", tableName);
326
			index = index.replace("@attribute", attribute);
327 7d7355ba Andreas M��ller
328 0f9d4e5a Andreas Müller
			String idSuffix = "_id";
329
			if (isRevAttribute(attribute) || attribute.endsWith(idSuffix)){
330
				idSuffix = "";
331
			}
332 a7c12369 Andreas Müller
			//OLD - don't remember why we used ADD INDEX here
333
//			String updateQuery = "ALTER TABLE @tableName ADD INDEX @index (@attribute), ADD FOREIGN KEY (@attribute) REFERENCES @referencedTable (@id)";
334
			String updateQuery = "ALTER TABLE @tableName ADD @constraintName FOREIGN KEY (@attribute) REFERENCES @referencedTable (@id)";
335 0f9d4e5a Andreas Müller
			updateQuery = updateQuery.replace("@tableName", tableName);
336 a7c12369 Andreas Müller
//			updateQuery = updateQuery.replace("@index", index);
337 0f9d4e5a Andreas Müller
			updateQuery = updateQuery.replace("@attribute", attribute + idSuffix);
338
			updateQuery = updateQuery.replace("@referencedTable", referencedTable);
339 a7c12369 Andreas Müller
			if (datasource.getDatabaseType().equals(DatabaseTypeEnum.MySQL)){
340
				updateQuery = updateQuery.replace("@constraintName", "CONSTRAINT " + index);
341
			}else{
342
				updateQuery = updateQuery.replace("@constraintName", "");  //H2 does not support "CONSTRAINT", didn't check for others
343
			}
344 7d7355ba Andreas M��ller
345 0f9d4e5a Andreas Müller
			if (isRevAttribute(attribute)){
346
				updateQuery = updateQuery.replace("@id", "revisionnumber");
347
			}else{
348
				updateQuery = updateQuery.replace("@id", "id");
349
			}
350
			logger.debug(updateQuery);
351
			try {
352
				datasource.executeUpdate(updateQuery);
353
			} catch (Exception e) {
354
				String message = "Problem when creating Foreign Key for " + tableName +"." + attribute +": " + e.getMessage();
355
				monitor.warning(message);
356
				logger.warn(message, e);
357 a7c12369 Andreas Müller
				return true;   //we do not interrupt update if only foreign key generation did not work
358 0f9d4e5a Andreas Müller
			}
359 7d7355ba Andreas M��ller
			return result;
360 0f9d4e5a Andreas Müller
		}else{
361
			return true;
362 1d36aa54 Andreas Müller
		}
363 0f9d4e5a Andreas Müller
364
	}
365
366
	/**
367
	 * Determines if the tables and the database support foreign keys. If determination is not possible true is returned as default.
368
	 * @param datasource
369
	 * @param monitor
370
	 * @param tableName
371
	 * @param referencedTable
372
	 * @return
373
	 */
374
	private static boolean supportsForeignKeys(ICdmDataSource datasource, IProgressMonitor monitor, String tableName, String referencedTable) {
375
		boolean result = true;
376
		if (! datasource.getDatabaseType().equals(DatabaseTypeEnum.MySQL)){
377
			return true;
378
		}else{
379
			try {
380
				String myIsamTables = "";
381
				String format = "SELECT ENGINE FROM information_schema.TABLES where TABLE_SCHEMA = '%s' AND TABLE_NAME = '%s'";
382
				String sql = String.format(format, datasource.getDatabase(), tableName);
383
				String engine = (String)datasource.getSingleValue(sql);
384
				if (engine.equals("MyISAM")){
385
					result = false;
386
					myIsamTables = CdmUtils.concat(",", myIsamTables, tableName);
387
				}
388
				sql = String.format(format,  datasource.getDatabase(), referencedTable);
389
				engine = (String)datasource.getSingleValue(sql);
390
				if (engine.equals("MyISAM")){
391
					result = false;
392
					myIsamTables = CdmUtils.concat(",", myIsamTables, referencedTable);
393
				}
394
				if (result == false){
395
					String message = "Tables (%s) use MyISAM engine. MyISAM does not support foreign keys.";
396
					message = String.format(message, myIsamTables);
397
					monitor.warning(message);
398
				}
399
				return result;
400
			} catch (Exception e) {
401
				String message = "Problems to determine table engine for MySQL.";
402
				monitor.warning(message);
403 7d7355ba Andreas M��ller
				return true;  //default
404 0f9d4e5a Andreas Müller
			}
405 7d7355ba Andreas M��ller
406 e4468df7 Andreas Müller
		}
407 7d7355ba Andreas M��ller
408
409 0f9d4e5a Andreas Müller
	}
410
411
	private static boolean isRevAttribute(String attribute) {
412
		return "REV".equalsIgnoreCase(attribute);
413 1d36aa54 Andreas Müller
	}
414
415
416 0f9d4e5a Andreas Müller
	/**
417
	 * Constructs the primary key creation string
418
	 * @param isAudit
419
	 * @return
420
	 */
421 1d36aa54 Andreas Müller
	protected String primaryKey(boolean isAudit){
422
		String result = null;
423 7d7355ba Andreas M��ller
		if (! isAudit && this.primaryKeyParams != null){
424 1d36aa54 Andreas Müller
			return this.primaryKeyParams;
425 7d7355ba Andreas M��ller
		}else if (isAudit && this.primaryKeyParams_AUD != null){
426 1d36aa54 Andreas Müller
			return this.primaryKeyParams_AUD;
427 7d7355ba Andreas M��ller
		}
428 1d36aa54 Andreas Müller
429
		if (includeCdmBaseAttributes || ! includeCdmBaseAttributes){ //TODO how to handle not CDMBase includes
430
			if (! isAudit){
431
				result = "id";
432
			}else{
433
				result = "id, REV";
434
			}
435
		}
436
		return result;
437
	}
438 7d7355ba Andreas M��ller
439 0f9d4e5a Andreas Müller
	/**
440
	 * Constructs the unique key creation string
441
	 * @param isAudit
442
	 * @return
443
	 */
444 1d36aa54 Andreas Müller
	protected String unique(boolean isAudit){
445
		if (! isAudit){
446
			if (this.uniqueParams != null){
447
				return this.uniqueParams;
448
			}
449
			if (includeCdmBaseAttributes){
450
				return "uuid"; //TODO how to handle not CDMBase includes
451
			}
452
			return null;
453
		}else{
454
			if (this.uniqueParams_AUD != null){
455
				return this.uniqueParams_AUD;
456
			}
457
			return null;
458
		}
459
	}
460
461
	public void setPrimaryKeyParams(String primaryKeyParams, String primaryKeyParams_AUD) {
462
		this.primaryKeyParams = primaryKeyParams;
463
		this.primaryKeyParams_AUD = primaryKeyParams_AUD;
464
	}
465
466
	public void setUniqueParams(String uniqueParams, String uniqueParams_AUD) {
467
		this.uniqueParams = uniqueParams;
468
		this.uniqueParams_AUD = uniqueParams_AUD;
469
	}
470 a50d65cd Andreas Müller
}