@@ -29,9 +29,11 @@ public class SqlVisitor implements ExpressionVisitor<StringBuilder> {
2929 try {
3030 operatorMethods .put (String .class .getDeclaredMethod ("equals" , Object .class ), ExpressionType .Equal );
3131 operatorMethods .put (Object .class .getDeclaredMethod ("equals" , Object .class ), ExpressionType .Equal );
32- operatorMethods . put ( LocalDate . class . getDeclaredMethod ( "isAfter" , ChronoLocalDate . class ), ExpressionType . GreaterThan );
32+
3333 operatorMethods .put (LocalTime .class .getDeclaredMethod ("isAfter" , LocalTime .class ), ExpressionType .GreaterThan );
34+ operatorMethods .put (LocalDate .class .getDeclaredMethod ("isAfter" , ChronoLocalDate .class ), ExpressionType .GreaterThan );
3435 operatorMethods .put (LocalDateTime .class .getDeclaredMethod ("isAfter" , ChronoLocalDateTime .class ), ExpressionType .GreaterThan );
36+
3537 operatorMethods .put (LocalDate .class .getDeclaredMethod ("isBefore" , ChronoLocalDate .class ), ExpressionType .LessThan );
3638 operatorMethods .put (LocalTime .class .getDeclaredMethod ("isBefore" , LocalTime .class ), ExpressionType .LessThan );
3739 operatorMethods .put (LocalDateTime .class .getDeclaredMethod ("isBefore" , ChronoLocalDateTime .class ), ExpressionType .LessThan );
@@ -52,7 +54,7 @@ public class SqlVisitor implements ExpressionVisitor<StringBuilder> {
5254 /**
5355 * More complex methods that can be used on Java objects inside the lambda expressions.
5456 */
55- private final Map <Member , TriFunction <Expression , Expression , Boolean , StringBuilder >> complexMethods ;
57+ private final Map <Member , TriFunction <Expression , Expression , Boolean , StringBuilder >> javaMethods ;
5658
5759 private final StringBuilder sb ;
5860 private Expression body ;
@@ -70,33 +72,61 @@ private SqlVisitor(String tableName, boolean withBackticks, Expression body, Lin
7072 this .sb = new StringBuilder ();
7173 this .parameterConsumptionCount = new HashMap <>();
7274
73- this .complexMethods = new HashMap <>(32 , 1 );
75+ this .javaMethods = new HashMap <>(1 << 6 , 1 );
7476 try {
75- this .complexMethods .put (String .class .getDeclaredMethod ("startsWith" , String .class ), this ::stringStartsWith );
76- this .complexMethods .put (String .class .getDeclaredMethod ("endsWith" , String .class ), this ::stringEndsWith );
77- this .complexMethods .put (String .class .getDeclaredMethod ("contains" , CharSequence .class ), this ::stringContains );
78- this .complexMethods .put (String .class .getDeclaredMethod ("length" ), (string , argument , isNegated ) -> applySqlFunction (string , "LENGTH" ));
79-
80- this .complexMethods .put (List .class .getDeclaredMethod ("contains" , Object .class ), this ::listContains );
81- this .complexMethods .put (ArrayList .class .getDeclaredMethod ("contains" , Object .class ), this ::listContains );
82- this .complexMethods .put (LinkedList .class .getDeclaredMethod ("contains" , Object .class ), this ::listContains );
83-
84- this .complexMethods .put (LocalTime .class .getDeclaredMethod ("getSecond" ), (date , argument , isNegated ) -> applySqlFunction (date , "SECOND" ));
85- this .complexMethods .put (LocalDateTime .class .getDeclaredMethod ("getSecond" ), (date , argument , isNegated ) -> applySqlFunction (date , "SECOND" ));
86- this .complexMethods .put (LocalTime .class .getDeclaredMethod ("getMinute" ), (date , argument , isNegated ) -> applySqlFunction (date , "MINUTE" ));
87- this .complexMethods .put (LocalDateTime .class .getDeclaredMethod ("getMinute" ), (date , argument , isNegated ) -> applySqlFunction (date , "MINUTE" ));
88- this .complexMethods .put (LocalTime .class .getDeclaredMethod ("getHour" ), (date , argument , isNegated ) -> applySqlFunction (date , "HOUR" ));
89- this .complexMethods .put (LocalDateTime .class .getDeclaredMethod ("getHour" ), (date , argument , isNegated ) -> applySqlFunction (date , "HOUR" ));
90- this .complexMethods .put (LocalDate .class .getDeclaredMethod ("getDayOfWeek" ), (date , argument , isNegated ) -> applySqlFunction (date , "DAYOFWEEK" ));
91- this .complexMethods .put (LocalDateTime .class .getDeclaredMethod ("getDayOfWeek" ), (date , argument , isNegated ) -> applySqlFunction (date , "DAYOFWEEK" ));
92- this .complexMethods .put (LocalDate .class .getDeclaredMethod ("getDayOfMonth" ), (date , argument , isNegated ) -> applySqlFunction (date , "DAY" ));
93- this .complexMethods .put (LocalDateTime .class .getDeclaredMethod ("getDayOfWeek" ), (date , argument , isNegated ) -> applySqlFunction (date , "DAY" ));
94- this .complexMethods .put (LocalDate .class .getDeclaredMethod ("getDayOfYear" ), (date , argument , isNegated ) -> applySqlFunction (date , "DAYOFYEAR" ));
95- this .complexMethods .put (LocalDateTime .class .getDeclaredMethod ("getDayOfYear" ), (date , argument , isNegated ) -> applySqlFunction (date , "DAYOFYEAR" ));
96- this .complexMethods .put (LocalDate .class .getDeclaredMethod ("getMonthValue" ), (date , argument , isNegated ) -> applySqlFunction (date , "MONTH" ));
97- this .complexMethods .put (LocalDateTime .class .getDeclaredMethod ("getMonthValue" ), (date , argument , isNegated ) -> applySqlFunction (date , "MONTH" ));
98- this .complexMethods .put (LocalDate .class .getDeclaredMethod ("getYear" ), (date , argument , isNegated ) -> applySqlFunction (date , "YEAR" ));
99- this .complexMethods .put (LocalDateTime .class .getDeclaredMethod ("getYear" ), (date , argument , isNegated ) -> applySqlFunction (date , "YEAR" ));
77+ this .javaMethods .put (String .class .getDeclaredMethod ("startsWith" , String .class ), this ::stringStartsWith );
78+ this .javaMethods .put (String .class .getDeclaredMethod ("endsWith" , String .class ), this ::stringEndsWith );
79+ this .javaMethods .put (String .class .getDeclaredMethod ("contains" , CharSequence .class ), this ::stringContains );
80+ this .javaMethods .put (String .class .getDeclaredMethod ("length" ), applySqlFunction ("LENGTH" ));
81+ this .javaMethods .put (String .class .getDeclaredMethod ("toLowerCase" ), applySqlFunction ("UPPER" ));
82+ this .javaMethods .put (String .class .getDeclaredMethod ("toUpperCase" ), applySqlFunction ("LOWER" ));
83+
84+ this .javaMethods .put (List .class .getDeclaredMethod ("contains" , Object .class ), this ::listContains );
85+ this .javaMethods .put (ArrayList .class .getDeclaredMethod ("contains" , Object .class ), this ::listContains );
86+ this .javaMethods .put (LinkedList .class .getDeclaredMethod ("contains" , Object .class ), this ::listContains );
87+
88+ this .javaMethods .put (LocalTime .class .getDeclaredMethod ("getSecond" ), applySqlFunction ("SECOND" ));
89+ this .javaMethods .put (LocalDateTime .class .getDeclaredMethod ("getSecond" ), applySqlFunction ("SECOND" ));
90+ this .javaMethods .put (OffsetTime .class .getDeclaredMethod ("getSecond" ), applySqlFunction ("SECOND" ));
91+ this .javaMethods .put (OffsetDateTime .class .getDeclaredMethod ("getSecond" ), applySqlFunction ("SECOND" ));
92+ this .javaMethods .put (ZonedDateTime .class .getDeclaredMethod ("getSecond" ), applySqlFunction ("SECOND" ));
93+
94+ this .javaMethods .put (LocalTime .class .getDeclaredMethod ("getMinute" ), applySqlFunction ("MINUTE" ));
95+ this .javaMethods .put (LocalDateTime .class .getDeclaredMethod ("getMinute" ), applySqlFunction ("MINUTE" ));
96+ this .javaMethods .put (OffsetTime .class .getDeclaredMethod ("getMinute" ), applySqlFunction ("MINUTE" ));
97+ this .javaMethods .put (OffsetDateTime .class .getDeclaredMethod ("getMinute" ), applySqlFunction ("MINUTE" ));
98+ this .javaMethods .put (ZonedDateTime .class .getDeclaredMethod ("getMinute" ), applySqlFunction ("MINUTE" ));
99+
100+ this .javaMethods .put (LocalTime .class .getDeclaredMethod ("getHour" ), applySqlFunction ("HOUR" ));
101+ this .javaMethods .put (LocalDateTime .class .getDeclaredMethod ("getHour" ), applySqlFunction ("HOUR" ));
102+ this .javaMethods .put (OffsetTime .class .getDeclaredMethod ("getHour" ), applySqlFunction ("HOUR" ));
103+ this .javaMethods .put (OffsetDateTime .class .getDeclaredMethod ("getHour" ), applySqlFunction ("HOUR" ));
104+ this .javaMethods .put (ZonedDateTime .class .getDeclaredMethod ("getHour" ), applySqlFunction ("HOUR" ));
105+
106+ this .javaMethods .put (LocalDate .class .getDeclaredMethod ("getDayOfWeek" ), applySqlFunction ("DAYOFWEEK" ));
107+ this .javaMethods .put (LocalDateTime .class .getDeclaredMethod ("getDayOfWeek" ), applySqlFunction ("DAYOFWEEK" ));
108+ this .javaMethods .put (OffsetDateTime .class .getDeclaredMethod ("getDayOfWeek" ), applySqlFunction ("DAYOFWEEK" ));
109+ this .javaMethods .put (ZonedDateTime .class .getDeclaredMethod ("getDayOfWeek" ), applySqlFunction ("DAYOFWEEK" ));
110+
111+ this .javaMethods .put (LocalDate .class .getDeclaredMethod ("getDayOfMonth" ), applySqlFunction ("DAY" ));
112+ this .javaMethods .put (LocalDateTime .class .getDeclaredMethod ("getDayOfWeek" ), applySqlFunction ("DAY" ));
113+ this .javaMethods .put (OffsetDateTime .class .getDeclaredMethod ("getDayOfWeek" ), applySqlFunction ("DAY" ));
114+ this .javaMethods .put (ZonedDateTime .class .getDeclaredMethod ("getDayOfWeek" ), applySqlFunction ("DAY" ));
115+
116+ this .javaMethods .put (LocalDate .class .getDeclaredMethod ("getDayOfYear" ), applySqlFunction ("DAYOFYEAR" ));
117+ this .javaMethods .put (LocalDateTime .class .getDeclaredMethod ("getDayOfYear" ), applySqlFunction ("DAYOFYEAR" ));
118+ this .javaMethods .put (OffsetDateTime .class .getDeclaredMethod ("getDayOfYear" ), applySqlFunction ("DAYOFYEAR" ));
119+ this .javaMethods .put (ZonedDateTime .class .getDeclaredMethod ("getDayOfYear" ), applySqlFunction ("DAYOFYEAR" ));
120+
121+ this .javaMethods .put (LocalDate .class .getDeclaredMethod ("getMonthValue" ), applySqlFunction ("MONTH" ));
122+ this .javaMethods .put (LocalDateTime .class .getDeclaredMethod ("getMonthValue" ), applySqlFunction ("MONTH" ));
123+ this .javaMethods .put (OffsetDateTime .class .getDeclaredMethod ("getMonthValue" ), applySqlFunction ("MONTH" ));
124+ this .javaMethods .put (ZonedDateTime .class .getDeclaredMethod ("getMonthValue" ), applySqlFunction ("MONTH" ));
125+
126+ this .javaMethods .put (LocalDate .class .getDeclaredMethod ("getYear" ), applySqlFunction ("YEAR" ));
127+ this .javaMethods .put (LocalDateTime .class .getDeclaredMethod ("getYear" ), applySqlFunction ("YEAR" ));
128+ this .javaMethods .put (OffsetDateTime .class .getDeclaredMethod ("getYear" ), applySqlFunction ("YEAR" ));
129+ this .javaMethods .put (ZonedDateTime .class .getDeclaredMethod ("getYear" ), applySqlFunction ("YEAR" ));
100130 } catch (NoSuchMethodException e ) {
101131 e .printStackTrace ();
102132 }
@@ -184,7 +214,7 @@ public StringBuilder visit(ConstantExpression e) {
184214 return sb .append ("'" ).append (escapeString (e .getValue ().toString ())).append ("'" );
185215 }
186216
187- return sb .append (e .getValue (). toString () );
217+ return sb .append (e .getValue ());
188218 }
189219
190220 /**
@@ -205,7 +235,7 @@ public StringBuilder visit(InvocationExpression e) {
205235 .map (ConstantExpression .class ::cast )
206236 .collect (Collectors .toList ());
207237 if (!list .isEmpty ()) {
208- arguments .push (list );
238+ this . arguments .push (list );
209239 }
210240 }
211241
@@ -219,7 +249,7 @@ public StringBuilder visit(InvocationExpression e) {
219249 }
220250
221251 if (e .getTarget ().getExpressionType () == ExpressionType .MethodAccess && !e .getArguments ().isEmpty ()) {
222- javaMethodParameter = e .getArguments ().get (0 );
252+ this . javaMethodParameter = e .getArguments ().get (0 );
223253 }
224254
225255 return e .getTarget ().accept (this );
@@ -261,8 +291,9 @@ public StringBuilder visit(MemberExpression e) {
261291 return Expression .binary (operatorMethods .get (e .getMember ()), e .getInstance (), this .javaMethodParameter ).accept (this );
262292 }
263293
264- if (this .complexMethods .containsKey (e .getMember ())) {
265- return sb .append (this .complexMethods .get (e .getMember ()).apply (e .getInstance (), this .javaMethodParameter , false ));
294+ var javaMethodReplacer = this .javaMethods .get (e .getMember ());
295+ if (javaMethodReplacer != null ) {
296+ return sb .append (javaMethodReplacer .apply (e .getInstance (), this .javaMethodParameter , false ));
266297 }
267298
268299 var nameArray = e .getMember ().getName ().replaceAll ("^(get)" , "" ).toCharArray ();
@@ -320,8 +351,8 @@ public StringBuilder visit(UnaryExpression e) {
320351 var memberExpression = (MemberExpression ) invocationExpression .getTarget ();
321352 if (operatorMethods .containsKey (memberExpression .getMember ())) {
322353 return Expression .logicalNot (Expression .binary (operatorMethods .get (memberExpression .getMember ()), memberExpression .getInstance (), invocationExpression .getArguments ().get (0 ))).accept (this );
323- } else if (complexMethods .containsKey (memberExpression .getMember ())) {
324- return sb .append (complexMethods .get (memberExpression .getMember ()).apply (memberExpression .getInstance (), invocationExpression .getArguments ().get (0 ), true ));
354+ } else if (this . javaMethods .containsKey (memberExpression .getMember ())) {
355+ return sb .append (this . javaMethods .get (memberExpression .getMember ()).apply (memberExpression .getInstance (), invocationExpression .getArguments ().get (0 ), true ));
325356 } else {
326357 sb .append ("!" );
327358 }
@@ -348,15 +379,16 @@ private StringBuilder stringContains(Expression string, Expression argument, boo
348379 }
349380
350381 private StringBuilder listContains (Expression list , Expression argument , boolean isNegated ) {
351- List l = (List ) arguments .pop ().get (((ParameterExpression ) list ).getIndex ()).getValue ();
382+ @ SuppressWarnings ("unchecked" )
383+ List <Object > l = (List <Object >) this .arguments .pop ().get (((ParameterExpression ) list ).getIndex ()).getValue ();
352384 var joiner = new StringJoiner (", " , "(" , ")" );
353385 l .forEach (x -> joiner .add (x .toString ()));
354386
355- return argument .accept (new SqlVisitor (this .tableName , this .withBackticks , this .body , this .arguments )).append (isNegated ? " NOT" : "" ).append (" IN " ).append (joiner . toString () );
387+ return argument .accept (new SqlVisitor (this .tableName , this .withBackticks , this .body , this .arguments )).append (isNegated ? " NOT" : "" ).append (" IN " ).append (joiner );
356388 }
357389
358- private StringBuilder applySqlFunction ( Expression date , String field ) {
359- return new StringBuilder ().append (field ).append ("(" ).append (date .accept (new SqlVisitor (this .tableName , this .withBackticks , this .body , this .arguments ))).append (')' );
390+ private TriFunction < Expression , Expression , Boolean , StringBuilder > applySqlFunction ( String field ) {
391+ return ( value , argument , isNegated ) -> new StringBuilder ().append (field ).append ("(" ).append (value .accept (new SqlVisitor (this .tableName , this .withBackticks , this .body , this .arguments ))).append (')' );
360392 }
361393
362394 //endregion
0 commit comments