Project

General

Profile

Download (8.17 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;
10

    
11
import java.sql.SQLException;
12
import java.util.HashMap;
13
import java.util.List;
14
import java.util.Map;
15

    
16
import org.apache.commons.lang.StringUtils;
17
import org.apache.logging.log4j.LogManager;
18
import org.apache.logging.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
 * This class represents one step in a schema update.
26
 * @author a.mueller
27
 * @since 13.09.2010
28
 *
29
 */
30
public class SimpleSchemaUpdaterStep extends SchemaUpdaterStepBase {
31
	private static final Logger logger = LogManager.getLogger(SimpleSchemaUpdaterStep.class);
32

    
33
	private final Map<DatabaseTypeEnum, String> queryMap = new HashMap<>();
34
	private final Map<DatabaseTypeEnum, String> auditQueryMap = new HashMap<>();
35

    
36
	private boolean includeAudit = false;
37
	private boolean withErrorRecovery = false;
38
	private String errorRecoveryMessage;
39

    
40
// *************************** FACTORY ********************************/
41

    
42
	/**
43
     * Simple schema updater with update query only for non_AUD tables.
44
	 *
45
	 * @param stepName step name
46
	 * @param defaultQuery the query
47
	 * @param adapt preliminary
48
	 * @return
49
	 */
50
	public static SimpleSchemaUpdaterStep NewNonAuditedInstance(List<ISchemaUpdaterStep> stepList, String stepName, String defaultQuery, int adapt){
51
		return new SimpleSchemaUpdaterStep(stepList, stepName, defaultQuery, false, null, null);
52
	}
53

    
54
	/**
55
	 * Simple schema updater with update query for AUD and non_AUD tables.
56
     *
57
     * @param stepName Step name
58
	 * @param defaultQuery query
59
	 * @param nonAuditedTableName the name of the non audited table. E.g. TaxonName
60
	 *     (while TaxonName_AUD is the audited table
61
	 * @param adapt preliminary
62
	 * @return
63
	 */
64
	public static SimpleSchemaUpdaterStep NewAuditedInstance(List<ISchemaUpdaterStep> stepList, String stepName, String defaultQuery, String nonAuditedTableName, int adapt){
65
		boolean audit = StringUtils.isNotBlank(nonAuditedTableName);
66
		return new SimpleSchemaUpdaterStep(stepList, stepName, defaultQuery, audit, nonAuditedTableName, null);
67
	}
68

    
69
	/**
70
	 * Simple schema updater with an explicit query for AUD table.
71
	 *
72
	 * @param stepName step name
73
	 * @param defaultQuery the non_AUD update query
74
	 * @param defaultQueryForAuditedTables the AUD update query
75
	 * @param adapt preliminary
76
	 * @return
77
	 */
78
	public static SimpleSchemaUpdaterStep NewExplicitAuditedInstance(List<ISchemaUpdaterStep> stepList, String stepName,
79
	        String defaultQuery, String defaultQueryForAuditedTables, int adapt){
80
		boolean audit = StringUtils.isNotBlank(defaultQueryForAuditedTables);
81
		return new SimpleSchemaUpdaterStep(stepList, stepName, defaultQuery, audit, null, defaultQueryForAuditedTables);
82
	}
83

    
84
//************************ CONSTRUCTOR ***********************************/
85

    
86
	private SimpleSchemaUpdaterStep(List<ISchemaUpdaterStep> stepList, String stepName, String defaultQuery,
87
	        boolean includeAudit, String tableName, String defaultQueryForAuditedTables){
88

    
89
	    super(stepList, stepName);
90
		this.includeAudit = includeAudit;
91
		queryMap.put(null, defaultQuery);
92

    
93
		if (includeAudit){
94
			if (StringUtils.isNotBlank(defaultQueryForAuditedTables)){
95
				auditQueryMap.put(null, defaultQueryForAuditedTables);
96
			}else if (isNotBlank(tableName)){
97
				setDefaultAuditing(tableName);
98
			}
99
		}
100
	}
101

    
102
// *************************** INVOKE *****************************
103

    
104
    @Override
105
    public void invoke(ICdmDataSource datasource, IProgressMonitor monitor,
106
            CaseType caseType, SchemaUpdateResult result) throws SQLException {
107

    
108
		//non audit
109
		invokeQueryMap(datasource, queryMap, caseType, result);
110
		//audit
111
		if (this.includeAudit){
112
			invokeQueryMap(datasource, auditQueryMap, caseType, result);
113
		}else{
114
			logger.info("SimpleSchemaUpdaterStep non Audited");
115
		}
116

    
117
		return;
118
	}
119

    
120
	private void invokeQueryMap(ICdmDataSource datasource, Map<DatabaseTypeEnum, String> queryMap, CaseType caseType, SchemaUpdateResult result) {
121
		String query = queryMap.get(datasource.getDatabaseType());
122
		if (query == null){
123
			query = queryMap.get(null);
124
		}
125
		if (query != null){
126
			query = doReplacements(query, caseType, datasource);
127
			executeQuery(datasource, query, result);
128
		}else{
129
		    result.addError("No query found to execute " + getStepName());
130
		}
131
		return;
132
	}
133

    
134
	private String doReplacements(String query, CaseType caseType, ICdmDataSource datasource) {
135
		query = caseType.replaceTableNames(query);
136
		query = query.replaceAll("@FALSE@", getBoolean(false, datasource));
137
		query = query.replaceAll("@TRUE@", getBoolean(true, datasource));
138
		return query;
139
	}
140

    
141
	private boolean executeQuery(ICdmDataSource datasource,  String replacedQuery, SchemaUpdateResult result) {
142
		try {
143
			datasource.executeUpdate(replacedQuery);
144
			return true;
145
		} catch (SQLException e) {
146
			logger.error(e);
147
			if (withErrorRecovery) {
148
			    result.addException(e, "Unexpected SQL Exception", getStepName());
149
			    return false;
150
			}else {
151
			    result.addError(errorRecoveryMessage, e, getStepName());
152
			    return true;
153
			}
154
		}
155
	}
156

    
157
	private void makeAuditedQuery(DatabaseTypeEnum dbType, String tableName, boolean addTable){
158
		String auditQuery = addTable? auditQueryMap.get(dbType) : queryMap.get(dbType);
159
		if (isBlank(auditQuery)){
160
			throw new IllegalArgumentException("Non-audit query must not be blank");
161
		}
162
	    auditQuery = auditQuery.replace("@@" + tableName + "@@", "@@" + tableName + "_AUD@@");
163
		//TODO warning if nothing changed
164
		this.auditQueryMap.put(dbType, auditQuery);
165
		this.includeAudit = true;
166
	}
167

    
168
//********************************* DELEGATES *********************************/
169

    
170
	/**
171
	 * For certain database types one may define special queries.<BR>
172
	 * Don't forget to put case-mask (@@) for table names and also
173
	 * add AUD query if required.
174
	 * @param dbType database type
175
	 * @param query query to use for the given database type.
176
	 * @return this schema updater step
177
     * @see #putAudited(DatabaseTypeEnum, String)
178
	 */
179
	public SimpleSchemaUpdaterStep put(DatabaseTypeEnum dbType, String query) {
180
		queryMap.put(dbType, query);
181
		return this;
182
	}
183

    
184
	/**
185
     * For certain database types one may define special queries.
186
     * This is for the AUD query.<BR>
187
     * Don't forget to put case-mask (@@) for table names
188
     * @param dbType database type
189
     * @param query query to use for the given database type.
190
     * @return this schema updater step
191
     * @see #put(DatabaseTypeEnum, String)
192
     */
193
    public SimpleSchemaUpdaterStep putAudited(DatabaseTypeEnum dbType, String query) {
194
        auditQueryMap.put(dbType, query);
195
        return this;
196
    }
197

    
198
	/**
199
	 * Defines the non audited table name for computing the audited query.
200
	 * @param nonAuditedTableName uncased table name that is to be audited
201
	 * @return the step
202
	 */
203
	public SimpleSchemaUpdaterStep setDefaultAuditing(String nonAuditedTableName){
204
		if (StringUtils.isBlank(nonAuditedTableName)){
205
			throw new IllegalArgumentException("TableName must not be blank");
206
		}
207
		makeAuditedQuery(null, nonAuditedTableName, false);
208
		return this;
209
	}
210

    
211
	 /**
212
     * Defines a further non audited table name for computing the audited query.
213
     * Requires at least one non audited table name to be defined already.
214
     * @param nonAuditedTableName non-cased table name that is to be audited
215
     * @return the step
216
     */
217
    public SimpleSchemaUpdaterStep addDefaultAuditing(String nonAuditedTableName){
218
        if (StringUtils.isBlank(nonAuditedTableName)){
219
            throw new IllegalArgumentException("TableName must not be blank");
220
        }
221
        makeAuditedQuery(null, nonAuditedTableName, true);
222
        return this;
223
    }
224

    
225
    /**
226
     * Setting error recovery will not make the step fail if the query execution
227
     * throws an exception. Only an error will be reported with the given
228
     * <code>message</code>.
229
     */
230
    public SimpleSchemaUpdaterStep withErrorRecovery(String message) {
231
        this.withErrorRecovery = true;
232
        this.errorRecoveryMessage = message;
233
        return this;
234
    }
235

    
236
}
(28-28/41)