|
| 1 | +package org.javalite.activejdbc.dialects; |
| 2 | + |
| 3 | +import org.javalite.activejdbc.MetaModel; |
| 4 | + |
| 5 | +import java.util.ArrayList; |
| 6 | +import java.util.List; |
| 7 | + |
| 8 | +/** |
| 9 | + * @author William Janssen, Arjo Poldervaart |
| 10 | + */ |
| 11 | + |
| 12 | +public class DB2Dialect extends DefaultDialect { |
| 13 | + private final List<String> EMPTY_LIST = new ArrayList<String>(); |
| 14 | + |
| 15 | + @Override |
| 16 | + public String formSelect(String tableName, String[] columns, String subQuery, List<String> orderBys, long limit, long offset) { |
| 17 | + // if table name is null, sub query contains a full SQL statement |
| 18 | + // we will need a more complex query if offset != -1 |
| 19 | + // example: |
| 20 | + // SELECT * FROM (SELECT ROW_NUMBER() OVER(ORDER BY item_number) as ROWNUMBER, items.* from items WHERE item_description like ?) as TEMP WHERE TEMP.ROWNUMBER BETWEEN 271 AND 280 |
| 21 | + // select * from (select row_number() over(order by item_number) as rownumber, ORIG.* from (select * from items where item_description like '%2%') as ORIG) as TEMP WHERE TEMP.ROWNUMBER BETWEEN 271 AND 280 |
| 22 | + boolean needOffset = offset != -1; |
| 23 | + boolean needLimit = limit != -1; |
| 24 | + StringBuilder fullQuery = new StringBuilder(subQuery == null? 0: subQuery.length()); |
| 25 | + |
| 26 | + if (needOffset) { |
| 27 | + // first create inner query without order by |
| 28 | + StringBuilder innerQuery = new StringBuilder(subQuery == null? 0: subQuery.length()); |
| 29 | + appendSelect(innerQuery, tableName, columns, null, subQuery, EMPTY_LIST); |
| 30 | + |
| 31 | + fullQuery.append("SELECT * FROM (SELECT ROW_NUMBER() OVER("); |
| 32 | + appendOrderBy(fullQuery, orderBys); |
| 33 | + fullQuery.append(") AS ROWNUMBER, ORIG.* from ("); |
| 34 | + fullQuery.append(innerQuery.toString()); |
| 35 | + fullQuery.append(") as ORIG) as TEMP WHERE TEMP.ROWNUMBER "); |
| 36 | + if (needLimit) { |
| 37 | + fullQuery.append(" BETWEEN "); |
| 38 | + fullQuery.append(offset+1); |
| 39 | + fullQuery.append(" AND "); |
| 40 | + fullQuery.append(offset+limit); |
| 41 | + } else { |
| 42 | + fullQuery.append(" > "); |
| 43 | + fullQuery.append(offset); |
| 44 | + } |
| 45 | + |
| 46 | + } else { |
| 47 | + appendSelect(fullQuery, tableName, columns, null, subQuery, orderBys); |
| 48 | + if (needLimit) { |
| 49 | + fullQuery.append(" FETCH FIRST ").append(limit).append(" ROWS ONLY"); |
| 50 | + } |
| 51 | + } |
| 52 | + |
| 53 | + return fullQuery.toString(); |
| 54 | + } |
| 55 | + |
| 56 | + @Override |
| 57 | + protected void appendEmptyRow(MetaModel metaModel, StringBuilder query) { |
| 58 | + query.append('(').append(metaModel.getIdName()).append(") VALUES (DEFAULT)"); |
| 59 | + } |
| 60 | +} |
0 commit comments