Skip to content

Commit

Permalink
Introduce Expressions.binaryCall() factory method
Browse files Browse the repository at this point in the history
  • Loading branch information
asereda-gs committed May 6, 2020
1 parent fb98841 commit 3427fa2
Show file tree
Hide file tree
Showing 11 changed files with 39 additions and 32 deletions.
Expand Up @@ -97,9 +97,16 @@ public static Call not(Expression call) {
}

public static Call unaryCall(Operator operator, Expression arg) {
Objects.requireNonNull(arg, "arg");
return call(operator, ImmutableSet.of(arg));
}

public static Call binaryCall(final Operator operator, Expression left, Expression right) {
Objects.requireNonNull(left, "left");
Objects.requireNonNull(right, "right");
return call(operator, ImmutableList.of(left, right));
}

public static Call call(final Operator operator, Expression ... operands) {
return call(operator, ImmutableList.copyOf(operands));
}
Expand Down
Expand Up @@ -35,7 +35,7 @@ default R isFalse() {
}

default R is(boolean value) {
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.call(Operators.EQUAL, e, Expressions.constant(value)));
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.binaryCall(Operators.EQUAL, e, Expressions.constant(value)));
}

/**
Expand Down
Expand Up @@ -97,7 +97,7 @@ static Call combineAndSimplify(Operator operator, Expression leftExpr, Expressio
Objects.requireNonNull(operator, "operator");
if (!(leftExpr instanceof Call && rightExpr instanceof Call)) {
// regular call which can't be simplified
return Expressions.call(operator, leftExpr, rightExpr);
return Expressions.binaryCall(operator, leftExpr, rightExpr);
}

Call left = (Call) leftExpr;
Expand All @@ -110,7 +110,7 @@ static Call combineAndSimplify(Operator operator, Expression leftExpr, Expressio
return Expressions.call(operator, args);
}

return Expressions.call(operator, left, right);
return Expressions.binaryCall(operator, left, right);
}

// combine expressions with same operator (AND / OR) into single expression
Expand Down
Expand Up @@ -37,7 +37,7 @@ public interface ComparableMatcher<R, V extends Comparable<? super V>> extends O
*/
default R lessThan(V upper) {
Objects.requireNonNull(upper, "upper");
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.call(ComparableOperators.LESS_THAN, e, Expressions.constant(upper)));
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.binaryCall(ComparableOperators.LESS_THAN, e, Expressions.constant(upper)));
}

/**
Expand All @@ -46,23 +46,23 @@ default R lessThan(V upper) {
*/
default R greaterThan(V lower) {
Objects.requireNonNull(lower, "lower");
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.call(ComparableOperators.GREATER_THAN, e, Expressions.constant(lower)));
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.binaryCall(ComparableOperators.GREATER_THAN, e, Expressions.constant(lower)));
}

/**
* Checks that attribute is less than or equal to {@code upperInclusive} (equivalent to {@code $this <= upperInclusive}).
*/
default R atMost(V upperInclusive) {
Objects.requireNonNull(upperInclusive, "upperInclusive");
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.call(ComparableOperators.LESS_THAN_OR_EQUAL, e, Expressions.constant(upperInclusive)));
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.binaryCall(ComparableOperators.LESS_THAN_OR_EQUAL, e, Expressions.constant(upperInclusive)));
}

/**
* Checks that attribute is greater or equal to {@code lowerInclusive} (equivalent to {@code $this >= lowerInclusive}).
*/
default R atLeast(V lowerInclusive) {
Objects.requireNonNull(lowerInclusive, "lowerInclusive");
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.call(ComparableOperators.GREATER_THAN_OR_EQUAL, e, Expressions.constant(lowerInclusive)));
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.binaryCall(ComparableOperators.GREATER_THAN_OR_EQUAL, e, Expressions.constant(lowerInclusive)));
}

/**
Expand All @@ -75,8 +75,8 @@ default R between(V lowerInclusive, V upperInclusive) {
Objects.requireNonNull(lowerInclusive, "lowerInclusive");
Objects.requireNonNull(upperInclusive, "upperInclusive");
final UnaryOperator<Expression> unary = expr -> {
final Call lower = Expressions.call(ComparableOperators.GREATER_THAN_OR_EQUAL, expr, Expressions.constant(lowerInclusive));
final Call upper = Expressions.call(ComparableOperators.LESS_THAN_OR_EQUAL, expr, Expressions.constant(upperInclusive));
final Call lower = Expressions.binaryCall(ComparableOperators.GREATER_THAN_OR_EQUAL, expr, Expressions.constant(lowerInclusive));
final Call upper = Expressions.binaryCall(ComparableOperators.LESS_THAN_OR_EQUAL, expr, Expressions.constant(upperInclusive));
return Expressions.and(lower, upper);
};

Expand Down
Expand Up @@ -29,25 +29,25 @@
public interface IterableMatcher<R, S, V> extends Matcher {

default R contains(V value) {
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.call(IterableOperators.CONTAINS, e, Expressions.constant(value)));
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.binaryCall(IterableOperators.CONTAINS, e, Expressions.constant(value)));
}

/**
* Match iterable attribute to be empty (equivalent to {@code iterable.size() == 0})
*/
default R isEmpty() {
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.call(IterableOperators.IS_EMPTY, e));
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.unaryCall(IterableOperators.IS_EMPTY, e));
}

/**
* Match iterable attribute to be NOT empty (equivalent to {@code iterable.size() > 0})
*/
default R notEmpty() {
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.call(IterableOperators.NOT_EMPTY, e));
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.unaryCall(IterableOperators.NOT_EMPTY, e));
}

default R hasSize(int size) {
UnaryOperator<Expression> expr = e -> Expressions.call(IterableOperators.HAS_SIZE, e, Expressions.constant(size));
UnaryOperator<Expression> expr = e -> Expressions.binaryCall(IterableOperators.HAS_SIZE, e, Expressions.constant(size));
return Matchers.extract(this).applyAndCreateRoot(expr);

}
Expand Down
Expand Up @@ -40,7 +40,7 @@ public interface ObjectMatcher<R, V> extends Matcher {
*/
default R is(V value) {
Objects.requireNonNull(value,"value");
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.call(Operators.EQUAL, e, Expressions.constant(value)));
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.binaryCall(Operators.EQUAL, e, Expressions.constant(value)));
}

/**
Expand All @@ -49,7 +49,7 @@ default R is(V value) {
*/
default R isNot(V value) {
Objects.requireNonNull(value,"value");
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.call(Operators.NOT_EQUAL, e, Expressions.constant(value)));
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.binaryCall(Operators.NOT_EQUAL, e, Expressions.constant(value)));
}

default R in(V v1, V v2, V ... rest) {
Expand All @@ -75,12 +75,12 @@ default R notIn(V v1, V v2, V ... rest) {
*/
default R in(Iterable<? extends V> values) {
Objects.requireNonNull(values, "values");
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.call(Operators.IN, e, Expressions.constant(ImmutableList.copyOf(values))));
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.binaryCall(Operators.IN, e, Expressions.constant(ImmutableList.copyOf(values))));
}

default R notIn(Iterable<? extends V> values) {
Objects.requireNonNull(values, "values");
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.call(Operators.NOT_IN, e, Expressions.constant(ImmutableList.copyOf(values))));
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.binaryCall(Operators.NOT_IN, e, Expressions.constant(ImmutableList.copyOf(values))));
}

/**
Expand Down
Expand Up @@ -29,12 +29,12 @@
public interface PresentAbsentMatcher<R> extends Matcher {

default R isPresent() {
final UnaryOperator<Expression> expr = e -> Expressions.call(OptionalOperators.IS_PRESENT, e);
final UnaryOperator<Expression> expr = e -> Expressions.unaryCall(OptionalOperators.IS_PRESENT, e);
return Matchers.extract(this).applyAndCreateRoot(expr);
}

default R isAbsent() {
final UnaryOperator<Expression> expr = e -> Expressions.call(OptionalOperators.IS_ABSENT, e);
final UnaryOperator<Expression> expr = e -> Expressions.unaryCall(OptionalOperators.IS_ABSENT, e);
return Matchers.extract(this).applyAndCreateRoot(expr);
}
}
Expand Up @@ -46,38 +46,38 @@ default R notEmpty() {
* Apply upper case function to current expression (equivalent to {@code $this.toUpperCase()})
*/
default StringMatcher<R> toUpperCase() {
return Matchers.extract(this).applyRaw(e -> Expressions.call(StringOperators.TO_UPPER_CASE, e)).create();
return Matchers.extract(this).applyRaw(e -> Expressions.unaryCall(StringOperators.TO_UPPER_CASE, e)).create();
}

/**
* Apply lower case function to current expression (equivalent to {@code $this.toLowerCase()})
*/
default StringMatcher<R> toLowerCase() {
return Matchers.extract(this).applyRaw(e -> Expressions.call(StringOperators.TO_LOWER_CASE, e)).create();
return Matchers.extract(this).applyRaw(e -> Expressions.unaryCall(StringOperators.TO_LOWER_CASE, e)).create();
}

/**
* Check that attribute contains {@code other}
*/
default R contains(CharSequence other) {
Objects.requireNonNull(other, "other");
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.call(StringOperators.CONTAINS, e, Expressions.constant(other.toString())));
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.binaryCall(StringOperators.CONTAINS, e, Expressions.constant(other.toString())));
}

/**
* Check that string attribute starts with {@code prefix} prefix
*/
default R startsWith(CharSequence prefix) {
Objects.requireNonNull(prefix, "prefix");
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.call(StringOperators.STARTS_WITH, e, Expressions.constant(prefix.toString())));
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.binaryCall(StringOperators.STARTS_WITH, e, Expressions.constant(prefix.toString())));
}

/**
* Check that string attribute ends with {@code suffix} suffix
*/
default R endsWith(CharSequence suffix) {
Objects.requireNonNull(suffix, "suffix");
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.call(StringOperators.ENDS_WITH, e, Expressions.constant(suffix.toString())));
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.binaryCall(StringOperators.ENDS_WITH, e, Expressions.constant(suffix.toString())));
}

/**
Expand All @@ -86,14 +86,14 @@ default R endsWith(CharSequence suffix) {
*/
default R matches(Pattern regex) {
Objects.requireNonNull(regex, "regexp");
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.call(StringOperators.MATCHES, e, Expressions.constant(regex)));
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.binaryCall(StringOperators.MATCHES, e, Expressions.constant(regex)));
}

/**
* Predicate for length of a string
*/
default R hasLength(int length) {
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.call(StringOperators.HAS_LENGTH, e, Expressions.constant(length)));
return Matchers.extract(this).applyAndCreateRoot(e -> Expressions.binaryCall(StringOperators.HAS_LENGTH, e, Expressions.constant(length)));
}

/**
Expand Down
Expand Up @@ -70,12 +70,12 @@ void call() throws Exception {
Path id1 = Path.ofMember(Person.class.getDeclaredMethod("id"));
Path id2 = Path.ofMember(Person.class.getDeclaredMethod("id"));

Expression e1 = Expressions.call(Operators.EQUAL, id1, Expressions.constant("1"));
Expression e2 = Expressions.call(Operators.EQUAL, id2, Expressions.constant("1"));
Expression e3 = Expressions.call(Operators.EQUAL, id1, Expressions.constant("2"));
Expression e1 = Expressions.binaryCall(Operators.EQUAL, id1, Expressions.constant("1"));
Expression e2 = Expressions.binaryCall(Operators.EQUAL, id2, Expressions.constant("1"));
Expression e3 = Expressions.binaryCall(Operators.EQUAL, id1, Expressions.constant("2"));

Path fullName = Path.ofMember(Person.class.getDeclaredMethod("fullName"));
Expression e4 = Expressions.call(Operators.EQUAL, fullName, Expressions.constant("1"));
Expression e4 = Expressions.binaryCall(Operators.EQUAL, fullName, Expressions.constant("1"));

new EqualsTester()
.addEqualityGroup(e1, e2)
Expand Down
Expand Up @@ -114,7 +114,7 @@ void pathNaming() {

check(generator.withoutBindVariables().generate(Query.of(Person.class)
.addProjections(type, value)
.withFilter(Expressions.call(Operators.EQUAL, select, Expressions.constant(42))))
.withFilter(Expressions.binaryCall(Operators.EQUAL, select, Expressions.constant(42))))
.oql()).is("SELECT type1, value1 FROM /myRegion WHERE select1 = 42");

check(generator.generate(Query.of(Person.class).addProjections(type, value).addGroupBy(type))
Expand Down
Expand Up @@ -146,7 +146,7 @@ private Bson binaryCall(Call call) {
if (values.size() == 1) {
// optimization: convert IN, NIN (where argument is a list with single element) into EQ / NE
Operators newOperator = op == Operators.IN ? Operators.EQUAL : Operators.NOT_EQUAL;
Call newCall = Expressions.call(newOperator, left, Expressions.constant(values.iterator().next()));
Call newCall = Expressions.binaryCall(newOperator, left, Expressions.constant(values.iterator().next()));
return binaryCall(newCall);
}
return op == Operators.IN ? Filters.in(field, values) : Filters.nin(field, values);
Expand Down

0 comments on commit 3427fa2

Please sign in to comment.