#1581 - ENH: Add query.asUpdate() ... to convert a query into an UpdateQuery (typically with query beans)

This commit is contained in:
rob bygrave
2018-12-19 14:45:33 +13:00
parent 8fc6c4c648
commit 138b587ff7
7 changed files with 106 additions and 2 deletions
+1 -1
View File
@@ -9,7 +9,7 @@
<groupId>io.ebean</groupId>
<artifactId>ebean</artifactId>
<version>11.29.2-SNAPSHOT</version>
<version>11.30.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>ebean</name>
@@ -128,6 +128,38 @@ public interface ExpressionList<T> {
*/
<D> DtoQuery<D> asDto(Class<D> dtoClass);
/**
* Return the underlying query as an UpdateQuery.
* <p>
* Typically this is used with query beans to covert a query bean
* query into an UpdateQuery like the examples below.
* </p>
*
* <pre>{@code
*
* int rowsUpdated = new QCustomer()
* .name.startsWith("Rob")
* .asUpdate()
* .set("active", false)
* .update();;
*
* }</pre>
*
* <pre>{@code
*
* int rowsUpdated = new QContact()
* .notes.note.startsWith("Make Inactive")
* .email.endsWith("@foo.com")
* .customer.id.equalTo(42)
* .asUpdate()
* .set("inactive", true)
* .setRaw("email = lower(email)")
* .update();
*
* }</pre>
*/
UpdateQuery<T> asUpdate();
/**
* Execute using "for update" clause which results in the DB locking the record.
*/
+32 -1
View File
@@ -244,6 +244,38 @@ public interface Query<T> {
*/
<D> DtoQuery<D> asDto(Class<D> dtoClass);
/**
* Convert the query to a UpdateQuery.
* <p>
* Typically this is used with query beans to covert a query bean
* query into an UpdateQuery like the examples below.
* </p>
*
* <pre>{@code
*
* int rowsUpdated = new QCustomer()
* .name.startsWith("Rob")
* .asUpdate()
* .set("active", false)
* .update();;
*
* }</pre>
*
* <pre>{@code
*
* int rowsUpdated = new QContact()
* .notes.note.startsWith("Make Inactive")
* .email.endsWith("@foo.com")
* .customer.id.equalTo(42)
* .asUpdate()
* .set("inactive", true)
* .setRaw("email = lower(email)")
* .update();
*
* }</pre>
*/
UpdateQuery<T> asUpdate();
/**
* Cancel the query execution if supported by the underlying database and
* driver.
@@ -1329,7 +1361,6 @@ public interface Query<T> {
* count:1 orderStatus:COMPLETE
*
* }</pre>
*
*/
Query<T> setCountDistinct(CountDistinctOrder orderBy);
@@ -18,6 +18,7 @@ import io.ebean.Pairs;
import io.ebean.Query;
import io.ebean.QueryIterator;
import io.ebean.Transaction;
import io.ebean.UpdateQuery;
import io.ebean.Version;
import io.ebean.event.BeanQueryRequest;
import io.ebean.search.Match;
@@ -302,6 +303,11 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
return query.asDto(dtoClass);
}
@Override
public UpdateQuery<T> asUpdate() {
return query.asUpdate();
}
@Override
public Query<T> setIncludeSoftDeletes() {
return query.setIncludeSoftDeletes();
@@ -17,6 +17,7 @@ import io.ebean.Pairs;
import io.ebean.Query;
import io.ebean.QueryIterator;
import io.ebean.Transaction;
import io.ebean.UpdateQuery;
import io.ebean.Version;
import io.ebean.event.BeanQueryRequest;
import io.ebean.search.Match;
@@ -349,6 +350,11 @@ class JunctionExpression<T> implements SpiJunction<T>, SpiExpression, Expression
return exprList.asDto(dtoClass);
}
@Override
public UpdateQuery<T> asUpdate() {
return exprList.asUpdate();
}
@Override
public Query<T> setIncludeSoftDeletes() {
return exprList.setIncludeSoftDeletes();
@@ -22,6 +22,7 @@ import io.ebean.QueryIterator;
import io.ebean.QueryType;
import io.ebean.RawSql;
import io.ebean.Transaction;
import io.ebean.UpdateQuery;
import io.ebean.Version;
import io.ebean.bean.CallStack;
import io.ebean.bean.ObjectGraphNode;
@@ -296,6 +297,11 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
return server.findDto(dtoClass, this);
}
@Override
public UpdateQuery<T> asUpdate() {
return new DefaultUpdateQuery<>(this);
}
@Override
public BeanDescriptor<T> getBeanDescriptor() {
return beanDescriptor;
@@ -75,6 +75,29 @@ public class UpdateQueryTest extends BaseTestCase {
assertThat(ormQueryMetrics.get(0).getLabel()).isEqualTo("updateAll");
}
@Test
public void query_asUpdate() {
ResetBasicData.reset();
LoggedSqlCollector.start();
int rows = server().find(Customer.class)
.where()
.gt("id", 1000)
.asUpdate()
.setRaw("status = status")
.setLabel("asUpdate")
.update();
List<String> sql = LoggedSqlCollector.stop();
assertThat(sql).hasSize(1);
assertThat(rows).isEqualTo(0);
assertThat(sql.get(0)).contains("update o_customer set status = status where id > ?");
}
@Test
public void update_withTransactionBatch() {