Skip to content

Commit

Permalink
feat: 增加isnull,notnull,all_match,any_match函数 (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
zhou-hao authored Nov 29, 2023
1 parent 6769cef commit 9aa019a
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import org.jetlinks.reactor.ql.ReactorQLMetadata;
import org.jetlinks.reactor.ql.ReactorQLRecord;
import org.jetlinks.reactor.ql.feature.Feature;
import org.jetlinks.reactor.ql.feature.FeatureId;
import org.jetlinks.reactor.ql.supports.agg.CollectListAggFeature;
Expand Down Expand Up @@ -240,6 +241,13 @@ static <T> void createCalculator(BiFunction<String, BiFunction<Number, Number, O

})));

addGlobal(new FunctionMapFeature("isnull", 9999, 1, stream -> BooleanUtils.not(stream.hasElements())));
addGlobal(new FunctionMapFeature("notnull", 9999, 1, Flux::hasElements));

addGlobal(new FunctionMapFeature("all_match", 9999, 1, stream -> stream.all(CastUtils::castBoolean))
.defaultValue(Boolean.FALSE));
addGlobal(new FunctionMapFeature("any_match", 9999, 1, stream -> stream.any(CastUtils::castBoolean)));

{
BiFunction<Flux<Object>, BiFunction<Collection<Object>, Flux<Object>, Publisher<?>>, Flux<?>> containsHandler =
(stream, handler) -> CastUtils
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.jetlinks.reactor.ql.feature.ValueMapFeature;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.function.Function;
Expand All @@ -18,15 +19,18 @@ public class FunctionMapFeature implements ValueMapFeature {
int maxParamSize;
int minParamSize;

public Function<Flux<Object>, Publisher<?>> mapper;
public Function<Flux<Object>, Publisher<Object>> mapper;

@Getter
private final String id;

private Object defaultValue;

@SuppressWarnings("all")
public FunctionMapFeature(String function, int max, int min, Function<Flux<Object>, Publisher<?>> mapper) {
this.maxParamSize = max;
this.minParamSize = min;
this.mapper = mapper;
this.mapper = (Function) mapper;
this.id = FeatureId.ValueMap.of(function).getId();
}

Expand All @@ -46,10 +50,29 @@ public Function<ReactorQLRecord, Publisher<?>> createMapper(Expression expressio
if (parameters.size() > maxParamSize || parameters.size() < minParamSize) {
throw new UnsupportedOperationException("函数[" + expression + "]参数数量错误");
}
List<Function<ReactorQLRecord, Publisher<?>>> mappers = parameters.stream()
@SuppressWarnings("all")
List<Function<ReactorQLRecord, Publisher<Object>>> mappers = (List) parameters
.stream()
.map(expr -> ValueMapFeature.createMapperNow(expr, metadata))
.collect(Collectors.toList());

return v -> mapper.apply(Flux.fromIterable(mappers).flatMap(mp->mp.apply(v)));
return v -> apply(v, mappers);
}

public FunctionMapFeature defaultValue(Object defaultValue){
this.defaultValue = defaultValue;
return this;
}

protected Publisher<Object> apply(ReactorQLRecord record,
List<Function<ReactorQLRecord, Publisher<Object>>> mappers) {
return mapper.apply(Flux.fromIterable(mappers).flatMap(mp -> {
if (defaultValue != null) {
return Mono
.from(mp.apply(record))
.defaultIfEmpty(defaultValue);
}
return mp.apply(record);
}));
}
}
68 changes: 68 additions & 0 deletions src/test/java/org/jetlinks/reactor/ql/ReactorQLTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1755,4 +1755,72 @@ void testStr() {

}

@Test
void testNullFunction(){
ReactorQL.builder()
.sql("select isnull(this.name) nameNull from dual")
.build()
.start(Flux.just(Collections.emptyMap()))
.as(StepVerifier::create)
.expectNext(Collections.singletonMap("nameNull", true))
.verifyComplete();

ReactorQL.builder()
.sql("select notnull(this.name) nameNotnull from dual")
.build()
.start(Flux.just(Collections.singletonMap("name",1)))
.as(StepVerifier::create)
.expectNext(Collections.singletonMap("nameNotnull", true))
.verifyComplete();
}

@Test
void testAllMatch(){
ReactorQL.builder()
.sql("select all_match(1,this.bool) allMatch from dual")
.build()
.start(Flux.just(Collections.emptyMap()))
.as(StepVerifier::create)
.expectNext(Collections.singletonMap("allMatch", false))
.verifyComplete();

ReactorQL.builder()
.sql("select all_match(1,this.bool) allMatch from dual")
.build()
.start(Flux.just(Collections.singletonMap("bool",true)))
.as(StepVerifier::create)
.expectNext(Collections.singletonMap("allMatch", true))
.verifyComplete();

}

@Test
void testAnyMatch(){

ReactorQL.builder()
.sql("select any_match(this.bool) anyMatch from dual")
.build()
.start(Flux.just(Collections.emptyMap()))
.as(StepVerifier::create)
.expectNext(Collections.singletonMap("anyMatch", false))
.verifyComplete();

ReactorQL.builder()
.sql("select any_match(this.bool,1) anyMatch from dual")
.build()
.start(Flux.just(Collections.emptyMap()))
.as(StepVerifier::create)
.expectNext(Collections.singletonMap("anyMatch", true))
.verifyComplete();

ReactorQL.builder()
.sql("select any_match(0,this.bool) anyMatch from dual")
.build()
.start(Flux.just(Collections.singletonMap("bool",false)))
.as(StepVerifier::create)
.expectNext(Collections.singletonMap("anyMatch", false))
.verifyComplete();

}

}

0 comments on commit 9aa019a

Please sign in to comment.