Skip to content

Commit 43fdf06

Browse files
committed
Make filter and map optional on list value conditions
1 parent 5094422 commit 43fdf06

9 files changed

+72
-52
lines changed

src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java

Lines changed: 50 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -73,26 +73,6 @@ protected <R, S extends AbstractListValueCondition<R>> S mapSupport(Function<? s
7373
}
7474
}
7575

76-
/**
77-
* If not empty, apply the predicate to each value in the list and return a new condition with the filtered values.
78-
* Else returns an empty condition (this).
79-
*
80-
* @param predicate predicate applied to the values, if not empty
81-
*
82-
* @return a new condition with filtered values if renderable, otherwise an empty condition
83-
*/
84-
public abstract AbstractListValueCondition<T> filter(Predicate<? super T> predicate);
85-
86-
/**
87-
* If not empty, apply the mapping to each value in the list return a new condition with the mapped values.
88-
* Else return an empty condition (this).
89-
*
90-
* @param mapper a mapping function to apply to the values, if not empty
91-
* @param <R> type of the new condition
92-
* @return a new condition with mapped values if renderable, otherwise an empty condition
93-
*/
94-
public abstract <R> AbstractListValueCondition<R> map(Function<? super T, ? extends R> mapper);
95-
9676
public abstract String operator();
9777

9878
@Override
@@ -110,4 +90,54 @@ private FragmentAndParameters toFragmentAndParameters(T value, RenderingContext
11090
.withParameter(parameterInfo.parameterMapKey(), leftColumn.convertParameterType(value))
11191
.build();
11292
}
93+
94+
/**
95+
* Conditions may implement Filterable to add optionality to rendering.
96+
*
97+
* <p>If a condition is Filterable, then a user may add a filter to the usage of the condition that makes a decision
98+
* whether to render the condition at runtime. Conditions that fail the filter will be dropped from the
99+
* rendered SQL.
100+
*
101+
* <p>Implementations of Filterable may call
102+
* {@link AbstractListValueCondition#filterSupport(Predicate, Function, AbstractListValueCondition, Supplier)} as
103+
* a common implementation of the filtering algorithm.
104+
*
105+
* @param <T> the Java type related to the database column type
106+
*/
107+
public interface Filterable<T> {
108+
/**
109+
* If renderable and the value matches the predicate, returns this condition. Else returns a condition
110+
* that will not render.
111+
*
112+
* @param predicate predicate applied to the value, if renderable
113+
* @return this condition if renderable and the value matches the predicate, otherwise a condition
114+
* that will not render.
115+
*/
116+
AbstractListValueCondition<T> filter(Predicate<? super T> predicate);
117+
}
118+
119+
/**
120+
* Conditions may implement Mappable to alter condition values or types during rendering.
121+
*
122+
* <p>If a condition is Mappable, then a user may add a mapper to the usage of the condition that can alter the
123+
* values of a condition, or change that datatype.
124+
*
125+
* <p>Implementations of Mappable may call
126+
* {@link AbstractListValueCondition#mapSupport(Function, Function, Supplier)} as
127+
* a common implementation of the mapping algorithm.
128+
*
129+
* @param <T> the Java type related to the database column type
130+
*/
131+
public interface Mappable<T> {
132+
/**
133+
* If renderable, apply the mapping to the value and return a new condition with the new value. Else return a
134+
* condition that will not render (this).
135+
*
136+
* @param mapper a mapping function to apply to the value, if renderable
137+
* @param <R> type of the new condition
138+
* @return a new condition with the result of applying the mapper to the value of this condition,
139+
* if renderable, otherwise a condition that will not render.
140+
*/
141+
<R> AbstractListValueCondition<R> map(Function<? super T, ? extends R> mapper);
142+
}
113143
}

src/main/java/org/mybatis/dynamic/sql/where/condition/IsIn.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
import org.mybatis.dynamic.sql.render.RenderingContext;
2626
import org.mybatis.dynamic.sql.util.Validator;
2727

28-
public class IsIn<T> extends AbstractListValueCondition<T> {
28+
public class IsIn<T> extends AbstractListValueCondition<T>
29+
implements AbstractListValueCondition.Filterable<T>, AbstractListValueCondition.Mappable<T>{
2930
private static final IsIn<?> EMPTY = new IsIn<>(Collections.emptyList());
3031

3132
public static <T> IsIn<T> empty() {
@@ -56,8 +57,7 @@ public IsIn<T> filter(Predicate<? super T> predicate) {
5657

5758
@Override
5859
public <R> IsIn<R> map(Function<? super T, ? extends R> mapper) {
59-
Function<Collection<R>, IsIn<R>> constructor = IsIn::new;
60-
return mapSupport(mapper, constructor, IsIn::empty);
60+
return mapSupport(mapper, IsIn::new, IsIn::empty);
6161
}
6262

6363
@SafeVarargs

src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
import org.mybatis.dynamic.sql.util.Validator;
2828

2929
public class IsInCaseInsensitive<T> extends AbstractListValueCondition<T>
30-
implements CaseInsensitiveRenderableCondition<T> {
30+
implements CaseInsensitiveRenderableCondition<T>, AbstractListValueCondition.Filterable<T>,
31+
AbstractListValueCondition.Mappable<T> {
3132
private static final IsInCaseInsensitive<?> EMPTY = new IsInCaseInsensitive<>(Collections.emptyList());
3233

3334
public static <T> IsInCaseInsensitive<T> empty() {

src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
import org.mybatis.dynamic.sql.AbstractListValueCondition;
2727

2828
public class IsInCaseInsensitiveWhenPresent<T> extends AbstractListValueCondition<T>
29-
implements CaseInsensitiveRenderableCondition<T> {
29+
implements CaseInsensitiveRenderableCondition<T>, AbstractListValueCondition.Filterable<T>,
30+
AbstractListValueCondition.Mappable<T> {
3031
private static final IsInCaseInsensitiveWhenPresent<?> EMPTY =
3132
new IsInCaseInsensitiveWhenPresent<>(Collections.emptyList());
3233

src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
import org.jspecify.annotations.Nullable;
2626
import org.mybatis.dynamic.sql.AbstractListValueCondition;
2727

28-
public class IsInWhenPresent<T> extends AbstractListValueCondition<T> {
28+
public class IsInWhenPresent<T> extends AbstractListValueCondition<T>
29+
implements AbstractListValueCondition.Filterable<T>, AbstractListValueCondition.Mappable<T>{
2930
private static final IsInWhenPresent<?> EMPTY = new IsInWhenPresent<>(Collections.emptyList());
3031

3132
public static <T> IsInWhenPresent<T> empty() {
@@ -48,17 +49,9 @@ public IsInWhenPresent<T> filter(Predicate<? super T> predicate) {
4849
return filterSupport(predicate, IsInWhenPresent::new, this, IsInWhenPresent::empty);
4950
}
5051

51-
/**
52-
* If not empty, apply the mapping to each value in the list return a new condition with the mapped values.
53-
* Else return an empty condition (this).
54-
*
55-
* @param mapper a mapping function to apply to the values, if not empty
56-
* @param <R> type of the new condition
57-
* @return a new condition with mapped values if renderable, otherwise an empty condition
58-
*/
52+
@Override
5953
public <R> IsInWhenPresent<R> map(Function<? super T, ? extends R> mapper) {
60-
Function<Collection<R>, IsInWhenPresent<R>> constructor = IsInWhenPresent::new;
61-
return mapSupport(mapper, constructor, IsInWhenPresent::empty);
54+
return mapSupport(mapper, IsInWhenPresent::new, IsInWhenPresent::empty);
6255
}
6356

6457
@SafeVarargs

src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
import org.mybatis.dynamic.sql.render.RenderingContext;
2626
import org.mybatis.dynamic.sql.util.Validator;
2727

28-
public class IsNotIn<T> extends AbstractListValueCondition<T> {
28+
public class IsNotIn<T> extends AbstractListValueCondition<T>
29+
implements AbstractListValueCondition.Filterable<T>, AbstractListValueCondition.Mappable<T>{
2930
private static final IsNotIn<?> EMPTY = new IsNotIn<>(Collections.emptyList());
3031

3132
public static <T> IsNotIn<T> empty() {
@@ -56,8 +57,7 @@ public IsNotIn<T> filter(Predicate<? super T> predicate) {
5657

5758
@Override
5859
public <R> IsNotIn<R> map(Function<? super T, ? extends R> mapper) {
59-
Function<Collection<R>, IsNotIn<R>> constructor = IsNotIn::new;
60-
return mapSupport(mapper, constructor, IsNotIn::empty);
60+
return mapSupport(mapper, IsNotIn::new, IsNotIn::empty);
6161
}
6262

6363
@SafeVarargs

src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
import org.mybatis.dynamic.sql.util.Validator;
2828

2929
public class IsNotInCaseInsensitive<T> extends AbstractListValueCondition<T>
30-
implements CaseInsensitiveRenderableCondition<T> {
30+
implements CaseInsensitiveRenderableCondition<T>, AbstractListValueCondition.Filterable<T>,
31+
AbstractListValueCondition.Mappable<T> {
3132
private static final IsNotInCaseInsensitive<?> EMPTY = new IsNotInCaseInsensitive<>(Collections.emptyList());
3233

3334
public static <T> IsNotInCaseInsensitive<T> empty() {

src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
import org.mybatis.dynamic.sql.AbstractListValueCondition;
2727

2828
public class IsNotInCaseInsensitiveWhenPresent<T> extends AbstractListValueCondition<T>
29-
implements CaseInsensitiveRenderableCondition<T> {
29+
implements CaseInsensitiveRenderableCondition<T>, AbstractListValueCondition.Filterable<T>,
30+
AbstractListValueCondition.Mappable<T> {
3031
private static final IsNotInCaseInsensitiveWhenPresent<?> EMPTY =
3132
new IsNotInCaseInsensitiveWhenPresent<>(Collections.emptyList());
3233

src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWhenPresent.java

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424

2525
import org.mybatis.dynamic.sql.AbstractListValueCondition;
2626

27-
public class IsNotInWhenPresent<T> extends AbstractListValueCondition<T> {
27+
public class IsNotInWhenPresent<T> extends AbstractListValueCondition<T>
28+
implements AbstractListValueCondition.Filterable<T>, AbstractListValueCondition.Mappable<T>{
2829
private static final IsNotInWhenPresent<?> EMPTY = new IsNotInWhenPresent<>(Collections.emptyList());
2930

3031
public static <T> IsNotInWhenPresent<T> empty() {
@@ -47,17 +48,9 @@ public IsNotInWhenPresent<T> filter(Predicate<? super T> predicate) {
4748
return filterSupport(predicate, IsNotInWhenPresent::new, this, IsNotInWhenPresent::empty);
4849
}
4950

50-
/**
51-
* If not empty, apply the mapping to each value in the list return a new condition with the mapped values.
52-
* Else return an empty condition (this).
53-
*
54-
* @param mapper a mapping function to apply to the values, if not empty
55-
* @param <R> type of the new condition
56-
* @return a new condition with mapped values if renderable, otherwise an empty condition
57-
*/
51+
@Override
5852
public <R> IsNotInWhenPresent<R> map(Function<? super T, ? extends R> mapper) {
59-
Function<Collection<R>, IsNotInWhenPresent<R>> constructor = IsNotInWhenPresent::new;
60-
return mapSupport(mapper, constructor, IsNotInWhenPresent::empty);
53+
return mapSupport(mapper, IsNotInWhenPresent::new, IsNotInWhenPresent::empty);
6154
}
6255

6356
@SafeVarargs

0 commit comments

Comments
 (0)