1
|
package vldc.aswi.service;
|
2
|
|
3
|
import lombok.extern.slf4j.Slf4j;
|
4
|
import org.springframework.beans.factory.annotation.Autowired;
|
5
|
import org.springframework.stereotype.Service;
|
6
|
import vldc.aswi.database.DatabaseInterface;
|
7
|
import vldc.aswi.domain.Assembly;
|
8
|
import vldc.aswi.domain.Function;
|
9
|
import vldc.aswi.domain.parameter.ParameterInConfiguration;
|
10
|
import vldc.aswi.model.table.NameUserName;
|
11
|
import vldc.aswi.model.table.TableColumn;
|
12
|
import vldc.aswi.model.table.ValueFunction;
|
13
|
import vldc.aswi.model.table.contingencyTable.ContingencyTableRow;
|
14
|
import vldc.aswi.utils.Converter;
|
15
|
|
16
|
import java.util.*;
|
17
|
import java.util.concurrent.TimeUnit;
|
18
|
|
19
|
/**
|
20
|
* Manager for SqlQuery.
|
21
|
*/
|
22
|
@Service
|
23
|
@Slf4j
|
24
|
public class SqlQueryManagerImpl implements SqlQueryManager {
|
25
|
|
26
|
/**
|
27
|
* Autowired databaseInterface component.
|
28
|
*/
|
29
|
@Autowired
|
30
|
private DatabaseInterface databaseInterface;
|
31
|
|
32
|
/**
|
33
|
* Get list of contingencyTableRow.
|
34
|
* @param assembly Assembly from which configuration was created.
|
35
|
* @param parametersInConfiguration Parameters in configuration with their locations and operators.
|
36
|
* @param isNotRemoveEmpty Sets if empty rows and columns should not be removed.
|
37
|
* @param tableName Name of the table.
|
38
|
* @return List of contingencyTableRow or null, if error in SQL query occurred.
|
39
|
*/
|
40
|
@Override
|
41
|
public List<ContingencyTableRow> getContingencyTableRow(Assembly assembly,
|
42
|
List<ParameterInConfiguration> parametersInConfiguration,
|
43
|
boolean isNotRemoveEmpty, String tableName) {
|
44
|
long startTime = System.nanoTime();
|
45
|
|
46
|
Map<String, TableColumn> tableColumns = this.databaseInterface.executeQueryAndReturnTableColumns(
|
47
|
generateFullSQLQuery(assembly.getSQLQuery(), parametersInConfiguration)
|
48
|
);
|
49
|
|
50
|
// there was an error in the query
|
51
|
if (tableColumns == null) {
|
52
|
return null;
|
53
|
}
|
54
|
|
55
|
// no rows were returned by query
|
56
|
if (tableColumns.values().iterator().next().getValues().size() == 0) {
|
57
|
return new ArrayList<>();
|
58
|
}
|
59
|
|
60
|
long stopTime = System.nanoTime();
|
61
|
System.out.println("Select:" + TimeUnit.MILLISECONDS.convert((stopTime - startTime), TimeUnit.NANOSECONDS));
|
62
|
List<NameUserName> rowNames = new ArrayList<>();
|
63
|
List<NameUserName> columnNames = new ArrayList<>();
|
64
|
List<ValueFunction> valueFunctions = new ArrayList<>();
|
65
|
|
66
|
// Create a copy of list.
|
67
|
List<ParameterInConfiguration> copiedParametersInConfiguration = new ArrayList<>(parametersInConfiguration);
|
68
|
|
69
|
// sort parameters in configuration to have them in order set by user
|
70
|
Collections.sort(copiedParametersInConfiguration);
|
71
|
|
72
|
initializeContingencyTableDataLists(rowNames, columnNames, valueFunctions, copiedParametersInConfiguration);
|
73
|
|
74
|
Converter converter = new Converter(tableColumns, rowNames, columnNames, valueFunctions, isNotRemoveEmpty, tableName);
|
75
|
return converter.convertTableColumnsToContingencyTableRows();
|
76
|
}
|
77
|
|
78
|
/**
|
79
|
* Validate given SQL query.
|
80
|
* @param sqlQuery - Validated SQL query.
|
81
|
* @return true if SQL query is ok, false if not.
|
82
|
*/
|
83
|
@Override
|
84
|
public boolean validateSQLQuery(String sqlQuery) {
|
85
|
return this.databaseInterface.validateSQLQuery(sqlQuery);
|
86
|
}
|
87
|
|
88
|
/**
|
89
|
* Get list of table column names from SQL query.
|
90
|
* @param sqlQuery - SQL query.
|
91
|
* @return List of table column names.
|
92
|
*/
|
93
|
public List<String> getNameOfColumnsFromQuery(String sqlQuery) {
|
94
|
return this.databaseInterface.getNameOfColumnsFromQuery(sqlQuery);
|
95
|
}
|
96
|
|
97
|
/**
|
98
|
* Initializes list with values.
|
99
|
* @param rowNames List of selected rows.
|
100
|
* @param columnNames List of selected columns.
|
101
|
* @param valueFunctions List of selected values and functions.
|
102
|
* @param parametersInConfiguration List of parameters in configuration.
|
103
|
*/
|
104
|
private void initializeContingencyTableDataLists(List<NameUserName> rowNames, List<NameUserName> columnNames,
|
105
|
List<ValueFunction> valueFunctions, List<ParameterInConfiguration> parametersInConfiguration) {
|
106
|
for (ParameterInConfiguration parameterInConfiguration : parametersInConfiguration) {
|
107
|
if (parameterInConfiguration.getLocation().getName() != null && parameterInConfiguration.getLocation().getName().equals("Řádek")) {
|
108
|
if (parameterInConfiguration.getColumnName() != null && !parameterInConfiguration.getColumnName().equals("")) {
|
109
|
rowNames.add(new NameUserName(parameterInConfiguration.getParameter().getNameOfSelect().toUpperCase(),
|
110
|
parameterInConfiguration.getColumnName()));
|
111
|
}
|
112
|
else {
|
113
|
rowNames.add(new NameUserName(parameterInConfiguration.getParameter().getNameOfSelect().toUpperCase(),
|
114
|
parameterInConfiguration.getParameter().getName()));
|
115
|
}
|
116
|
} else if (parameterInConfiguration.getLocation().getName() != null && parameterInConfiguration.getLocation().getName().equals("Sloupec")) {
|
117
|
if (parameterInConfiguration.getColumnName() != null && !parameterInConfiguration.getColumnName().equals("")) {
|
118
|
columnNames.add(new NameUserName(parameterInConfiguration.getParameter().getNameOfSelect().toUpperCase(),
|
119
|
parameterInConfiguration.getColumnName()));
|
120
|
}
|
121
|
else {
|
122
|
columnNames.add(new NameUserName(parameterInConfiguration.getParameter().getNameOfSelect().toUpperCase(),
|
123
|
parameterInConfiguration.getParameter().getName()));
|
124
|
}
|
125
|
} else if (parameterInConfiguration.getLocation().getName() != null && parameterInConfiguration.getLocation().getName().equals("Hodnota")) {
|
126
|
for (Function function : parameterInConfiguration.getFunctions()) {
|
127
|
valueFunctions.add(new ValueFunction(parameterInConfiguration.getParameter().getNameOfSelect().toUpperCase(),
|
128
|
parameterInConfiguration.getParameter().getName(), function.getName().toUpperCase(),
|
129
|
parameterInConfiguration.getParameter().getParameterType().getName()));
|
130
|
}
|
131
|
if (valueFunctions.size() == 0) {
|
132
|
valueFunctions.add(new ValueFunction(parameterInConfiguration.getParameter().getNameOfSelect().toUpperCase(),
|
133
|
parameterInConfiguration.getParameter().getName(), "",
|
134
|
parameterInConfiguration.getParameter().getParameterType().getName()));
|
135
|
}
|
136
|
}
|
137
|
}
|
138
|
|
139
|
if (valueFunctions.size() == 0) {
|
140
|
valueFunctions.add(new ValueFunction("", "nic", "NIC", ""));
|
141
|
}
|
142
|
}
|
143
|
|
144
|
/**
|
145
|
* Generates full SQL query with all the filters
|
146
|
* @param basicSQLQuery SQL query saved in assembly
|
147
|
* @param parametersInConfiguration Parameters in configuration.
|
148
|
* @return SQL query with filters.
|
149
|
*/
|
150
|
private String generateFullSQLQuery(String basicSQLQuery, List<ParameterInConfiguration> parametersInConfiguration) {
|
151
|
StringBuilder finalSQLQuery = new StringBuilder("SELECT * FROM (");
|
152
|
finalSQLQuery.append(basicSQLQuery);
|
153
|
finalSQLQuery.append(")");
|
154
|
|
155
|
boolean isWhereDefined = false;
|
156
|
|
157
|
for (ParameterInConfiguration parameterInConfiguration : parametersInConfiguration) {
|
158
|
if (parameterInConfiguration.getParameter().getParameterType().getName().equals("Výčet") && false) {
|
159
|
isWhereDefined = processListing(parameterInConfiguration, finalSQLQuery, isWhereDefined);
|
160
|
}
|
161
|
else if (parameterInConfiguration.getOperator() != null && !parameterInConfiguration.getOperator().getName().equals("zadny") &&
|
162
|
parameterInConfiguration.getOperatorValue() != null && !parameterInConfiguration.getOperatorValue().equals("")) {
|
163
|
isWhereDefined = processFilter(parameterInConfiguration, finalSQLQuery, isWhereDefined);
|
164
|
}
|
165
|
}
|
166
|
|
167
|
return finalSQLQuery.toString();
|
168
|
}
|
169
|
|
170
|
/**
|
171
|
* Processes listing (enum) type.
|
172
|
* @param parameterInConfiguration Listing type parameter iin configuration.
|
173
|
* @param finalSQLQuery Resulting SQL query.
|
174
|
* @param isWhereDefined Variable storing information if WHERE clause was defined in the resulting SQL query.
|
175
|
* @return Information that WHERE clause was defined.
|
176
|
*/
|
177
|
private boolean processListing(ParameterInConfiguration parameterInConfiguration, StringBuilder finalSQLQuery, boolean isWhereDefined) {
|
178
|
if (!isWhereDefined) {
|
179
|
finalSQLQuery.append(" WHERE ");
|
180
|
} else {
|
181
|
finalSQLQuery.append(" AND ");
|
182
|
}
|
183
|
|
184
|
finalSQLQuery.append(parameterInConfiguration.getParameter().getNameOfSelect());
|
185
|
finalSQLQuery.append(" IN ");
|
186
|
inNotIn(null, "Text");
|
187
|
|
188
|
return true;
|
189
|
}
|
190
|
|
191
|
/**
|
192
|
* Process filter of parameter in configuration.
|
193
|
* @param parameterInConfiguration Parameter in configuration.
|
194
|
* @param finalSQLQuery Resulting SQL query.
|
195
|
* @param isWhereDefined Variable storing information if WHERE clause was defined in the resulting SQL query.
|
196
|
* @return Information that WHERE clause was defined
|
197
|
*/
|
198
|
private boolean processFilter(ParameterInConfiguration parameterInConfiguration, StringBuilder finalSQLQuery, boolean isWhereDefined) {
|
199
|
String[] values = parameterInConfiguration.getOperatorValue().split(";");
|
200
|
if (!isWhereDefined) {
|
201
|
finalSQLQuery.append(" WHERE ");
|
202
|
} else {
|
203
|
finalSQLQuery.append(" AND ");
|
204
|
}
|
205
|
|
206
|
finalSQLQuery.append(parameterInConfiguration.getParameter().getNameOfSelect());
|
207
|
finalSQLQuery.append(" ");
|
208
|
finalSQLQuery.append(parameterInConfiguration.getOperator().getName());
|
209
|
if (parameterInConfiguration.getOperator().getName().equals("IS NULL") ||
|
210
|
parameterInConfiguration.getOperator().getName().equals("IS NOT NULL")) {
|
211
|
return true;
|
212
|
}
|
213
|
finalSQLQuery.append(" ");
|
214
|
switch (parameterInConfiguration.getOperator().getName()) {
|
215
|
case "BETWEEN":
|
216
|
case "NOT BETWEEN":
|
217
|
finalSQLQuery.append(betweenNotBetween(values, parameterInConfiguration.getParameter().getParameterType().getName()));
|
218
|
break;
|
219
|
case "IN":
|
220
|
case "NOT IN":
|
221
|
finalSQLQuery.append(inNotIn(values, parameterInConfiguration.getParameter().getParameterType().getName()));
|
222
|
break;
|
223
|
case "LIKE":
|
224
|
case "NOT LIKE":
|
225
|
finalSQLQuery.append(likeNotLike(values, parameterInConfiguration.getParameter().getParameterType().getName()));
|
226
|
break;
|
227
|
default:
|
228
|
finalSQLQuery.append(otherOperators(values, parameterInConfiguration.getParameter().getParameterType().getName()));
|
229
|
break;
|
230
|
}
|
231
|
|
232
|
return true;
|
233
|
}
|
234
|
|
235
|
/**
|
236
|
* Validate LIKE and NOT LIKE operator.
|
237
|
* @param values Values set by user.
|
238
|
* @param type Type of the parameter.
|
239
|
* @return String to be added to SQL query.
|
240
|
*/
|
241
|
private String likeNotLike(String[] values, String type) {
|
242
|
StringBuilder SQLQueryPart = new StringBuilder();
|
243
|
addQuotes(type, SQLQueryPart);
|
244
|
SQLQueryPart.append(values[0]);
|
245
|
addQuotes(type, SQLQueryPart);
|
246
|
|
247
|
return SQLQueryPart.toString();
|
248
|
}
|
249
|
|
250
|
/**
|
251
|
* Validate IN and NOT IN operator.
|
252
|
* @param values Values set by user.
|
253
|
* @param type Type of the parameter.
|
254
|
* @return String to be added to SQL query.
|
255
|
*/
|
256
|
private String inNotIn(String[] values, String type) {
|
257
|
StringBuilder SQLQueryPart = new StringBuilder();
|
258
|
SQLQueryPart.append("(");
|
259
|
for (int i = 0; i < values.length; i++) {
|
260
|
if (type.equals("Datum")) {
|
261
|
SQLQueryPart.append("date ");
|
262
|
}
|
263
|
|
264
|
addQuotes(type, SQLQueryPart);
|
265
|
SQLQueryPart.append(values[i]);
|
266
|
addQuotes(type, SQLQueryPart);
|
267
|
if (i < values.length - 1) {
|
268
|
SQLQueryPart.append(",");
|
269
|
}
|
270
|
}
|
271
|
SQLQueryPart.append(")");
|
272
|
|
273
|
return SQLQueryPart.toString();
|
274
|
}
|
275
|
|
276
|
/**
|
277
|
* Validate BETWEEN and NOT BETWEEN operator.
|
278
|
* @param values Values set by user.
|
279
|
* @param type Type of the parameter.
|
280
|
* @return String to be added to SQL query.
|
281
|
*/
|
282
|
private String betweenNotBetween(String[] values, String type) {
|
283
|
StringBuilder SQLQueryPart = new StringBuilder();
|
284
|
|
285
|
if (type.equals("Datum")) {
|
286
|
SQLQueryPart.append("date ");
|
287
|
}
|
288
|
|
289
|
addQuotes(type, SQLQueryPart);
|
290
|
SQLQueryPart.append(values[0]);
|
291
|
addQuotes(type, SQLQueryPart);
|
292
|
|
293
|
SQLQueryPart.append(" AND ");
|
294
|
|
295
|
if (type.equals("Datum")) {
|
296
|
SQLQueryPart.append("date ");
|
297
|
}
|
298
|
|
299
|
addQuotes(type, SQLQueryPart);
|
300
|
SQLQueryPart.append(values[1]);
|
301
|
addQuotes(type, SQLQueryPart);
|
302
|
|
303
|
return SQLQueryPart.toString();
|
304
|
}
|
305
|
|
306
|
/**
|
307
|
* Validate other operators.
|
308
|
* @param values Values set by user.
|
309
|
* @param type Type of the parameter.
|
310
|
* @return String to be added to SQL query.
|
311
|
*/
|
312
|
private String otherOperators(String[] values, String type) {
|
313
|
StringBuilder SQLQueryPart = new StringBuilder();
|
314
|
|
315
|
if (type.equals("Datum")) {
|
316
|
SQLQueryPart.append("date ");
|
317
|
}
|
318
|
|
319
|
addQuotes(type, SQLQueryPart);
|
320
|
SQLQueryPart.append(values[0]);
|
321
|
addQuotes(type, SQLQueryPart);
|
322
|
|
323
|
return SQLQueryPart.toString();
|
324
|
}
|
325
|
|
326
|
/**
|
327
|
* Adds quote to the value.
|
328
|
* @param type Type Type of the parameter.
|
329
|
* @param SQLQueryPart Appends quote to the final SQL query.
|
330
|
*/
|
331
|
private void addQuotes(String type, StringBuilder SQLQueryPart) {
|
332
|
if (type.equals("Text") || type.equals("Datum")) {
|
333
|
SQLQueryPart.append("'");
|
334
|
}
|
335
|
}
|
336
|
}
|