Make Query.Property parameterised with <BT> "Base Type" as Number, String, Temporal, Boolean or Object

These types then determine which functions are valid for the types. So:
- Number functions
- String/varchar functions
- Temporal Date, DateTime, Time functions
- Boolean functions
- Object being everything else
This commit is contained in:
Rob Bygrave
2022-11-08 21:57:36 +13:00
parent 0b9d199829
commit 97bbce321d
43 changed files with 353 additions and 145 deletions
+7 -3
View File
@@ -1772,14 +1772,18 @@ public interface Query<T> extends CancelableQuery {
* Type safe query bean properties and expressions (marker interface).
* <p>
* Implemented by query bean properties and expressions based on those properties.
* <p>
* The base type determines which {@link StdFunctions} can be used on the property.
*
* @param <BT> The base type of the property Number, String, Temporal, Boolean or Object.
*/
interface Property {
interface Property<BT> {
/**
* Return a property given the expression.
*/
static Property of(String expression) {
return new SimpleProperty(expression);
static <BT> Property<BT> of(String expression) {
return new SimpleProperty<>(expression);
}
/**
@@ -1,6 +1,6 @@
package io.ebean;
final class SimpleProperty implements Query.Property {
final class SimpleProperty<BT> implements Query.Property<BT> {
private final String expression;
@@ -2,37 +2,43 @@ package io.ebean;
import io.ebean.Query.Property;
import java.time.temporal.Temporal;
public final class StdFunctions {
public static Property avg(Property property) {
return Property.of("avg(" + property + ")");
}
public static Property count(Property property) {
public static Property<Number> count(Property<?> property) {
return Property.of("count(" + property + ")");
}
public static Property max(Property property) {
return Property.of("max(" + property + ")");
}
public static Property min(Property property) {
return Property.of("min(" + property + ")");
}
public static Property sum(Property property) {
public static Property<Number> sum(Property<Number> property) {
return Property.of("sum(" + property + ")");
}
public static Property lower(Property property) {
public static <BT> Property<BT> avg(Property<BT> property) {
return Property.of("avg(" + property + ")");
}
public static <BT> Property<BT> max(Property<BT> property) {
return Property.of("max(" + property + ")");
}
public static <BT> Property<BT> min(Property<BT> property) {
return Property.of("min(" + property + ")");
}
public static <BT> Property<BT> coalesce(Property<BT> property, Object value) {
return Property.of("coalesce(" + property.toString() + "," + sqlValue(value) + ")");
}
public static Property<String> lower(Property<String> property) {
return Property.of("lower(" + property + ")");
}
public static Property upper(Property property) {
public static Property<String> upper(Property<String> property) {
return Property.of("upper(" + property + ")");
}
public static Property concat(Property property, Object... values) {
public static Property<String> concat(Property<?> property, Object... values) {
StringBuilder expression = new StringBuilder(50);
expression.append("concat(").append(property.toString());
for (Object value : values) {
@@ -42,10 +48,6 @@ public final class StdFunctions {
return Property.of(expression.toString());
}
public static Property coalesce(Property property, Object value) {
return Property.of("coalesce(" + property.toString() + "," + sqlValue(value) + ")");
}
private static String sqlConcatString(Object value) {
String asStr = String.valueOf(value);
return (value instanceof Property || isSqlQuoted(asStr)) ? asStr : "'" + value + "'";
@@ -66,35 +68,67 @@ public final class StdFunctions {
// -------------------------------------------------------------------------------------------- //
// ---- Expressions --------------------------------------------------------------------------- //
public static Expression eq(Property property, Object value) {
public static Expression eq(Property<Number> property, Number value) {
return Expr.eq(property.toString(), value);
}
public static Expression gt(Property property, Object value) {
public static Expression eq(Property<String> property, String value) {
return Expr.eq(property.toString(), value);
}
public static Expression eq(Property<Temporal> property, Temporal value) {
return Expr.eq(property.toString(), value);
}
public static Expression eq(Property<Boolean> property, boolean value) {
return Expr.eq(property.toString(), value);
}
public static Expression eq(Property<Object> property, Object value) {
return Expr.eq(property.toString(), value);
}
//----
public static Expression gt(Property<Number> property, Number value) {
return Expr.gt(property.toString(), value);
}
public static Expression like(Property property, String value) {
public static Expression gt(Property<String> property, String value) {
return Expr.gt(property.toString(), value);
}
public static Expression gt(Property<Temporal> property, Temporal value) {
return Expr.gt(property.toString(), value);
}
public static Expression gt(Property<Object> property, Object value) {
return Expr.gt(property.toString(), value);
}
//----
public static Expression like(Property<String> property, String value) {
return Expr.like(property.toString(), value);
}
public static Expression ilike(Property property, String value) {
public static Expression ilike(Property<String> property, String value) {
return Expr.ilike(property.toString(), value);
}
public static Expression startsWith(Property property, String value) {
public static Expression startsWith(Property<String> property, String value) {
return Expr.startsWith(property.toString(), value);
}
public static Expression istartsWith(Property property, String value) {
public static Expression istartsWith(Property<String> property, String value) {
return Expr.istartsWith(property.toString(), value);
}
public static Expression contains(Property property, String value) {
public static Expression contains(Property<String> property, String value) {
return Expr.contains(property.toString(), value);
}
public static Expression icontains(Property property, String value) {
public static Expression icontains(Property<String> property, String value) {
return Expr.icontains(property.toString(), value);
}
}
@@ -118,7 +118,7 @@ public interface UpdateQuery<T> {
* @param property The bean property to be set
* @param value The value to set the property to
*/
UpdateQuery<T> set(Query.Property property, Object value);
UpdateQuery<T> set(Query.Property<?> property, Object value);
/**
* Set the property to be null.
@@ -142,7 +142,7 @@ public interface UpdateQuery<T> {
*
* @param property The bean property to be set
*/
UpdateQuery<T> setNull(Query.Property property);
UpdateQuery<T> setNull(Query.Property<?> property);
/**
* Set using a property expression that does not need any bind values.