001: /**
002: * Objective Database Abstraction Layer (ODAL)
003: * Copyright (c) 2004, The ODAL Development Group
004: * All rights reserved.
005: * For definition of the ODAL Development Group please refer to LICENCE.txt file
006: *
007: * Distributable under LGPL license.
008: * See terms of license at gnu.org.
009: */package com.completex.objective.components.persistency.core.impl;
010:
011: import com.completex.objective.components.log.Log;
012: import com.completex.objective.components.persistency.AbstractParameters;
013: import com.completex.objective.components.persistency.LifeCycleController;
014: import com.completex.objective.components.persistency.ResultableQueryManager;
015: import com.completex.objective.components.persistency.core.ResultSetCtl;
016: import com.completex.objective.components.persistency.core.ResultSetExecutor;
017: import com.completex.objective.components.persistency.core.ResultSetIterator;
018: import com.completex.objective.components.persistency.core.impl.query.QueryContext;
019: import com.completex.objective.components.persistency.transact.Transaction;
020: import com.completex.objective.components.persistency.type.MultipartCollection;
021:
022: import java.sql.PreparedStatement;
023: import java.sql.ResultSet;
024: import java.sql.SQLException;
025: import java.util.Collection;
026:
027: /**
028: * ResultSetExecutor implementation that is sutable for all the statements that
029: * have result sets retrieved trough statement.getMoreResults() method (as opposed to
030: * refenrence cursor ones)
031: *
032: * @author Gennady Krizhevsky
033: */
034: public class QueryResultSetExecutor extends AbstractResultSetExecutor
035: implements ResultSetExecutor {
036:
037: QueryResultSetExecutor() {
038: }
039:
040: public QueryResultSetExecutor(Log logger,
041: BasicDatabasePersistencyImpl persistency,
042: ResultSetCtl resultSetCtl) {
043: super (logger, persistency, resultSetCtl);
044: }
045:
046: public void execute(Transaction transaction,
047: PreparedStatement statement, ResultableQueryManager query,
048: ResultSetCtl resultSetCtl, MultipartCollection results,
049: LifeCycleController controller, boolean firstOnly,
050: QueryContext queryContext) throws SQLException {
051: boolean rc = statement.execute();
052: int index = 0;
053: if (rc) {
054: index = retrieve(transaction, statement, resultSetCtl,
055: query, index, results, controller, queryContext);
056: while (statement.getMoreResults()
057: && statement.getUpdateCount() == -1) {
058: if (!firstOnly) {
059: index = retrieve(transaction, statement,
060: resultSetCtl, query, index, results,
061: controller, queryContext);
062: }
063: }
064: }
065: }
066:
067: private int retrieve(Transaction transaction,
068: PreparedStatement statement, ResultSetCtl resultSetCtl,
069: ResultableQueryManager query, int index,
070: MultipartCollection results,
071: LifeCycleController controller, QueryContext queryContext)
072: throws SQLException {
073: ResultSet resultSet = statement.getResultSet();
074: try {
075: resultSetCtl.retrieve(transaction, query, resultSet, index,
076: results, controller, queryContext);
077: } finally {
078: closeRs(resultSet);
079: }
080: index++;
081: return index;
082: }
083:
084: public Collection executeFetch(DatabaseTransactionImpl transaction,
085: ResultableQueryManager query, ResultSetCtl resultSetCtl,
086: LifeCycleController controller, QueryContext queryContext)
087: throws SQLException {
088: if (query.isClosed()) {
089: BasicDatabasePersistencyImpl.warn(logger,
090: "Attempt to executeQueryFetch from closed query");
091: return query.getMultipleResultFactory()
092: .nullCollectionFactory().newCollection();
093: }
094: query.setRetrievedCount(0);
095: ResultSetWrapper resultSetWrapper = (ResultSetWrapper) query
096: .getResultSetWrapper();
097: PreparedStatementWrapper statementWrapper = query
098: .getStatementWrapper();
099: PreparedStatement statement = statementWrapper.getStatement();
100: ResultSet resultSet;
101: int index = 0;
102: //
103: // Execute query if this is the 1st time we access it:
104: //
105: boolean hasResults = executeStatementIfNeeded(resultSetWrapper,
106: statement, query);
107:
108: MultipartCollection results = new MultipartCollection();
109: if (hasResults) {
110: if (resultSetWrapper == null) {
111: resultSet = statement.getResultSet();
112: resultSetWrapper = new ResultSetWrapper(resultSet,
113: index);
114: transaction.addMultiPageResultSet(resultSetWrapper);
115: query.setResultSetWrapper(resultSetWrapper);
116: } else {
117: resultSet = resultSetWrapper.getResultSet();
118: }
119: index = resultSetWrapper.getIndex();
120: resultSetCtl.retrieve(transaction, query, resultSet, index,
121: results, controller, queryContext);
122: if (query.getRetrievedCount() == 0) {
123: if (statement.getMoreResults()
124: && statement.getUpdateCount() == -1) {
125: resultSetWrapper.close();
126: index++;
127: resultSet = statement.getResultSet();
128: resultSetWrapper = new ResultSetWrapper(resultSet,
129: index);
130: transaction.addMultiPageResultSet(resultSetWrapper);
131: query.setResultSetWrapper(resultSetWrapper);
132: query.setRetrievedCount(-1);
133: }
134: }
135: }
136: return results.getFirst();
137: }
138:
139: public ResultSetIterator resultSetIterator(
140: PreparedStatement statement, AbstractParameters parameters)
141: throws SQLException {
142: return new ResultSetIteratorImpl(statement);
143: }
144:
145: static class ResultSetIteratorImpl implements ResultSetIterator {
146: private PreparedStatement statement;
147: private ResultSet resultSet;
148: private int resultSetIndex = -1;
149: private boolean hasFirst;
150:
151: public ResultSetIteratorImpl(PreparedStatement statement)
152: throws SQLException {
153: this .hasFirst = statement.execute();
154: this .statement = statement;
155: }
156:
157: public boolean next() throws SQLException {
158: ResultSet resultSet;
159: if (!hasFirst) {
160: return false;
161: }
162: resultSetIndex++;
163: if (resultSetIndex > 0) {
164: if (statement.getMoreResults()
165: && statement.getUpdateCount() == -1) {
166: resultSet = statement.getResultSet();
167: } else {
168: resultSet = null;
169: }
170: } else if (resultSetIndex == 0) {
171: resultSet = statement.getResultSet();
172: } else {
173: throw new RuntimeException("Unexpected index value: "
174: + resultSetIndex);
175: }
176: this .resultSet = resultSet;
177: return hasResultSet();
178: }
179:
180: public ResultSet getResultSet() throws SQLException {
181: return resultSet;
182: }
183:
184: public boolean hasResultSet() {
185: return resultSet != null;
186: }
187:
188: public boolean isAfterLast() {
189: return !hasResultSet();
190: }
191:
192: public int getResultSetIndex() {
193: return resultSetIndex;
194: }
195:
196: }
197:
198: }
|