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
|
}
|