#2873 - Query Beans: Support more TQProperty's as target value for inRangeWith()

This commit is contained in:
Rob Bygrave
2022-11-02 17:35:00 +13:00
parent 600aa10453
commit dd0ed8ea76
7 changed files with 88 additions and 0 deletions
@@ -181,6 +181,23 @@ public interface ExpressionFactory {
*/
Expression inRangeWith(String lowProperty, String highProperty, Object value);
/**
* A Property is in Range between 2 properties.
*
* <pre>{@code
*
* .orderDate.inRangeWith(QOrder.Alias.product.startDate, QOrder.Alias.product.endDate)
*
* // which equates to
* product.startDate <= orderDate and (orderDate < product.endDate or product.endDate is null)
*
* }</pre>
*
* <p>
* This is a convenience expression combining a number of simple expressions.
*/
Expression inRangeWithProperties(String propertyName, String lowProperty, String highProperty);
/**
* Between - property between the two given values.
*/
@@ -890,6 +890,23 @@ public interface ExpressionList<T> {
*/
ExpressionList<T> inRangeWith(String lowProperty, String highProperty, Object value);
/**
* A Property is in Range between 2 properties.
*
* <pre>{@code
*
* .orderDate.inRangeWith(QOrder.Alias.product.startDate, QOrder.Alias.product.endDate)
*
* // which equates to
* product.startDate <= orderDate and (orderDate < product.endDate or product.endDate is null)
*
* }</pre>
*
* <p>
* This is a convenience expression combining a number of simple expressions.
*/
ExpressionList<T> inRangeWithProperties(String propertyName, String lowProperty, String highProperty);
/**
* In Range - {@code property >= value1 and property < value2}.
* <p>
@@ -237,6 +237,11 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
return and(le(lowProperty, value), gtOrNull(highProperty, value));
}
@Override
public Expression inRangeWithProperties(String propertyName, String lowProperty, String highProperty) {
return raw(lowProperty + " <= " + propertyName + " and (" + propertyName + " < " + highProperty + " or " + highProperty + " is null)");
}
/**
* Between - property between the two given values.
*/
@@ -833,6 +833,11 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
return add(expr.inRangeWith(lowProperty, highProperty, value));
}
@Override
public ExpressionList<T> inRangeWithProperties(String propertyName, String lowProperty, String highProperty) {
return add(expr.inRangeWithProperties(propertyName, lowProperty, highProperty));
}
@Override
public ExpressionList<T> inRange(String propertyName, Object value1, Object value2) {
return add(expr.inRange(propertyName, value1, value2));
@@ -279,6 +279,11 @@ final class JunctionExpression<T> implements SpiJunction<T>, SpiExpression, Expr
return exprList.inRangeWith(lowProperty, highProperty, value);
}
@Override
public ExpressionList<T> inRangeWithProperties(String propertyName, String lowProperty, String highProperty) {
return exprList.inRangeWithProperties(propertyName, lowProperty, highProperty);
}
@Override
public ExpressionList<T> inRange(String propertyName, Object value1, Object value2) {
return exprList.inRange(propertyName, value1, value2);
@@ -200,6 +200,29 @@ public class PBaseCompareable<R, T> extends PBaseValueEqual<R, T> {
return _root;
}
/**
* A Property is in Range between 2 other properties.
*
* <pre>{@code
* var o = QOrder.alias();
*
* new QOrder()
* .orderDate.inRangeWith(o.product.startDate, o.product.endDate)
* .findList();
*
* // which equates to
* product.startDate <= orderDate and (product.endDate > orderDate or product.endDate is null)
*
* }</pre>
*
* <p>
* This is a convenience expression combining a number of simple expressions.
*/
public final R inRangeWith(TQProperty<?> lowProperty, TQProperty<?> highProperty) {
expr().inRangeWithProperties(_name, lowProperty.propertyName(), highProperty.propertyName());
return _root;
}
/**
* Between lower and upper values.
*
@@ -665,6 +665,22 @@ public class QCustomerTest {
.findList();
}
@Test
void query_inRangeWithOtherProperties() {
var c = QCustomer.alias();
Query<Customer> query = new QCustomer()
.select(c.id)
.name.inRangeWith(c.contacts.firstName, c.contacts.lastName)
.query();
// select distinct t0.id from be_customer t0
// left join be_contact t1 on t1.customer_id = t0.id
// where t1.first_name <= t0.name and (t0.name < t1.last_name or t1.last_name is null)
query.findList();
assertThat(query.getGeneratedSql()).contains(" where t1.first_name <= t0.name and (t0.name < t1.last_name or t1.last_name is null)");
}
@Test
public void query_exists() {