Skip to content

Commit 9ffa2e8

Browse files
committed
Add Simpler Overloads for Map/Filter on Two Value Conditions
1 parent f3e78fc commit 9ffa2e8

File tree

4 files changed

+109
-5
lines changed

4 files changed

+109
-5
lines changed

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.util.function.BiFunction;
1919
import java.util.function.BiPredicate;
2020
import java.util.function.Function;
21+
import java.util.function.Predicate;
2122
import java.util.function.Supplier;
2223

2324
public abstract class AbstractTwoValueCondition<T>
@@ -52,6 +53,11 @@ protected <S extends AbstractTwoValueCondition<T>> S filterSupport(BiPredicate<?
5253
}
5354
}
5455

56+
protected <S extends AbstractTwoValueCondition<T>> S filterSupport(Predicate<? super T> predicate,
57+
Supplier<S> emptySupplier, S self) {
58+
return filterSupport((v1, v2) -> predicate.test(v1) && predicate.test(v2), emptySupplier, self);
59+
}
60+
5561
protected <R, S extends AbstractTwoValueCondition<R>> S mapSupport(Function<? super T, ? extends R> mapper1,
5662
Function<? super T, ? extends R> mapper2, BiFunction<R, R, S> constructor, Supplier<S> emptySupplier) {
5763
if (shouldRender()) {
@@ -71,5 +77,16 @@ protected <R, S extends AbstractTwoValueCondition<R>> S mapSupport(Function<? su
7177
*/
7278
public abstract AbstractTwoValueCondition<T> filter(BiPredicate<? super T, ? super T> predicate);
7379

80+
/**
81+
* If renderable and both values match the predicate, returns this condition. Else returns a condition
82+
* that will not render. This function implements a short-circuiting test. If the
83+
* first value does not match the predicate, then the second value will not be tested.
84+
*
85+
* @param predicate predicate applied to both values, if renderable
86+
* @return this condition if renderable and the values match the predicate, otherwise a condition
87+
* that will not render.
88+
*/
89+
public abstract AbstractTwoValueCondition<T> filter(Predicate<? super T> predicate);
90+
7491
public abstract String renderCondition(String columnName, String placeholder1, String placeholder2);
7592
}

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

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@
1515
*/
1616
package org.mybatis.dynamic.sql.where.condition;
1717

18+
import java.util.Objects;
1819
import java.util.function.BiPredicate;
1920
import java.util.function.Function;
21+
import java.util.function.Predicate;
2022
import java.util.function.UnaryOperator;
2123

2224
import org.mybatis.dynamic.sql.AbstractTwoValueCondition;
23-
import org.mybatis.dynamic.sql.util.Predicates;
2425

2526
public class IsBetween<T> extends AbstractTwoValueCondition<T> {
2627
private static final IsBetween<?> EMPTY = new IsBetween<Object>(null, null) {
@@ -79,6 +80,11 @@ public IsBetween<T> filter(BiPredicate<? super T, ? super T> predicate) {
7980
return filterSupport(predicate, IsBetween::empty, this);
8081
}
8182

83+
@Override
84+
public IsBetween<T> filter(Predicate<? super T> predicate) {
85+
return filterSupport(predicate, IsBetween::empty, this);
86+
}
87+
8288
/**
8389
* If renderable, apply the mappings to the values and return a new condition with the new values. Else return a
8490
* condition that will not render (this).
@@ -93,6 +99,19 @@ public <R> IsBetween<R> map(Function<? super T, ? extends R> mapper1, Function<?
9399
return mapSupport(mapper1, mapper2, IsBetween::new, IsBetween::empty);
94100
}
95101

102+
/**
103+
* If renderable, apply the mapping to both values and return a new condition with the new values. Else return a
104+
* condition that will not render (this).
105+
*
106+
* @param mapper a mapping function to apply to both values, if renderable
107+
* @param <R> type of the new condition
108+
* @return a new condition with the result of applying the mappers to the values of this condition,
109+
* if renderable, otherwise a condition that will not render.
110+
*/
111+
public <R> IsBetween<R> map(Function<? super T, ? extends R> mapper) {
112+
return map(mapper, mapper);
113+
}
114+
96115
public static <T> Builder<T> isBetween(T value1) {
97116
return new Builder<>(value1);
98117
}
@@ -119,7 +138,7 @@ private WhenPresentBuilder(T value1) {
119138

120139
@Override
121140
protected IsBetween<T> build() {
122-
return new IsBetween<>(value1, value2).filter(Predicates.bothPresent());
141+
return new IsBetween<>(value1, value2).filter(Objects::nonNull);
123142
}
124143
}
125144
}

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

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@
1515
*/
1616
package org.mybatis.dynamic.sql.where.condition;
1717

18+
import java.util.Objects;
1819
import java.util.function.BiPredicate;
1920
import java.util.function.Function;
21+
import java.util.function.Predicate;
2022
import java.util.function.UnaryOperator;
2123

2224
import org.mybatis.dynamic.sql.AbstractTwoValueCondition;
23-
import org.mybatis.dynamic.sql.util.Predicates;
2425

2526
public class IsNotBetween<T> extends AbstractTwoValueCondition<T> {
2627
private static final IsNotBetween<?> EMPTY = new IsNotBetween<Object>(null, null) {
@@ -79,6 +80,11 @@ public IsNotBetween<T> filter(BiPredicate<? super T, ? super T> predicate) {
7980
return filterSupport(predicate, IsNotBetween::empty, this);
8081
}
8182

83+
@Override
84+
public IsNotBetween<T> filter(Predicate<? super T> predicate) {
85+
return filterSupport(predicate, IsNotBetween::empty, this);
86+
}
87+
8288
/**
8389
* If renderable, apply the mappings to the values and return a new condition with the new values. Else return a
8490
* condition that will not render (this).
@@ -90,10 +96,23 @@ public IsNotBetween<T> filter(BiPredicate<? super T, ? super T> predicate) {
9096
* if renderable, otherwise a condition that will not render.
9197
*/
9298
public <R> IsNotBetween<R> map(Function<? super T, ? extends R> mapper1,
93-
Function<? super T, ? extends R> mapper2) {
99+
Function<? super T, ? extends R> mapper2) {
94100
return mapSupport(mapper1, mapper2, IsNotBetween::new, IsNotBetween::empty);
95101
}
96102

103+
/**
104+
* If renderable, apply the mapping to both values and return a new condition with the new values. Else return a
105+
* condition that will not render (this).
106+
*
107+
* @param mapper a mapping function to apply to both values, if renderable
108+
* @param <R> type of the new condition
109+
* @return a new condition with the result of applying the mappers to the values of this condition,
110+
* if renderable, otherwise a condition that will not render.
111+
*/
112+
public <R> IsNotBetween<R> map(Function<? super T, ? extends R> mapper) {
113+
return map(mapper, mapper);
114+
}
115+
97116
public static <T> Builder<T> isNotBetween(T value1) {
98117
return new Builder<>(value1);
99118
}
@@ -122,7 +141,7 @@ private WhenPresentBuilder(T value1) {
122141

123142
@Override
124143
protected IsNotBetween<T> build() {
125-
return new IsNotBetween<>(value1, value2).filter(Predicates.bothPresent());
144+
return new IsNotBetween<>(value1, value2).filter(Objects::nonNull);
126145
}
127146
}
128147
}

src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,11 +510,60 @@ void testBetweenUnRenderableFilterShouldReturnSameObject() {
510510
assertThat(cond).isSameAs(filtered);
511511
}
512512

513+
@Test
514+
void testBetweenUnRenderableFirstNullFilterShouldReturnSameObject() {
515+
IsBetween<Integer> cond = SqlBuilder.isBetween((Integer) null).and(4).filter(Objects::nonNull);
516+
assertThat(cond.shouldRender()).isFalse();
517+
IsBetween<Integer> filtered = cond.filter(v -> true);
518+
assertThat(cond).isSameAs(filtered);
519+
}
520+
521+
@Test
522+
void testBetweenUnRenderableSecondNullFilterShouldReturnSameObject() {
523+
IsBetween<Integer> cond = SqlBuilder.isBetween(3).and((Integer) null).filter(Objects::nonNull);
524+
assertThat(cond.shouldRender()).isFalse();
525+
IsBetween<Integer> filtered = cond.filter(v -> true);
526+
assertThat(cond).isSameAs(filtered);
527+
}
528+
529+
@Test
530+
void testBetweenMapWithSingleMapper() {
531+
IsBetween<Integer> cond = SqlBuilder.isBetween("3").and("4").map(Integer::parseInt);
532+
assertThat(cond.shouldRender()).isTrue();
533+
assertThat(cond.value1()).isEqualTo(3);
534+
assertThat(cond.value2()).isEqualTo(4);
535+
}
536+
513537
@Test
514538
void testNotBetweenUnRenderableFilterShouldReturnSameObject() {
515539
IsNotBetween<Integer> cond = SqlBuilder.isNotBetween(3).and(4).filter((i1, i2) -> false);
516540
assertThat(cond.shouldRender()).isFalse();
517541
IsNotBetween<Integer> filtered = cond.filter((v1, v2) -> true);
518542
assertThat(cond).isSameAs(filtered);
519543
}
544+
545+
@Test
546+
void testNotBetweenUnRenderableFirstNullFilterShouldReturnSameObject() {
547+
IsNotBetween<Integer> cond = SqlBuilder.isNotBetween((Integer) null).and(4).filter(Objects::nonNull);
548+
assertThat(cond.shouldRender()).isFalse();
549+
IsNotBetween<Integer> filtered = cond.filter(v -> true);
550+
assertThat(cond).isSameAs(filtered);
551+
}
552+
553+
@Test
554+
void testNotBetweenUnRenderableSecondNullFilterShouldReturnSameObject() {
555+
IsNotBetween<Integer> cond = SqlBuilder.isNotBetween(3).and((Integer) null).filter(Objects::nonNull);
556+
assertThat(cond.shouldRender()).isFalse();
557+
IsNotBetween<Integer> filtered = cond.filter(v -> true);
558+
assertThat(cond).isSameAs(filtered);
559+
}
560+
561+
@Test
562+
void testNotBetweenMapWithSingleMapper() {
563+
IsNotBetween<Integer> cond = SqlBuilder.isNotBetween("3").and("4").map(Integer::parseInt);
564+
assertThat(cond.shouldRender()).isTrue();
565+
assertThat(cond.value1()).isEqualTo(3);
566+
assertThat(cond.value2()).isEqualTo(4);
567+
}
568+
520569
}

0 commit comments

Comments
 (0)