mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Merge pull request #3171 from ebean-orm/feature/filterMany-raw-expression
FIX for filterMany with raw expression with single SQL query
This commit is contained in:
@@ -2,6 +2,9 @@ package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebeaninternal.api.*;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.deploy.BeanProperty;
|
||||
import io.ebeaninternal.server.deploy.BeanPropertyAssoc;
|
||||
import io.ebeaninternal.server.deploy.DeployPropertyParser;
|
||||
import io.ebeaninternal.server.persist.MultiValueWrapper;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -11,6 +14,7 @@ final class RawExpression extends NonPrepareExpression {
|
||||
|
||||
final String sql;
|
||||
final Object[] values;
|
||||
private String prefixPath;
|
||||
|
||||
RawExpression(String sql, Object[] values) {
|
||||
this.sql = sql;
|
||||
@@ -51,9 +55,39 @@ final class RawExpression extends NonPrepareExpression {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prefixProperty(String path) {
|
||||
this.prefixPath = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSql(SpiExpressionRequest request) {
|
||||
request.parse(sql);
|
||||
if (prefixPath == null) {
|
||||
request.parse(sql);
|
||||
} else {
|
||||
BeanDescriptor<?> descriptor = request.descriptor();
|
||||
BeanProperty beanProperty = descriptor.findPropertyFromPath(prefixPath);
|
||||
BeanPropertyAssoc bpa = (BeanPropertyAssoc)beanProperty;
|
||||
DeployPropertyParser parser = bpa.targetDescriptor().parser();
|
||||
request.append(filterManyPaths(prefixPath, parser.parse(sql)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static String filterManyPaths(String prefix, String raw) {
|
||||
final StringBuilder sb = new StringBuilder(raw.length() + 50);
|
||||
int lastPos = 0;
|
||||
int nextPos = raw.indexOf("${");
|
||||
while (nextPos > -1) {
|
||||
sb.append(raw.substring(lastPos, nextPos)).append("${").append(prefix);
|
||||
if (raw.charAt(nextPos + 2) != '}') {
|
||||
sb.append('.');
|
||||
}
|
||||
lastPos = nextPos + 2;
|
||||
nextPos = raw.indexOf("${", nextPos + 2);
|
||||
}
|
||||
sb.append(raw.substring(lastPos));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -74,4 +74,22 @@ public class RawExpressionTest extends BaseExpressionTest {
|
||||
query.queryBindKey(bindValuesKey);
|
||||
return bindValuesKey;
|
||||
}
|
||||
|
||||
@Test
|
||||
void filterManyPaths_one() {
|
||||
String result = RawExpression.filterManyPaths("contacts", "${}first is not null");
|
||||
assertThat(result).isEqualTo("${contacts}first is not null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void filterManyPaths_nested() {
|
||||
String result = RawExpression.filterManyPaths("contacts", "${address}city");
|
||||
assertThat(result).isEqualTo("${contacts.address}city");
|
||||
}
|
||||
|
||||
@Test
|
||||
void filterManyPaths_2() {
|
||||
String result = RawExpression.filterManyPaths("contacts", "${}first ${}last");
|
||||
assertThat(result).isEqualTo("${contacts}first ${contacts}last");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,18 +134,40 @@ public class TestQueryFilterMany extends BaseTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_with_findOne() {
|
||||
|
||||
public void test_with_findOne_rawSeparateQuery() {
|
||||
ResetBasicData.reset();
|
||||
|
||||
LoggedSql.start();
|
||||
Customer customer = DB.find(Customer.class)
|
||||
.setMaxRows(1)
|
||||
.order().asc("id")
|
||||
.fetch("orders")
|
||||
.filterMany("orders").raw("1 = 0")
|
||||
.filterMany("orders").raw("orderDate is not null")
|
||||
.findOne();
|
||||
|
||||
assertThat(customer).isNotNull();
|
||||
List<String> sql = LoggedSql.stop();
|
||||
assertThat(sql).hasSize(2);
|
||||
assertThat(sql.get(0)).contains("from o_customer t0 order by");
|
||||
assertThat(sql.get(1)).contains("from o_order t0 join o_customer t1 on t1.id = t0.kcustomer_id where");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_with_findOne_rawSameQuery() {
|
||||
ResetBasicData.reset();
|
||||
|
||||
LoggedSql.start();
|
||||
var result = DB.find(Customer.class)
|
||||
.order().asc("id")
|
||||
.fetch("orders")
|
||||
.filterMany("orders").raw("orderDate is not null")
|
||||
.findList();
|
||||
|
||||
assertThat(result).isNotEmpty();
|
||||
List<String> sql = LoggedSql.stop();
|
||||
assertThat(sql).hasSize(1);
|
||||
assertThat(sql.get(0)).contains("from o_customer t0 left join o_order t1");
|
||||
assertThat(sql.get(0)).contains("where t1.order_date is not null");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user