mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-10-24 10:38:57 +00:00
#681 - Remove SqlQuery.cancel() ... migrate to SqlQuery.findEachWhile() and stop while iterating
This commit is contained in:
@@ -21,31 +21,25 @@ import java.util.Set;
|
||||
* conversion support added.
|
||||
* </p>
|
||||
*
|
||||
* <pre class="code">
|
||||
* // its typically a good idea to use a named query
|
||||
* // and put the sql in the orm.xml instead of in your code
|
||||
* <pre>{@code
|
||||
*
|
||||
* // its typically a good idea to use a named query
|
||||
* // and put the sql in the orm.xml instead of in your code
|
||||
*
|
||||
* String sql = "select id, name from customer where name like :name and status_code = :status";
|
||||
* String sql = "select id, name from customer where name like :name and status_code = :status";
|
||||
*
|
||||
* SqlQuery sqlQuery = Ebean.createSqlQuery(sql);
|
||||
* sqlQuery.setParameter("name", "Acme%");
|
||||
* sqlQuery.setParameter("status", "ACTIVE");
|
||||
* SqlQuery sqlQuery = Ebean.createSqlQuery(sql);
|
||||
* sqlQuery.setParameter("name", "Acme%");
|
||||
* sqlQuery.setParameter("status", "ACTIVE");
|
||||
*
|
||||
* // execute the query returning a List of MapBean objects
|
||||
* List<SqlRow> list = sqlQuery.findList();
|
||||
* </pre>
|
||||
* // execute the query returning a List of MapBean objects
|
||||
* List<SqlRow> list = sqlQuery.findList();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
*/
|
||||
public interface SqlQuery extends Serializable {
|
||||
|
||||
/**
|
||||
* Cancel the query if support by the underlying database and driver.
|
||||
* <p>
|
||||
* This must be called from a different thread to the one executing the query.
|
||||
* </p>
|
||||
*/
|
||||
void cancel();
|
||||
|
||||
/**
|
||||
* Execute the query returning a list.
|
||||
*/
|
||||
|
||||
@@ -39,23 +39,9 @@ public interface SpiSqlQuery extends SqlQuery {
|
||||
*/
|
||||
int getBufferFetchSizeHint();
|
||||
|
||||
/**
|
||||
* Return true if this is a future fetch type query.
|
||||
*/
|
||||
boolean isFutureFetch();
|
||||
|
||||
/**
|
||||
* Set to true if this is a future fetch type query.
|
||||
*/
|
||||
void setFutureFetch(boolean futureFetch);
|
||||
|
||||
/**
|
||||
* Set the PreparedStatement for the purposes of supporting cancel.
|
||||
*/
|
||||
void setPreparedStatement(PreparedStatement pstmt);
|
||||
|
||||
/**
|
||||
* Return true if the query has been cancelled.
|
||||
*/
|
||||
boolean isCancelled();
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import com.avaje.ebean.SqlRow;
|
||||
import com.avaje.ebean.Transaction;
|
||||
import com.avaje.ebeaninternal.api.BindParams;
|
||||
import com.avaje.ebeaninternal.api.SpiEbeanServer;
|
||||
import com.avaje.ebeaninternal.api.SpiQuery;
|
||||
import com.avaje.ebeaninternal.api.SpiSqlQuery;
|
||||
import com.avaje.ebeaninternal.api.SpiTransaction;
|
||||
import com.avaje.ebeaninternal.server.lib.util.Str;
|
||||
@@ -46,8 +45,6 @@ public final class RelationalQueryRequest {
|
||||
|
||||
private boolean createdTransaction;
|
||||
|
||||
private SpiQuery.Type queryType;
|
||||
|
||||
private String sql;
|
||||
|
||||
private ResultSet resultSet;
|
||||
@@ -96,17 +93,14 @@ public final class RelationalQueryRequest {
|
||||
}
|
||||
|
||||
public void findEach(QueryEachConsumer<SqlRow> consumer) {
|
||||
queryType = SpiQuery.Type.ITERATE;
|
||||
queryEngine.findEach(this, consumer);
|
||||
}
|
||||
|
||||
public void findEachWhile(QueryEachWhileConsumer<SqlRow> consumer) {
|
||||
queryType = SpiQuery.Type.ITERATE;
|
||||
queryEngine.findEach(this, consumer);
|
||||
}
|
||||
|
||||
public List<SqlRow> findList() {
|
||||
queryType = SpiQuery.Type.LIST;
|
||||
return queryEngine.findList(this);
|
||||
}
|
||||
|
||||
@@ -117,13 +111,6 @@ public final class RelationalQueryRequest {
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type (List, Set or Map) that this fetch returns.
|
||||
*/
|
||||
public SpiQuery.Type getQueryType() {
|
||||
return queryType;
|
||||
}
|
||||
|
||||
public EbeanServer getEbeanServer() {
|
||||
return ebeanServer;
|
||||
}
|
||||
@@ -231,49 +218,36 @@ public final class RelationalQueryRequest {
|
||||
/**
|
||||
* Prepare and execute the SQL using the Binder.
|
||||
*/
|
||||
public boolean executeSql(Binder binder) throws SQLException {
|
||||
public void executeSql(Binder binder) throws SQLException {
|
||||
|
||||
prepareSql();
|
||||
synchronized (query) {
|
||||
if (query.isCancelled()) {
|
||||
logger.trace("Query already cancelled");
|
||||
return false;
|
||||
}
|
||||
|
||||
Connection conn = trans.getInternalConnection();
|
||||
Connection conn = trans.getInternalConnection();
|
||||
|
||||
// synchronise for query.cancel() support
|
||||
pstmt = conn.prepareStatement(sql);
|
||||
if (query.getTimeout() > 0) {
|
||||
pstmt.setQueryTimeout(query.getTimeout());
|
||||
}
|
||||
if (query.getBufferFetchSizeHint() > 0) {
|
||||
pstmt.setFetchSize(query.getBufferFetchSizeHint());
|
||||
}
|
||||
|
||||
BindParams bindParams = query.getBindParams();
|
||||
if (!bindParams.isEmpty()) {
|
||||
this.bindLog = binder.bind(bindParams, pstmt);
|
||||
}
|
||||
|
||||
if (isLogSql()) {
|
||||
String logSql = sql;
|
||||
if (TransactionManager.SQL_LOGGER.isTraceEnabled()) {
|
||||
logSql = Str.add(logSql, "; --bind(", bindLog, ")");
|
||||
}
|
||||
trans.logSql(logSql);
|
||||
}
|
||||
|
||||
setResultSet(pstmt.executeQuery());
|
||||
return true;
|
||||
// synchronise for query.cancel() support
|
||||
pstmt = conn.prepareStatement(sql);
|
||||
if (query.getTimeout() > 0) {
|
||||
pstmt.setQueryTimeout(query.getTimeout());
|
||||
}
|
||||
if (query.getBufferFetchSizeHint() > 0) {
|
||||
pstmt.setFetchSize(query.getBufferFetchSizeHint());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the query has been cancelled.
|
||||
*/
|
||||
public boolean isCancelled() {
|
||||
return query.isCancelled();
|
||||
BindParams bindParams = query.getBindParams();
|
||||
if (!bindParams.isEmpty()) {
|
||||
this.bindLog = binder.bind(bindParams, pstmt);
|
||||
}
|
||||
|
||||
if (isLogSql()) {
|
||||
String logSql = sql;
|
||||
if (TransactionManager.SQL_LOGGER.isTraceEnabled()) {
|
||||
logSql = Str.add(logSql, "; --bind(", bindLog, ")");
|
||||
}
|
||||
trans.logSql(logSql);
|
||||
}
|
||||
|
||||
setResultSet(pstmt.executeQuery());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+6
-29
@@ -3,13 +3,10 @@ package com.avaje.ebeaninternal.server.query;
|
||||
import com.avaje.ebean.QueryEachConsumer;
|
||||
import com.avaje.ebean.QueryEachWhileConsumer;
|
||||
import com.avaje.ebean.SqlRow;
|
||||
import com.avaje.ebeaninternal.api.SpiSqlQuery;
|
||||
import com.avaje.ebeaninternal.server.core.Message;
|
||||
import com.avaje.ebeaninternal.server.core.RelationalQueryEngine;
|
||||
import com.avaje.ebeaninternal.server.core.RelationalQueryRequest;
|
||||
import com.avaje.ebeaninternal.server.persist.Binder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.sql.SQLException;
|
||||
@@ -21,9 +18,6 @@ import java.util.List;
|
||||
*/
|
||||
public class DefaultRelationalQueryEngine implements RelationalQueryEngine {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DefaultRelationalQueryEngine.class);
|
||||
|
||||
|
||||
private final Binder binder;
|
||||
|
||||
private final String dbTrueValue;
|
||||
@@ -78,9 +72,7 @@ public class DefaultRelationalQueryEngine implements RelationalQueryEngine {
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
try {
|
||||
if (!request.executeSql(binder)) {
|
||||
return null;
|
||||
}
|
||||
request.executeSql(binder);
|
||||
|
||||
int maxRows = request.getMaxRows();
|
||||
|
||||
@@ -88,23 +80,12 @@ public class DefaultRelationalQueryEngine implements RelationalQueryEngine {
|
||||
|
||||
List<SqlRow> rows = new ArrayList<SqlRow>();
|
||||
|
||||
SpiSqlQuery query = request.getQuery();
|
||||
|
||||
while (request.next()) {
|
||||
SqlRow bean;
|
||||
synchronized (query) {
|
||||
if (request.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
bean = readRow(request);
|
||||
}
|
||||
if (bean != null) {
|
||||
rows.add(bean);
|
||||
loadRowCount++;
|
||||
if (loadRowCount == maxRows) {
|
||||
// break, as we have hit the max rows to fetch...
|
||||
break;
|
||||
}
|
||||
rows.add(readRow(request));
|
||||
loadRowCount++;
|
||||
if (loadRowCount == maxRows) {
|
||||
// break, as we have hit the max rows to fetch...
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,10 +107,6 @@ public class DefaultRelationalQueryEngine implements RelationalQueryEngine {
|
||||
long exeTime = System.currentTimeMillis() - startTime;
|
||||
request.getTransaction().logSummary("SqlQuery rows[" + request.getRowCount() + "] time[" + exeTime + "] bind[" + request.getBindLog() + "]");
|
||||
}
|
||||
|
||||
if (request.isCancelled()) {
|
||||
logger.debug("Query was cancelled during execution rows: {}", request.getRowCount());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,9 +7,7 @@ import com.avaje.ebean.SqlRow;
|
||||
import com.avaje.ebeaninternal.api.BindParams;
|
||||
import com.avaje.ebeaninternal.api.SpiSqlQuery;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -29,10 +27,6 @@ public class DefaultRelationalQuery implements SpiSqlQuery {
|
||||
|
||||
private int timeout;
|
||||
|
||||
private boolean futureFetch;
|
||||
|
||||
private boolean cancelled;
|
||||
|
||||
/**
|
||||
* For the purposes of cancelling the query.
|
||||
*/
|
||||
@@ -134,37 +128,10 @@ public class DefaultRelationalQuery implements SpiSqlQuery {
|
||||
return query;
|
||||
}
|
||||
|
||||
public boolean isFutureFetch() {
|
||||
return futureFetch;
|
||||
}
|
||||
|
||||
public void setFutureFetch(boolean futureFetch) {
|
||||
this.futureFetch = futureFetch;
|
||||
}
|
||||
|
||||
public void setPreparedStatement(PreparedStatement pstmt) {
|
||||
synchronized (this) {
|
||||
this.pstmt = pstmt;
|
||||
}
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
synchronized (this) {
|
||||
this.cancelled = true;
|
||||
if (pstmt != null) {
|
||||
try {
|
||||
pstmt.cancel();
|
||||
} catch (SQLException e) {
|
||||
throw new PersistenceException("Error cancelling query", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
synchronized (this) {
|
||||
return cancelled;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user