001: /*
002: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: * $Id: LimitOffsetCompensator.java 3634 2007-01-08 21:42:24Z gbevin $
007: */
008: package com.uwyn.rife.database.capabilities;
009:
010: import com.uwyn.rife.database.DbPreparedStatement;
011: import com.uwyn.rife.database.DbResultSet;
012: import com.uwyn.rife.database.VirtualParameters;
013: import com.uwyn.rife.database.VirtualParametersHandler;
014: import com.uwyn.rife.database.exceptions.DatabaseException;
015: import com.uwyn.rife.database.queries.Query;
016: import com.uwyn.rife.database.queries.QueryParameterType;
017: import com.uwyn.rife.database.queries.QueryParameters;
018: import java.sql.SQLException;
019:
020: public class LimitOffsetCompensator implements VirtualParametersHandler {
021: private boolean mUseRelativeForScrolling = false;
022:
023: public void setUseRelativeForScrolling(boolean useRelativeForCursors) {
024: mUseRelativeForScrolling = useRelativeForCursors;
025: }
026:
027: public void handleCapablePreparedStatement(
028: DbPreparedStatement statement) throws DatabaseException {
029: Query query = statement.getQuery();
030: if (query != null) {
031: // obtain capabilities
032: Capabilities capabilities = query.getCapabilities();
033: if (capabilities != null) {
034: // handle limit and offset capabilities
035: if (capabilities.containsKey(Capability.LIMIT)) {
036: // limit the fetch size of the resultset
037: int max_rows = 0;
038: int limit = (Integer) capabilities
039: .get(Capability.LIMIT);
040: statement.setFetchSize(limit);
041: max_rows += limit;
042:
043: // limit the maximum number of rows
044: if (capabilities.containsKey(Capability.OFFSET)) {
045: max_rows += (Integer) capabilities
046: .get(Capability.OFFSET);
047: }
048: if (max_rows != 0) {
049: statement.setMaxRows(max_rows);
050: }
051: }
052: // handle limit and offset parameter capabilities
053: else if (capabilities
054: .containsKey(Capability.LIMIT_PARAMETER)) {
055: QueryParameters parameters = query.getParameters();
056: if (parameters != null) {
057: QueryParameters virtual_query_parameters = parameters
058: .getNewInstance();
059:
060: virtual_query_parameters
061: .addTypedParameter(
062: QueryParameterType.LIMIT,
063: (String) capabilities
064: .get(Capability.LIMIT_PARAMETER));
065: if (capabilities
066: .containsKey(Capability.OFFSET_PARAMETER)) {
067: virtual_query_parameters
068: .addTypedParameter(
069: QueryParameterType.OFFSET,
070: (String) capabilities
071: .get(Capability.OFFSET_PARAMETER));
072: }
073:
074: VirtualParameters virtual_parameters = new VirtualParameters(
075: virtual_query_parameters, this );
076: statement
077: .setVirtualParameters(virtual_parameters);
078: }
079: }
080: }
081: }
082: }
083:
084: public void handleValues(DbPreparedStatement statement)
085: throws DatabaseException {
086: Query query = statement.getQuery();
087: if (query != null) {
088: // obtain capabilities
089: Capabilities capabilities = query.getCapabilities();
090: if (capabilities != null) {
091: // handle limit and offset capabilities
092: if (capabilities
093: .containsKey(Capability.LIMIT_PARAMETER)) {
094: // limit the fetch size of the resultset
095: int max_rows = 0;
096: String limit_parameter_name = (String) capabilities
097: .get(Capability.LIMIT_PARAMETER);
098: int limit = Integer
099: .parseInt(String
100: .valueOf(statement
101: .getVirtualParameterValue(limit_parameter_name)));
102: statement.setFetchSize(limit);
103: max_rows += limit;
104:
105: // limit the maximum number of rows
106: if (capabilities
107: .containsKey(Capability.OFFSET_PARAMETER)) {
108: String offset_parameter_name = (String) capabilities
109: .get(Capability.OFFSET_PARAMETER);
110: int offset = Integer
111: .parseInt(String
112: .valueOf(statement
113: .getVirtualParameterValue(offset_parameter_name)));
114: max_rows += offset;
115: }
116: if (max_rows != 0) {
117: statement.setMaxRows(max_rows);
118: }
119: }
120: }
121: }
122: }
123:
124: public void handleCapableResultSet(DbPreparedStatement statement)
125: throws DatabaseException {
126: DbResultSet resultset = statement.getResultSet();
127:
128: // obtain capabilities
129: Capabilities capabilities = statement.getQuery()
130: .getCapabilities();
131: if (capabilities != null
132: && (capabilities.containsKey(Capability.LIMIT) || capabilities
133: .containsKey(Capability.LIMIT_PARAMETER))) {
134: int offset = -1;
135:
136: // handle limit and offset capabilities
137: if (capabilities.containsKey(Capability.OFFSET)) {
138: offset = (Integer) capabilities.get(Capability.OFFSET);
139: } else if (capabilities
140: .containsKey(Capability.OFFSET_PARAMETER)) {
141: String parameter_name = (String) capabilities
142: .get(Capability.OFFSET_PARAMETER);
143: offset = Integer.parseInt(String.valueOf(statement
144: .getVirtualParameterValue(parameter_name)));
145: }
146:
147: // apply the offset
148: if (offset > 0) {
149: try {
150: if (mUseRelativeForScrolling) {
151: resultset.relative(offset);
152: } else {
153: while (offset > 0) {
154: resultset.next();
155: offset--;
156: }
157: }
158: } catch (SQLException e) {
159: throw new DatabaseException(e);
160: }
161: }
162: }
163: }
164: }
|