001package com.avaje.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 public SqlLimitResponse limit(SqlLimitRequest request) { 032 033 String dbSql = request.getDbSql(); 034 035 StringBuilder sb = new StringBuilder(60 + dbSql.length()); 036 037 int firstRow = request.getFirstRow(); 038 039 int lastRow = request.getMaxRows(); 040 if (lastRow > 0) { 041 lastRow = lastRow + firstRow; 042 } 043 044 sb.append("select * from ( "); 045 046 sb.append("select "); 047 if (request.isDistinct()) { 048 sb.append("distinct "); 049 } 050 051 sb.append(ROW_NUMBER_OVER); 052 sb.append(request.getDbOrderBy()); 053 sb.append(ROW_NUMBER_AS); 054 055 sb.append(dbSql); 056 057 sb.append(" ) "); 058 sb.append(rowNumberWindowAlias); 059 sb.append(" where "); 060 if (firstRow > 0) { 061 sb.append(" rn > ").append(firstRow); 062 if (lastRow > 0) { 063 sb.append(" and "); 064 } 065 } 066 if (lastRow > 0) { 067 sb.append(" rn <= ").append(lastRow); 068 } 069 070 String sql = request.getDbPlatform().completeSql(sb.toString(), request.getOrmQuery()); 071 072 return new SqlLimitResponse(sql, true); 073 } 074}