Project

General

Profile

Download (6.58 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.ResultSet;
12
import java.sql.SQLException;
13
import java.util.ArrayList;
14
import java.util.List;
15

    
16
import org.apache.log4j.Logger;
17

    
18
import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
19
import eu.etaxonomy.cdm.database.ICdmDataSource;
20

    
21
/**
22
 * Removes a given term if it is not in use.
23
 * TODO does not yet check all DefinedTermBase_XXX tables except for representations.
24
 * Does also not handle AUD tables => should probably be handled as DeleteEvent, not simply delete the record;
25
 * There is now a factory method for handling AUDs.
26
 *
27
 * @author a.mueller
28
 * @since 06.09.2013
29
  */
30
public class SingleTermRemover
31
        extends SchemaUpdaterStepBase{
32

    
33
    private String uuidTerm ;
34
    private List<String> checkUsedQueries = new ArrayList<>();
35
    private boolean isAudit = false;
36

    
37
    @SuppressWarnings("unused")
38
	private static final Logger logger = Logger.getLogger(SingleTermRemover.class);
39

    
40
	public static final SingleTermRemover NewInstance(List<ISchemaUpdaterStep> stepList, String stepName,
41
	        String uuidTerm, List<String> checkUsedQueries, int adapt){
42
		return new SingleTermRemover(stepList, stepName, uuidTerm, checkUsedQueries, false);
43
	}
44

    
45
	/**
46
	 * @param firstCheckUsedQuery The first query to check if this term is used. Must return a single int value > 0
47
	 * if this term is used at the given place.
48
	 * @return
49
	 */
50
	public static final SingleTermRemover NewInstance(List<ISchemaUpdaterStep> stepList, String stepName,
51
	        String uuidTerm, String firstCheckUsedQuery, int adapt){
52
		List<String> checkUsedQueries = new ArrayList<>();
53
		checkUsedQueries.add(firstCheckUsedQuery);
54
		return new SingleTermRemover(stepList, stepName, uuidTerm, checkUsedQueries, false);
55
	}
56

    
57
	/**
58
     * @param firstCheckUsedQuery The first query to check if this term is used. Must return a single int value > 0
59
     * if this term is used at the given place.
60
     * @return
61
     */
62
    public static final SingleTermRemover NewAudInstance(List<ISchemaUpdaterStep> stepList, String stepName,
63
            String uuidTerm, String firstCheckUsedQuery, int adapt){
64
        List<String> checkUsedQueries = new ArrayList<>();
65
        checkUsedQueries.add(firstCheckUsedQuery);
66
        return new SingleTermRemover(stepList, stepName, uuidTerm, checkUsedQueries, true);
67
    }
68

    
69
	private SingleTermRemover(List<ISchemaUpdaterStep> stepList, String stepName, String uuidTerm,
70
	        List<String> checkUsedQueries, boolean isAudit) {
71
		super(stepList, stepName);
72
		this.uuidTerm = uuidTerm;
73
		this.checkUsedQueries = checkUsedQueries;
74
		this.isAudit = isAudit;
75
	}
76

    
77
    @Override
78
    public void invoke(ICdmDataSource datasource, IProgressMonitor monitor,
79
            CaseType caseType, SchemaUpdateResult result) throws SQLException {
80

    
81
        //get term id
82
		String sql = " SELECT id FROM %s WHERE uuid = '%s'";
83
		String tableName = isAudit ? "DefinedTermBase_AUD" : "DefinedTermBase";
84
		Integer id = (Integer)datasource.getSingleValue(String.format(sql,
85
				caseType.transformTo(tableName), this.uuidTerm));
86
		if (id == null || id == 0){
87
			return;
88
		}
89

    
90
		//check if in use
91
		if (checkTermInUse(datasource, monitor, id, caseType)){
92
			return;
93
		}
94

    
95
		//if not ... remove
96
		removeTerm(datasource, monitor, id, caseType, result);
97

    
98
		return;
99
	}
100

    
101
	private void removeTerm(ICdmDataSource datasource, IProgressMonitor monitor, int id,
102
	        CaseType caseType, SchemaUpdateResult result) {
103

    
104
		try {
105
            //get representation ids
106
            List<Integer> repIDs = new ArrayList<>();
107
            String tableName = isAudit ? "DefinedTermBase_Representation_AUD" : "DefinedTermBase_Representation";
108
            String inverseTableName = isAudit ? "DefinedTermBase_InverseRepresentation_AUD" : "DefinedTermBase_InverseRepresentation";
109
            getRepIds(datasource, id, repIDs, "representations_id", tableName, caseType );
110
            getRepIds(datasource, id, repIDs, "inverserepresentations_id", inverseTableName, caseType);
111

    
112
            //remove from MN table
113
            String sql = " DELETE FROM %s WHERE DefinedTermBase_id = %d";
114
            sql = String.format(sql, caseType.transformTo(tableName), id);
115
            datasource.executeUpdate(sql);
116
            sql = " DELETE FROM %s WHERE DefinedTermBase_id = %d";
117
            sql = String.format(sql, caseType.transformTo(inverseTableName), id);
118
            datasource.executeUpdate(sql);
119

    
120
            //remove representations
121
            tableName = isAudit ? "Representation_AUD" : "Representation";
122
            for (Integer repId : repIDs){
123
            	sql = " DELETE FROM %s WHERE id = %d ";
124
            	sql = String.format(sql,
125
            			caseType.transformTo(tableName),
126
            			repId);
127
            	datasource.executeUpdate(sql);
128
            }
129

    
130
            //remove term
131
            tableName = isAudit ? "DefinedTermBase_AUD" : "DefinedTermBase";
132
            sql = " DELETE FROM %s WHERE id = %d";
133
            sql = String.format(sql,
134
            		caseType.transformTo(tableName),
135
            		id);
136
            datasource.executeUpdate(sql);
137
        } catch (SQLException e) {
138
            String message = e.getMessage();
139
            monitor.warning(message, e);
140
            result.addException(e, message, this, "removeTerm");
141
        }
142
	}
143

    
144
	private void getRepIds(ICdmDataSource datasource, int id,
145
			List<Integer> repIDs, String mnRepresentationIdAttr, String mnTableName, CaseType caseType) throws SQLException {
146
		String sql = " SELECT DISTINCT %s as repId FROM %s WHERE DefinedTermBase_id = %d";
147
		sql = String.format(sql, mnRepresentationIdAttr, caseType.transformTo(mnTableName), id);
148
		ResultSet rs = datasource.executeQuery(sql);
149
		while (rs.next()){
150
			int repId = rs.getInt("repId");  //TODO nullSafe, but should not happen
151
			repIDs.add(repId);
152
		}
153
	}
154

    
155
	private boolean checkTermInUse(ICdmDataSource datasource, IProgressMonitor monitor, int id, CaseType caseType) throws SQLException {
156
		for (String query : checkUsedQueries){
157
			query = String.format(caseType.replaceTableNames(query), id);
158
			Number i = (Number)datasource.getSingleValue(query);
159
			if (i != null && (Long)i > 0.0){
160
				return true;
161
			}
162
		}
163
		return false;
164
	}
165

    
166
	public SingleTermRemover addCheckUsedQuery(String query, int adapt){
167
		this.checkUsedQueries.add(query);
168
		return this;
169
	}
170
}
(29-29/41)