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.
@@ -9,8 +9,9 @@ import static org.assertj.core.api.Assertions.assertThat;
class StdFunctionsTest {
final Query.Property foo = Query.Property.of("foo");
final Query.Property bar = Query.Property.of("bar");
final Query.Property<Number> amount = Query.Property.of("amount");
final Query.Property<String> foo = Query.Property.of("foo");
final Query.Property<String> bar = Query.Property.of("bar");
@Test
void testAvg() {
@@ -34,7 +35,7 @@ class StdFunctionsTest {
@Test
void testSum() {
assertThat(sum(foo).toString()).isEqualTo("sum(foo)");
assertThat(sum(amount).toString()).isEqualTo("sum(amount)");
}
@Test
@@ -6,7 +6,7 @@ package io.ebean.typequery;
* @param <R> the root query bean type
* @param <E> the element type of the DbArray
*/
public final class PArray<R, E> extends TQPropertyBase<R> {
public final class PArray<R, E> extends TQPropertyBase<R, E> {
/**
* Construct with a property name and root instance.
@@ -6,11 +6,11 @@ import io.ebean.Query;
/**
* Base property for all comparable types.
*
* @param <R> the root query bean type
* @param <T> the type of the scalar property
* @param <R> the root query bean type
* @param <T> the type of the scalar property
* @param <BT> the base type of the property
*/
@SuppressWarnings("rawtypes")
public class PBaseCompareable<R, T> extends PBaseValueEqual<R, T> {
public abstract class PBaseCompareable<R, T, BT> extends PBaseValueEqual<R, T, BT> {
/**
* Construct with a property name and root instance.
@@ -44,11 +44,14 @@ public class PBaseCompareable<R, T> extends PBaseValueEqual<R, T> {
/**
* Greater than other property.
* <p>
* Note that the other property must have the same common "Base type" (String, Number, Temporal, Boolean or Object).
*
* @param other the other property to compare
*
* @return the root query bean instance
*/
public final R gt(TQProperty<?> other) {
public final R gt(TQProperty<?, BT> other) {
expr().raw(_name + " > " + other.propertyName());
return _root;
}
@@ -81,7 +84,7 @@ public class PBaseCompareable<R, T> extends PBaseValueEqual<R, T> {
* @param other the other property to compare
* @return the root query bean instance
*/
public final R ge(TQProperty<?> other) {
public final R ge(TQProperty<?, BT> other) {
expr().raw(_name + " >= " + other.propertyName());
return _root;
}
@@ -114,7 +117,7 @@ public class PBaseCompareable<R, T> extends PBaseValueEqual<R, T> {
* @param other the other property to compare
* @return the root query bean instance
*/
public final R lt(TQProperty<?> other) {
public final R lt(TQProperty<?, BT> other) {
expr().raw(_name + " < " + other.propertyName());
return _root;
}
@@ -147,7 +150,7 @@ public class PBaseCompareable<R, T> extends PBaseValueEqual<R, T> {
* @param other the other property to compare
* @return the root query bean instance
*/
public final R le(TQProperty<?> other) {
public final R le(TQProperty<?, BT> other) {
expr().raw(_name + " <= " + other.propertyName());
return _root;
}
@@ -197,7 +200,7 @@ public class PBaseCompareable<R, T> extends PBaseValueEqual<R, T> {
* The most common use of this could be called "effective dating" where 2 date or
* timestamp columns represent the date range in which
*/
public final R inRangeWith(TQProperty<R> highProperty, T value) {
public final R inRangeWith(TQProperty<?, BT> highProperty, T value) {
expr().inRangeWith(_name, highProperty._name, value);
return _root;
}
@@ -220,7 +223,7 @@ public class PBaseCompareable<R, T> extends PBaseValueEqual<R, T> {
* <p>
* This is a convenience expression combining a number of simple expressions.
*/
public final R inRangeWith(TQProperty<?> lowProperty, TQProperty<?> highProperty) {
public final R inRangeWith(TQProperty<?, BT> lowProperty, TQProperty<?, BT> highProperty) {
expr().inRangeWithProperties(_name, lowProperty.propertyName(), highProperty.propertyName());
return _root;
}
@@ -1,5 +1,7 @@
package io.ebean.typequery;
import java.time.temporal.Temporal;
/**
* Base property for date and date time types.
*
@@ -7,7 +9,7 @@ package io.ebean.typequery;
* @param <D> the date time type
*/
@SuppressWarnings("rawtypes")
public abstract class PBaseDate<R, D extends Comparable> extends PBaseCompareable<R, D> {
public abstract class PBaseDate<R, D extends Comparable> extends PBaseCompareable<R, D, Temporal> {
/**
* Construct with a property name and root instance.
@@ -7,7 +7,7 @@ package io.ebean.typequery;
* @param <T> the number type
*/
@SuppressWarnings("rawtypes")
public abstract class PBaseNumber<R,T extends Comparable> extends PBaseCompareable<R,T> {
public abstract class PBaseNumber<R, T extends Comparable> extends PBaseCompareable<R, T, Number> {
/**
* Construct with a property name and root instance.
@@ -16,7 +16,7 @@ public abstract class PBaseNumber<R,T extends Comparable> extends PBaseCompareab
* @param root the root query bean instance
*/
public PBaseNumber(String name, R root) {
super(name , root);
super(name, root);
}
/**
@@ -5,7 +5,7 @@ package io.ebean.typequery;
*
* @param <R> the root query bean type
*/
public abstract class PBaseString<R,T> extends PBaseCompareable<R, String> {
public abstract class PBaseString<R, T> extends PBaseCompareable<R, T, String> {
/**
* Construct with a property name and root instance.
@@ -25,22 +25,28 @@ public abstract class PBaseString<R,T> extends PBaseCompareable<R, String> {
}
/**
* Deprecated migrate to eq().
* <p>
* Is equal to. The same as <code>eq</code> but uses the strong type as argument rather than String.
*
* @param value the equal to bind value
* @return the root query bean instance
*/
@Deprecated
public final R equalToType(T value) {
expr().eq(_name, value);
return _root;
}
/**
* Deprecated migrate to ne().
* <p>
* Is not equal to. The same as <code>ne</code> but uses the strong type as argument rather than String.
*
* @param value the equal to bind value
* @return the root query bean instance
*/
@Deprecated
public final R notEqualToType(T value) {
expr().ne(_name, value);
return _root;
@@ -49,7 +55,146 @@ public abstract class PBaseString<R,T> extends PBaseCompareable<R, String> {
// common string / expressions ------------
/**
* Case insensitive is equal to.
* Equal to.
*
* @param value the bind value
* @return the root query bean instance
*/
public final R eq(String value) {
expr().eq(_name, value);
return _root;
}
/**
* Not equal to.
*
* @param value the bind value
* @return the root query bean instance
*/
public final R ne(String value) {
expr().ne(_name, value);
return _root;
}
/**
* Greater than.
*
* @param value the bind value
* @return the root query bean instance
*/
public final R gt(String value) {
expr().gt(_name, value);
return _root;
}
/**
* Greater than OR Null.
*
* @param value the bind value
* @return the root query bean instance
*/
public final R gtOrNull(String value) {
expr().gtOrNull(_name, value);
return _root;
}
/**
* Greater than or Equal to.
*
* @param value the bind value
* @return the root query bean instance
*/
public final R ge(String value) {
expr().ge(_name, value);
return _root;
}
/**
* Greater than or Equal to OR Null.
*
* @param value the bind value
* @return the root query bean instance
*/
public final R geOrNull(String value) {
expr().geOrNull(_name, value);
return _root;
}
/**
* Less than.
*
* @param value the bind value
* @return the root query bean instance
*/
public final R lt(String value) {
expr().lt(_name, value);
return _root;
}
/**
* Less than OR Null.
*
* @param value the bind value
* @return the root query bean instance
*/
public final R ltOrNull(String value) {
expr().ltOrNull(_name, value);
return _root;
}
/**
* Less than or Equal to.
*
* @param value the bind value
* @return the root query bean instance
*/
public final R le(String value) {
expr().le(_name, value);
return _root;
}
/**
* Less than or Equal to OR null.
*
* @param value the bind value
* @return the root query bean instance
*/
public final R leOrNull(String value) {
expr().leOrNull(_name, value);
return _root;
}
/**
* Greater or equal to lower value and strictly less than upper value.
* <p>
* This is generally preferable over Between for date and datetime types
* as SQL Between is inclusive on the upper bound ({@code <= }) and generally
* we need the upper bound to be exclusive ({@code < }).
* </p>
*
* @param lower the lower bind value ({@code >= })
* @param upper the upper bind value ({@code < })
* @return the root query bean instance
*/
public final R inRange(String lower, String upper) {
expr().inRange(_name, lower, upper);
return _root;
}
/**
* Between lower and upper values.
*
* @param lower the lower bind value
* @param upper the upper bind value
* @return the root query bean instance
*/
public final R between(String lower, String upper) {
expr().between(_name, lower, upper);
return _root;
}
/**
* Case-insensitive is equal to.
*
* @param value the equal to bind value
* @return the root query bean instance
@@ -60,7 +205,7 @@ public abstract class PBaseString<R,T> extends PBaseCompareable<R, String> {
}
/**
* Case insensitive is equal to.
* Case-insensitive is equal to.
*
* @param value the equal to bind value
* @return the root query bean instance
@@ -115,7 +260,7 @@ public abstract class PBaseString<R,T> extends PBaseCompareable<R, String> {
}
/**
* Case insensitive like.
* Case-insensitive like.
*
* @param value the equal to bind value
* @return the root query bean instance
@@ -126,7 +271,7 @@ public abstract class PBaseString<R,T> extends PBaseCompareable<R, String> {
}
/**
* Case insensitive starts with.
* Case-insensitive starts with.
*
* @param value the equal to bind value
* @return the root query bean instance
@@ -137,7 +282,7 @@ public abstract class PBaseString<R,T> extends PBaseCompareable<R, String> {
}
/**
* Case insensitive ends with.
* Case-insensitive ends with.
*
* @param value the equal to bind value
* @return the root query bean instance
@@ -148,7 +293,7 @@ public abstract class PBaseString<R,T> extends PBaseCompareable<R, String> {
}
/**
* Case insensitive contains.
* Case-insensitive contains.
*
* @param value the equal to bind value
* @return the root query bean instance
@@ -0,0 +1,52 @@
package io.ebean.typequery;
import java.time.temporal.Temporal;
/**
* Base property for time types.
*
* @param <R> the root query bean type
* @param <T> the number type
*/
@SuppressWarnings("rawtypes")
public abstract class PBaseTime<R, T extends Comparable> extends PBaseCompareable<R, T, Temporal> {
/**
* Construct with a property name and root instance.
*
* @param name property name
* @param root the root query bean instance
*/
public PBaseTime(String name, R root) {
super(name, root);
}
/**
* Construct with additional path prefix.
*/
public PBaseTime(String name, R root, String prefix) {
super(name, root, prefix);
}
/**
* Same as greater than.
*
* @param value the equal to bind value
* @return the root query bean instance
*/
public final R after(T value) {
expr().gt(_name, value);
return _root;
}
/**
* Same as less than.
*
* @param value the equal to bind value
* @return the root query bean instance
*/
public final R before(T value) {
expr().lt(_name, value);
return _root;
}
}
@@ -11,7 +11,7 @@ import java.util.Collection;
* @param <R> the root query bean type
* @param <T> the number type
*/
public abstract class PBaseValueEqual<R, T> extends TQPropertyBase<R> {
public abstract class PBaseValueEqual<R, T, BT> extends TQPropertyBase<R, BT> {
/**
* Construct with a property name and root instance.
@@ -89,7 +89,7 @@ public abstract class PBaseValueEqual<R, T> extends TQPropertyBase<R> {
* @param other the other property to compare
* @return the root query bean instance
*/
public final R eq(TQProperty<?> other) {
public final R eq(TQProperty<?, BT> other) {
expr().raw(_name + " = " + other.propertyName());
return _root;
}
@@ -152,7 +152,7 @@ public abstract class PBaseValueEqual<R, T> extends TQPropertyBase<R> {
* @param other the other property to compare
* @return the root query bean instance
*/
public final R ne(TQProperty<?> other) {
public final R ne(TQProperty<?, BT> other) {
expr().raw(_name + " <> " + other.propertyName());
return _root;
}
@@ -5,7 +5,7 @@ package io.ebean.typequery;
*
* @param <R> the root query bean type
*/
public final class PBoolean<R> extends PBaseValueEqual<R, Boolean> {
public final class PBoolean<R> extends PBaseValueEqual<R, Boolean, Boolean> {
/**
* Construct with a property name and root instance.
@@ -5,7 +5,7 @@ package io.ebean.typequery;
*
* @param <R> the root query bean type
*/
public final class PByteArray<R> extends PBaseValueEqual<R, byte[]> {
public final class PByteArray<R> extends PBaseValueEqual<R, byte[], Object> {
/**
* Construct with a property name and root instance.
@@ -24,5 +24,4 @@ public final class PByteArray<R> extends PBaseValueEqual<R, byte[]> {
super(name, root, prefix);
}
}
@@ -7,7 +7,7 @@ import io.ebean.types.Cidr;
*
* @param <R> the root query bean type
*/
public final class PCidr<R> extends PBaseValueEqual<R, Cidr> {
public final class PCidr<R> extends PBaseString<R, Cidr> {
/**
* Construct with a property name and root instance.
@@ -7,7 +7,7 @@ import java.util.Currency;
*
* @param <R> the root query bean type
*/
public final class PCurrency<R> extends PBaseValueEqual<R,Currency> {
public final class PCurrency<R> extends PBaseString<R, Currency> {
/**
* Construct with a property name and root instance.
@@ -1,12 +1,12 @@
package io.ebean.typequery;
/**
* BigDecimal property.
* Enum property.
*
* @param <E> the enum specific type
* @param <R> the root query bean type
*/
public final class PEnum<R,E> extends PBaseValueEqual<R,E> {
public final class PEnum<R, E> extends PBaseValueEqual<R, E, Object> {
/**
* Construct with a property name and root instance.
@@ -9,7 +9,7 @@ package io.ebean.typequery;
*
* @param <R> the root query bean type
*/
public final class PFile<R> extends TQPropertyBase<R> {
public final class PFile<R> extends TQPropertyBase<R, Object> {
/**
* Construct with a property name and root instance.
@@ -7,7 +7,7 @@ import io.ebean.types.Inet;
*
* @param <R> the root query bean type
*/
public final class PInet<R> extends PBaseValueEqual<R, Inet> {
public final class PInet<R> extends PBaseString<R, Inet> {
/**
* Construct with a property name and root instance.
@@ -7,8 +7,7 @@ import java.net.InetAddress;
*
* @param <R> the root query bean type
*/
public final class PInetAddress<R> extends PBaseValueEqual<R,InetAddress> {
public final class PInetAddress<R> extends PBaseString<R, InetAddress> {
/**
* Construct with a property name and root instance.
@@ -8,7 +8,7 @@ import org.joda.time.LocalTime;
*
* @param <R> the root query bean type
*/
public final class PJodaLocalTime<R> extends PBaseNumber<R,LocalTime> {
public final class PJodaLocalTime<R> extends PBaseTime<R, LocalTime> {
/**
* Construct with a property name and root instance.
@@ -17,7 +17,7 @@ package io.ebean.typequery;
*
* @param <R> the root query bean type
*/
public final class PJson<R> extends TQPropertyBase<R> {
public final class PJson<R> extends TQPropertyBase<R, String> {
/**
* Construct with a property name and root instance.
@@ -8,7 +8,7 @@ import java.time.LocalTime;
*
* @param <R> the root query bean type
*/
public final class PLocalTime<R> extends PBaseNumber<R,LocalTime> {
public final class PLocalTime<R> extends PBaseTime<R, LocalTime> {
/**
* Construct with a property name and root instance.
@@ -7,7 +7,7 @@ import java.time.OffsetDateTime;
*
* @param <R> the root query bean type
*/
public final class POffsetDateTime<R> extends PBaseNumber<R,OffsetDateTime> {
public final class POffsetDateTime<R> extends PBaseDate<R,OffsetDateTime> {
/**
* Construct with a property name and root instance.
@@ -7,7 +7,7 @@ import java.time.OffsetTime;
*
* @param <R> the root query bean type
*/
public final class POffsetTime<R> extends PBaseNumber<R,OffsetTime> {
public final class POffsetTime<R> extends PBaseTime<R, OffsetTime> {
/**
* Construct with a property name and root instance.
@@ -1,13 +1,12 @@
package io.ebean.typequery;
/**
* Property for classes that are serialized/deserialized by
* ScalarType/AttributeConverter.
* Property for classes that are serialized/deserialized by ScalarType/AttributeConverter.
*
* @param <R> the root query bean type
* @param <D> the scalar type
*/
public final class PScalar<R, D> extends PBaseValueEqual<R, D> {
public final class PScalar<R, D> extends PBaseValueEqual<R, D, Object> {
/**
* Construct with a property name and root instance.
@@ -8,7 +8,7 @@ package io.ebean.typequery;
* @param <R> the root query bean type
* @param <D> the scalar type
*/
public final class PScalarComparable<R, D extends Comparable<D>> extends PBaseCompareable<R, D> {
public final class PScalarComparable<R, D extends Comparable<D>> extends PBaseCompareable<R, D, Object> {
/**
* Construct with a property name and root instance.
@@ -5,7 +5,7 @@ package io.ebean.typequery;
*
* @param <R> the root query bean type
*/
public final class PString<R> extends PBaseCompareable<R, String> {
public final class PString<R> extends PBaseCompareable<R, String, String> {
/**
* Construct with a property name and root instance.
@@ -8,7 +8,7 @@ import java.sql.Time;
*
* @param <R> the root query bean type
*/
public final class PTime<R> extends PBaseNumber<R,Time> {
public final class PTime<R> extends PBaseTime<R,Time> {
/**
* Construct with a property name and root instance.
@@ -7,7 +7,7 @@ import java.util.TimeZone;
*
* @param <R> the root query bean type
*/
public final class PTimeZone<R> extends PBaseValueEqual<R,TimeZone> {
public final class PTimeZone<R> extends PBaseString<R, TimeZone> {
/**
* Construct with a property name and root instance.
@@ -7,7 +7,7 @@ import java.util.UUID;
*
* @param <R> the root query bean type
*/
public final class PUuid<R> extends PBaseValueEqual<R,UUID> {
public final class PUuid<R> extends PBaseValueEqual<R, UUID, Object> {
/**
* Construct with a property name and root instance.
@@ -16,7 +16,7 @@ public final class PUuid<R> extends PBaseValueEqual<R,UUID> {
* @param root the root query bean instance
*/
public PUuid(String name, R root) {
super(name , root);
super(name, root);
}
/**
@@ -7,7 +7,7 @@ import java.time.ZoneId;
*
* @param <R> the root query bean type
*/
public final class PZoneId<R> extends PBaseValueEqual<R,ZoneId> {
public final class PZoneId<R> extends PBaseString<R, ZoneId> {
/**
* Construct with a property name and root instance.
@@ -7,7 +7,7 @@ import java.time.ZoneOffset;
*
* @param <R> the root query bean type
*/
public final class PZoneOffset<R> extends PBaseValueEqual<R,ZoneOffset> {
public final class PZoneOffset<R> extends PBaseString<R, ZoneOffset> {
/**
* Construct with a property name and root instance.
@@ -7,7 +7,7 @@ import java.time.ZonedDateTime;
*
* @param <R> the root query bean type
*/
public final class PZonedDateTime<R> extends PBaseCompareable<R, ZonedDateTime> {
public final class PZonedDateTime<R> extends PBaseDate<R, ZonedDateTime> {
/**
* Construct with a property name and root instance.
@@ -26,25 +26,4 @@ public final class PZonedDateTime<R> extends PBaseCompareable<R, ZonedDateTime>
super(name, root, prefix);
}
/**
* Same as greater than.
*
* @param value the equal to bind value
* @return the root query bean instance
*/
public R after(ZonedDateTime value) {
expr().gt(_name, value);
return _root;
}
/**
* Same as less than.
*
* @param value the equal to bind value
* @return the root query bean instance
*/
public R before(ZonedDateTime value) {
expr().lt(_name, value);
return _root;
}
}
@@ -17,7 +17,7 @@ import java.util.Set;
* @param <R> the specific root query bean type (e.g. QCustomer)
*/
@SuppressWarnings("rawtypes")
public abstract class TQAssocBean<T, R> extends TQProperty<R> {
public abstract class TQAssocBean<T, R> extends TQProperty<R, Object> {
private static final FetchConfig FETCH_DEFAULT = FetchConfig.ofDefault();
private static final FetchConfig FETCH_QUERY = FetchConfig.ofQuery();
@@ -111,7 +111,7 @@ public abstract class TQAssocBean<T, R> extends TQProperty<R> {
* Eagerly fetch this association fetching some of the properties.
*/
@SafeVarargs
protected final R fetchProperties(TQProperty<?>... props) {
protected final R fetchProperties(TQProperty<?, ?>... props) {
return fetchWithProperties(FETCH_DEFAULT, props);
}
@@ -119,7 +119,7 @@ public abstract class TQAssocBean<T, R> extends TQProperty<R> {
* Eagerly fetch query this association fetching some of the properties.
*/
@SafeVarargs
protected final R fetchQueryProperties(TQProperty<?>... props) {
protected final R fetchQueryProperties(TQProperty<?, ?>... props) {
return fetchWithProperties(FETCH_QUERY, props);
}
@@ -127,7 +127,7 @@ public abstract class TQAssocBean<T, R> extends TQProperty<R> {
* Eagerly fetch this association using L2 bean cache.
*/
@SafeVarargs
protected final R fetchCacheProperties(TQProperty<?>... props) {
protected final R fetchCacheProperties(TQProperty<?, ?>... props) {
return fetchWithProperties(FETCH_CACHE, props);
}
@@ -135,12 +135,12 @@ public abstract class TQAssocBean<T, R> extends TQProperty<R> {
* Eagerly fetch query this association fetching some of the properties.
*/
@SafeVarargs
protected final R fetchLazyProperties(TQProperty<?>... props) {
protected final R fetchLazyProperties(TQProperty<?, ?>... props) {
return fetchWithProperties(FETCH_LAZY, props);
}
@SafeVarargs
private R fetchWithProperties(FetchConfig config, TQProperty<?>... props) {
private R fetchWithProperties(FetchConfig config, TQProperty<?, ?>... props) {
spiQuery().fetchProperties(_name, properties(props), config);
return _root;
}
@@ -173,13 +173,13 @@ public abstract class TQAssocBean<T, R> extends TQProperty<R> {
}
private SpiQueryFetch spiQuery() {
return (SpiQueryFetch)((TQRootBean) _root).query();
return (SpiQueryFetch) ((TQRootBean) _root).query();
}
@SafeVarargs
private Set<String> properties(TQProperty<?>... props) {
private Set<String> properties(TQProperty<?, ?>... props) {
Set<String> set = new LinkedHashSet<>();
for (TQProperty<?> prop : props) {
for (TQProperty<?, ?> prop : props) {
set.add(prop.propertyName());
}
return set;
@@ -6,12 +6,12 @@ import io.ebean.Query;
/**
* A property used in type query.
*
* @param <R> The type of the owning root bean
* @param <R> The type of the owning root bean
* @param <BT> The base type, one of String, Number, Temporal, Boolean, Object.
*/
public class TQProperty<R> implements Query.Property {
public class TQProperty<R, BT> implements Query.Property<BT> {
protected final String _name;
protected final R _root;
/**
@@ -41,7 +41,7 @@ public class TQProperty<R> implements Query.Property {
* Internal method to return the underlying expression list.
*/
protected final ExpressionList<?> expr() {
return ((TQRootBean<?,?>) _root).peekExprList();
return ((TQRootBean<?, ?>) _root).peekExprList();
}
/**
@@ -3,9 +3,10 @@ package io.ebean.typequery;
/**
* Base scalar property.
*
* @param <R> The type of the owning root bean
* @param <R> The type of the owning root bean
* @param <BT> The base type of the property
*/
public class TQPropertyBase<R> extends TQProperty<R> {
public abstract class TQPropertyBase<R, BT> extends TQProperty<R, BT> {
/**
* Construct with a property name and root instance.
@@ -263,14 +263,14 @@ public abstract class TQRootBean<T, R> {
* @param properties the list of properties to fetch
*/
@SafeVarargs
public final R select(TQProperty<R>... properties) {
public final R select(TQProperty<R, ?>... properties) {
((SpiQueryFetch) query).selectProperties(properties(properties));
return root;
}
private Set<String> properties(Query.Property[] properties) {
private Set<String> properties(Query.Property<?>[] properties) {
Set<String> props = new LinkedHashSet<>();
for (Query.Property property : properties) {
for (Query.Property<?> property : properties) {
props.add(property.toString());
}
return props;
@@ -261,7 +261,7 @@ public class QOrderTest {
.add(gt(coalesce(o.customer.version, 0), 42))
.id.lt(12)
.endOr()
.query();
.query();
query.findList();
@@ -15,8 +15,7 @@ public class TestStdFunctions {
@Test
void coalesceLike() {
var name = Query.Property.of("name");
Query.Property<String> name = Query.Property.of("name");
var query = DB.find(Customer.class)
.select(coalesce(name, "na").toString())
.where()
+1 -1
View File
@@ -113,7 +113,7 @@
<annotationProcessorPath>
<groupId>io.ebean</groupId>
<artifactId>kotlin-querybean-generator</artifactId>
<version>13.7.0</version>
<version>13.10.2-SNAPSHOT</version>
</annotationProcessorPath>
</annotationProcessorPaths>
</configuration>
@@ -14,7 +14,6 @@ class KotlinLangAdapter implements LangAdapter {
@Override
public void alias(Append writer, String shortName) {
writer.append(" companion object {").eol();
writer.append(" /**").eol();
writer.append(" * shared 'Alias' instance used to provide").eol();
@@ -33,7 +32,6 @@ class KotlinLangAdapter implements LangAdapter {
@Override
public void assocBeanConstructor(Append writer, String shortName) {
writer.append(" constructor(name: String, root: R) : super(name, root)").eol();
writer.eol();
writer.append(" constructor(name: String, root: R, prefix: String) : super(name, root, prefix)").eol();
@@ -41,7 +39,6 @@ class KotlinLangAdapter implements LangAdapter {
@Override
public void fetch(Append writer, String origShortName) {
writeAssocBeanFetch(writer, origShortName, "", "Eagerly fetch this association loading the specified properties.");
writeAssocBeanFetch(writer, origShortName, "Query", "Eagerly fetch this association using a 'query join' loading the specified properties.");
writeAssocBeanFetch(writer, origShortName, "Cache", "Eagerly fetch this association using L2 cache.");
@@ -49,26 +46,21 @@ class KotlinLangAdapter implements LangAdapter {
}
private void writeAssocBeanFetch(Append writer, String origShortName, String fetchType, String comment) {
// fun fetch(vararg properties: TQProperty<QContact>): R {
// fun fetch(vararg properties: TQProperty<QContact,?>): R {
// return fetchProperties(*properties)
// }
writer.append(" /**").eol();
writer.append(" * ").append(comment).eol();
writer.append(" */").eol();
writer.append(" fun fetch%s(vararg properties: TQProperty<Q%s>) : R {", fetchType, origShortName).eol();
writer.append(" fun fetch%s(vararg properties: TQProperty<Q%s,Any>) : R {", fetchType, origShortName).eol();
writer.append(" return fetch%sProperties(*properties)", fetchType).eol();
writer.append(" }").eol();
writer.eol();
}
@Override
public void rootBeanConstructor(Append writer, String shortName, String dbName) {
String name = (dbName == null) ? "default" : dbName;
writer.append(" /**").eol();
writer.append(" * Construct using the %s Database.", name).eol();
writer.append(" */").eol();
@@ -106,7 +98,6 @@ class KotlinLangAdapter implements LangAdapter {
@Override
public void fieldDefn(Append writer, String propertyName, String typeDefn) {
writer.append(" lateinit var %s: ", propertyName);
if (typeDefn.endsWith(",Integer>")) {
typeDefn = typeDefn.replace(",Integer>", ",Int>");
@@ -275,7 +275,7 @@ class SimpleQueryBeanWriter {
writer.append(" * ").append(comment).eol();
writer.append(" */").eol();
writer.append(" @SafeVarargs @SuppressWarnings(\"varargs\")").eol();
writer.append(" public final R fetch%s(TQProperty<Q%s>... properties) {", fetchType, origShortName).eol();
writer.append(" public final R fetch%s(TQProperty<Q%s,?>... properties) {", fetchType, origShortName).eol();
writer.append(" return fetch%sProperties(properties);", fetchType).eol();
writer.append(" }").eol();
writer.eol();