diff --git a/ebean-api/src/main/java/io/ebean/StdOperators.java b/ebean-api/src/main/java/io/ebean/StdOperators.java
index 40bf84916..1ab0c55cf 100644
--- a/ebean-api/src/main/java/io/ebean/StdOperators.java
+++ b/ebean-api/src/main/java/io/ebean/StdOperators.java
@@ -4,43 +4,75 @@ import io.ebean.Query.Property;
import java.util.Collection;
+/**
+ * Standard Operators for use with strongly typed query construction.
+ *
+ * This is currently deemed to be experimental and subject to change.
+ */
@Deprecated(since = "experimental")
public final class StdOperators {
// ---- Functions ---- //
+ /**
+ * Sum of the given property.
+ */
public static Property sum(Property extends Number> property) {
return Property.of("sum(" + property + ")");
}
+ /**
+ * Count of the given property.
+ */
public static Property count(Property> property) {
return Property.of("count(" + property + ")");
}
+ /**
+ * Average of the given property.
+ */
public static Property avg(Property property) {
return Property.of("avg(" + property + ")");
}
+ /**
+ * Max of the given property.
+ */
public static Property max(Property property) {
return Property.of("max(" + property + ")");
}
+ /**
+ * Min of the given property.
+ */
public static Property min(Property property) {
return Property.of("min(" + property + ")");
}
+ /**
+ * Coalesce of the property and value.
+ */
public static Property coalesce(Property property, Object value) {
return Property.of("coalesce(" + property.toString() + "," + sqlValue(value) + ")");
}
+ /**
+ * Lower of the given property.
+ */
public static Property lower(Property property) {
return Property.of("lower(" + property + ")");
}
+ /**
+ * Upper of the given property.
+ */
public static Property upper(Property property) {
return Property.of("upper(" + property + ")");
}
+ /**
+ * Concat of the given property and values or other properties.
+ */
public static Property concat(Property> property, Object... values) {
StringBuilder expression = new StringBuilder(50);
expression.append("concat(").append(property.toString());
@@ -52,146 +84,248 @@ public final class StdOperators {
}
private static String sqlConcatString(Object value) {
- String asStr = String.valueOf(value);
- return (value instanceof Property || isSqlQuoted(asStr)) ? asStr : "'" + value + "'";
- }
-
- private static boolean isSqlQuoted(String asStr) {
- return asStr.length() > 0 && asStr.charAt(0) == '\'';
+ if (value instanceof Property) {
+ return value.toString();
+ } else {
+ return sqlQuote(value);
+ }
}
+ /**
+ * Allows numbers to be unquoted.
+ */
private static String sqlValue(Object value) {
if (value instanceof Property || value instanceof Number) {
return value.toString();
} else {
- return "'" + value + "'";
+ return sqlQuote(value);
}
}
+ /**
+ * SQL quoted escaping single quotes.
+ */
+ private static String sqlQuote(Object value) {
+ return "'" + String.valueOf(value).replace("'", "''") + "'";
+ }
+
// ---- Operators ---- //
+ /**
+ * Equal to - for a property and value.
+ */
public static Expression eq(Property property, T value) {
return Expr.eq(property.toString(), value);
}
+ /**
+ * Equal to - for a property and sub-query.
+ */
public static Expression eq(Property property, Query> subQuery) {
return Expr.in(property.toString(), subQuery);
}
+ /**
+ * Equal to or null - for a property and value.
+ */
public static Expression eqOrNull(Property property, T value) {
return Expr.factory().eqOrNull(property.toString(), value);
}
+ /**
+ * Not equal to - for a property and value.
+ */
public static Expression ne(Property property, T value) {
return Expr.ne(property.toString(), value);
}
+ /**
+ * Not equal to - for a property and sub-query.
+ */
public static Expression ne(Property property, Query> subQuery) {
return Expr.ne(property.toString(), subQuery);
}
+ /**
+ * Greater than - for a property and value.
+ */
public static Expression gt(Property property, T value) {
return Expr.gt(property.toString(), value);
}
+ /**
+ * Greater than - for a property and sub-query.
+ */
public static Expression gt(Property property, Query> subQuery) {
return Expr.gt(property.toString(), subQuery);
}
+ /**
+ * Greater than or null - for a property and value.
+ */
public static Expression gtOrNull(Property property, T value) {
return Expr.factory().gtOrNull(property.toString(), value);
}
+ /**
+ * Greater than or equal to - for a property and value.
+ */
public static Expression ge(Property property, T value) {
return Expr.ge(property.toString(), value);
}
+ /**
+ * Greater than or equal to - for a property and sub-query.
+ */
public static Expression ge(Property property, Query> subQuery) {
return Expr.ge(property.toString(), subQuery);
}
+ /**
+ * Greater than or null - for a property and value.
+ */
public static Expression geOrNull(Property property, T value) {
return Expr.factory().geOrNull(property.toString(), value);
}
+ /**
+ * Less than - for a property and value.
+ */
public static Expression lt(Property property, T value) {
return Expr.lt(property.toString(), value);
}
+ /**
+ * Less than - for a property and sub-query.
+ */
public static Expression lt(Property property, Query> subQuery) {
return Expr.lt(property.toString(), subQuery);
}
+ /**
+ * Less than or null - for a property and value.
+ */
public static Expression ltOrNull(Property property, T value) {
return Expr.factory().ltOrNull(property.toString(), value);
}
+ /**
+ * Greater than or equal to - for a property and value.
+ */
public static Expression le(Property property, T value) {
return Expr.le(property.toString(), value);
}
+ /**
+ * Greater than or equal to - for a property and sub-query.
+ */
public static Expression le(Property property, Query> subQuery) {
return Expr.le(property.toString(), subQuery);
}
+ /**
+ * Greater than or equal to or null - for a property and value.
+ */
public static Expression leOrNull(Property property, T value) {
return Expr.factory().leOrNull(property.toString(), value);
}
+ /**
+ * In range - for a property and values.
+ */
public static Expression inRange(Property property, T lowValue, T highValue) {
return Expr.factory().inRange(property.toString(), lowValue, highValue);
}
+ /**
+ * In range - for properties and a value.
+ */
public static Expression inRange(Property lowProperty, Property highProperty, T value) {
return Expr.factory().inRangeWith(lowProperty.toString(), highProperty.toString(), value);
}
+ /**
+ * In range - for properties.
+ */
public static Expression inRange(Property lowProperty, Property property, Property highProperty) {
return Expr.factory().inRangeWithProperties(lowProperty.toString(), property.toString(), highProperty.toString());
}
+ /**
+ * In - for a given property and collection of values.
+ */
public static Expression in(Property property, Collection value) {
return Expr.in(property.toString(), value);
}
+ /**
+ * In - for a given property and sub-query.
+ */
public static Expression in(Property property, Query> subQuery) {
return Expr.in(property.toString(), subQuery);
}
+ /**
+ * In or empty - for a given property and collection of values.
+ */
public static Expression inOrEmpty(Property property, Collection value) {
return Expr.inOrEmpty(property.toString(), value);
}
+ /**
+ * Not In - for a given property and collection of values.
+ */
public static Expression notIn(Property property, Collection value) {
return Expr.factory().notIn(property.toString(), value);
}
+ /**
+ * Not In - for a given property and sub-query.
+ */
public static Expression notIn(Property property, Query> subQuery) {
return Expr.factory().notIn(property.toString(), subQuery);
}
// ---- String operators ---- //
+ /**
+ * Like - for a given property and value.
+ */
public static Expression like(Property property, String value) {
return Expr.like(property.toString(), value);
}
+ /**
+ * Case-insensitive Like - for a given property and value.
+ */
public static Expression ilike(Property property, String value) {
return Expr.ilike(property.toString(), value);
}
+ /**
+ * Starts with - for a given property and value.
+ */
public static Expression startsWith(Property property, String value) {
return Expr.startsWith(property.toString(), value);
}
+ /**
+ * Case-insensitive starts with - for a given property and value.
+ */
public static Expression istartsWith(Property property, String value) {
return Expr.istartsWith(property.toString(), value);
}
+ /**
+ * Contains - for a given property and value.
+ */
public static Expression contains(Property property, String value) {
return Expr.contains(property.toString(), value);
}
+ /**
+ * Case-insensitive contains - for a given property and value.
+ */
public static Expression icontains(Property property, String value) {
return Expr.icontains(property.toString(), value);
}
diff --git a/ebean-api/src/test/java/io/ebean/StdFunctionsTest.java b/ebean-api/src/test/java/io/ebean/StdFunctionsTest.java
index 7c48d7fe7..a1a4c9891 100644
--- a/ebean-api/src/test/java/io/ebean/StdFunctionsTest.java
+++ b/ebean-api/src/test/java/io/ebean/StdFunctionsTest.java
@@ -66,4 +66,13 @@ class StdFunctionsTest {
assertThat(coalesce(foo, "banana").toString()).isEqualTo("coalesce(foo,'banana')");
}
+ @Test
+ void testCoalesceWithQuoted() {
+ assertThat(coalesce(foo, "ba'nana").toString()).isEqualTo("coalesce(foo,'ba''nana')");
+ }
+
+ @Test
+ void testConcatWithQuoted() {
+ assertThat(concat(foo, "ba'nana").toString()).isEqualTo("concat(foo,'ba''nana')");
+ }
}