1 package fr.ifremer.quadrige3.synchro.intercept.data.attachement;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 import com.google.common.collect.ImmutableSet;
25 import com.google.common.collect.Lists;
26 import com.google.common.eventbus.Subscribe;
27 import fr.ifremer.common.synchro.SynchroTechnicalException;
28 import fr.ifremer.common.synchro.dao.SynchroBaseDao;
29 import fr.ifremer.common.synchro.dao.SynchroTableDao;
30 import fr.ifremer.common.synchro.intercept.SynchroInterceptorBase;
31 import fr.ifremer.common.synchro.intercept.SynchroOperationRepository;
32 import fr.ifremer.common.synchro.meta.SynchroDatabaseMetadata;
33 import fr.ifremer.common.synchro.meta.SynchroJoinMetadata;
34 import fr.ifremer.common.synchro.meta.SynchroTableMetadata;
35 import fr.ifremer.common.synchro.meta.event.LoadJoinEvent;
36 import fr.ifremer.common.synchro.meta.event.LoadTableEvent;
37 import fr.ifremer.common.synchro.service.SynchroResult;
38 import fr.ifremer.common.synchro.service.SynchroTableOperation;
39 import fr.ifremer.common.synchro.util.file.FileOperation;
40 import fr.ifremer.common.synchro.util.file.FileOperationBuilder;
41 import fr.ifremer.common.synchro.util.file.impl.BasicFileOperation;
42 import fr.ifremer.quadrige3.core.dao.referential.ObjectTypeCode;
43 import fr.ifremer.quadrige3.core.dao.technical.Assert;
44 import fr.ifremer.quadrige3.core.dao.technical.Daos;
45 import fr.ifremer.quadrige3.core.dao.technical.Images;
46 import fr.ifremer.quadrige3.core.exception.QuadrigeTechnicalException;
47 import fr.ifremer.quadrige3.synchro.intercept.data.AbstractDataInterceptor;
48 import fr.ifremer.quadrige3.synchro.meta.DatabaseColumns;
49 import fr.ifremer.quadrige3.synchro.meta.data.DataSynchroTables;
50 import fr.ifremer.quadrige3.synchro.service.SynchroDirection;
51 import fr.ifremer.quadrige3.synchro.service.data.DataSynchroContext;
52 import org.apache.commons.io.FileUtils;
53 import org.apache.commons.io.FilenameUtils;
54 import org.apache.commons.logging.Log;
55 import org.apache.commons.logging.LogFactory;
56 import org.hibernate.tool.hbm2ddl.TableMetadata;
57
58 import java.io.File;
59 import java.io.IOException;
60 import java.sql.PreparedStatement;
61 import java.sql.ResultSet;
62 import java.sql.SQLException;
63 import java.sql.Timestamp;
64 import java.util.ArrayList;
65 import java.util.LinkedHashMap;
66 import java.util.List;
67 import java.util.Map;
68
69
70
71
72 public class PhotoInterceptor extends AbstractDataInterceptor {
73
74 private static final Log LOG = LogFactory.getLog(PhotoInterceptor.class);
75
76 private int photoIdIndex = -1;
77 private int surveyIdIndex = -1;
78 private int samplingOperIdIndex = -1;
79 private int sampleIdIndex = -1;
80 private int objectIdIndex = -1;
81 private int objectTypeCdIndex = -1;
82 private int updateDateIndex = -1;
83 private int pathIndex = -1;
84 private int remoteIdIndex = -1;
85
86 private PreparedStatement selectRemoteIdAndParentIdsFromSampleIdStatement = null;
87 private String selectRemoteIdAndParentIdsFromSampleIdQuery;
88 private PreparedStatement selectParentIdFromSamplingOperIdStatement = null;
89 private String selectRemoteIdAndParentIdFromSamplingOperIdQuery;
90 private String selectRemoteIdBySurveyIdQuery;
91
92 private String selectLocalIdBySampleIdQuery;
93 private String selectLocalIdBySamplingOperIdQuery;
94 private String selectLocalIdBySurveyIdQuery;
95
96 private File sourceDirectory = null;
97 private File targetDirectory = null;
98
99 public PhotoInterceptor() {
100 super();
101 this.selectRemoteIdAndParentIdsFromSampleIdQuery = initSelectRemoteIdAndParentIdFromSampleIdQuery();
102 this.selectRemoteIdAndParentIdFromSamplingOperIdQuery = initSelectRemoteIdAndParentIdFromSamplingOperIdQuery();
103 this.selectRemoteIdBySurveyIdQuery = initSelectRemoteIdFromSurveyId();
104 this.selectLocalIdBySurveyIdQuery = initSelectLocalIdFromSurveyId();
105 this.selectLocalIdBySamplingOperIdQuery = initSelectLocalIdFromSamplingOperId();
106 this.selectLocalIdBySampleIdQuery = initSelectLocalIdFromSampleId();
107
108 setEnableOnWrite(true);
109 }
110
111 @Override
112 public boolean doApply(SynchroDatabaseMetadata meta, TableMetadata table) {
113 return table.getName().equalsIgnoreCase(DataSynchroTables.PHOTO.name());
114 }
115
116 @Override
117 public SynchroInterceptorBase clone() {
118 PhotoInterceptor newBean = (PhotoInterceptor) super.clone();
119 newBean.selectRemoteIdAndParentIdFromSamplingOperIdQuery = this.selectRemoteIdAndParentIdFromSamplingOperIdQuery;
120 newBean.selectRemoteIdAndParentIdsFromSampleIdQuery = this.selectRemoteIdAndParentIdsFromSampleIdQuery;
121 newBean.selectRemoteIdBySurveyIdQuery = this.selectRemoteIdBySurveyIdQuery;
122 newBean.selectLocalIdBySampleIdQuery = this.selectLocalIdBySampleIdQuery;
123 newBean.selectLocalIdBySamplingOperIdQuery = this.selectLocalIdBySamplingOperIdQuery;
124 newBean.selectLocalIdBySurveyIdQuery = this.selectLocalIdBySurveyIdQuery;
125
126 newBean.photoIdIndex = this.photoIdIndex;
127 newBean.surveyIdIndex = this.surveyIdIndex;
128 newBean.samplingOperIdIndex = this.samplingOperIdIndex;
129 newBean.sampleIdIndex = this.sampleIdIndex;
130 newBean.objectIdIndex = this.objectIdIndex;
131 newBean.objectTypeCdIndex = this.objectTypeCdIndex;
132 newBean.updateDateIndex = this.updateDateIndex;
133 newBean.pathIndex = this.pathIndex;
134 newBean.remoteIdIndex = this.remoteIdIndex;
135 return newBean;
136 }
137
138 @Override
139 protected void doClose() throws IOException {
140 super.doClose();
141
142 sourceDirectory = null;
143 targetDirectory = null;
144 }
145
146
147
148
149
150
151
152
153 @Subscribe
154 public void handleJoinLoad(LoadJoinEvent e) {
155 SynchroJoinMetadata join = e.join;
156
157 if (!join.isValid()) {
158 return;
159 }
160
161 SynchroTableMetadata pkTable = join.getPkTable();
162 String pkTableName = pkTable.getName();
163 SynchroDirection direction = getConfig().getDirection();
164
165
166 if (direction == SynchroDirection.IMPORT_SERVER2TEMP) {
167
168
169 if (DataSynchroTables.SAMPLING_OPERATION.name().equalsIgnoreCase(pkTableName)
170 || DataSynchroTables.SAMPLE.name().equalsIgnoreCase(pkTableName)) {
171
172 join.setIsValid(false);
173 }
174 }
175 }
176
177
178
179
180
181
182
183
184 @Subscribe
185 public void handleTableLoad(LoadTableEvent e) {
186 SynchroTableMetadata table = e.table;
187
188 photoIdIndex = table.getSelectColumnIndex(DatabaseColumns.PHOTO_ID.name());
189 surveyIdIndex = table.getSelectColumnIndex(DatabaseColumns.SURVEY_ID.name());
190 samplingOperIdIndex = table.getSelectColumnIndex(DatabaseColumns.SAMPLING_OPER_ID.name());
191 sampleIdIndex = table.getSelectColumnIndex(DatabaseColumns.SAMPLE_ID.name());
192 objectIdIndex = table.getSelectColumnIndex(DatabaseColumns.OBJECT_ID.name());
193 objectTypeCdIndex = table.getSelectColumnIndex(DatabaseColumns.OBJECT_TYPE_CD.name());
194 updateDateIndex = table.getSelectColumnIndex(getConfig().getColumnUpdateDate());
195 remoteIdIndex = table.getSelectColumnIndex(getConfig().getColumnRemoteId());
196 pathIndex = table.getSelectColumnIndex(DatabaseColumns.PHOTO_LK.name());
197
198
199 if (getConfig().getDirection() == SynchroDirection.EXPORT_TEMP2SERVER) {
200
201
202 table.addSelectByFksWhereClause(DatabaseColumns.SURVEY_ID.name(),
203 String.format("t.%s IS NULL AND t.%s IS NULL",
204 DatabaseColumns.SAMPLING_OPER_ID.name(),
205 DatabaseColumns.SAMPLE_ID.name()));
206
207
208 table.addSelectByFksWhereClause(DatabaseColumns.SAMPLING_OPER_ID.name(),
209 String.format("t.%s IS NULL",
210 DatabaseColumns.SAMPLE_ID.name()));
211 }
212 }
213
214 @Override
215 protected void doOnWrite(Object[] data, List<Object> pk, SynchroTableDao sourceDao, SynchroTableDao targetDao, SynchroOperationRepository buffer, boolean insert) throws SQLException {
216
217 if (buffer == null) return;
218
219 SynchroDirection direction = getConfig().getDirection();
220 DataSynchroContext context = (DataSynchroContext) buffer.getSynchroContext();
221 SynchroResult result = context.getResult();
222
223
224 if (direction == SynchroDirection.IMPORT_SERVER2TEMP) {
225
226 if (data[samplingOperIdIndex] != null) {
227 data[surveyIdIndex] = null;
228 }
229
230
231 if (data[sampleIdIndex] != null) {
232 data[samplingOperIdIndex] = null;
233 data[surveyIdIndex] = null;
234 }
235
236
237 Timestamp updateDate = (Timestamp) data[updateDateIndex];
238
239
240 Timestamp lastSynchronizationDate = context.getLastSynchronizationDate();
241
242 int updateDateCompare = fr.ifremer.common.synchro.dao.Daos.compareUpdateDates(updateDate, lastSynchronizationDate);
243 if (updateDateCompare > 0) {
244
245
246 String path = String.valueOf(data[pathIndex]);
247
248 addCopyOperation(path, path, context, result, buffer, false);
249 }
250
251 }
252
253
254 else if (direction == SynchroDirection.IMPORT_TEMP2LOCAL) {
255
256 Number remoteObjectId = (Number) data[objectIdIndex];
257 String objectTypeCode = String.valueOf(data[objectTypeCdIndex]);
258 String remotePath = String.valueOf(data[pathIndex]);
259
260
261 Number localObjectId = null;
262 if (data[sampleIdIndex] != null) {
263 localObjectId = getLocalIdFromSampleId(targetDao, Long.parseLong(data[sampleIdIndex].toString()));
264 } else if (data[samplingOperIdIndex] != null) {
265 localObjectId = getLocalIdFromSamplingOperId(targetDao, Long.parseLong(data[samplingOperIdIndex].toString()));
266 } else if (data[surveyIdIndex] != null) {
267 localObjectId = getLocalIdFromSurveyId(targetDao, Long.parseLong(data[surveyIdIndex].toString()));
268 }
269 if (localObjectId == null) {
270 throw new SynchroTechnicalException("The local Id is not found for the object " + objectTypeCode + " remoteId=" + remoteObjectId);
271 }
272 data[objectIdIndex] = localObjectId;
273
274
275 String localPath = Daos.computePhotoFilePath(objectTypeCode, localObjectId, (Number) pk.get(0), FilenameUtils.getExtension(remotePath));
276 data[pathIndex] = localPath;
277
278
279 addCopyOperation(remotePath, localPath, context, result, buffer, false);
280
281 }
282
283
284 else if (direction == SynchroDirection.IMPORT_FILE2LOCAL) {
285
286 }
287
288
289 else if (direction == SynchroDirection.EXPORT_LOCAL2TEMP) {
290
291
292 Object remoteObjectId = data[remoteIdIndex];
293 if (remoteObjectId == null && insert) {
294
295
296 String path = String.valueOf(data[pathIndex]);
297 addCopyOperation(path, path, context, result, buffer, true);
298 }
299
300 }
301
302
303 else if (direction == SynchroDirection.EXPORT_TEMP2SERVER) {
304
305 String objectTypeCode = String.valueOf(data[objectTypeCdIndex]);
306 String localPath = String.valueOf(data[pathIndex]);
307
308
309 Number remoteObjectId;
310
311
312 if (data[sampleIdIndex] != null) {
313 Number[] ids = getRemoteIdAndParentIdFromSampleId(sourceDao, Long.parseLong(data[sampleIdIndex].toString()));
314 remoteObjectId = ids[0];
315 data[surveyIdIndex] = ids[1];
316 data[samplingOperIdIndex] = ids[2];
317 }
318
319
320 else if (data[samplingOperIdIndex] != null) {
321 Number[] ids = getRemoteIdAndParentIdFromSamplingOperId(sourceDao, Long.parseLong(data[samplingOperIdIndex].toString()));
322 remoteObjectId = ids[0];
323 data[surveyIdIndex] = ids[1];
324 }
325
326
327 else if (data[surveyIdIndex] != null) {
328 remoteObjectId = getRemoteIdFromSurveyId(sourceDao, Long.parseLong(data[surveyIdIndex].toString()));
329 }
330
331
332 else {
333 throw new QuadrigeTechnicalException("Photo found, without any parent filled. This should never append.");
334 }
335
336 data[objectIdIndex] = remoteObjectId;
337
338
339 String remotePath = Daos.computePhotoFilePath(objectTypeCode, remoteObjectId, (Number) pk.get(0), FilenameUtils.getExtension(localPath));
340 data[pathIndex] = remotePath;
341
342
343 boolean copy = addCopyOperation(localPath, remotePath, context, result, buffer, false);
344
345 if (!copy) {
346
347 buffer.addMissingColumnUpdate(getConfig().getColumnUpdateDate(), pk, data[updateDateIndex]);
348 }
349
350 }
351
352 Object photoId = data[photoIdIndex];
353 if (photoId != null) {
354 buffer.addChildToUpdateFromManyColumns(DataSynchroTables.QUALIFICATION_HISTORY.name(),
355 ImmutableSet.of(DatabaseColumns.OBJECT_TYPE_CD.name(), DatabaseColumns.QUAL_HIST_ELEMENT_ID.name()),
356 Lists.newArrayList(ObjectTypeCode.PHOTO.value(), Long.parseLong(photoId.toString())));
357 }
358 }
359
360 @Override
361 protected void doOnDelete(List<Object> pk, SynchroTableDao sourceDao, SynchroTableDao targetDao, SynchroOperationRepository buffer) throws SQLException {
362
363 if (buffer == null)
364 return;
365
366 SynchroResult result = buffer.getSynchroContext().getResult();
367 DataSynchroContext context = (DataSynchroContext) buffer.getSynchroContext();
368
369
370 if (context.getDirection() == SynchroDirection.IMPORT_FILE2LOCAL || context.getDirection() == SynchroDirection.EXPORT_LOCAL2FILE)
371 return;
372
373 Object id = pk.get(0);
374 String query = String.format("SELECT %s FROM %s WHERE %s=?",
375 DatabaseColumns.PHOTO_LK.name(),
376 DataSynchroTables.PHOTO.name(),
377 DatabaseColumns.PHOTO_ID.name()
378 );
379 String path = targetDao.getUniqueTyped(query, new Object[]{id});
380
381
382 addDeleteOperation(path, context, result, buffer);
383
384 }
385
386 private boolean addCopyOperation(String srcPath, String destPath,
387 DataSynchroContext context,
388 SynchroResult result,
389 SynchroOperationRepository buffer,
390 boolean throwExceptionIfScrNotFound) {
391
392 if (!getConfig().isEnablePhoto()) {
393
394 return false;
395 }
396
397 Map<File, File> fileCopyMap = new LinkedHashMap<>();
398 {
399
400 File src = new File(getSourceDirectory(context), srcPath);
401 if (!src.exists()) {
402 if (throwExceptionIfScrNotFound) {
403 throw new SynchroTechnicalException("Unable to locate source file: " + src.getPath());
404 }
405 return false;
406 }
407
408
409 File dest = new File(getTargetDirectory(context), destPath);
410
411 if (src.equals(dest)) {
412 throw new SynchroTechnicalException("Source and destination are the same, please set photo directory correctly");
413 }
414
415 fileCopyMap.put(src, dest);
416
417
418 File mediumSrc = Images.getMediumImageFile(src);
419 if (mediumSrc.exists()) {
420 fileCopyMap.put(mediumSrc, Images.getMediumImageFile(dest));
421 }
422 File smallSrc = Images.getSmallImageFile(src);
423 if (smallSrc.exists()) {
424 fileCopyMap.put(smallSrc, Images.getSmallImageFile(dest));
425 }
426 }
427
428 for (File src : fileCopyMap.keySet()) {
429 File dest = null;
430 try {
431 dest = fileCopyMap.get(src);
432 Assert.notNull(dest);
433
434 if (LOG.isDebugEnabled()) {
435 LOG.debug(String.format("[%s] preparing copy [%s] -> [%s]",
436 DataSynchroTables.PHOTO.name(),
437 srcPath,
438 destPath));
439 }
440
441 FileOperation copy;
442
443 if (context.getTarget().isMirrorDatabase()) {
444 copy = FileOperationBuilder.prepareCopy(src, dest)
445 .build();
446 }
447
448 else {
449 copy = FileOperationBuilder.prepareCopy(src, dest)
450 .withLock()
451 .withUndo()
452 .build();
453 }
454 buffer.addFileOperation(copy);
455
456
457 result.addCopiedFiles(DataSynchroTables.PHOTO.name(), 1);
458 } catch (IOException e) {
459 throw new SynchroTechnicalException("Could not create operation to copy file into: " + dest.getPath(), e);
460 }
461 }
462 return true;
463 }
464
465 private void addDeleteOperation(String srcPath,
466 DataSynchroContext context,
467 SynchroResult result,
468 SynchroOperationRepository buffer) {
469
470 List<File> fileDeleteList = new ArrayList<>();
471 {
472
473 File src = new File(getTargetDirectory(context), srcPath);
474
475
476 if (buffer instanceof SynchroTableOperation) {
477 SynchroTableOperation operations = (SynchroTableOperation) buffer;
478 if (operations.getFileOperations().stream()
479 .filter(fileOperation -> fileOperation instanceof BasicFileOperation)
480 .map(fileOperation -> ((BasicFileOperation) fileOperation))
481 .anyMatch(basicFileOperation ->
482 basicFileOperation.getType() == BasicFileOperation.Type.DELETE_FILE
483 && basicFileOperation.getDest().equals(src)))
484
485 return;
486 }
487
488
489 if (!src.exists()) {
490 LOG.warn(String.format("[%s] Unable to delete the non-existent file [%s]",
491 DataSynchroTables.PHOTO.name(),
492 srcPath));
493 return;
494 }
495
496 fileDeleteList.add(src);
497
498
499 File mediumSrc = Images.getMediumImageFile(src);
500 if (mediumSrc.exists()) {
501 fileDeleteList.add(mediumSrc);
502 }
503 File smallSrc = Images.getSmallImageFile(src);
504 if (smallSrc.exists()) {
505 fileDeleteList.add(smallSrc);
506 }
507
508 }
509
510 for (File src : fileDeleteList) {
511 try {
512 if (LOG.isDebugEnabled()) {
513 LOG.debug(String.format("[%s] Delete file [%s]",
514 DataSynchroTables.PHOTO.name(),
515 srcPath));
516 }
517
518 FileOperation delete;
519
520
521 if (context.getTarget().isMirrorDatabase()) {
522 delete = FileOperationBuilder.prepareDelete(src)
523 .build();
524 }
525
526 else {
527 delete = FileOperationBuilder.prepareDelete(src)
528 .withLock()
529 .withUndo()
530 .build();
531 }
532 buffer.addFileOperation(delete);
533
534
535 FileOperation deleteParentDirIfEmpty = FileOperationBuilder.prepareDeleteDir(src.getParentFile())
536 .onlyIfEmpty()
537 .build();
538 buffer.addFileOperation(deleteParentDirIfEmpty);
539
540
541 result.addDeletedFiles(DataSynchroTables.PHOTO.name(), 1);
542 } catch (IOException e) {
543 throw new SynchroTechnicalException("Could not delete file: " + src.getPath(), e);
544 }
545 }
546 }
547
548 private File getSourceDirectory(DataSynchroContext context) {
549
550 if (sourceDirectory == null) {
551 sourceDirectory = context.getSource().getDbPhotoDirectory();
552 if (sourceDirectory == null || !sourceDirectory.exists() || !sourceDirectory.isDirectory()) {
553 throw new SynchroTechnicalException("Could not find source photo directory: " + sourceDirectory);
554 }
555 }
556 return sourceDirectory;
557 }
558
559 private File getTargetDirectory(DataSynchroContext context) {
560 if (targetDirectory == null) {
561 targetDirectory = context.getTarget().getDbPhotoDirectory();
562 if (!targetDirectory.exists() || !targetDirectory.isDirectory()) {
563 try {
564 FileUtils.forceMkdir(targetDirectory);
565 } catch (IOException e) {
566 throw new SynchroTechnicalException("Could not create directory " + targetDirectory.getPath(), e);
567 }
568 }
569 }
570 return targetDirectory;
571 }
572
573
574
575
576
577
578
579
580
581
582
583 private Number[] getRemoteIdAndParentIdFromSampleId(SynchroBaseDao dao, long sampleId) throws SQLException {
584 if (selectRemoteIdAndParentIdsFromSampleIdStatement == null || selectRemoteIdAndParentIdsFromSampleIdStatement.isClosed()) {
585 selectRemoteIdAndParentIdsFromSampleIdStatement = dao.getPreparedStatement(selectRemoteIdAndParentIdsFromSampleIdQuery);
586 }
587 Number[] result = null;
588 selectRemoteIdAndParentIdsFromSampleIdStatement.setLong(1, sampleId);
589 ResultSet resultSet = null;
590 try {
591 resultSet = selectRemoteIdAndParentIdsFromSampleIdStatement.executeQuery();
592 if (resultSet.next()) {
593 Number remoteId = null;
594 if (resultSet.getObject(1) != null) {
595 remoteId = (Number) resultSet.getObject(1);
596 }
597 Number surveyId = null;
598 if (resultSet.getObject(2) != null) {
599 surveyId = (Number) resultSet.getObject(2);
600 }
601 Number samplingOperId = null;
602 if (resultSet.getObject(3) != null) {
603 samplingOperId = (Number) resultSet.getObject(3);
604 }
605 result = new Number[]{remoteId, surveyId, samplingOperId};
606 }
607 } finally {
608 Daos.closeSilently(resultSet);
609 }
610 if (result == null)
611 throw new SynchroTechnicalException(String.format("Unable to find remote and parent ids from %s with local id = %s", DataSynchroTables.SAMPLE.name(), sampleId));
612 return result;
613 }
614
615
616
617
618
619
620
621
622
623 private String initSelectRemoteIdAndParentIdFromSampleIdQuery() {
624 return String.format("select %s, %s, %s from %s where %s = ?",
625 DatabaseColumns.REMOTE_ID.name(),
626 DatabaseColumns.SURVEY_ID.name(),
627 DatabaseColumns.SAMPLING_OPER_ID.name(),
628 DataSynchroTables.SAMPLE.name(),
629 DatabaseColumns.SAMPLE_ID.name()
630 );
631 }
632
633
634
635
636
637
638
639
640
641
642
643 private Number[] getRemoteIdAndParentIdFromSamplingOperId(SynchroBaseDao dao, long samplingOperId) throws SQLException {
644 if (selectParentIdFromSamplingOperIdStatement == null || selectParentIdFromSamplingOperIdStatement.isClosed()) {
645 selectParentIdFromSamplingOperIdStatement = dao.getPreparedStatement(selectRemoteIdAndParentIdFromSamplingOperIdQuery);
646 }
647 Number[] result = null;
648 selectParentIdFromSamplingOperIdStatement.setLong(1, samplingOperId);
649 ResultSet resultSet = null;
650 try {
651 resultSet = selectParentIdFromSamplingOperIdStatement.executeQuery();
652 if (resultSet.next()) {
653 Number remoteId = null;
654 if (resultSet.getObject(1) != null) {
655 remoteId = (Number) resultSet.getObject(1);
656 }
657 Number surveyId = null;
658 if (resultSet.getObject(2) != null) {
659 surveyId = (Number) resultSet.getObject(2);
660 }
661 result = new Number[]{remoteId, surveyId};
662 }
663 } finally {
664 Daos.closeSilently(resultSet);
665 }
666 if (result == null)
667 throw new SynchroTechnicalException(String.format("Unable to find remote and parent ids from %s with local id = %s", DataSynchroTables.SAMPLING_OPERATION.name(), samplingOperId));
668 return result;
669 }
670
671
672
673
674
675
676
677
678 private String initSelectRemoteIdAndParentIdFromSamplingOperIdQuery() {
679 return String.format("select %s, %s from %s where %s = ?",
680 DatabaseColumns.REMOTE_ID.name(),
681 DatabaseColumns.SURVEY_ID.name(),
682 DataSynchroTables.SAMPLING_OPERATION.name(),
683 DatabaseColumns.SAMPLING_OPER_ID.name()
684 );
685 }
686
687
688
689
690
691
692
693
694
695
696
697 private Number getRemoteIdFromSurveyId(SynchroBaseDao dao, long surveyId) throws SQLException {
698 Number remoteId = dao.getUniqueTyped(selectRemoteIdBySurveyIdQuery, new Object[]{surveyId});
699 if (remoteId == null)
700 throw new SynchroTechnicalException(String.format("Unable to find remote id from %s with local id = %s", DataSynchroTables.SURVEY.name(), surveyId));
701 return remoteId;
702 }
703
704
705
706
707
708
709
710
711 private String initSelectRemoteIdFromSurveyId() {
712 return String.format("select %s from %s where %s = ?",
713 DatabaseColumns.REMOTE_ID.name(),
714 DataSynchroTables.SURVEY.name(),
715 DatabaseColumns.SURVEY_ID.name());
716 }
717
718 private Number getLocalIdFromSurveyId(SynchroBaseDao dao, long remoteId) throws SQLException {
719 Number localId = dao.getUniqueTyped(selectLocalIdBySurveyIdQuery, new Object[]{remoteId});
720 if (localId == null)
721 throw new SynchroTechnicalException(String.format("Unable to find local id from %s with remote id = %s", DataSynchroTables.SURVEY.name(), remoteId));
722 return localId;
723 }
724
725 private String initSelectLocalIdFromSurveyId() {
726 return String.format("select %s from %s where %s = ?",
727 DatabaseColumns.SURVEY_ID.name(),
728 DataSynchroTables.SURVEY.name(),
729 DatabaseColumns.REMOTE_ID.name()
730 );
731 }
732
733 private Number getLocalIdFromSamplingOperId(SynchroBaseDao dao, long remoteId) throws SQLException {
734 Number localId = dao.getUniqueTyped(selectLocalIdBySamplingOperIdQuery, new Object[]{remoteId});
735 if (localId == null)
736 throw new SynchroTechnicalException(String.format("Unable to find local id from %s with remote id = %s", DataSynchroTables.SAMPLING_OPERATION.name(), remoteId));
737 return localId;
738 }
739
740 private String initSelectLocalIdFromSamplingOperId() {
741 return String.format("select %s from %s where %s = ?",
742 DatabaseColumns.SAMPLING_OPER_ID.name(),
743 DataSynchroTables.SAMPLING_OPERATION.name(),
744 DatabaseColumns.REMOTE_ID.name()
745 );
746 }
747
748 private Number getLocalIdFromSampleId(SynchroBaseDao dao, long remoteId) throws SQLException {
749 Number localId = dao.getUniqueTyped(selectLocalIdBySampleIdQuery, new Object[]{remoteId});
750 if (localId == null)
751 throw new SynchroTechnicalException(String.format("Unable to find local id from %s with remote id = %s", DataSynchroTables.SAMPLE.name(), remoteId));
752 return localId;
753 }
754
755 private String initSelectLocalIdFromSampleId() {
756 return String.format("select %s from %s where %s = ?",
757 DatabaseColumns.SAMPLE_ID.name(),
758 DataSynchroTables.SAMPLE.name(),
759 DatabaseColumns.REMOTE_ID.name()
760 );
761 }
762
763 }