15
15
*/
16
16
package org .springframework .data .jpa .repository .query ;
17
17
18
+ import static org .springframework .data .jpa .repository .query .JSqlParserUtils .*;
19
+ import static org .springframework .data .jpa .repository .query .QueryUtils .*;
20
+
18
21
import net .sf .jsqlparser .JSQLParserException ;
19
22
import net .sf .jsqlparser .expression .Alias ;
20
23
import net .sf .jsqlparser .expression .Expression ;
24
27
import net .sf .jsqlparser .parser .CCJSqlParserUtil ;
25
28
import net .sf .jsqlparser .schema .Column ;
26
29
import net .sf .jsqlparser .schema .Table ;
27
- import net .sf .jsqlparser .statement .select .*;
30
+ import net .sf .jsqlparser .statement .select .OrderByElement ;
31
+ import net .sf .jsqlparser .statement .select .PlainSelect ;
32
+ import net .sf .jsqlparser .statement .select .Select ;
33
+ import net .sf .jsqlparser .statement .select .SelectExpressionItem ;
34
+ import net .sf .jsqlparser .statement .select .SelectItem ;
28
35
import net .sf .jsqlparser .util .SelectUtils ;
36
+
37
+ import java .util .ArrayList ;
38
+ import java .util .Collections ;
39
+ import java .util .HashSet ;
40
+ import java .util .List ;
41
+ import java .util .Objects ;
42
+ import java .util .Set ;
43
+ import java .util .stream .Collectors ;
44
+
29
45
import org .springframework .data .domain .Sort ;
30
46
import org .springframework .data .util .Streamable ;
31
47
import org .springframework .util .Assert ;
32
48
import org .springframework .util .CollectionUtils ;
33
49
import org .springframework .util .StringUtils ;
34
50
35
- import java .util .*;
36
- import java .util .stream .Collectors ;
37
-
38
- import static org .springframework .data .jpa .repository .query .JSqlParserUtils .*;
39
- import static org .springframework .data .jpa .repository .query .QueryUtils .checkSortExpression ;
40
-
41
51
/**
42
52
* The implementation of {@link QueryEnhancer} using JSqlParser.
43
53
*
44
54
* @author Diego Krupitza
55
+ * @author Greg Turnquist
56
+ * @since 2.7.0
45
57
*/
46
58
public class JSqlParserQueryEnhancer implements QueryEnhancer {
47
59
@@ -58,6 +70,7 @@ public JSqlParserQueryEnhancer(DeclaredQuery query) {
58
70
59
71
@ Override
60
72
public String getExistsQueryString (String entityName , String countQueryPlaceHolder , Iterable <String > idAttributes ) {
73
+
61
74
final Table tableNameWithAlias = getTableWithAlias (entityName , DEFAULT_TABLE_ALIAS );
62
75
Function jSqlCount = getJSqlCount (Collections .singletonList (countQueryPlaceHolder ), false );
63
76
@@ -74,6 +87,7 @@ public String getExistsQueryString(String entityName, String countQueryPlaceHold
74
87
}).collect (Collectors .toList ());
75
88
76
89
if (equalityExpressions .size () > 1 ) {
90
+
77
91
AndExpression rootOfWhereClause = concatenateWithAndExpression (equalityExpressions );
78
92
selectBody .setWhere (rootOfWhereClause );
79
93
} else if (equalityExpressions .size () == 1 ) {
@@ -85,12 +99,14 @@ public String getExistsQueryString(String entityName, String countQueryPlaceHold
85
99
86
100
@ Override
87
101
public String getQueryString (String template , String entityName ) {
102
+
88
103
Assert .hasText (entityName , "Entity name must not be null or empty!" );
89
104
return String .format (template , entityName );
90
105
}
91
106
92
107
@ Override
93
108
public String applySorting (Sort sort , String alias ) {
109
+
94
110
String queryString = query .getQueryString ();
95
111
Assert .hasText (queryString , "Query must not be null or empty!" );
96
112
@@ -145,6 +161,7 @@ private Set<String> getSelectionAliases(PlainSelect selectBody) {
145
161
* @return a {@literal Set} containing all found aliases. Guaranteed to be not {@literal null}.
146
162
*/
147
163
Set <String > getSelectionAliases () {
164
+
148
165
Select selectStatement = parseSelectStatement (this .query .getQueryString ());
149
166
PlainSelect selectBody = (PlainSelect ) selectStatement .getSelectBody ();
150
167
return this .getSelectionAliases (selectBody );
@@ -234,6 +251,7 @@ public String detectAlias() {
234
251
* @return Might return {@literal null}.
235
252
*/
236
253
private String detectAlias (String query ) {
254
+
237
255
Select selectStatement = parseSelectStatement (query );
238
256
PlainSelect selectBody = (PlainSelect ) selectStatement .getSelectBody ();
239
257
return detectAlias (selectBody );
@@ -247,6 +265,7 @@ private String detectAlias(String query) {
247
265
* @return Might return {@literal null}.
248
266
*/
249
267
private static String detectAlias (PlainSelect selectBody ) {
268
+
250
269
Alias alias = selectBody .getFromItem ().getAlias ();
251
270
return alias == null ? null : alias .getName ();
252
271
}
@@ -298,6 +317,7 @@ public String createCountQueryFor(String countProjection) {
298
317
299
318
@ Override
300
319
public String getProjection () {
320
+
301
321
Assert .hasText (query .getQueryString (), "Query must not be null or empty!" );
302
322
303
323
Select selectStatement = parseSelectStatement (query .getQueryString ());
@@ -321,6 +341,7 @@ public Set<String> getJoinAliases() {
321
341
* @return the parsed query
322
342
*/
323
343
private static Select parseSelectStatement (String query ) {
344
+
324
345
try {
325
346
return (Select ) CCJSqlParserUtil .parse (query );
326
347
} catch (JSQLParserException e ) {
@@ -335,6 +356,7 @@ private static Select parseSelectStatement(String query) {
335
356
* @return <code>true</code> when the projection only contains a single column definition otherwise <code>false</code>
336
357
*/
337
358
private boolean onlyASingleColumnProjection (List <SelectItem > projection ) {
359
+
338
360
// this is unfortunately the only way to check without any hacky & hard string regex magic
339
361
return projection .size () == 1 && projection .get (0 ) instanceof SelectExpressionItem
340
362
&& (((SelectExpressionItem ) projection .get (0 )).getExpression ()) instanceof Column ;
0 commit comments