1 package fr.ifremer.quadrige3.synchro.intercept.data;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 import com.google.common.base.Joiner;
27 import com.google.common.collect.ImmutableList;
28 import com.google.common.collect.ImmutableSet;
29 import com.google.common.collect.Sets;
30 import com.google.common.eventbus.Subscribe;
31 import fr.ifremer.common.synchro.intercept.SynchroInterceptorBase;
32 import fr.ifremer.common.synchro.meta.SynchroTableMetadata;
33 import fr.ifremer.common.synchro.meta.event.CreateQueryEvent;
34 import fr.ifremer.common.synchro.meta.event.LoadTableEvent;
35 import fr.ifremer.common.synchro.query.SynchroQueryBuilder;
36 import fr.ifremer.common.synchro.query.SynchroQueryOperator;
37 import fr.ifremer.quadrige3.core.dao.ObjectTypes;
38 import fr.ifremer.quadrige3.synchro.meta.DatabaseColumns;
39 import fr.ifremer.quadrige3.synchro.meta.data.DataSynchroTables;
40 import fr.ifremer.quadrige3.synchro.service.SynchroDirection;
41 import org.apache.commons.collections4.CollectionUtils;
42
43 import java.util.Collection;
44 import java.util.HashSet;
45 import java.util.List;
46 import java.util.Set;
47
48
49
50
51
52
53
54 public class DeletedItemHistoryInterceptor extends AbstractDataInterceptor {
55
56
57 private static final List<String> NATURAL_ID_COLUMNS = ImmutableList.of(
58 DatabaseColumns.OBJECT_TYPE_CD.name(),
59 DatabaseColumns.OBJECT_ID.name(),
60 DatabaseColumns.OBJECT_CD.name());
61
62 private String whereClauseOnTableIncludes = null;
63 private String whereClauseOnTableIncludesExceptSurvey = null;
64
65
66
67
68
69
70 public DeletedItemHistoryInterceptor() {
71
72 super(DataSynchroTables.DELETED_ITEM_HISTORY.name(),
73
74 SynchroDirection.IMPORT_SERVER2TEMP,
75 SynchroDirection.EXPORT_LOCAL2TEMP,
76 SynchroDirection.EXPORT_TEMP2SERVER);
77 }
78
79
80 @Override
81 public SynchroInterceptorBase clone() {
82 DeletedItemHistoryInterceptor newBean = (DeletedItemHistoryInterceptor) super.clone();
83 newBean.whereClauseOnTableIncludes = this.whereClauseOnTableIncludes;
84 newBean.whereClauseOnTableIncludesExceptSurvey = this.whereClauseOnTableIncludesExceptSurvey;
85 return newBean;
86 }
87
88
89
90
91
92
93
94
95
96 @Subscribe
97 public void handleCreateQuery(CreateQueryEvent e) {
98 SynchroDirection direction = getConfig().getDirection();
99
100 switch (e.queryName) {
101 case count:
102 case countFromUpdateDate:
103 case select:
104 case selectFromUpdateDate:
105 case selectMaxUpdateDate:
106 if (direction == SynchroDirection.EXPORT_LOCAL2TEMP) {
107
108 e.sql = addRestrictionsOnExportToTemp(e.sql);
109 } else {
110
111 e.sql = addRestrictionsOnIncludedTables(e.sql);
112 }
113 break;
114
115 default:
116 break;
117 }
118 }
119
120
121
122
123
124
125
126
127
128 @Subscribe
129 public void handleTableLoad(LoadTableEvent e) {
130 SynchroTableMetadata table = e.table;
131 SynchroDirection direction = getConfig().getDirection();
132
133
134 boolean isRoot = isInDirections(SynchroDirection.IMPORT_SERVER2TEMP,
135 SynchroDirection.EXPORT_LOCAL2TEMP,
136 SynchroDirection.EXPORT_TEMP2SERVER);
137
138 e.table.setRoot(isRoot);
139
140
141 if (direction == SynchroDirection.EXPORT_TEMP2SERVER) {
142
143 table.addUniqueConstraint("NATURAL_ID_UNIQUE_C", NATURAL_ID_COLUMNS, SynchroTableMetadata.DuplicateKeyStrategy.WARN);
144 }
145 }
146
147
148
149 private String addRestrictionsOnIncludedTables(String sql) {
150
151 SynchroQueryBuilder query = SynchroQueryBuilder.newBuilder(sql);
152
153
154 if (whereClauseOnTableIncludes == null) {
155 whereClauseOnTableIncludes = createWhereClauseOnTableIncludes(null);
156 }
157 query.addWhere(SynchroQueryOperator.AND, whereClauseOnTableIncludes);
158
159 return query.build();
160 }
161
162
163
164
165 private String addRestrictionsOnExportToTemp(String sql) {
166
167 Set<String> programCodes = getConfig().getProgramCodes();
168
169
170 if (CollectionUtils.isEmpty(programCodes))
171 return addRestrictionsOnIncludedTables(sql);
172
173
174 SynchroQueryBuilder query = SynchroQueryBuilder.newBuilder(sql);
175
176
177 query.addWhere(SynchroQueryOperator.AND, DatabaseColumns.REMOTE_ID.name() + " is null");
178
179
180 if (whereClauseOnTableIncludesExceptSurvey == null) {
181 whereClauseOnTableIncludesExceptSurvey = createWhereClauseOnTableIncludes(ImmutableSet.of(DataSynchroTables.SURVEY.name()));
182 }
183
184
185 Set<String> objectTypeCds = ObjectTypes.getObjectTypeFromTableName(DataSynchroTables.SURVEY.name());
186 String whereClauseOnSurveyToDelete = String.format("%s IN ('%s') AND %s IN " +
187 "(SELECT s.%s FROM %s s INNER JOIN %s sp ON sp.%s = s.%s " +
188 "WHERE sp.%s IN ('%s'))",
189 DatabaseColumns.OBJECT_TYPE_CD, Joiner.on("','").join(objectTypeCds), DatabaseColumns.OBJECT_ID,
190 DatabaseColumns.REMOTE_ID, DataSynchroTables.SURVEY, DataSynchroTables.SURVEY_PROG, DatabaseColumns.SURVEY_ID, DatabaseColumns.SURVEY_ID,
191 DatabaseColumns.PROG_CD, Joiner.on("','").join(programCodes));
192
193 query.addWhere(SynchroQueryOperator.AND, String.format("((%s) OR (%s))", whereClauseOnTableIncludesExceptSurvey, whereClauseOnSurveyToDelete));
194
195
196 return query.build();
197 }
198
199 private String createWhereClauseOnTableIncludes(Collection<String> tablesToIgnore) {
200 Set<String> tableToIncludes = new HashSet<>(DataSynchroTables.getImportTablesIncludes());
201 if (CollectionUtils.isNotEmpty(tablesToIgnore)) {
202 tableToIncludes.removeAll(tablesToIgnore);
203 }
204
205
206 if (CollectionUtils.isEmpty(tableToIncludes)) {
207 return "1=2";
208 }
209
210 Set<String> allObjectTypeCds = Sets.newHashSet();
211 for (String tableName : tableToIncludes) {
212 Set<String> objectTypeCds = ObjectTypes.getObjectTypeFromTableName(tableName);
213 if (CollectionUtils.isNotEmpty(objectTypeCds)) {
214 allObjectTypeCds.addAll(objectTypeCds);
215 }
216 else {
217
218 allObjectTypeCds.add(tableName);
219 }
220 }
221
222
223 allObjectTypeCds.remove(DataSynchroTables.DELETED_ITEM_HISTORY.name());
224
225 return String.format("%s IN ('%s')", DatabaseColumns.OBJECT_TYPE_CD, Joiner.on("','").join(allObjectTypeCds));
226 }
227
228 }