diff --git a/src/main/java/com/avaje/ebean/ExpressionFactory.java b/src/main/java/com/avaje/ebean/ExpressionFactory.java index 72b07e117..6fcd5a590 100644 --- a/src/main/java/com/avaje/ebean/ExpressionFactory.java +++ b/src/main/java/com/avaje/ebean/ExpressionFactory.java @@ -76,6 +76,11 @@ public interface ExpressionFactory { */ Expression jsonLessOrEqualTo(String propertyName, String path, Object val); + /** + * Between - for the given path in a JSON document. + */ + Expression jsonBetween(String propertyName, String path, Object lowerValue, Object upperValue); + /** * Equal To - property equal to the given value. */ diff --git a/src/main/java/com/avaje/ebean/ExpressionList.java b/src/main/java/com/avaje/ebean/ExpressionList.java index 9209ccad8..6b3f16199 100644 --- a/src/main/java/com/avaje/ebean/ExpressionList.java +++ b/src/main/java/com/avaje/ebean/ExpressionList.java @@ -447,6 +447,17 @@ public interface ExpressionList extends Serializable { */ ExpressionList jsonLessOrEqualTo(String propertyName, String path, Object value); + /** + * Between - for the given path in a JSON document. + * + *
{@code
+   *
+   *   where().jsonBetween("content", "orderDate", lowerDateTime, upperDateTime)
+   *
+   * }
+ */ + ExpressionList jsonBetween(String propertyName, String path, Object lowerValue, Object upperValue); + /** * Add an Expression to the list. *

diff --git a/src/main/java/com/avaje/ebeaninternal/server/expression/DefaultExpressionFactory.java b/src/main/java/com/avaje/ebeaninternal/server/expression/DefaultExpressionFactory.java index c66eb28df..a85c62cf5 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/expression/DefaultExpressionFactory.java +++ b/src/main/java/com/avaje/ebeaninternal/server/expression/DefaultExpressionFactory.java @@ -68,6 +68,10 @@ public class DefaultExpressionFactory implements SpiExpressionFactory { return new JsonPathExpression(propertyName, path, Op.LT_EQ, val); } + public Expression jsonBetween(String propertyName, String path, Object lowerValue, Object upperValue) { + return new JsonPathExpression(propertyName, path, lowerValue, upperValue); + } + /** * Equal To - property equal to the given value. */ diff --git a/src/main/java/com/avaje/ebeaninternal/server/expression/JsonPathExpression.java b/src/main/java/com/avaje/ebeaninternal/server/expression/JsonPathExpression.java index 5f3244c0b..03cff50af 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/expression/JsonPathExpression.java +++ b/src/main/java/com/avaje/ebeaninternal/server/expression/JsonPathExpression.java @@ -30,11 +30,31 @@ class JsonPathExpression extends AbstractExpression { */ protected final Object value; + /** + * For Between this is the upper bind value. + */ + protected final Object upperValue; + + /** + * Construct for Operator (not BETWEEN though). + */ JsonPathExpression(String propertyName, String path, Op operator, Object value) { super(propertyName); this.path = path; this.operator = operator; this.value = value; + this.upperValue = null; + } + + /** + * Construct for BETWEEN expression. + */ + JsonPathExpression(String propertyName, String path, Object value, Object upperValue) { + super(propertyName); + this.path = path; + this.operator = Op.BETWEEN; + this.value = value; + this.upperValue = upperValue; } @Override @@ -49,7 +69,9 @@ class JsonPathExpression extends AbstractExpression { @Override public int queryBindHash() { - return (value == null) ? 0 : value.hashCode(); + int hc = (value == null) ? 0 : value.hashCode(); + hc = (upperValue == null) ? hc : hc * 31 + upperValue.hashCode(); + return hc; } @Override @@ -63,7 +85,12 @@ class JsonPathExpression extends AbstractExpression { public void addBindValues(SpiExpressionRequest request) { if (value != null) { + // value is null for EXISTS/NOT EXISTS request.addBindValue(value); } + if (upperValue != null) { + // upperValue only for BETWEEN operator + request.addBindValue(upperValue); + } } } diff --git a/src/main/java/com/avaje/ebeaninternal/server/expression/JunctionExpression.java b/src/main/java/com/avaje/ebeaninternal/server/expression/JunctionExpression.java index 71fdae0be..845b4aba2 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/expression/JunctionExpression.java +++ b/src/main/java/com/avaje/ebeaninternal/server/expression/JunctionExpression.java @@ -377,6 +377,14 @@ abstract class JunctionExpression implements Junction, SpiExpression, Expr return exprList.jsonLessOrEqualTo(propertyName, path, val); } + /** + * Between - for the given path in a JSON document. + */ + @Override + public ExpressionList jsonBetween(String propertyName, String path, Object lowerValue, Object upperValue){ + return exprList.jsonBetween(propertyName, path, lowerValue, upperValue); + } + @Override public ExpressionList ge(String propertyName, Object value) { return exprList.ge(propertyName, value); diff --git a/src/main/java/com/avaje/ebeaninternal/server/expression/Op.java b/src/main/java/com/avaje/ebeaninternal/server/expression/Op.java index bb41a1191..77d06c557 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/expression/Op.java +++ b/src/main/java/com/avaje/ebeaninternal/server/expression/Op.java @@ -15,6 +15,11 @@ public enum Op { */ NOT_EXISTS(" is null "), + /** + * Between (JSON). + */ + BETWEEN(" between ? and ? "), + /** * Equal to */ diff --git a/src/main/java/com/avaje/ebeaninternal/util/DefaultExpressionList.java b/src/main/java/com/avaje/ebeaninternal/util/DefaultExpressionList.java index f59733a0a..9474f6001 100644 --- a/src/main/java/com/avaje/ebeaninternal/util/DefaultExpressionList.java +++ b/src/main/java/com/avaje/ebeaninternal/util/DefaultExpressionList.java @@ -435,6 +435,15 @@ public class DefaultExpressionList implements SpiExpressionList { return this; } + /** + * Between - for the given path in a JSON document. + */ + @Override + public ExpressionList jsonBetween(String propertyName, String path, Object lowerValue, Object upperValue){ + add(expr.jsonBetween(propertyName, path, lowerValue, upperValue)); + return this; + } + @Override public ExpressionList eq(String propertyName, Object value) { add(expr.eq(propertyName, value));