/**
* This allows for the rows to be fetched concurrently to the objects being built.
* This code is not currently publicly supported.
*/
protected Vector buildThreadCursoredResult(final DatabaseCall dbCall, final ResultSet resultSet, final Statement statement, final ResultSetMetaData metaData, final AbstractSession session) {
final ThreadCursoredList results = new ThreadCursoredList(20);
Runnable runnable = new Runnable() {
public void run() {
try {
session.startOperationProfile(SessionProfiler.RowFetch, dbCall.getQuery(), SessionProfiler.ALL);
try {
// Initial next was already validated before this method is called.
boolean hasNext = true;
while (hasNext) {
results.add(fetchRow(dbCall.getFields(), dbCall.getFieldsArray(), resultSet, metaData, session));
hasNext = resultSet.next();
}
resultSet.close();// This must be closed in case the statement is cached and not closed.
} catch (SQLException exception) {
//If this is a connection from an external pool then closeStatement will close the connection.
//we must test the connection before that happens.
RuntimeException exceptionToThrow = processExceptionForCommError(session, exception, dbCall);
try {// Ensure that the statement is closed, but still ensure that the real exception is thrown.
closeStatement(statement, session, dbCall);
} catch (Exception closeException) {
}
if (exceptionToThrow == null){
results.throwException(DatabaseException.sqlException(exception, dbCall, DatabaseAccessor.this, session, false));
}
results.throwException(exceptionToThrow);
} catch (RuntimeException exception) {
try {// Ensure that the statement is closed, but still ensure that the real exception is thrown.
closeStatement(statement, session, dbCall);
} catch (Exception closeException) {
}
if (exception instanceof DatabaseException) {
((DatabaseException)exception).setCall(dbCall);
}
results.throwException(exception);
} finally {
session.endOperationProfile(SessionProfiler.RowFetch, dbCall.getQuery(), SessionProfiler.ALL);
}
// This is in a separate try block to ensure that the real exception is not masked by the close exception.
try {
// Allow for caching of statement, forced closes are not cache as they failed execution so are most likely bad.
DatabaseAccessor.this.releaseStatement(statement, dbCall.getSQLString(), dbCall, session);
} catch (SQLException exception) {
//With an external connection pool the connection may be null after this call, if it is we will
//be unable to determine if it is a connection based exception so treat it as if it wasn't.
DatabaseException commException = processExceptionForCommError(session, exception, dbCall);
if (commException != null) results.throwException(commException);
results.throwException(DatabaseException.sqlException(exception, DatabaseAccessor.this, session, false));
}
} finally {
results.setIsComplete(true);
session.releaseReadConnection(DatabaseAccessor.this);
}
}
};
session.getServerPlatform().launchContainerRunnable(runnable);