Project

General

Profile

Download (12.7 KB) Statistics
| Branch: | Tag: | Revision:
1
// $Id$
2
/**
3
* Copyright (C) 2009 EDIT
4
* European Distributed Institute of Taxonomy 
5
* http://www.e-taxonomy.eu
6
* 
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.
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
import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
21
import eu.etaxonomy.cdm.database.DatabaseTypeEnum;
22
import eu.etaxonomy.cdm.database.ICdmDataSource;
23

    
24
/**
25
 * @author a.mueller
26
 * @date 16.09.2010
27
 *
28
 */
29
public class TableCreator extends SchemaUpdaterStepBase implements ISchemaUpdaterStep {
30
	@SuppressWarnings("unused")
31
	private static final Logger logger = Logger.getLogger(TableCreator.class);
32
	
33
	private static final boolean SORT_INDEX = true;
34
	
35
	protected String tableName;
36
	private List<String> columnNames;
37
	private List<String> columnTypes;
38
	private List<Object> defaultValues;
39
	private List<Boolean> isNotNull;
40
	private List<String> referencedTables;
41
	private boolean includeAudTable;
42
	private boolean includeCdmBaseAttributes;
43
	private boolean includeIdentifiableEntity;
44
	protected List<ColumnAdder> columnAdders = new ArrayList<ColumnAdder>();
45
	protected List<ISchemaUpdaterStep> mnTablesStepList = new ArrayList<ISchemaUpdaterStep>();
46
	private String primaryKeyParams;
47
	private String primaryKeyParams_AUD;
48
	private String uniqueParams;
49
	private String uniqueParams_AUD;
50

    
51
	
52
//	public static final TableCreator NewInstance(String stepName, String tableName, List<String> columnNames, List<String> columnTypes, List<Object> defaultValues, List<Boolean> isNull, boolean includeAudTable){
53
	public static final TableCreator NewInstance(String stepName, String tableName, List<String> columnNames, List<String> columnTypes, boolean includeAudTable, boolean includeCdmBaseAttributes){
54
		return new TableCreator(stepName, tableName, columnNames, columnTypes, null, null, null, includeAudTable, includeCdmBaseAttributes, false);
55
	}
56
	
57
	public static final TableCreator NewInstance(String stepName, String tableName, String[] columnNames, String[] columnTypes, String[] referencedTables, boolean includeAudTable, boolean includeCdmBaseAttributes){
58
		return new TableCreator(stepName, tableName, Arrays.asList(columnNames), Arrays.asList(columnTypes), null, null, Arrays.asList(referencedTables), includeAudTable, includeCdmBaseAttributes, false);
59
	}
60
	
61
	public static final TableCreator NewIdentifiableInstance(String stepName, String tableName, String[] columnNames, String[] columnTypes, String[] referencedTables, boolean includeAudTable){
62
		return new TableCreator(stepName, tableName, Arrays.asList(columnNames), Arrays.asList(columnTypes), null, null, Arrays.asList(referencedTables), includeAudTable, true, true);
63
	}
64
	
65
	protected TableCreator(String stepName, String tableName, List<String> columnNames, List<String> columnTypes, List<Object> defaultValues, List<Boolean> isNotNull, List<String> referencedTables, boolean includeAudTable, boolean includeCdmBaseAttributes, boolean includeIdentifiableEntity) {
66
		super(stepName);
67
		this.tableName = tableName;
68
		this.columnNames = columnNames;
69
		this.columnTypes = columnTypes;
70
		this.defaultValues = defaultValues;
71
		this.isNotNull = isNotNull;
72
		this.referencedTables = referencedTables;
73
		this.includeAudTable = includeAudTable;
74
		this.includeCdmBaseAttributes = includeCdmBaseAttributes;
75
		this.includeIdentifiableEntity = includeIdentifiableEntity;
76
		makeColumnAdders();
77
		makeMnTables();
78
	}
79

    
80

    
81
	private void makeColumnAdders() {
82
		if (columnNames.size() != columnTypes.size()){
83
			throw new RuntimeException ("ColumnNames and columnTypes must be of same size. Step: " + getStepName());
84
		}
85
			
86
		for (int i = 0; i < columnNames.size(); i++){
87
			boolean isNotNull = this.isNotNull == null ? false : this.isNotNull.get(i);
88
			if ("integer".equals(columnTypes.get(i)) || "int".equals(columnTypes.get(i))){
89
				String referencedTable = (this.referencedTables == null) ?  null : this.referencedTables.get(i);
90
				ColumnAdder adder = ColumnAdder.NewIntegerInstance(this.getStepName(), this.tableName, this.columnNames.get(i), includeAudTable, isNotNull, referencedTable);
91
				this.columnAdders.add(adder);
92
			}else if ("boolean".equals(columnTypes.get(i)) || "bit".equals(columnTypes.get(i))){
93
				ColumnAdder adder = ColumnAdder.NewBooleanInstance(getStepName(), this.tableName,  this.columnNames.get(i), includeAudTable, Boolean.valueOf(this.defaultValues.get(i).toString()));
94
				this.columnAdders.add(adder);
95
			}else if (columnTypes.get(i).startsWith("string")){
96
				Integer length = Integer.valueOf(columnTypes.get(i).substring("string_".length()));
97
				ColumnAdder adder = ColumnAdder.NewStringInstance(this.getStepName(), this.tableName, this.columnNames.get(i), length, includeAudTable);
98
				this.columnAdders.add(adder);
99
			}else if ("tinyint".equals(columnTypes.get(i)) ){
100
				ColumnAdder adder = ColumnAdder.NewTinyIntegerInstance(this.getStepName(), this.tableName, this.columnNames.get(i), includeAudTable, isNotNull);
101
				this.columnAdders.add(adder);
102
			}
103
		}
104
	}
105

    
106
	
107
	/* (non-Javadoc)
108
	 * @see eu.etaxonomy.cdm.database.update.SchemaUpdaterStepBase#invoke(eu.etaxonomy.cdm.database.ICdmDataSource, eu.etaxonomy.cdm.common.IProgressMonitor)
109
	 */
110
	@Override
111
	public Integer invoke(ICdmDataSource datasource, IProgressMonitor monitor) throws SQLException {
112
		try {
113
			boolean result = true;
114
			result &= createTable(tableName, false, datasource, monitor);
115
			if (includeAudTable){
116
				String aud = "_AUD";
117
				result &= createTable(tableName + aud, true, datasource, monitor);
118
			}
119
//			result &= invokeMns();
120
			return (result == true )? 0 : null;
121
		} catch (DatabaseTypeNotSupportedException e) {
122
			throw new SQLException(e);
123
		}
124
	}
125

    
126

    
127

    
128
	@Override
129
	public List<ISchemaUpdaterStep> getInnerSteps() {
130
		return mnTablesStepList;
131
	}
132

    
133
	private String getColumnsSql(String tableName, ICdmDataSource datasource, IProgressMonitor monitor) throws DatabaseTypeNotSupportedException {
134
		String result = "";
135
		for (ColumnAdder adder : this.columnAdders){
136
			String singleAdderSQL = adder.getUpdateQueryString(tableName, datasource, monitor) + ", ";
137
			
138
			String[] split = singleAdderSQL.split(ColumnAdder.getAddColumnSeperator(datasource));
139
			result += split[1];
140
		}
141
		return result;
142
	}
143

    
144
	private boolean createTable(String tableName, boolean isAudit, ICdmDataSource datasource, IProgressMonitor monitor) throws DatabaseTypeNotSupportedException {
145
		String updateQuery = "CREATE TABLE @tableName (";
146
		if (isAudit){
147
			updateQuery += " REV integer not null, revtype tinyint, ";
148
		}
149
		if (includeCdmBaseAttributes){
150
				updateQuery += " id integer not null,"
151
					+ " created datetime, "
152
					+ " uuid varchar(36),"
153
					+ " updated datetime, "
154
					+ " createdby_id integer,"
155
					+ " updatedby_id integer, ";
156
				
157
		}
158
		if (this.includeIdentifiableEntity){
159
			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),";
160
		}
161
		
162
		updateQuery += 	getColumnsSql(tableName, datasource, monitor);
163
		
164
		String primaryKeySql = primaryKey(isAudit)==null ? "" : "primary key (" + primaryKey(isAudit) + "),";
165
		String uniqueSql = unique(isAudit)== null ? "" : "unique(" + unique(isAudit) + "),";
166
		updateQuery += primaryKeySql + uniqueSql;
167
		
168
		updateQuery = StringUtils.chomp(updateQuery.trim(), ",");
169
		updateQuery += ")";
170
		
171
		updateQuery = updateQuery.replace("@tableName", tableName);
172
		if (datasource.getDatabaseType().equals(DatabaseTypeEnum.MySQL)){
173
			updateQuery += " ENGINE=MYISAM DEFAULT CHARSET=utf8 ";
174
		}
175
		logger.debug(updateQuery);
176
		datasource.executeUpdate(updateQuery);
177
		createForeignKeys(tableName, isAudit, datasource, monitor);
178
		return true;
179
	}
180

    
181

    
182
	private void makeMnTables() {
183
		if (this.includeIdentifiableEntity){
184
			TableCreator tableCreator;
185
			//annotations
186
			stepName= "Add @tableName annotations";
187
			stepName = stepName.replace("@tableName", this.tableName);
188
			tableCreator = MnTableCreator.NewMnInstance(stepName, this.tableName, "Annotation", SchemaUpdaterBase.INCLUDE_AUDIT);
189
			mnTablesStepList.add(tableCreator);
190

    
191
			//credits
192
			stepName= "Add @tableName credits";
193
			stepName = stepName.replace("@tableName", this.tableName);
194
			tableCreator = MnTableCreator.NewMnInstance(stepName, this.tableName, null, "Credit", null, SchemaUpdaterBase.INCLUDE_AUDIT, SORT_INDEX, false);
195
			mnTablesStepList.add(tableCreator);
196
			
197
			//extensions
198
			stepName= "Add @tableName extensions";
199
			stepName = stepName.replace("@tableName", this.tableName);
200
			tableCreator = MnTableCreator.NewMnInstance(stepName, this.tableName, "Extension", SchemaUpdaterBase.INCLUDE_AUDIT);
201
			mnTablesStepList.add(tableCreator);
202

    
203
			//marker
204
			stepName= "Add @tableName marker";
205
			stepName = stepName.replace("@tableName", this.tableName);
206
			tableCreator = MnTableCreator.NewMnInstance(stepName, this.tableName, "Marker", SchemaUpdaterBase.INCLUDE_AUDIT);
207
			mnTablesStepList.add(tableCreator);
208
			
209
			//OriginalSourceBase
210
			stepName= "Add @tableName sources";
211
			stepName = stepName.replace("@tableName", this.tableName);
212
			tableCreator = MnTableCreator.NewMnInstance(stepName, this.tableName, null, "OriginalSourceBase", "sources", SchemaUpdaterBase.INCLUDE_AUDIT, false, true);
213
			mnTablesStepList.add(tableCreator);
214

    
215
			//Rights
216
			stepName= "Add @tableName rights";
217
			stepName = stepName.replace("@tableName", this.tableName);
218
			tableCreator = MnTableCreator.NewMnInstance(stepName, this.tableName, "Rights", SchemaUpdaterBase.INCLUDE_AUDIT);
219
			mnTablesStepList.add(tableCreator);
220

    
221
			
222
		}
223
	}
224
	
225
	private void createForeignKeys(String tableName, boolean isAudit, ICdmDataSource datasource, IProgressMonitor monitor) {
226
		if (includeCdmBaseAttributes){
227
			String attribute = "updatedby";
228
			String referencedTable = "UserAccount";
229
			makeForeignKey(tableName, datasource, attribute, referencedTable);
230
			
231
			attribute = "createdby";
232
			referencedTable = "UserAccount";
233
			makeForeignKey(tableName, datasource, attribute, referencedTable);			
234
		
235
		}
236
		if (isAudit){
237
			String attribute = "REV";
238
			String referencedTable = "AuditEvent";
239
			makeForeignKey(tableName, datasource, attribute, referencedTable);
240
		}
241
		for (ColumnAdder adder : this.columnAdders){
242
			if (adder.getReferencedTable() != null){
243
				makeForeignKey(tableName, datasource, adder.getNewColumnName(), adder.getReferencedTable()); 
244
			}
245
		}
246
	}
247

    
248
	public static void makeForeignKey(String tableName, ICdmDataSource datasource, String attribute, String referencedTable) {
249
		String index = "FK@tableName_@attribute";
250
		index = index.replace("@tableName", tableName);
251
		index = index.replace("@attribute", attribute);
252
		
253
		String idSuffix = "_id";
254
		if ("REV".equalsIgnoreCase(attribute) || attribute.endsWith(idSuffix)){
255
			idSuffix = "";
256
		}
257
		String updateQuery = "ALTER TABLE @tableName ADD INDEX @index (@attribute), ADD CONSTRAINT @index FOREIGN KEY (@attribute) REFERENCES @referencedTable (id)";
258
		updateQuery = updateQuery.replace("@tableName", tableName);
259
		updateQuery = updateQuery.replace("@index", index);
260
		updateQuery = updateQuery.replace("@attribute", attribute + idSuffix);
261
		updateQuery = updateQuery.replace("@referencedTable", referencedTable);
262
		
263
		logger.debug(updateQuery);
264
		datasource.executeUpdate(updateQuery);
265
	}
266

    
267

    
268
	protected String primaryKey(boolean isAudit){
269
		String result = null;
270
		if (! isAudit && this.primaryKeyParams != null){ 
271
			return this.primaryKeyParams;
272
		}else if (isAudit && this.primaryKeyParams_AUD != null){ 
273
			return this.primaryKeyParams_AUD;
274
		} 
275

    
276
		if (includeCdmBaseAttributes || ! includeCdmBaseAttributes){ //TODO how to handle not CDMBase includes
277
			if (! isAudit){
278
				result = "id";
279
			}else{
280
				result = "id, REV";
281
			}
282
		}
283
		return result;
284
	}
285
	
286
	protected String unique(boolean isAudit){
287
		if (! isAudit){
288
			if (this.uniqueParams != null){
289
				return this.uniqueParams;
290
			}
291
			if (includeCdmBaseAttributes){
292
				return "uuid"; //TODO how to handle not CDMBase includes
293
			}
294
			return null;
295
		}else{
296
			if (this.uniqueParams_AUD != null){
297
				return this.uniqueParams_AUD;
298
			}
299
			return null;
300
		}
301
	}
302

    
303
	public void setPrimaryKeyParams(String primaryKeyParams, String primaryKeyParams_AUD) {
304
		this.primaryKeyParams = primaryKeyParams;
305
		this.primaryKeyParams_AUD = primaryKeyParams_AUD;
306
	}
307

    
308
	public void setUniqueParams(String uniqueParams, String uniqueParams_AUD) {
309
		this.uniqueParams = uniqueParams;
310
		this.uniqueParams_AUD = uniqueParams_AUD;
311
	}
312
}
(17-17/24)