Project

General

Profile

Download (15.8 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2020 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.v515_518;
10

    
11
import java.sql.ResultSet;
12
import java.sql.SQLException;
13
import java.util.ArrayList;
14
import java.util.List;
15
import java.util.UUID;
16

    
17
import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;
18

    
19
import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
20
import eu.etaxonomy.cdm.database.ICdmDataSource;
21
import eu.etaxonomy.cdm.database.update.CaseType;
22
import eu.etaxonomy.cdm.database.update.ISchemaUpdaterStep;
23
import eu.etaxonomy.cdm.database.update.SchemaUpdateResult;
24
import eu.etaxonomy.cdm.database.update.SchemaUpdaterStepBase;
25
import eu.etaxonomy.cdm.model.media.ExternalLinkType;
26

    
27
/**
28
 * @author a.mueller
29
 * @since 12.06.2020
30
 */
31
public class ProtologMover  extends SchemaUpdaterStepBase {
32

    
33
    @SuppressWarnings("unused")
34
    private static final Logger logger = LogManager.getLogger(ProtologMover.class);
35

    
36
    private static final String stepName = "Move protologues to nomenclatural source";
37

    
38
    public static final ProtologMover NewInstance(List<ISchemaUpdaterStep> stepList){
39
        ProtologMover result = new ProtologMover(stepList);
40
        return result;
41
    }
42

    
43
    protected ProtologMover(List<ISchemaUpdaterStep> stepList) {
44
        super(stepList, stepName);
45
    }
46

    
47
    @Override
48
    public List<ISchemaUpdaterStep> getInnerSteps() {
49
        List<ISchemaUpdaterStep> result = new ArrayList<>();
50
        return result;
51
    }
52

    
53
    @Override
54
    public void invoke(ICdmDataSource datasource, IProgressMonitor monitor, CaseType caseType,
55
            SchemaUpdateResult result) throws SQLException {
56

    
57
        String sql =
58
            " SELECT n.titleCache, mrp.uri uri, osb.id sid, "
59
                + "  n.id nameId, db.id dbid, deb.id debId, m.id AS mid, mr.id mrId, mrp.id mrpid, feature.id fid "
60
            + " FROM @@TaxonName@@ n "
61
            + " INNER JOIN @@DescriptionBase@@ db ON db.taxonName_id = n.id "
62
            + " INNER JOIN @@DescriptionElementBase@@ deb ON deb.inDescription_id = db.id "
63
            + " INNER JOIN @@DescriptionElementBase_Media@@ MN ON deb.id = MN.DescriptionElementBase_id "
64
            + " INNER JOIN @@Media@@ m ON m.id = MN.media_id "
65
            + " INNER JOIN @@MediaRepresentation@@ mr ON mr.media_id = m.id "
66
            + " INNER JOIN @@MediaRepresentationPart@@ mrp ON mrp.representation_id = mr.id "
67
            + " INNER JOIN @@DefinedTermBase@@ feature ON feature.id = deb.feature_id "
68
            + "                                       AND feature.uuid = '71b356c5-1e3f-4f5d-9b0f-c2cf8ae7779f' "
69
            + " LEFT OUTER JOIN @@OriginalSourceBase@@ osb ON n.id = osb.sourcedName_id "
70
            + " ORDER BY n.titleCache";
71

    
72
        ResultSet rs = datasource.executeQuery(caseType.replaceTableNames(sql));
73
        while (rs.next()){
74
            int nameId = rs.getInt("nameId");
75
            String uri = rs.getString("uri");
76
            Integer nomSourceId = nullSafeInt(rs, "sid");
77
            if (isNotBlank(uri)){
78
                createSourceLink(datasource, caseType, rs, monitor, result, nameId, uri, nomSourceId);
79
            }
80
            deleteMedia(datasource, caseType, result, rs);
81
        }
82
    }
83

    
84
    private void deleteMedia(ICdmDataSource datasource, CaseType caseType, SchemaUpdateResult result, ResultSet rs)
85
            throws SQLException {
86

    
87
        int mediaId = rs.getInt("mid");  //null should not happen with SQL above
88
        int debId = rs.getInt("debId");
89
        if (!mediaIsLinked(datasource, caseType, result, mediaId, debId)){
90
            Integer mediaRepId = nullSafeInt(rs, "mrId");
91
            Integer mediaRepPartId = nullSafeInt(rs, "mrpid");
92
            if (!anotherMediaRepresentationPartExists(datasource, caseType, result, mediaRepId, mediaRepPartId)){
93
                removeMediaRepresentationPart(datasource, caseType, result, mediaRepPartId);
94
                if (!anotherMediaRepresentationExists(datasource, caseType, result, mediaId, mediaRepId)){
95
                    removeMediaRepresentation(datasource, caseType, result, mediaRepPartId);
96
                    removeMedia(datasource, caseType, result, mediaId);
97
                }
98
            }
99
        }
100
        removeDescriptionElementBaseMediaMN(datasource, caseType, result, debId, mediaId);
101
        if (textDataIsEmpty(datasource, caseType, result, debId)){
102
            removeTextData(datasource, caseType, result, debId);
103
            int dbId = rs.getInt("dbid");
104
            if (descriptionBaseIsEmpty(datasource, caseType, result, dbId)){
105
                removeImageGallery(datasource, caseType, result, dbId);
106
            }
107
        }
108
    }
109

    
110
    private void removeImageGallery(ICdmDataSource datasource, CaseType caseType, SchemaUpdateResult result, int dbId) throws SQLException {
111
        String sql = " DELETE FROM @@DescriptionBase@@ "
112
                + " WHERE id = %d ";
113
        sql = caseType.replaceTableNames(String.format(sql, dbId));
114
        datasource.executeUpdate(sql);
115

    
116
        sql = " DELETE FROM @@DescriptionBase_AUD@@ "
117
                + " WHERE id = %d ";
118
        sql = caseType.replaceTableNames(String.format(sql, dbId));
119
        datasource.executeUpdate(sql);
120
    }
121

    
122
    private boolean descriptionBaseIsEmpty(ICdmDataSource datasource, CaseType caseType, SchemaUpdateResult result,
123
            int dbId) throws SQLException {
124
        //handle supplementalData and other linking data => done, data only existed in caryo_spp (only original sources)
125
        String sql = "SELECT count(*) as n From @@DescriptionElementBase@@ deb "
126
                + " WHERE deb.inDescription_id = %d ";
127
        sql = caseType.replaceTableNames(String.format(sql, dbId));
128
        Long n = (Long)datasource.getSingleValue(sql);
129
        return n == 0;
130
    }
131

    
132
    private void removeTextData(ICdmDataSource datasource, CaseType caseType, SchemaUpdateResult result,
133
            int debId) throws SQLException {
134

    
135
        String sql = " DELETE FROM @@DescriptionElementBase@@ "
136
                + " WHERE id = %d ";
137
        sql = caseType.replaceTableNames(String.format(sql, debId));
138
        datasource.executeUpdate(sql);
139

    
140
        sql = " DELETE FROM @@DescriptionElementBase_AUD@@ "
141
                + " WHERE id = %d ";
142
        sql = caseType.replaceTableNames(String.format(sql, debId));
143
        datasource.executeUpdate(sql);
144
    }
145

    
146
    private boolean textDataIsEmpty(ICdmDataSource datasource, CaseType caseType, SchemaUpdateResult result,
147
            int debId) {
148
        // checkTextData (other media, text, ...) => checked, does not exist on production or integration
149
        //remove supplemental data => done manually in relevant DBs on production
150
        return true;
151
    }
152

    
153
    private void removeDescriptionElementBaseMediaMN(ICdmDataSource datasource, CaseType caseType,
154
            SchemaUpdateResult result, int debId, Integer mediaId) throws SQLException {
155

    
156
        String sql = " DELETE FROM @@DescriptionElementBase_Media@@ "
157
                + " WHERE DescriptionElementBase_id = %d AND media_id = %d ";
158
        sql = caseType.replaceTableNames(String.format(sql, debId, mediaId));
159
        datasource.executeUpdate(sql);
160

    
161
        sql = " DELETE FROM @@DescriptionElementBase_Media_AUD@@ "
162
                + " WHERE DescriptionElementBase_id = %d AND media_id = %d ";
163
        sql = caseType.replaceTableNames(String.format(sql, debId, mediaId));
164
        datasource.executeUpdate(sql);
165
    }
166

    
167
    private void removeMedia(ICdmDataSource datasource, CaseType caseType, SchemaUpdateResult result,
168
            Integer mediaId) throws SQLException {
169
        //check supplementalData => checked, do not exist on production or integration
170
        String sql = " DELETE FROM @@Media@@ "
171
                + " WHERE id = %d ";
172
        sql = caseType.replaceTableNames(String.format(sql, mediaId));
173
        datasource.executeUpdate(sql);
174

    
175
        sql = " DELETE FROM @@Media_AUD@@ "
176
                + " WHERE id = %d ";
177
        sql = caseType.replaceTableNames(String.format(sql, mediaId));
178
        datasource.executeUpdate(sql);
179
    }
180

    
181
    private void removeMediaRepresentation(ICdmDataSource datasource, CaseType caseType, SchemaUpdateResult result,
182
            Integer mediaRepId) throws SQLException {
183

    
184
        String sql = " DELETE FROM @@MediaRepresentation@@ "
185
                + " WHERE id = %d ";
186
        sql = caseType.replaceTableNames(String.format(sql, mediaRepId));
187
        datasource.executeUpdate(sql);
188

    
189
        sql = " DELETE FROM @@MediaRepresentation_AUD@@ "
190
                + " WHERE id = %d ";
191
        sql = caseType.replaceTableNames(String.format(sql, mediaRepId));
192
        datasource.executeUpdate(sql);
193
    }
194

    
195
    private void removeMediaRepresentationPart(ICdmDataSource datasource, CaseType caseType, SchemaUpdateResult result,
196
            Integer mediaRepPartId) throws SQLException {
197
        String sql = " DELETE FROM @@MediaRepresentationPart@@ "
198
                + " WHERE id = %d ";
199
        sql = caseType.replaceTableNames(String.format(sql, mediaRepPartId));
200
        datasource.executeUpdate(sql);
201

    
202
        sql = " DELETE FROM @@MediaRepresentation_MediaRepresentationPart_AUD@@ "
203
                + " WHERE id = %d ";
204
        sql = caseType.replaceTableNames(String.format(sql, mediaRepPartId));
205
        datasource.executeUpdate(sql);
206

    
207
        sql = " DELETE FROM @@MediaRepresentationPart_AUD@@ "
208
                + " WHERE id = %d ";
209
        sql = caseType.replaceTableNames(String.format(sql, mediaRepPartId));
210
        datasource.executeUpdate(sql);
211
    }
212

    
213
    private boolean anotherMediaRepresentationExists(ICdmDataSource datasource, CaseType caseType,
214
            SchemaUpdateResult result, Integer mediaId, Integer mediaRepId) throws SQLException {
215

    
216
        String sql = "SELECT count(*) as n From @@MediaRepresentation@@ mr "
217
                + " WHERE mr.media_id = %d AND mr.id <> %d ";
218
        sql = caseType.replaceTableNames(String.format(sql, mediaId, mediaRepId));
219
        Long n = (Long)datasource.getSingleValue(sql);
220
        return n > 0;
221
    }
222

    
223
    private boolean anotherMediaRepresentationPartExists(ICdmDataSource datasource, CaseType caseType,
224
            SchemaUpdateResult result, Integer mediaRepId, Integer mediaRepPartId) throws SQLException {
225

    
226
        String sql = "SELECT count(*) as n From @@MediaRepresentationPart@@ mrp "
227
                + " WHERE mrp.representation_id = %d AND mrp.id <> %d ";
228
        sql = caseType.replaceTableNames(String.format(sql, mediaRepId, mediaRepPartId));
229
        Long n = (Long)datasource.getSingleValue(sql);
230
        return n > 0;
231
    }
232

    
233
    private boolean mediaIsLinked(ICdmDataSource datasource, CaseType caseType, SchemaUpdateResult result,
234
            Integer mediaId, int debId) throws SQLException {
235

    
236
        String sql = "SELECT count(*) as n "
237
          + " FROM @@Media@@ m "
238
          + " WHERE m.id = %d "
239
           + " AND ( m.id IN (SELECT l.media_id FROM @@CdmLink@@ l ) "
240
               + " OR m.id IN (SELECT ab.media_id FROM @@AgentBase_Media@@ ab) "
241
               + " OR m.id IN (SELECT MN.media_id FROM @@Collection_Media@@ MN) "
242
               + " OR m.id IN (SELECT MN.media_id FROM @@DefinedTermBase_Media@@ MN) "
243
               + " OR m.id IN (SELECT MN.media_id FROM @@DescriptionElementBase_Media@@ MN WHERE MN.DescriptionElementBase_id <> %d) "
244
               + " OR m.id IN (SELECT MN.media_id FROM @@Reference_Media@@ MN) "
245
               + " OR m.id IN (SELECT l.mediaSpecimen_id FROM @@SpecimenOrObservationBase@@ l) "
246
               + " OR m.id IN (SELECT l.contigFile_id FROM @@Sequence@@ l) "
247
               + " OR m.id IN (SELECT l.shape_id FROM @@DefinedTermBase@@ l) "
248
               + " OR m.id IN (SELECT l.pherogram_id FROM @@SingleRead@@ l)) ";
249
        sql = caseType.replaceTableNames(String.format(sql, mediaId, debId));
250
        Long n = (Long)datasource.getSingleValue(sql);
251
        return n > 0;
252
    }
253

    
254
    private void createSourceLink(ICdmDataSource datasource, CaseType caseType, ResultSet rs, IProgressMonitor monitor, SchemaUpdateResult result, int nameId, String uri, Integer nomSourceId) throws SQLException {
255
        int mrpid = rs.getInt("mrpid");
256
        String sql = "SELECT REV FROM @@MediaRepresentationPart_AUD@@ WHERE id = " + mrpid + " AND REVTYPE = 0";
257
        ResultSet rs2 = datasource.executeQuery(caseType.replaceTableNames(sql));
258
        long rev;
259
        if (rs2.next()){
260
            rev = rs2.getLong("REV");
261
        }else{
262
            rev = createAuditEvent(datasource, caseType, monitor, result);
263
        }
264

    
265
        if (nomSourceId == null){
266
            nomSourceId = createSource(datasource, caseType, result, nameId, rev);
267
        }
268
        addLink(datasource, caseType, result, nomSourceId, uri, rev);
269
    }
270

    
271

    
272
    /**
273
     * @return the new source id
274
     */
275
    private int createSource(ICdmDataSource datasource, CaseType caseType, SchemaUpdateResult result, int nameId, Long rev) throws SQLException {
276

    
277
        //insert empty OriginalSourceBase record
278
        int nextSourceId = this.getMaxId1(datasource, "OriginalSourceBase", true, null, caseType, result);
279
        String sql = "INSERT INTO @@OriginalSourceBase@@ (DTYPE, id, uuid, sourceType, sourcedName_id, created, createdBy_id ) "
280
                + " VALUES ('NomenclaturalSource', %d, '%s', '%s', %d, '%s', NULL)";
281
        sql = String.format(sql, nextSourceId, UUID.randomUUID(), "NOR",
282
                nameId, this.getNowString());
283
        datasource.executeUpdate(caseType.replaceTableNames(sql));
284

    
285
        if (rev != null){
286
            sql = "INSERT INTO @@OriginalSourceBase_AUD@@ (REV, revtype, DTYPE, id, uuid, sourceType, sourcedName_id, created, createdBy_id ) "
287
                    + " VALUES (%d, 0, 'NomenclaturalSource', %d, '%s', '%s', %d, '%s', NULL)";
288
            sql = String.format(sql, rev, nextSourceId, UUID.randomUUID(), "NOR",
289
                    nameId, this.getNowString());
290
            datasource.executeUpdate(caseType.replaceTableNames(sql));
291
        }
292

    
293
        return nextSourceId;
294
    }
295

    
296
    private void addLink(ICdmDataSource datasource, CaseType caseType, SchemaUpdateResult result,
297
            Integer nomSourceId, String uri, Long rev) throws SQLException {
298

    
299
        //insert ExternalLink record
300
        int nextLinkId = this.getMaxId1(datasource, "ExternalLink", true, null, caseType, result);
301
        String sql = "INSERT INTO @@ExternalLink@@ (id, uuid, linkType, uri, created, createdBy_id) "
302
                + " VALUES (%d, '%s', '%s', '%s', '%s', NULL )";
303
        ExternalLinkType elt = isFile(uri)? ExternalLinkType.File : ExternalLinkType.WebSite;
304
        sql = String.format(sql, nextLinkId, UUID.randomUUID(), elt.getKey(),
305
                uri, this.getNowString());
306
        datasource.executeUpdate(caseType.replaceTableNames(sql));
307

    
308
        //insert MN value in OriginalSourceBase_ExternalLink
309
        sql = String.format("INSERT INTO @@OriginalSourceBase_ExternalLink@@ (OriginalSourceBase_id, links_id) "
310
                + "VALUES (%d, %d) ", nomSourceId, nextLinkId);
311
        datasource.executeUpdate(caseType.replaceTableNames(sql));
312

    
313
        if (rev != null){
314
            sql = "INSERT INTO @@ExternalLink_AUD@@ (REV, revtype, id, uuid, linkType, uri, created, createdBy_id) "
315
                    + " VALUES (%d, 0, %d, '%s', '%s', '%s', '%s', NULL )";
316
            sql = String.format(sql, rev, nextLinkId, UUID.randomUUID(), elt.getKey(),
317
                    uri, this.getNowString());
318
            datasource.executeUpdate(caseType.replaceTableNames(sql));
319

    
320
            sql = String.format("INSERT INTO @@OriginalSourceBase_ExternalLink_AUD@@ (REV, revtype, OriginalSourceBase_id, links_id) "
321
                    + "VALUES (%d, 0, %d, %d) ", rev, nomSourceId, nextLinkId);
322
            datasource.executeUpdate(caseType.replaceTableNames(sql));
323
        }
324
    }
325

    
326
    private boolean isFile(String uri) {
327
        return uri.endsWith(".png") || uri.endsWith(".jpg") || uri.endsWith(".tiff") || uri.endsWith(".pdf")
328
                || uri.endsWith(".jpeg");
329
    }
330

    
331
}
(3-3/11)