001package io.ebean.config.dbplatform; 002 003/** 004 * Adds the ROW_NUMBER() OVER function to a query. 005 */ 006public class RowNumberSqlLimiter implements SqlLimiter { 007 008 /** 009 * ROW_NUMBER() OVER (ORDER BY 010 */ 011 private static final String ROW_NUMBER_OVER = "row_number() over (order by "; 012 013 /** 014 * ) as rn, 015 */ 016 private static final String ROW_NUMBER_AS = ") as rn, "; 017 018 private final String rowNumberWindowAlias; 019 020 /** 021 * Specify the name of the rowNumberWindowAlias. 022 */ 023 public RowNumberSqlLimiter(String rowNumberWindowAlias) { 024 this.rowNumberWindowAlias = rowNumberWindowAlias; 025 } 026 027 public RowNumberSqlLimiter() { 028 this("as limitresult"); 029 } 030 031 @Override 032 public SqlLimitResponse limit(SqlLimitRequest request) { 033 034 String dbSql = request.getDbSql(); 035 036 StringBuilder sb = new StringBuilder(60 + dbSql.length()); 037 038 int firstRow = request.getFirstRow(); 039 040 int lastRow = request.getMaxRows(); 041 if (lastRow > 0) { 042 lastRow += firstRow; 043 } 044 045 sb.append("select * from ( "); 046 047 sb.append("select "); 048 if (request.isDistinct()) { 049 sb.append("distinct "); 050 } 051 052 sb.append(ROW_NUMBER_OVER); 053 sb.append(request.getDbOrderBy()); 054 sb.append(ROW_NUMBER_AS); 055 056 sb.append(dbSql); 057 058 sb.append(" ) "); 059 sb.append(rowNumberWindowAlias); 060 sb.append(" where "); 061 if (firstRow > 0) { 062 sb.append(" rn > ").append(firstRow); 063 if (lastRow > 0) { 064 sb.append(" and "); 065 } 066 } 067 if (lastRow > 0) { 068 sb.append(" rn <= ").append(lastRow); 069 } 070 071 String sql = request.getDbPlatform().completeSql(sb.toString(), request.getOrmQuery()); 072 073 return new SqlLimitResponse(sql, true); 074 } 075}