mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-11-09 08:42:18 +00:00
#417 - ENH: Add JSON expressions ... path exists and value at path equals value
This commit is contained in:
1 parent
054f7dc86f
commit
5726410f6f
18 files changed
+584
-33
No files matched your search
@@ -36,6 +36,46 @@ import java.util.Map;
|
||||
*/
|
||||
public interface ExpressionFactory {
|
||||
|
||||
/**
|
||||
* Path exists - for the given path in a JSON document.
|
||||
*/
|
||||
Expression jsonExists(String propertyName, String path);
|
||||
|
||||
/**
|
||||
* Path does not exist - for the given path in a JSON document.
|
||||
*/
|
||||
Expression jsonNotExists(String propertyName, String path);
|
||||
|
||||
/**
|
||||
* Equal to - for the given path in a JSON document.
|
||||
*/
|
||||
Expression jsonEqualTo(String propertyName, String path, Object val);
|
||||
|
||||
/**
|
||||
* Not Equal to - for the given path in a JSON document.
|
||||
*/
|
||||
Expression jsonNotEqualTo(String propertyName, String path, Object val);
|
||||
|
||||
/**
|
||||
* Greater than - for the given path in a JSON document.
|
||||
*/
|
||||
Expression jsonGreaterThan(String propertyName, String path, Object val);
|
||||
|
||||
/**
|
||||
* Greater than or equal to - for the given path in a JSON document.
|
||||
*/
|
||||
Expression jsonGreaterOrEqual(String propertyName, String path, Object val);
|
||||
|
||||
/**
|
||||
* Less than - for the given path in a JSON document.
|
||||
*/
|
||||
Expression jsonLessThan(String propertyName, String path, Object val);
|
||||
|
||||
/**
|
||||
* Less than or equal to - for the given path in a JSON document.
|
||||
*/
|
||||
Expression jsonLessOrEqualTo(String propertyName, String path, Object val);
|
||||
|
||||
/**
|
||||
* Equal To - property equal to the given value.
|
||||
*/
|
||||
|
||||
@@ -345,12 +345,66 @@ public interface ExpressionList<T> extends Serializable {
|
||||
*/
|
||||
ExpressionList<T> where();
|
||||
|
||||
/**
|
||||
* Path exists - for the given path in a JSON document.
|
||||
*
|
||||
* @param propertyName the property that holds a JSON document
|
||||
* @param path the nested path in the JSON document in dot notation
|
||||
*/
|
||||
ExpressionList<T> jsonExists(String propertyName, String path);
|
||||
|
||||
/**
|
||||
* Path does not exist - for the given path in a JSON document.
|
||||
*
|
||||
* @param propertyName the property that holds a JSON document
|
||||
* @param path the nested path in the JSON document in dot notation
|
||||
*/
|
||||
ExpressionList<T> jsonNotExists(String propertyName, String path);
|
||||
|
||||
/**
|
||||
* Equal to expression for the value at the given path in the JSON document.
|
||||
*
|
||||
* @param propertyName the property that holds a JSON document
|
||||
* @param path the nested path in the JSON document in dot notation
|
||||
* @param value the value used to test equality against the document path's value
|
||||
*/
|
||||
ExpressionList<T> jsonEqualTo(String propertyName, String path, Object value);
|
||||
|
||||
/**
|
||||
* Not Equal to - for the given path in a JSON document.
|
||||
*
|
||||
* @param propertyName the property that holds a JSON document
|
||||
* @param path the nested path in the JSON document in dot notation
|
||||
* @param value the value used to test equality against the document path's value
|
||||
*/
|
||||
ExpressionList<T> jsonNotEqualTo(String propertyName, String path, Object value);
|
||||
|
||||
/**
|
||||
* Greater than - for the given path in a JSON document.
|
||||
*/
|
||||
ExpressionList<T> jsonGreaterThan(String propertyName, String path, Object val);
|
||||
|
||||
/**
|
||||
* Greater than or equal to - for the given path in a JSON document.
|
||||
*/
|
||||
ExpressionList<T> jsonGreaterOrEqual(String propertyName, String path, Object val);
|
||||
|
||||
/**
|
||||
* Less than - for the given path in a JSON document.
|
||||
*/
|
||||
ExpressionList<T> jsonLessThan(String propertyName, String path, Object val);
|
||||
|
||||
/**
|
||||
* Less than or equal to - for the given path in a JSON document.
|
||||
*/
|
||||
ExpressionList<T> jsonLessOrEqualTo(String propertyName, String path, Object val);
|
||||
|
||||
/**
|
||||
* Add an Expression to the list.
|
||||
* <p>
|
||||
* This returns the list so that add() can be chained.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* Query<Customer> query = Ebean.find(Customer.class);
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.avaje.ebeaninternal.api;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.avaje.ebeaninternal.server.core.JsonExpressionHandler;
|
||||
import com.avaje.ebeaninternal.server.core.SpiOrmQueryRequest;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
|
||||
@@ -10,6 +11,11 @@ import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
*/
|
||||
public interface SpiExpressionRequest {
|
||||
|
||||
/**
|
||||
* Return the DB specific JSON expression handler.
|
||||
*/
|
||||
JsonExpressionHandler getJsonHander();
|
||||
|
||||
/**
|
||||
* Parse the logical property name to the deployment name.
|
||||
*/
|
||||
|
||||
@@ -209,11 +209,29 @@ public class InternalConfiguration {
|
||||
* For 'As Of' queries return the number of bind variables per predicate.
|
||||
*/
|
||||
private Binder getBinder(TypeManager typeManager, DatabasePlatform databasePlatform) {
|
||||
|
||||
JsonExpressionHandler jsonHandler = getJsonExpressionHandler(databasePlatform);
|
||||
|
||||
DbHistorySupport historySupport = databasePlatform.getHistorySupport();
|
||||
if (historySupport == null) {
|
||||
return new Binder(typeManager, 0, false);
|
||||
return new Binder(typeManager, 0, false, jsonHandler);
|
||||
}
|
||||
return new Binder(typeManager, historySupport.getBindCount(), historySupport.isBindWithFromClause());
|
||||
return new Binder(typeManager, historySupport.getBindCount(), historySupport.isBindWithFromClause(), jsonHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the JSON expression handler for the given database platform.
|
||||
*/
|
||||
private JsonExpressionHandler getJsonExpressionHandler(DatabasePlatform databasePlatform) {
|
||||
|
||||
String name = databasePlatform.getName();
|
||||
if ("postgres".equalsIgnoreCase(name)) {
|
||||
return new PostgresJsonExpression();
|
||||
}
|
||||
if ("oracle".equalsIgnoreCase(name)) {
|
||||
return new OracleJsonExpression();
|
||||
}
|
||||
return new NotSupportedJsonExpression();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.avaje.ebeaninternal.server.core;
|
||||
|
||||
import com.avaje.ebeaninternal.api.SpiExpressionRequest;
|
||||
import com.avaje.ebeaninternal.server.expression.Op;
|
||||
|
||||
/**
|
||||
* Adds the db platform specific json expression.
|
||||
*/
|
||||
public interface JsonExpressionHandler {
|
||||
|
||||
|
||||
/**
|
||||
* Write the db platform specific json expression.
|
||||
*/
|
||||
void addSql(SpiExpressionRequest request, String propName, String path, Op operator, Object value);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.avaje.ebeaninternal.server.core;
|
||||
|
||||
import com.avaje.ebeaninternal.api.SpiExpressionRequest;
|
||||
import com.avaje.ebeaninternal.server.expression.Op;
|
||||
|
||||
/**
|
||||
* Not supported JSON expression handler.
|
||||
*/
|
||||
public class NotSupportedJsonExpression implements JsonExpressionHandler {
|
||||
|
||||
@Override
|
||||
public void addSql(SpiExpressionRequest request, String propName, String path, Op operator, Object value) {
|
||||
throw new RuntimeException("JSON expressions only supported on Postgres and Oracle");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.avaje.ebeaninternal.server.core;
|
||||
|
||||
import com.avaje.ebeaninternal.api.SpiExpressionRequest;
|
||||
import com.avaje.ebeaninternal.server.expression.Op;
|
||||
|
||||
/**
|
||||
* Postgres JSON expression handler
|
||||
*/
|
||||
public class OracleJsonExpression implements JsonExpressionHandler {
|
||||
|
||||
@Override
|
||||
public void addSql(SpiExpressionRequest request, String propName, String path, Op operator, Object value) {
|
||||
|
||||
if (operator == Op.EXISTS) {
|
||||
request.append("json_exists(").append(propName).append(", '$.").append(path).append("')");
|
||||
} else if (operator == Op.NOT_EXISTS) {
|
||||
request.append("not json_exists(").append(propName).append(", '$.").append(path).append("')");
|
||||
} else {
|
||||
request.append("json_value(").append(propName).append(", '$.").append(path).append("')");
|
||||
request.append(operator.bind());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.avaje.ebeaninternal.server.core;
|
||||
|
||||
import com.avaje.ebeaninternal.api.SpiExpressionRequest;
|
||||
import com.avaje.ebeaninternal.server.expression.Op;
|
||||
|
||||
/**
|
||||
* Postgres JSON expression handler
|
||||
*/
|
||||
public class PostgresJsonExpression implements JsonExpressionHandler {
|
||||
|
||||
@Override
|
||||
public void addSql(SpiExpressionRequest request, String propName, String path, Op operator, Object value) {
|
||||
|
||||
StringBuilder sb = new StringBuilder(50);
|
||||
String[] paths = path.split("\\.");
|
||||
if (paths.length == 1) {
|
||||
// (t0.content ->> 'title') = 'Some value'
|
||||
sb.append("(").append(propName).append(" ->> '").append(path).append("')");
|
||||
|
||||
} else {
|
||||
// (t0.content #>> '{path,inner}') = 'Some value'
|
||||
sb.append("(").append(propName).append(" #>> '{");
|
||||
for (int i = 0; i < paths.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append(paths[i]);
|
||||
}
|
||||
sb.append("}')");
|
||||
}
|
||||
|
||||
request.append(castType(sb.toString(), value));
|
||||
request.append(operator.bind());
|
||||
}
|
||||
|
||||
/**
|
||||
* Postgres CAST the type if necessary as text values always returned from the json operators used.
|
||||
*/
|
||||
private String castType(String expression, Object value) {
|
||||
|
||||
if (value == null) {
|
||||
// for exists and not-exists expressions
|
||||
return expression;
|
||||
}
|
||||
|
||||
// Postgres cast of returned text value
|
||||
if (isIntegerType(value)) {
|
||||
return expression+"::INTEGER";
|
||||
}
|
||||
if (isNumberType(value)) {
|
||||
return expression+"::DECIMAL";
|
||||
}
|
||||
if (isBooleanType(value)) {
|
||||
return expression+"::BOOLEAN";
|
||||
}
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
private boolean isBooleanType(Object value) {
|
||||
return (value instanceof Boolean);
|
||||
}
|
||||
|
||||
private boolean isIntegerType(Object value) {
|
||||
return (value instanceof Integer) || (value instanceof Long);
|
||||
}
|
||||
|
||||
private boolean isNumberType(Object value) {
|
||||
return (value instanceof Number);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -211,7 +211,7 @@ public class DefaultExampleExpression implements SpiExpression, ExampleExpressio
|
||||
// exclude the zero values typically to weed out
|
||||
// primitive int and long that initialise to 0
|
||||
if (includeZeros || !isZero(value)) {
|
||||
list.add(new SimpleExpression(propName, SimpleExpression.Op.EQ, value));
|
||||
list.add(new SimpleExpression(propName, Op.EQ, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+42
-10
@@ -1,9 +1,5 @@
|
||||
package com.avaje.ebeaninternal.server.expression;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.avaje.ebean.ExampleExpression;
|
||||
import com.avaje.ebean.Expression;
|
||||
import com.avaje.ebean.ExpressionFactory;
|
||||
@@ -15,6 +11,10 @@ import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.api.SpiExpressionFactory;
|
||||
import com.avaje.ebeaninternal.api.SpiQuery;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Default Expression factory for creating standard expressions.
|
||||
*/
|
||||
@@ -36,6 +36,38 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
return "sql";
|
||||
}
|
||||
|
||||
public Expression jsonExists(String propertyName, String path) {
|
||||
return new JsonPathExpression(propertyName, path, Op.EXISTS, null);
|
||||
}
|
||||
|
||||
public Expression jsonNotExists(String propertyName, String path) {
|
||||
return new JsonPathExpression(propertyName, path, Op.NOT_EXISTS, null);
|
||||
}
|
||||
|
||||
public Expression jsonEqualTo(String propertyName, String path, Object val) {
|
||||
return new JsonPathExpression(propertyName, path, Op.EQ, val);
|
||||
}
|
||||
|
||||
public Expression jsonNotEqualTo(String propertyName, String path, Object val) {
|
||||
return new JsonPathExpression(propertyName, path, Op.NOT_EQ, val);
|
||||
}
|
||||
|
||||
public Expression jsonGreaterThan(String propertyName, String path, Object val) {
|
||||
return new JsonPathExpression(propertyName, path, Op.GT, val);
|
||||
}
|
||||
|
||||
public Expression jsonGreaterOrEqual(String propertyName, String path, Object val) {
|
||||
return new JsonPathExpression(propertyName, path, Op.GT_EQ, val);
|
||||
}
|
||||
|
||||
public Expression jsonLessThan(String propertyName, String path, Object val) {
|
||||
return new JsonPathExpression(propertyName, path, Op.LT, val);
|
||||
}
|
||||
|
||||
public Expression jsonLessOrEqualTo(String propertyName, String path, Object val) {
|
||||
return new JsonPathExpression(propertyName, path, Op.LT_EQ, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Equal To - property equal to the given value.
|
||||
*/
|
||||
@@ -43,7 +75,7 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
if (value == null) {
|
||||
return equalsWithNullAsNoop ? NoopExpression.INSTANCE : isNull(propertyName);
|
||||
}
|
||||
return new SimpleExpression(propertyName, SimpleExpression.Op.EQ, value);
|
||||
return new SimpleExpression(propertyName, Op.EQ, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,7 +85,7 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
if (value == null) {
|
||||
return equalsWithNullAsNoop ? NoopExpression.INSTANCE : isNotNull(propertyName);
|
||||
}
|
||||
return new SimpleExpression(propertyName, SimpleExpression.Op.NOT_EQ, value);
|
||||
return new SimpleExpression(propertyName, Op.NOT_EQ, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,7 +120,7 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
*/
|
||||
public Expression gt(String propertyName, Object value) {
|
||||
|
||||
return new SimpleExpression(propertyName, SimpleExpression.Op.GT, value);
|
||||
return new SimpleExpression(propertyName, Op.GT, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,7 +129,7 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
*/
|
||||
public Expression ge(String propertyName, Object value) {
|
||||
|
||||
return new SimpleExpression(propertyName, SimpleExpression.Op.GT_EQ, value);
|
||||
return new SimpleExpression(propertyName, Op.GT_EQ, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,7 +137,7 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
*/
|
||||
public Expression lt(String propertyName, Object value) {
|
||||
|
||||
return new SimpleExpression(propertyName, SimpleExpression.Op.LT, value);
|
||||
return new SimpleExpression(propertyName, Op.LT, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,7 +145,7 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
*/
|
||||
public Expression le(String propertyName, Object value) {
|
||||
|
||||
return new SimpleExpression(propertyName, SimpleExpression.Op.LT_EQ, value);
|
||||
return new SimpleExpression(propertyName, Op.LT_EQ, value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.avaje.ebeaninternal.server.expression;
|
||||
|
||||
import com.avaje.ebean.event.BeanQueryRequest;
|
||||
import com.avaje.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import com.avaje.ebeaninternal.api.SpiExpressionRequest;
|
||||
|
||||
/**
|
||||
* Generally speaking tests the value at a given path in the JSON document.
|
||||
* <p>
|
||||
* Supports the usual operators (equal to, greater than etc).
|
||||
* </p>
|
||||
* <p>
|
||||
* The value passed in is expected to be a valid JSON type so string, number, boolean.
|
||||
* </p>
|
||||
*/
|
||||
class JsonPathExpression extends AbstractExpression {
|
||||
|
||||
/**
|
||||
* The path in the JSON document in dot notation form.
|
||||
*/
|
||||
protected final String path;
|
||||
|
||||
/**
|
||||
* The expression operator.
|
||||
*/
|
||||
protected final Op operator;
|
||||
|
||||
/**
|
||||
* The bind value used to compare against the document path value.
|
||||
*/
|
||||
protected final Object value;
|
||||
|
||||
JsonPathExpression(String propertyName, String path, Op operator, Object value) {
|
||||
super(propertyName);
|
||||
this.path = path;
|
||||
this.operator = operator;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queryAutoTuneHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(JsonPathExpression.class).add(propName).add(path).add(operator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queryPlanHash(BeanQueryRequest<?> request, HashQueryPlanBuilder builder) {
|
||||
queryAutoTuneHash(builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int queryBindHash() {
|
||||
return (value == null) ? 0 : value.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSql(SpiExpressionRequest request) {
|
||||
|
||||
// Use DB specific expression handling (Postgres and Oracle supported)
|
||||
request.getJsonHander().addSql(request, propName, path, operator, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBindValues(SpiExpressionRequest request) {
|
||||
|
||||
if (value != null) {
|
||||
request.addBindValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -313,6 +313,70 @@ abstract class JunctionExpression<T> implements Junction<T>, SpiExpression, Expr
|
||||
return exprList.findUnique();
|
||||
}
|
||||
|
||||
/**
|
||||
* Path exists - for the given path in a JSON document.
|
||||
*/
|
||||
@Override
|
||||
public ExpressionList<T> jsonExists(String propertyName, String path) {
|
||||
return exprList.jsonExists(propertyName, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Path does not exist - for the given path in a JSON document.
|
||||
*/
|
||||
@Override
|
||||
public ExpressionList<T> jsonNotExists(String propertyName, String path){
|
||||
return exprList.jsonNotExists(propertyName, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Equal to - for the value at the given path in the JSON document.
|
||||
*/
|
||||
@Override
|
||||
public ExpressionList<T> jsonEqualTo(String propertyName, String path, Object value){
|
||||
return exprList.jsonEqualTo(propertyName, path, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Not Equal to - for the given path in a JSON document.
|
||||
*/
|
||||
@Override
|
||||
public ExpressionList<T> jsonNotEqualTo(String propertyName, String path, Object val){
|
||||
return exprList.jsonNotEqualTo(propertyName, path, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater than - for the given path in a JSON document.
|
||||
*/
|
||||
@Override
|
||||
public ExpressionList<T> jsonGreaterThan(String propertyName, String path, Object val){
|
||||
return exprList.jsonGreaterThan(propertyName, path, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater than or equal to - for the given path in a JSON document.
|
||||
*/
|
||||
@Override
|
||||
public ExpressionList<T> jsonGreaterOrEqual(String propertyName, String path, Object val){
|
||||
return exprList.jsonGreaterOrEqual(propertyName, path, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Less than - for the given path in a JSON document.
|
||||
*/
|
||||
@Override
|
||||
public ExpressionList<T> jsonLessThan(String propertyName, String path, Object val){
|
||||
return exprList.jsonLessThan(propertyName, path, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Less than or equal to - for the given path in a JSON document.
|
||||
*/
|
||||
@Override
|
||||
public ExpressionList<T> jsonLessOrEqualTo(String propertyName, String path, Object val){
|
||||
return exprList.jsonLessOrEqualTo(propertyName, path, val);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExpressionList<T> ge(String propertyName, Object value) {
|
||||
return exprList.ge(propertyName, value);
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.avaje.ebeaninternal.server.expression;
|
||||
|
||||
/**
|
||||
* Simple operators - equals, greater than, less than etc.
|
||||
*/
|
||||
public enum Op {
|
||||
|
||||
/**
|
||||
* Exists (JSON).
|
||||
*/
|
||||
EXISTS(" is not null "),
|
||||
|
||||
/**
|
||||
* Not Exists (JSON).
|
||||
*/
|
||||
NOT_EXISTS(" is null "),
|
||||
|
||||
/**
|
||||
* Equal to
|
||||
*/
|
||||
EQ(" = ? "),
|
||||
|
||||
/**
|
||||
* Not equal to.
|
||||
*/
|
||||
NOT_EQ(" <> ? "),
|
||||
|
||||
/**
|
||||
*
|
||||
* Less than.
|
||||
*/
|
||||
|
||||
LT(" < ? "),
|
||||
|
||||
/**
|
||||
* Less than or equal to.
|
||||
*/
|
||||
LT_EQ(" <= ? "),
|
||||
|
||||
/**
|
||||
* Greater than.
|
||||
*/
|
||||
GT(" > ? "),
|
||||
|
||||
/**
|
||||
* Greater than or equal to.
|
||||
*/
|
||||
GT_EQ(" >= ? ");
|
||||
|
||||
final String exp;
|
||||
|
||||
Op(String exp) {
|
||||
this.exp = exp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the bind expression include JDBC ? bind placeholder.
|
||||
*/
|
||||
public String bind() {
|
||||
return exp;
|
||||
}
|
||||
}
|
||||
@@ -10,20 +10,6 @@ public class SimpleExpression extends AbstractExpression {
|
||||
|
||||
private static final long serialVersionUID = -382881395755603790L;
|
||||
|
||||
enum Op {
|
||||
EQ(" = ? "), NOT_EQ(" <> ? "), LT(" < ? "), LT_EQ(" <= ? "), GT(" > ? "), GT_EQ(" >= ? ");
|
||||
|
||||
final String exp;
|
||||
|
||||
Op(String exp) {
|
||||
this.exp = exp;
|
||||
}
|
||||
|
||||
public String bind() {
|
||||
return exp;
|
||||
}
|
||||
}
|
||||
|
||||
private final Op type;
|
||||
|
||||
private final Object value;
|
||||
|
||||
@@ -10,6 +10,7 @@ import java.util.List;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import com.avaje.ebeaninternal.api.BindParams;
|
||||
import com.avaje.ebeaninternal.server.core.JsonExpressionHandler;
|
||||
import com.avaje.ebeaninternal.server.core.Message;
|
||||
import com.avaje.ebeaninternal.server.type.DataBind;
|
||||
import com.avaje.ebeaninternal.server.type.ScalarType;
|
||||
@@ -30,13 +31,16 @@ public class Binder {
|
||||
|
||||
private final boolean bindAsOfWithFromClause;
|
||||
|
||||
private final JsonExpressionHandler jsonExpressionHandler;
|
||||
|
||||
/**
|
||||
* Set the PreparedStatement with which to bind variables to.
|
||||
*/
|
||||
public Binder(TypeManager typeManager, int asOfBindCount, boolean bindAsOfWithFromClause) {
|
||||
public Binder(TypeManager typeManager, int asOfBindCount, boolean bindAsOfWithFromClause, JsonExpressionHandler jsonExpressionHandler) {
|
||||
this.typeManager = typeManager;
|
||||
this.asOfBindCount = asOfBindCount;
|
||||
this.bindAsOfWithFromClause = bindAsOfWithFromClause;
|
||||
this.jsonExpressionHandler = jsonExpressionHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -375,4 +379,11 @@ public class Binder {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the JsonExpressionHandler specific to the database.
|
||||
*/
|
||||
public JsonExpressionHandler getJsonExpressionHandler() {
|
||||
return jsonExpressionHandler;
|
||||
}
|
||||
}
|
||||
@@ -302,7 +302,7 @@ public class CQueryPredicates {
|
||||
|
||||
SpiExpressionList<?> whereExp = query.getWhereExpressions();
|
||||
if (whereExp != null) {
|
||||
DefaultExpressionRequest whereReq = new DefaultExpressionRequest(request, deployParser);
|
||||
DefaultExpressionRequest whereReq = new DefaultExpressionRequest(request, deployParser, binder);
|
||||
whereExprBindValues = whereExp.buildBindValues(whereReq);
|
||||
if (buildSql) {
|
||||
whereExprSql = whereExp.buildSql(whereReq);
|
||||
@@ -314,7 +314,7 @@ public class CQueryPredicates {
|
||||
OrmQueryProperties chunk = query.getDetail().getChunk(manyProperty.getName(), false);
|
||||
SpiExpressionList<?> filterMany = chunk.getFilterMany();
|
||||
if (filterMany != null) {
|
||||
DefaultExpressionRequest filterReq = new DefaultExpressionRequest(request, deployParser);
|
||||
DefaultExpressionRequest filterReq = new DefaultExpressionRequest(request, deployParser, binder);
|
||||
filterManyExprBindValues = filterMany.buildBindValues(filterReq);
|
||||
if (buildSql) {
|
||||
filterManyExprSql = filterMany.buildSql(filterReq);
|
||||
@@ -325,7 +325,7 @@ public class CQueryPredicates {
|
||||
// having expression
|
||||
SpiExpressionList<?> havingExpr = query.getHavingExpressions();
|
||||
if (havingExpr != null) {
|
||||
DefaultExpressionRequest havingReq = new DefaultExpressionRequest(request, deployParser);
|
||||
DefaultExpressionRequest havingReq = new DefaultExpressionRequest(request, deployParser, binder);
|
||||
havingExprBindValues = havingExpr.buildBindValues(havingReq);
|
||||
if (buildSql) {
|
||||
havingExprSql = havingExpr.buildSql(havingReq);
|
||||
|
||||
@@ -363,6 +363,78 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Path exists - for the given path in a JSON document.
|
||||
*/
|
||||
@Override
|
||||
public ExpressionList<T> jsonExists(String propertyName, String path) {
|
||||
add(expr.jsonExists(propertyName, path));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Path does not exist - for the given path in a JSON document.
|
||||
*/
|
||||
@Override
|
||||
public ExpressionList<T> jsonNotExists(String propertyName, String path){
|
||||
add(expr.jsonNotExists(propertyName, path));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Equal to expression for the value at the given path in the JSON document.
|
||||
*/
|
||||
@Override
|
||||
public ExpressionList<T> jsonEqualTo(String propertyName, String path, Object value){
|
||||
add(expr.jsonEqualTo(propertyName, path, value));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not Equal to - for the given path in a JSON document.
|
||||
*/
|
||||
@Override
|
||||
public ExpressionList<T> jsonNotEqualTo(String propertyName, String path, Object val){
|
||||
add(expr.jsonNotEqualTo(propertyName, path, val));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater than - for the given path in a JSON document.
|
||||
*/
|
||||
@Override
|
||||
public ExpressionList<T> jsonGreaterThan(String propertyName, String path, Object val){
|
||||
add(expr.jsonGreaterThan(propertyName, path, val));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Greater than or equal to - for the given path in a JSON document.
|
||||
*/
|
||||
@Override
|
||||
public ExpressionList<T> jsonGreaterOrEqual(String propertyName, String path, Object val){
|
||||
add(expr.jsonGreaterOrEqual(propertyName, path, val));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Less than - for the given path in a JSON document.
|
||||
*/
|
||||
@Override
|
||||
public ExpressionList<T> jsonLessThan(String propertyName, String path, Object val){
|
||||
add(expr.jsonLessThan(propertyName, path, val));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Less than or equal to - for the given path in a JSON document.
|
||||
*/
|
||||
@Override
|
||||
public ExpressionList<T> jsonLessOrEqualTo(String propertyName, String path, Object val){
|
||||
add(expr.jsonLessOrEqualTo(propertyName, path, val));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExpressionList<T> eq(String propertyName, Object value) {
|
||||
add(expr.eq(propertyName, value));
|
||||
|
||||
@@ -3,9 +3,11 @@ package com.avaje.ebeaninternal.util;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.avaje.ebeaninternal.api.SpiExpressionRequest;
|
||||
import com.avaje.ebeaninternal.server.core.JsonExpressionHandler;
|
||||
import com.avaje.ebeaninternal.server.core.SpiOrmQueryRequest;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import com.avaje.ebeaninternal.server.deploy.DeployParser;
|
||||
import com.avaje.ebeaninternal.server.persist.Binder;
|
||||
|
||||
public class DefaultExpressionRequest implements SpiExpressionRequest {
|
||||
|
||||
@@ -19,18 +21,26 @@ public class DefaultExpressionRequest implements SpiExpressionRequest {
|
||||
|
||||
private final DeployParser deployParser;
|
||||
|
||||
private final Binder binder;
|
||||
|
||||
private int paramIndex;
|
||||
|
||||
public DefaultExpressionRequest(SpiOrmQueryRequest<?> queryRequest, DeployParser deployParser) {
|
||||
public DefaultExpressionRequest(SpiOrmQueryRequest<?> queryRequest, DeployParser deployParser, Binder binder) {
|
||||
this.queryRequest = queryRequest;
|
||||
this.beanDescriptor = queryRequest.getBeanDescriptor();
|
||||
this.deployParser = deployParser;
|
||||
this.binder = binder;
|
||||
}
|
||||
|
||||
public DefaultExpressionRequest(BeanDescriptor<?> beanDescriptor) {
|
||||
this.beanDescriptor = beanDescriptor;
|
||||
this.queryRequest = null;
|
||||
this.deployParser = null;
|
||||
this.binder = null;
|
||||
}
|
||||
|
||||
public JsonExpressionHandler getJsonHander() {
|
||||
return binder.getJsonExpressionHandler();
|
||||
}
|
||||
|
||||
public String parseDeploy(String logicalProp) {
|
||||
|
||||
Reference in new issue
Block a user