2 * Copyright (C) 2009 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
9 package eu
.etaxonomy
.cdm
.database
.update
;
11 import java
.sql
.SQLException
;
12 import java
.util
.List
;
13 import java
.util
.UUID
;
15 import org
.apache
.logging
.log4j
.LogManager
;import org
.apache
.logging
.log4j
.Logger
;
17 import eu
.etaxonomy
.cdm
.common
.monitor
.IProgressMonitor
;
18 import eu
.etaxonomy
.cdm
.database
.ICdmDataSource
;
21 * Swaps a relationship. The related_from object becomes the related_to object
22 * and vice versa. Also the relationship type label and inverse label are swapped.
27 public class RelationSwapper
extends AuditedSchemaUpdaterStepBase
{
29 private static final Logger logger
= LogManager
.getLogger(RelationSwapper
.class);
31 private static final int PLACEHOLDER
= -987;
33 private String relTypeColumnName
;
34 private UUID uuidRelationType
;
35 private String newTitleCache
;
36 private String newIdInVocabulary
;
39 * @param tableName the relations table name
40 * @param uuidRelationType
41 * @param newIdInVocabulary if not <code>null</code> the newIdInVocabulary is updated
44 public static final RelationSwapper
NewInstance(List
<ISchemaUpdaterStep
> stepList
, String stepName
,
45 String tableName
, UUID uuidRelationType
, String relTypeColumnName
,
46 String newTitleCache
, String newIdInVocabulary
, boolean includeAudit
){
47 return new RelationSwapper(stepList
, stepName
, tableName
, uuidRelationType
,
48 relTypeColumnName
, newTitleCache
, newIdInVocabulary
, includeAudit
);
51 private RelationSwapper(List
<ISchemaUpdaterStep
> stepList
, String stepName
,
52 String tableName
, UUID uuidRelationType
, String relTypeColumnName
,
53 String newTitleCache
, String newIdInVocabulary
, boolean includeAudit
) {
54 super(stepList
, stepName
, tableName
, includeAudit
);
55 this.uuidRelationType
= uuidRelationType
;
56 this.relTypeColumnName
= relTypeColumnName
;
57 this.newTitleCache
= newTitleCache
;
58 this.newIdInVocabulary
= newIdInVocabulary
;
62 protected void invokeOnTable(String tableName
, ICdmDataSource datasource
, IProgressMonitor monitor
,
63 CaseType caseType
, SchemaUpdateResult result
) {
66 String defTermTable
= this.isAuditing ?
"DefinedTermBase_AUD": "DefinedTermBase ";
67 String mnTable
= this.isAuditing ?
"DefinedTermBase_Representation_AUD": "DefinedTermBase_Representation ";
68 String inverseMnTable
= this.isAuditing ?
"DefinedTermBase_InverseRepresentation_AUD": "DefinedTermBase_InverseRepresentation ";
69 String audParams
= this.isAuditing ?
", REV, REVTYPE ": "";
72 String sql
= " SELECT id FROM %s WHERE uuid = '%s'";
73 Integer termId
= (Integer
)datasource
.getSingleValue(String
.format(sql
,
74 caseType
.transformTo(defTermTable
) , this.uuidRelationType
));
76 if (termId
== null || termId
== 0){
77 String message
= "RelationshipType term ("+uuidRelationType
+") does not exist. Can't swap terms";
78 monitor
.warning(message
);
80 result
.addError(message
, this, "invoke");
84 //swap relatedFrom and relatedTo
86 + " SET relatedFrom_id = relatedTo_id, relatedTo_id = relatedFrom_id "
88 sql
= String
.format(sql
, caseType
.transformTo(tableName
), this.relTypeColumnName
, termId
);
89 datasource
.executeUpdate(sql
);
91 // insert inverse into not-inverse with placeholder term id
92 sql
= " INSERT INTO %s (definedTermBase_id, representations_id %s) "
93 + " SELECT %d, inverseRepresentations_id %s"
95 + " WHERE DefinedTermBase_id = %d ";
96 sql
= String
.format(sql
, caseType
.transformTo(mnTable
),
97 audParams
, PLACEHOLDER
, audParams
, caseType
.transformTo(inverseMnTable
), termId
);
98 datasource
.executeUpdate(sql
);
100 // delete inverse terms
101 sql
= " DELETE FROM %s WHERE definedTermBase_id = %d ";
102 sql
= String
.format(sql
, caseType
.transformTo(inverseMnTable
), termId
);
103 datasource
.executeUpdate(sql
);
105 // insert not-inverse into inverse with placeholder term id
106 sql
= " INSERT INTO %s (definedTermBase_id, inverseRepresentations_id %s) "
107 + " SELECT definedTermBase_id, representations_id %s "
109 + " WHERE DefinedTermBase_id = %d ";
110 sql
= String
.format(sql
, caseType
.transformTo(inverseMnTable
),
111 audParams
, audParams
, caseType
.transformTo(mnTable
), termId
);
112 datasource
.executeUpdate(sql
);
114 // delete inverse terms
115 sql
= " DELETE FROM %s WHERE definedTermBase_id = %d ";
116 sql
= String
.format(sql
, caseType
.transformTo(mnTable
), termId
);
117 datasource
.executeUpdate(sql
);
119 // replace placeholder in former inverse terms
120 sql
= " UPDATE %s SET definedTermBase_id = %d WHERE definedTermBase_id = %d ";
121 sql
= String
.format(sql
, caseType
.transformTo(mnTable
), termId
, PLACEHOLDER
);
122 datasource
.executeUpdate(sql
);
125 //NOTE: of course better the titleCache would be computed then set manually, but in most
126 //cases this should be ok for now
127 if (this.newTitleCache
!= null){
128 sql
= " UPDATE %s SET titleCache = '%s' WHERE id = %d ";
129 sql
= String
.format(sql
, caseType
.transformTo(defTermTable
), newTitleCache
, termId
);
130 datasource
.executeUpdate(sql
);
134 if (this.newIdInVocabulary
!= null){
135 sql
= " UPDATE %s SET idInVocabulary = '%d' WHERE id = %d ";
136 sql
= String
.format(sql
, caseType
.transformTo(defTermTable
), newIdInVocabulary
, termId
);
137 datasource
.executeUpdate(sql
);
141 //not yet implemented
143 } catch (SQLException e
) {
144 String message
= e
.getMessage();
145 monitor
.warning(message
, e
);
147 result
.addException(e
, message
, getStepName() + ", RelationSwapper.invokeOnTable");