mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-10-24 12:53:59 +00:00
Merge remote-tracking branch 'ebean/master' into native-uuid-sqlserver
This commit is contained in:
@@ -10,3 +10,4 @@ indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
spaces_around_operators = true
|
||||
max_line_length = 130
|
||||
|
||||
@@ -480,6 +480,36 @@ public interface ExpressionList<T> {
|
||||
*/
|
||||
Query<T> setUseQueryCache(CacheMode useCache);
|
||||
|
||||
/**
|
||||
* Extended version for setDistinct in conjunction with "findSingleAttributeList";
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* List<CountedValue<Order.Status>> orderStatusCount =
|
||||
*
|
||||
* Ebean.find(Order.class)
|
||||
* .select("status")
|
||||
* .where()
|
||||
* .gt("orderDate", LocalDate.now().minusMonths(3))
|
||||
*
|
||||
* // fetch as single attribute with a COUNT
|
||||
* .setCountDistinct(CountDistinctOrder.COUNT_DESC_ATTR_ASC)
|
||||
* .findSingleAttributeList();
|
||||
*
|
||||
* for (CountedValue<Order.Status> entry : orderStatusCount) {
|
||||
* System.out.println(" count:" + entry.getCount()+" orderStatus:" + entry.getValue() );
|
||||
* }
|
||||
*
|
||||
* // produces
|
||||
*
|
||||
* count:3 orderStatus:NEW
|
||||
* count:1 orderStatus:SHIPPED
|
||||
* count:1 orderStatus:COMPLETE
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
Query<T> setCountDistinct(CountDistinctOrder orderBy);
|
||||
|
||||
/**
|
||||
* Calls {@link #setUseQueryCache(CacheMode)} with <code>ON</code> or <code>OFF</code>.
|
||||
*
|
||||
|
||||
@@ -1279,6 +1279,32 @@ public interface Query<T> {
|
||||
|
||||
/**
|
||||
* Extended version for setDistinct in conjunction with "findSingleAttributeList";
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* List<CountedValue<Order.Status>> orderStatusCount =
|
||||
*
|
||||
* Ebean.find(Order.class)
|
||||
* .select("status")
|
||||
* .where()
|
||||
* .gt("orderDate", LocalDate.now().minusMonths(3))
|
||||
*
|
||||
* // fetch as single attribute with a COUNT
|
||||
* .setCountDistinct(CountDistinctOrder.COUNT_DESC_ATTR_ASC)
|
||||
* .findSingleAttributeList();
|
||||
*
|
||||
* for (CountedValue<Order.Status> entry : orderStatusCount) {
|
||||
* System.out.println(" count:" + entry.getCount()+" orderStatus:" + entry.getValue() );
|
||||
* }
|
||||
*
|
||||
* // produces
|
||||
*
|
||||
* count:3 orderStatus:NEW
|
||||
* count:1 orderStatus:SHIPPED
|
||||
* count:1 orderStatus:COMPLETE
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
*/
|
||||
Query<T> setCountDistinct(CountDistinctOrder orderBy);
|
||||
|
||||
|
||||
@@ -26,12 +26,10 @@ public interface RawSqlBuilder {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return a SqlRow based on the resultSet and the dbTrueValue.
|
||||
* @throws SQLException
|
||||
* Create and return a SqlRow based on the resultSet with dbTrueValue and binaryOptimizedUUID options.
|
||||
*/
|
||||
static SqlRow sqlRow(ResultSet resultSet, final String dbTrueValue) throws SQLException {
|
||||
return XServiceProvider.rawSql().sqlRow(resultSet, dbTrueValue);
|
||||
|
||||
static SqlRow sqlRow(ResultSet resultSet, final String dbTrueValue, boolean binaryOptimizedUUID) throws SQLException {
|
||||
return XServiceProvider.rawSql().sqlRow(resultSet, dbTrueValue, binaryOptimizedUUID);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -293,7 +293,7 @@ public class ServerConfig {
|
||||
/**
|
||||
* When true create a read only DataSource using readOnlyDataSourceConfig defaulting values from dataSourceConfig.
|
||||
* I believe this will default to true in some future release (as it has a nice performance benefit).
|
||||
*
|
||||
* <p>
|
||||
* autoReadOnlyDataSource is an unfortunate name for this config option but I haven't come up with a better one.
|
||||
*/
|
||||
private boolean autoReadOnlyDataSource;
|
||||
@@ -483,8 +483,7 @@ public class ServerConfig {
|
||||
|
||||
/**
|
||||
* Should the javax.validation.constraints.NotNull enforce a notNull column in DB.
|
||||
* If set to false, you have to use io.ebean.annotation.NotNull to explicityl create
|
||||
* a not null column.
|
||||
* If set to false, use io.ebean.annotation.NotNull or Column(nullable=true).
|
||||
*/
|
||||
private boolean useJavaxValidationNotNull = true;
|
||||
|
||||
@@ -3034,14 +3033,12 @@ public class ServerConfig {
|
||||
}
|
||||
|
||||
/**
|
||||
* Controlws when Ebean should generate a <code>NOT NULL</code> column.
|
||||
* If an <code>io.ebean.annotation.NotNull</code> is present, Ebean generates
|
||||
* <code>NOT NULL</code> columns
|
||||
* If set to <code>true</code> (default) Ebean generates also
|
||||
* <code>NOT NULL</code> columns when a <code>&x64;javax.validation.contstraints.NotNull</code>
|
||||
* annotation is present (and it is in <code>Default</code> group.)
|
||||
* If set to <code>false</code> the <code>&x64;javax.validation.contstraints.NotNull</code> is
|
||||
* ignored
|
||||
* Controls if Ebean should ignore <code>&x64;javax.validation.contstraints.NotNull</code>
|
||||
* with respect to generating a <code>NOT NULL</code> column.
|
||||
* <p>
|
||||
* Normally when Ebean sees javax NotNull annotation it means that column is defined as NOT NULL.
|
||||
* Set this to <code>false</code> and the javax NotNull annotation is effectively ignored (and
|
||||
* we instead use Ebean's own NotNull annotation or JPA Column(nullable=false) annotation.
|
||||
*/
|
||||
public void setUseJavaxValidationNotNull(boolean useJavaxValidationNotNull) {
|
||||
this.useJavaxValidationNotNull = useJavaxValidationNotNull;
|
||||
@@ -3091,7 +3088,6 @@ public class ServerConfig {
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Specify how UUID is stored.
|
||||
*/
|
||||
@@ -3164,5 +3160,5 @@ public class ServerConfig {
|
||||
VERSION4,
|
||||
VERSION1,
|
||||
VERSION1RND
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,10 @@ public interface SpiRawSqlService {
|
||||
|
||||
/**
|
||||
* Create based on a JDBC ResultSet.
|
||||
* @throws SQLException
|
||||
*
|
||||
* @param resultSet The ResultSet row to read as a SqlRow
|
||||
* @param dbTrueValue The DB true value
|
||||
* @param binaryOptimizedUUID Flag set to true if the UUID value is stored as optimised binary(16)
|
||||
*/
|
||||
SqlRow sqlRow(ResultSet resultSet, String dbTrueValue) throws SQLException;
|
||||
SqlRow sqlRow(ResultSet resultSet, String dbTrueValue, boolean binaryOptimizedUUID) throws SQLException;
|
||||
}
|
||||
|
||||
@@ -268,8 +268,7 @@ public class DefaultDbMigration implements DbMigration {
|
||||
if (extraDdl != null) {
|
||||
List<DdlScript> ddlScript = extraDdl.getDdlScript();
|
||||
for (DdlScript script : ddlScript) {
|
||||
if (script.isDrop() == false
|
||||
&& ExtraDdlXmlReader.matchPlatform(dbPlatform.getName(), script.getPlatforms())) {
|
||||
if (!script.isDrop() && ExtraDdlXmlReader.matchPlatform(dbPlatform.getName(), script.getPlatforms())) {
|
||||
writeExtraDdl(migrationDir, script);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package io.ebeaninternal.extraddl.model;
|
||||
|
||||
import io.ebean.util.StringHelper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.ebean.util.StringHelper;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
@@ -28,8 +27,7 @@ public class ExtraDdlXmlReader {
|
||||
}
|
||||
StringBuilder sb = new StringBuilder(300);
|
||||
for (DdlScript script : read.getDdlScript()) {
|
||||
if (script.isDrop() == drops
|
||||
&& matchPlatform(platformName, script.getPlatforms())) {
|
||||
if (script.isDrop() == drops && matchPlatform(platformName, script.getPlatforms())) {
|
||||
logger.debug("include script {}", script.getName());
|
||||
String value = script.getValue();
|
||||
sb.append(value);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebean.CacheMode;
|
||||
import io.ebean.CountDistinctOrder;
|
||||
import io.ebean.Expression;
|
||||
import io.ebean.ExpressionFactory;
|
||||
import io.ebean.ExpressionList;
|
||||
@@ -493,6 +494,10 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
|
||||
return query.setUseQueryCache(useCache);
|
||||
}
|
||||
|
||||
public Query<T> setCountDistinct(CountDistinctOrder orderBy) {
|
||||
return query.setCountDistinct(orderBy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query<T> setUseDocStore(boolean useDocsStore) {
|
||||
return query.setUseDocStore(useDocsStore);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.ebeaninternal.server.expression;
|
||||
|
||||
import io.ebean.CacheMode;
|
||||
import io.ebean.CountDistinctOrder;
|
||||
import io.ebean.Expression;
|
||||
import io.ebean.ExpressionList;
|
||||
import io.ebean.FetchPath;
|
||||
@@ -792,6 +793,11 @@ class JunctionExpression<T> implements SpiJunction<T>, SpiExpression, Expression
|
||||
return exprList.setDisableReadAuditing();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query<T> setCountDistinct(CountDistinctOrder orderBy) {
|
||||
return exprList.setCountDistinct(orderBy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExpressionList<T> startsWith(String propertyName, String value) {
|
||||
return exprList.startsWith(propertyName, value);
|
||||
|
||||
@@ -34,10 +34,11 @@ public class DRawSqlService implements SpiRawSqlService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlRow sqlRow(ResultSet resultSet, String dbTrueValue) throws SQLException {
|
||||
public SqlRow sqlRow(ResultSet resultSet, String dbTrueValue, boolean binaryOptimizedUUID) throws SQLException {
|
||||
|
||||
ResultSetMetaData meta = resultSet.getMetaData();
|
||||
int estCap = (int) (meta.getColumnCount() / 0.7f) + 1;
|
||||
DefaultSqlRow ret = new DefaultSqlRow(estCap, 0.75f, dbTrueValue);
|
||||
DefaultSqlRow ret = new DefaultSqlRow(estCap, 0.75f, dbTrueValue, binaryOptimizedUUID);
|
||||
|
||||
for (int i = 1; i <= meta.getColumnCount(); i++) {
|
||||
String name = meta.getColumnLabel(i);
|
||||
|
||||
@@ -12,9 +12,11 @@ import org.tests.inherit.Data;
|
||||
import org.tests.inherit.EUncle;
|
||||
import org.tests.model.basic.Contact;
|
||||
import org.tests.model.basic.Customer;
|
||||
import org.tests.model.basic.Order;
|
||||
import org.tests.model.basic.ResetBasicData;
|
||||
|
||||
import java.sql.Date;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -161,11 +163,11 @@ public class TestQuerySingleAttribute extends BaseTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void distinctOnIdProperty(){
|
||||
public void distinctOnIdProperty() {
|
||||
Query<Customer> query = Ebean.find(Customer.class)
|
||||
.setDistinct(true)
|
||||
.select("id")
|
||||
.setMaxRows(100);
|
||||
.setDistinct(true)
|
||||
.select("id")
|
||||
.setMaxRows(100);
|
||||
|
||||
List<String> ids = query.findSingleAttributeList();
|
||||
if (isSqlServer()) {
|
||||
@@ -185,8 +187,8 @@ public class TestQuerySingleAttribute extends BaseTestCase {
|
||||
ResetBasicData.reset();
|
||||
|
||||
Query<Customer> query = Ebean.find(Customer.class)
|
||||
.setDistinct(true)
|
||||
.fetch("billingAddress","city");
|
||||
.setDistinct(true)
|
||||
.fetch("billingAddress", "city");
|
||||
|
||||
List<String> cities = query.findSingleAttributeList();
|
||||
|
||||
@@ -200,22 +202,23 @@ public class TestQuerySingleAttribute extends BaseTestCase {
|
||||
ResetBasicData.reset();
|
||||
|
||||
Query<Contact> query = Ebean.find(Contact.class)
|
||||
.setDistinct(true)
|
||||
.fetch("customer.billingAddress","city");
|
||||
.setDistinct(true)
|
||||
.fetch("customer.billingAddress", "city");
|
||||
|
||||
List<String> cities = query.findSingleAttributeList();
|
||||
|
||||
assertThat(sqlOf(query)).contains("select distinct t2.city from contact t0 join o_customer t1 on t1.id = t0.customer_id left join o_address t2 on t2.id = t1.billing_address_id");
|
||||
assertThat(cities).contains("Auckland").containsNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void distinctSelectOnInheritedBean() {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
Query<ChildA> query = Ebean.find(ChildA.class)
|
||||
.setDistinct(true)
|
||||
.select("more");
|
||||
.setDistinct(true)
|
||||
.select("more");
|
||||
|
||||
query.findSingleAttributeList();
|
||||
assertThat(sqlOf(query)).contains("select distinct t0.more from rawinherit_parent t0 where t0.type = 'A' ");
|
||||
@@ -228,8 +231,8 @@ public class TestQuerySingleAttribute extends BaseTestCase {
|
||||
ResetBasicData.reset();
|
||||
|
||||
Query<EUncle> query = Ebean.find(EUncle.class)
|
||||
.setDistinct(true)
|
||||
.fetch("parent","more");
|
||||
.setDistinct(true)
|
||||
.fetch("parent", "more");
|
||||
|
||||
query.findSingleAttributeList();
|
||||
|
||||
@@ -239,10 +242,10 @@ public class TestQuerySingleAttribute extends BaseTestCase {
|
||||
|
||||
// hmm - same problem when not using distinct
|
||||
@Test
|
||||
public void findSingleOnIdProperty(){
|
||||
public void findSingleOnIdProperty() {
|
||||
Query<Customer> query = Ebean.find(Customer.class)
|
||||
.select("id")
|
||||
.setMaxRows(100);
|
||||
.select("id")
|
||||
.setMaxRows(100);
|
||||
|
||||
List<String> ids = query.findSingleAttributeList();
|
||||
if (isSqlServer()) {
|
||||
@@ -261,7 +264,7 @@ public class TestQuerySingleAttribute extends BaseTestCase {
|
||||
ResetBasicData.reset();
|
||||
|
||||
Query<Customer> query = Ebean.find(Customer.class)
|
||||
.fetch("billingAddress","city");
|
||||
.fetch("billingAddress", "city");
|
||||
|
||||
List<String> cities = query.findSingleAttributeList();
|
||||
|
||||
@@ -275,7 +278,7 @@ public class TestQuerySingleAttribute extends BaseTestCase {
|
||||
ResetBasicData.reset();
|
||||
|
||||
Query<ChildA> query = Ebean.find(ChildA.class)
|
||||
.select("more");
|
||||
.select("more");
|
||||
|
||||
query.findSingleAttributeList();
|
||||
assertThat(sqlOf(query)).contains("select t0.more from rawinherit_parent t0 where t0.type = 'A'");
|
||||
@@ -288,7 +291,7 @@ public class TestQuerySingleAttribute extends BaseTestCase {
|
||||
ResetBasicData.reset();
|
||||
|
||||
Query<EUncle> query = Ebean.find(EUncle.class)
|
||||
.fetch("parent","more");
|
||||
.fetch("parent", "more");
|
||||
|
||||
query.findSingleAttributeList();
|
||||
|
||||
@@ -301,7 +304,7 @@ public class TestQuerySingleAttribute extends BaseTestCase {
|
||||
ResetBasicData.reset();
|
||||
|
||||
Query<EUncle> query = Ebean.find(EUncle.class)
|
||||
.fetch("parent","more");
|
||||
.fetch("parent", "more");
|
||||
|
||||
Ebean.getDefaultServer().findSingleAttributeList(query, null);
|
||||
|
||||
@@ -315,15 +318,15 @@ public class TestQuerySingleAttribute extends BaseTestCase {
|
||||
ResetBasicData.reset();
|
||||
|
||||
Query<Data> query = Ebean.find(Data.class)
|
||||
.setDistinct(true)
|
||||
.fetch("parents","more")
|
||||
.setMaxRows(100);
|
||||
.setDistinct(true)
|
||||
.fetch("parents", "more")
|
||||
.setMaxRows(100);
|
||||
|
||||
query.findSingleAttributeList();
|
||||
|
||||
assertThat(sqlOf(query)).contains("select distinct t0.more from rawinherit_data t0 "
|
||||
+ "join rawinherit_parent_rawinherit_data t1 on t0.id = t1.rawinherit_data_id "
|
||||
+ "join parent t2 on t1.rawinherit_parent_id = t2.id");
|
||||
+ "join rawinherit_parent_rawinherit_data t1 on t0.id = t1.rawinherit_data_id "
|
||||
+ "join parent t2 on t1.rawinherit_parent_id = t2.id");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -348,7 +351,7 @@ public class TestQuerySingleAttribute extends BaseTestCase {
|
||||
|
||||
Query<Contact> query = Ebean.find(Contact.class)
|
||||
.setDistinct(true)
|
||||
.fetch("customer","billingAddress")
|
||||
.fetch("customer", "billingAddress")
|
||||
.orderBy().desc("customer.billingAddress");
|
||||
|
||||
query.findSingleAttributeList();
|
||||
@@ -362,19 +365,19 @@ public class TestQuerySingleAttribute extends BaseTestCase {
|
||||
ResetBasicData.reset();
|
||||
|
||||
Query<Contact> query = Ebean.find(Contact.class)
|
||||
.setDistinct(true)
|
||||
.fetch("customer","billingAddress")
|
||||
.where().eq("customer.billingAddress.city", "Auckland")
|
||||
.orderBy().desc("customer.billingAddress.id");
|
||||
.setDistinct(true)
|
||||
.fetch("customer", "billingAddress")
|
||||
.where().eq("customer.billingAddress.city", "Auckland")
|
||||
.orderBy().desc("customer.billingAddress.id");
|
||||
|
||||
List<Integer> ids = query.findSingleAttributeList();
|
||||
assertThat(ids).isNotEmpty();
|
||||
|
||||
assertThat(sqlOf(query)).contains("select distinct t1.billing_address_id from contact t0 "
|
||||
+ "join o_customer t1 on t1.id = t0.customer_id " // two spaces!
|
||||
+ "left join o_address t2 on t2.id = t1.billing_address_id "
|
||||
+ "where t2.city = ? "
|
||||
+ "order by t1.billing_address_id desc");
|
||||
+ "join o_customer t1 on t1.id = t0.customer_id " // two spaces!
|
||||
+ "left join o_address t2 on t2.id = t1.billing_address_id "
|
||||
+ "where t2.city = ? "
|
||||
+ "order by t1.billing_address_id desc");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -383,19 +386,19 @@ public class TestQuerySingleAttribute extends BaseTestCase {
|
||||
ResetBasicData.reset();
|
||||
|
||||
Query<Contact> query = Ebean.find(Contact.class)
|
||||
.setDistinct(true)
|
||||
.fetch("customer","billingAddress")
|
||||
.where().eq("customer.billingAddress.city", "Auckland")
|
||||
.orderBy().desc("customer.billingAddress.id");
|
||||
.setDistinct(true)
|
||||
.fetch("customer", "billingAddress")
|
||||
.where().eq("customer.billingAddress.city", "Auckland")
|
||||
.orderBy().desc("customer.billingAddress.id");
|
||||
|
||||
List<Short> ids = query.findSingleAttributeList();
|
||||
assertThat(ids).isNotEmpty();
|
||||
|
||||
assertThat(sqlOf(query)).contains("select distinct t1.billing_address_id from contact t0 "
|
||||
+ "join o_customer t1 on t1.id = t0.customer_id "
|
||||
+ "left join o_address t2 on t2.id = t1.billing_address_id "
|
||||
+ "where t2.city = ? "
|
||||
+ "order by t1.billing_address_id desc");
|
||||
+ "join o_customer t1 on t1.id = t0.customer_id "
|
||||
+ "left join o_address t2 on t2.id = t1.billing_address_id "
|
||||
+ "where t2.city = ? "
|
||||
+ "order by t1.billing_address_id desc");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -404,19 +407,19 @@ public class TestQuerySingleAttribute extends BaseTestCase {
|
||||
ResetBasicData.reset();
|
||||
|
||||
Query<Contact> query = Ebean.find(Contact.class)
|
||||
.setDistinct(true)
|
||||
.fetch("customer","billingAddress")
|
||||
.where().eq("customer.billingAddress.city", "Auckland")
|
||||
.orderBy().desc("customer.billingAddress.id");
|
||||
.setDistinct(true)
|
||||
.fetch("customer", "billingAddress")
|
||||
.where().eq("customer.billingAddress.city", "Auckland")
|
||||
.orderBy().desc("customer.billingAddress.id");
|
||||
|
||||
List<Integer> ids = query.findSingleAttributeList();
|
||||
assertThat(ids).isNotEmpty();
|
||||
|
||||
assertThat(sqlOf(query)).contains("select distinct t1.billing_address_id from contact t0 "
|
||||
+ "join o_customer t1 on t1.id = t0.customer_id "
|
||||
+ "left join o_address t2 on t2.id = t1.billing_address_id "
|
||||
+ "where t2.city = ? "
|
||||
+ "order by t1.billing_address");
|
||||
+ "join o_customer t1 on t1.id = t0.customer_id "
|
||||
+ "left join o_address t2 on t2.id = t1.billing_address_id "
|
||||
+ "where t2.city = ? "
|
||||
+ "order by t1.billing_address");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -425,21 +428,22 @@ public class TestQuerySingleAttribute extends BaseTestCase {
|
||||
ResetBasicData.reset();
|
||||
|
||||
Query<Contact> query = Ebean.find(Contact.class)
|
||||
.setDistinct(true)
|
||||
.fetch("customer","billingAddress")
|
||||
.where().eq("customer.shippingAddress.city", "Auckland") // query on shippingAddress
|
||||
.orderBy().desc("customer.billingAddress.id");
|
||||
.setDistinct(true)
|
||||
.fetch("customer", "billingAddress")
|
||||
.where().eq("customer.shippingAddress.city", "Auckland") // query on shippingAddress
|
||||
.orderBy().desc("customer.billingAddress.id");
|
||||
|
||||
List<Short> ids = query.findSingleAttributeList();
|
||||
assertThat(ids).isNotEmpty();
|
||||
|
||||
assertThat(sqlOf(query)).contains("select distinct t1.billing_address_id from contact t0 "
|
||||
+ "join o_customer t1 on t1.id = t0.customer_id "
|
||||
+ "left join o_address t2 on t2.id = t1.shipping_address_id "
|
||||
+ "where t2.city = ? "
|
||||
+ "order by t1.billing_address_id desc");
|
||||
+ "join o_customer t1 on t1.id = t0.customer_id "
|
||||
+ "left join o_address t2 on t2.id = t1.shipping_address_id "
|
||||
+ "where t2.city = ? "
|
||||
+ "order by t1.billing_address_id desc");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void distinctWithCascadedFetchCount() {
|
||||
|
||||
@@ -450,15 +454,15 @@ public class TestQuerySingleAttribute extends BaseTestCase {
|
||||
assertThat(count).isGreaterThanOrEqualTo(12);
|
||||
|
||||
Query<Contact> query = Ebean.find(Contact.class)
|
||||
.select("firstName");
|
||||
.select("firstName");
|
||||
|
||||
List<CountedValue<Object>> list1 = query
|
||||
.setCountDistinct(CountDistinctOrder.ATTR_ASC)
|
||||
.setCountDistinct(CountDistinctOrder.ATTR_ASC)
|
||||
|
||||
.findSingleAttributeList();
|
||||
.findSingleAttributeList();
|
||||
assertThat(sqlOf(query)).contains("select r1.attribute_, count(*) from ("
|
||||
+ "select t0.first_name as attribute_ from contact t0"
|
||||
+ ") r1 group by r1.attribute_ order by r1.attribute_");
|
||||
+ "select t0.first_name as attribute_ from contact t0"
|
||||
+ ") r1 group by r1.attribute_ order by r1.attribute_");
|
||||
assertThat(list1.get(0)).isInstanceOf(CountedValue.class);
|
||||
// FIXME: These asserts will fail, because other tests will interfere. see #1298
|
||||
//assertThat(list1.toString()).isEqualTo("[3: Bugs1, 1: Fiona, 3: Fred1, 1: Jack, 3: Jim1, 1: Tracy]");
|
||||
@@ -466,85 +470,103 @@ public class TestQuerySingleAttribute extends BaseTestCase {
|
||||
|
||||
query = Ebean.find(Contact.class).select("firstName");
|
||||
list1 = query
|
||||
.setCountDistinct(CountDistinctOrder.ATTR_DESC)
|
||||
.findSingleAttributeList();
|
||||
.setCountDistinct(CountDistinctOrder.ATTR_DESC)
|
||||
.findSingleAttributeList();
|
||||
assertThat(list1.get(0)).isInstanceOf(CountedValue.class);
|
||||
//assertThat(list1.toString()).isEqualTo("[1: Tracy, 3: Jim1, 1: Jack, 3: Fred1, 1: Fiona, 3: Bugs1]");
|
||||
|
||||
query = Ebean.find(Contact.class).select("firstName");
|
||||
list1 = query
|
||||
.setCountDistinct(CountDistinctOrder.COUNT_ASC_ATTR_DESC)
|
||||
.findSingleAttributeList();
|
||||
.setCountDistinct(CountDistinctOrder.COUNT_ASC_ATTR_DESC)
|
||||
.findSingleAttributeList();
|
||||
assertThat(list1.get(0)).isInstanceOf(CountedValue.class);
|
||||
//assertThat(list1.toString()).isEqualTo("[1: Tracy, 1: Jack, 1: Fiona, 3: Jim1, 3: Fred1, 3: Bugs1]");
|
||||
|
||||
query = Ebean.find(Contact.class).fetch("customer.shippingAddress","line1");//("firstName")
|
||||
query = Ebean.find(Contact.class).fetch("customer.shippingAddress", "line1");//("firstName")
|
||||
List<CountedValue<Object>> list2 = query
|
||||
.setCountDistinct(CountDistinctOrder.ATTR_ASC)
|
||||
.findSingleAttributeList();
|
||||
.setCountDistinct(CountDistinctOrder.ATTR_ASC)
|
||||
.findSingleAttributeList();
|
||||
assertThat(sqlOf(query)).contains("select r1.attribute_, count(*) from ("
|
||||
+ "select t2.line_1 as attribute_ "
|
||||
+ "from contact t0 join o_customer t1 on t1.id = t0.customer_id "
|
||||
+ "left join o_address t2 on t2.id = t1.shipping_address_id "
|
||||
+ ") r1 group by r1.attribute_ order by r1.attribute_");
|
||||
+ "select t2.line_1 as attribute_ "
|
||||
+ "from contact t0 join o_customer t1 on t1.id = t0.customer_id "
|
||||
+ "left join o_address t2 on t2.id = t1.shipping_address_id "
|
||||
+ ") r1 group by r1.attribute_ order by r1.attribute_");
|
||||
assertThat(list2.get(0)).isInstanceOf(CountedValue.class);
|
||||
//assertThat(list2.toString()).isEqualTo("[1: null, 3: 1 Banana St, 5: 12 Apple St, 3: 15 Kumera Way]");
|
||||
|
||||
|
||||
query = Ebean.find(Contact.class).select("firstName")
|
||||
.where().eq("customer.shippingAddress.line1", "12 Apple St").query();
|
||||
.where().eq("customer.shippingAddress.line1", "12 Apple St").query();
|
||||
List<CountedValue<Object>> list3 = query
|
||||
.setCountDistinct(CountDistinctOrder.ATTR_ASC)
|
||||
.findSingleAttributeList();
|
||||
.setCountDistinct(CountDistinctOrder.ATTR_ASC)
|
||||
.findSingleAttributeList();
|
||||
assertThat(sqlOf(query)).contains("select r1.attribute_, count(*) from ("
|
||||
+ "select t0.first_name as attribute_ from contact t0 "
|
||||
+ "join o_customer t1 on t1.id = t0.customer_id "
|
||||
+ "left join o_address t2 on t2.id = t1.shipping_address_id where t2.line_1 = ? "
|
||||
+ ") r1 group by r1.attribute_ order by r1.attribute_");
|
||||
+ "select t0.first_name as attribute_ from contact t0 "
|
||||
+ "join o_customer t1 on t1.id = t0.customer_id "
|
||||
+ "left join o_address t2 on t2.id = t1.shipping_address_id where t2.line_1 = ? "
|
||||
+ ") r1 group by r1.attribute_ order by r1.attribute_");
|
||||
assertThat(list3.get(0)).isInstanceOf(CountedValue.class);
|
||||
//assertThat(list3.toString()).isEqualTo("[1: Bugs1, 1: Fiona, 1: Fred1, 1: Jim1, 1: Tracy]");
|
||||
|
||||
|
||||
query = Ebean.find(Contact.class).fetch("customer.billingAddress","line1")
|
||||
.where().or()
|
||||
.ne("customer.shippingAddress.line1", "12 Apple St")
|
||||
.isNull("customer.shippingAddress.line1")
|
||||
.endOr().query();
|
||||
query = Ebean.find(Contact.class).fetch("customer.billingAddress", "line1")
|
||||
.where().or()
|
||||
.ne("customer.shippingAddress.line1", "12 Apple St")
|
||||
.isNull("customer.shippingAddress.line1")
|
||||
.endOr().query();
|
||||
List<CountedValue<Object>> list4 = query
|
||||
.setCountDistinct(CountDistinctOrder.ATTR_ASC)
|
||||
.findSingleAttributeList();
|
||||
.setCountDistinct(CountDistinctOrder.ATTR_ASC)
|
||||
.findSingleAttributeList();
|
||||
assertThat(sqlOf(query)).contains("select r1.attribute_, count(*) from ("
|
||||
+ "select t2.line_1 as attribute_ "
|
||||
+ "from contact t0 join o_customer t1 on t1.id = t0.customer_id "
|
||||
+ "left join o_address t2 on t2.id = t1.billing_address_id "
|
||||
+ "left join o_address t3 on t3.id = t1.shipping_address_id "
|
||||
+ "where (t3.line_1 <> ? or t3.line_1 is null ) "
|
||||
+ ") r1 group by r1.attribute_ order by r1.attribute_");
|
||||
+ "select t2.line_1 as attribute_ "
|
||||
+ "from contact t0 join o_customer t1 on t1.id = t0.customer_id "
|
||||
+ "left join o_address t2 on t2.id = t1.billing_address_id "
|
||||
+ "left join o_address t3 on t3.id = t1.shipping_address_id "
|
||||
+ "where (t3.line_1 <> ? or t3.line_1 is null ) "
|
||||
+ ") r1 group by r1.attribute_ order by r1.attribute_");
|
||||
assertThat(list4.get(0)).isInstanceOf(CountedValue.class);
|
||||
//assertThat(list4.toString()).isEqualTo("[1: null, 3: Bos town, 3: P.O.Box 1234]");
|
||||
|
||||
|
||||
// Test Limiter for MSSQL
|
||||
query = Ebean.find(Contact.class).fetch("customer.billingAddress","line1").setFirstRow(1).setMaxRows(2);
|
||||
query = Ebean.find(Contact.class).fetch("customer.billingAddress", "line1").setFirstRow(1).setMaxRows(2);
|
||||
List<CountedValue<Object>> list5 = query
|
||||
.where().isNotNull("customer.billingAddress.line1").query()
|
||||
.setCountDistinct(CountDistinctOrder.ATTR_DESC)
|
||||
.findSingleAttributeList();
|
||||
.where().isNotNull("customer.billingAddress.line1").query()
|
||||
.setCountDistinct(CountDistinctOrder.ATTR_DESC)
|
||||
.findSingleAttributeList();
|
||||
assertThat(sqlOf(query)).contains("select r1.attribute_, count(*) from ("
|
||||
+ "select t2.line_1 as attribute_ from contact t0 "
|
||||
+ "join o_customer t1 on t1.id = t0.customer_id "
|
||||
+ "left join o_address t2 on t2.id = t1.billing_address_id "
|
||||
+ "where t2.line_1 is not null "
|
||||
+ ") r1 group by r1.attribute_ order by r1.attribute_ desc ");
|
||||
+ "select t2.line_1 as attribute_ from contact t0 "
|
||||
+ "join o_customer t1 on t1.id = t0.customer_id "
|
||||
+ "left join o_address t2 on t2.id = t1.billing_address_id "
|
||||
+ "where t2.line_1 is not null "
|
||||
+ ") r1 group by r1.attribute_ order by r1.attribute_ desc ");
|
||||
if (isSqlServer()) {
|
||||
assertThat(sqlOf(query)).endsWith(" fetch next 2 rows only");
|
||||
assertThat(sqlOf(query)).endsWith(" fetch next 2 rows only");
|
||||
} else if (isDb2()) {
|
||||
assertThat(query.getGeneratedSql()).endsWith("FETCH FIRST 2 ROWS ONLY");
|
||||
} else {
|
||||
assertThat(sqlOf(query)).endsWith(" limit 2 offset 1");
|
||||
assertThat(sqlOf(query)).endsWith(" limit 2 offset 1");
|
||||
}
|
||||
assertThat(list5.get(0)).isInstanceOf(CountedValue.class);
|
||||
//assertThat(list5.toString()).isEqualTo("[3: P.O.Box 1234, 3: Bos town]");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void example() {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
List<CountedValue<Order.Status>> orderStatusCount =
|
||||
|
||||
Ebean.find(Order.class)
|
||||
.select("status")
|
||||
.where()
|
||||
.gt("orderDate", LocalDate.now().minusMonths(3))
|
||||
.setCountDistinct(CountDistinctOrder.COUNT_DESC_ATTR_ASC)
|
||||
.findSingleAttributeList();
|
||||
|
||||
for (CountedValue<Order.Status> entry : orderStatusCount) {
|
||||
System.out.println(" count:" + entry.getCount()+" orderStatus:" + entry.getValue() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user