0cd432cafd341b694c99c9ada7def5c3e6f7ce82
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / database / update / SimpleSchemaUpdaterStep.java
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.HashMap;
14 import java.util.Map;
15
16 import org.apache.commons.lang.StringUtils;
17 import org.apache.log4j.Logger;
18
19 import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
20 import eu.etaxonomy.cdm.database.DatabaseTypeEnum;
21 import eu.etaxonomy.cdm.database.ICdmDataSource;
22
23 /**
24 * This class represents one step in a schema update.
25 * @author a.mueller
26 * @date 13.09.2010
27 *
28 */
29 public class SimpleSchemaUpdaterStep extends SchemaUpdaterStepBase<SimpleSchemaUpdaterStep> implements ISchemaUpdaterStep, ITermUpdaterStep{
30 private static final Logger logger = Logger.getLogger(SimpleSchemaUpdaterStep.class);
31
32 private final Map<DatabaseTypeEnum, String> queryMap = new HashMap<DatabaseTypeEnum, String>();
33 private final Map<DatabaseTypeEnum, String> auditQueryMap = new HashMap<DatabaseTypeEnum, String>();
34
35 private boolean includeAudit = false;
36 // private String tableName;
37
38 // *************************** FACTORY ********************************/
39
40 /**
41 * Deprecated method
42 * @deprecated use {@link #NewNonAuditedInstance(String, String)},
43 * {@link #NewAuditedInstance(String, String, boolean, String)},
44 * or {@link #NewExplicitAuditedInstance(String, String, String)} instead
45 */
46 @Deprecated
47 public static SimpleSchemaUpdaterStep NewInstance(String stepName, String defaultQuery, int adapt){
48 return new SimpleSchemaUpdaterStep(stepName, defaultQuery, false, null, null);
49 }
50
51 /**
52 * Simple schema updater with update query only for non_AUD tables.
53 *
54 * @param stepName step name
55 * @param defaultQuery the query
56 * @param adapt preliminary
57 * @return
58 */
59 public static SimpleSchemaUpdaterStep NewNonAuditedInstance(String stepName, String defaultQuery, int adapt){
60 return new SimpleSchemaUpdaterStep(stepName, defaultQuery, false, null, null);
61 }
62
63 /**
64 * Simple schema updater with update query for AUD and non_AUD tables.
65 *
66 * @param stepName Step name
67 * @param defaultQuery query
68 * @param nonAuditedTableName the name of the non audited table. E.g. TaxonNameBase
69 * (while TaxonNameBase_AUD is the audited table
70 * @param adapt preliminary
71 * @return
72 */
73 public static SimpleSchemaUpdaterStep NewAuditedInstance(String stepName, String defaultQuery, String nonAuditedTableName, int adapt){
74 boolean audit = StringUtils.isNotBlank(nonAuditedTableName);
75 return new SimpleSchemaUpdaterStep(stepName, defaultQuery, audit, nonAuditedTableName, null);
76 }
77
78 /**
79 * Simple schema updater with an explicit query for AUD table.
80 * @param stepName step name
81 * @param defaultQuery the non_AUD update query
82 * @param defaultQueryForAuditedTables the AUD update query
83 * @param adapt preliminary
84 * @return
85 */
86 public static SimpleSchemaUpdaterStep NewExplicitAuditedInstance(String stepName, String defaultQuery, String defaultQueryForAuditedTables, int adapt){
87 boolean audit = StringUtils.isNotBlank(defaultQueryForAuditedTables);
88 return new SimpleSchemaUpdaterStep(stepName, defaultQuery, audit, null, defaultQueryForAuditedTables);
89 }
90
91
92 //************************ CONSTRUCTOR ***********************************/
93 private SimpleSchemaUpdaterStep(String stepName, String defaultQuery, boolean includeAudit, String tableName, String defaultQueryForAuditedTables){
94 super(stepName);
95 this.includeAudit = includeAudit;
96 queryMap.put(null, defaultQuery);
97
98 if (includeAudit){
99 if (StringUtils.isNotBlank(defaultQueryForAuditedTables)){
100 auditQueryMap.put(null, defaultQueryForAuditedTables);
101 }else if (StringUtils.isNotBlank(tableName)){
102 setDefaultAuditing(tableName);
103 }
104 }
105 }
106
107 // *************************** INVOKE *****************************
108
109
110
111 @Override
112 public Integer invoke (ICdmDataSource datasource, IProgressMonitor monitor, CaseType caseType){
113 boolean result = true;
114
115 //non audit
116 result &= invokeQueryMap(datasource, queryMap, caseType); ;
117 //audit
118 if (this.includeAudit){
119 result &= invokeQueryMap(datasource, auditQueryMap, caseType);
120 }else{
121 logger.info("SimpleSchemaUpdaterStep non Audited");
122 }
123
124 return (result == true )? 0 : null;
125 }
126
127 private boolean invokeQueryMap(ICdmDataSource datasource, Map<DatabaseTypeEnum, String> queryMap, CaseType caseType) {
128 boolean result = true;
129 String query = queryMap.get(datasource.getDatabaseType());
130 if (query == null){
131 query = queryMap.get(null);
132 }
133 if (query != null){
134 query = doReplacements(query, caseType, datasource);
135 result = executeQuery(datasource, query);
136 }else{
137 //TODO exception ?
138 logger.warn("No query found to execute");
139 }
140 return result;
141 }
142
143 private String doReplacements(String query, CaseType caseType, ICdmDataSource datasource) {
144 query = caseType.replaceTableNames(query);
145 query = query.replaceAll("@FALSE@", getBoolean(false, datasource));
146 query = query.replaceAll("@TRUE@", getBoolean(true, datasource));
147 return query;
148 }
149
150 private boolean executeQuery(ICdmDataSource datasource, String replacedQuery) {
151 try {
152 datasource.executeUpdate(replacedQuery);
153 } catch (SQLException e) {
154 logger.error(e);
155 return false;
156 }
157 return true;
158 }
159
160 private void makeAuditedQuery(DatabaseTypeEnum dbType, String tableName, boolean addTable){
161 String auditQuery = addTable? auditQueryMap.get(dbType) : queryMap.get(dbType);
162 if (StringUtils.isBlank(auditQuery)){
163 throw new IllegalArgumentException("Non-audit query must not be blank");
164 }
165 auditQuery = auditQuery.replace("@@" + tableName + "@@", "@@" + tableName + "_AUD@@");
166 //TODO warning if nothing changed
167 this.auditQueryMap.put(dbType, auditQuery);
168 this.includeAudit = true;
169 }
170
171 //********************************* DELEGATES *********************************/
172
173 /**
174 * For certain database types one may define special queries.<BR>
175 * Don't forget to put case-mask (@@) for table names
176 * @param dbType database type
177 * @param query query to use for the given database type.
178 * @return this schema updater step
179 */
180 public SimpleSchemaUpdaterStep put(DatabaseTypeEnum dbType, String query) {
181 queryMap.put(dbType, query);
182 return this;
183 }
184
185 /**
186 * Defines the non audited table name for computing the audited query.
187 * @param nonAuditedTableName uncased table name that is to be audited
188 * @return the step
189 */
190 public SimpleSchemaUpdaterStep setDefaultAuditing(String nonAuditedTableName){
191 if (StringUtils.isBlank(nonAuditedTableName)){
192 throw new IllegalArgumentException("TableName must not be blank");
193 }
194 makeAuditedQuery(null, nonAuditedTableName, false);
195 return this;
196 }
197
198 /**
199 * Defines a further non audited table name for computing the audited query.
200 * Requires at least one non audieted table name to be defined already.
201 * @param nonAuditedTableName uncased table name that is to be audited
202 * @return the step
203 */
204 public SimpleSchemaUpdaterStep addDefaultAuditing(String nonAuditedTableName){
205 if (StringUtils.isBlank(nonAuditedTableName)){
206 throw new IllegalArgumentException("TableName must not be blank");
207 }
208 makeAuditedQuery(null, nonAuditedTableName, true);
209 return this;
210 }
211
212 }