mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-10-25 07:57:39 +00:00
#278 - SqlQuery setFirstRow fail - modify SQL using LIMIT/OFFSET etc to support firstRows/maxRows
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
package com.avaje.ebean.config.dbplatform;
|
||||
|
||||
/**
|
||||
* Adds ANSI based OFFSET FETCH NEXT clauses to a SQL query.
|
||||
*/
|
||||
public class BasicSqlAnsiLimiter implements BasicSqlLimiter {
|
||||
|
||||
@Override
|
||||
public String limit(String dbSql, int firstRow, int maxRows) {
|
||||
|
||||
StringBuilder sb = new StringBuilder(50 + dbSql.length());
|
||||
|
||||
sb.append(dbSql);
|
||||
if (firstRow > 0) {
|
||||
sb.append(" ").append("offset");
|
||||
sb.append(" ").append(firstRow).append(" rows");
|
||||
}
|
||||
if (maxRows > 0) {
|
||||
sb.append(" fetch next ").append(maxRows).append(" rows only");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.avaje.ebean.config.dbplatform;
|
||||
|
||||
/**
|
||||
* Adds LIMIT OFFSET clauses to a SQL query.
|
||||
*/
|
||||
public class BasicSqlLimitOffset implements BasicSqlLimiter {
|
||||
|
||||
/**
|
||||
* LIMIT keyword.
|
||||
*/
|
||||
private static final String LIMIT = "limit";
|
||||
|
||||
/**
|
||||
* OFFSET keyword.
|
||||
*/
|
||||
private static final String OFFSET = "offset";
|
||||
|
||||
@Override
|
||||
public String limit(String dbSql, int firstRow, int maxRows) {
|
||||
|
||||
StringBuilder sb = new StringBuilder(50 + dbSql.length());
|
||||
|
||||
sb.append(dbSql);
|
||||
|
||||
if (maxRows > 0) {
|
||||
sb.append(" ").append(LIMIT);
|
||||
sb.append(" ").append(maxRows);
|
||||
}
|
||||
if (firstRow > 0) {
|
||||
sb.append(" ").append(OFFSET).append(" ");
|
||||
sb.append(firstRow);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.avaje.ebean.config.dbplatform;
|
||||
|
||||
/**
|
||||
* Simple SQL limiter for use with SqlQuery.
|
||||
*/
|
||||
public interface BasicSqlLimiter {
|
||||
|
||||
/**
|
||||
* Add basic offset/limit clause to SqlQuery query.
|
||||
*/
|
||||
String limit(String dbSql, int firstRow, int maxRows);
|
||||
}
|
||||
@@ -71,6 +71,11 @@ public class DatabasePlatform {
|
||||
*/
|
||||
protected SqlLimiter sqlLimiter = new LimitOffsetSqlLimiter();
|
||||
|
||||
/**
|
||||
* Limit/offset support for SqlQuery only.
|
||||
*/
|
||||
protected BasicSqlLimiter basicSqlLimiter = new BasicSqlLimitOffset();
|
||||
|
||||
/**
|
||||
* Mapping of JDBC to Database types.
|
||||
*/
|
||||
@@ -454,6 +459,13 @@ public class DatabasePlatform {
|
||||
return sqlLimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the BasicSqlLimiter for limit/offset of SqlQuery queries.
|
||||
*/
|
||||
public BasicSqlLimiter getBasicSqlLimiter() {
|
||||
return basicSqlLimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the DB TRUE literal (from the registered boolean ScalarType)
|
||||
*/
|
||||
|
||||
@@ -18,6 +18,7 @@ public class OraclePlatform extends DatabasePlatform {
|
||||
this.maxConstraintNameLength = 30;
|
||||
this.dbEncrypt = new OracleDbEncrypt();
|
||||
this.sqlLimiter = new RownumSqlLimiter();
|
||||
this.basicSqlLimiter = new BasicSqlAnsiLimiter();
|
||||
this.platformDdl = new Oracle10Ddl(this);
|
||||
this.historySupport = new OracleDbHistorySupport();
|
||||
|
||||
|
||||
@@ -31,8 +31,6 @@ import java.util.List;
|
||||
*/
|
||||
public final class RelationalQueryRequest {
|
||||
|
||||
private static final int GLOBAL_ROW_LIMIT = Integer.valueOf(System.getProperty("ebean.query.globallimit", "1000000"));
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(RelationalQueryRequest.class);
|
||||
|
||||
private final SpiSqlQuery query;
|
||||
@@ -212,7 +210,18 @@ public final class RelationalQueryRequest {
|
||||
// convert any named parameters if required
|
||||
sql = BindParamsParser.parse(bindParams, sql);
|
||||
}
|
||||
this.sql = sql;
|
||||
this.sql = limitOffset(sql);
|
||||
}
|
||||
|
||||
private String limitOffset(String sql) {
|
||||
|
||||
int firstRow = query.getFirstRow();
|
||||
int maxRows = query.getMaxRows();
|
||||
if (firstRow > 0 || maxRows > 0) {
|
||||
return ebeanServer.getDatabasePlatform().getBasicSqlLimiter()
|
||||
.limit(query.getQuery(), firstRow, maxRows);
|
||||
}
|
||||
return sql;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -250,13 +259,6 @@ public final class RelationalQueryRequest {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the maxRows allowed to fetch.
|
||||
*/
|
||||
public int getMaxRows() {
|
||||
return query.getMaxRows() >= 1 ? query.getMaxRows() : GLOBAL_ROW_LIMIT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the SQL executed for this query.
|
||||
*/
|
||||
|
||||
@@ -74,19 +74,9 @@ public class DefaultRelationalQueryEngine implements RelationalQueryEngine {
|
||||
try {
|
||||
request.executeSql(binder);
|
||||
|
||||
int maxRows = request.getMaxRows();
|
||||
|
||||
int loadRowCount = 0;
|
||||
|
||||
List<SqlRow> rows = new ArrayList<SqlRow>();
|
||||
|
||||
while (request.next()) {
|
||||
rows.add(readRow(request));
|
||||
loadRowCount++;
|
||||
if (loadRowCount == maxRows) {
|
||||
// break, as we have hit the max rows to fetch...
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
logSummary(request, startTime);
|
||||
|
||||
Reference in New Issue
Block a user