{
NucleusLogger.QUERY.debug(LOCALISER.msg("021046", getLanguage(), getSingleStringQuery(),
null));
}
RDBMSStoreManager storeMgr = (RDBMSStoreManager)getStoreManager();
AbstractClassMetaData acmd = ec.getMetaDataManager().getMetaDataForClass(candidateClass, clr);
SQLController sqlControl = storeMgr.getSQLController();
PreparedStatement ps = null;
try
{
if (type == Query.SELECT)
{
// Create PreparedStatement and apply parameters, result settings etc
ps = RDBMSQueryUtils.getPreparedStatementForQuery(mconn,
datastoreCompilation.getSQL(), this);
SQLStatementHelper.applyParametersToStatement(ps, ec,
datastoreCompilation.getStatementParameters(),
datastoreCompilation.getParameterNameByPosition(), parameters);
RDBMSQueryUtils.prepareStatementForExecution(ps, this, true);
registerTask(ps);
ResultSet rs = null;
try
{
rs = sqlControl.executeStatementQuery(mconn, toString(), ps);
}
finally
{
deregisterTask();
}
QueryResult qr = null;
try
{
if (inMemory)
{
// IN-MEMORY EVALUATION
ResultObjectFactory rof = storeMgr.newResultObjectFactory(acmd,
datastoreCompilation.getResultDefinitionForClass(),
RDBMSQueryUtils.useUpdateLockForQuery(this), getFetchPlan(),
candidateClass);
// Just instantiate the candidates for later in-memory processing
// TODO Use a queryResult rather than an ArrayList so we load when required
List candidates = new ArrayList();
while (rs.next())
{
candidates.add(rof.getObject(ec, rs));
}
// Perform in-memory filter/result/order etc
JavaQueryEvaluator resultMapper =
new JDOQLEvaluator(this, candidates, compilation, parameters, clr);
results = resultMapper.execute(true, true, true, true, true);
}
else
{
// IN-DATASTORE EVALUATION
ResultObjectFactory rof = null;
if (result != null)
{
// Each result row is of a result type
rof = new ResultClassROF(resultClass, datastoreCompilation.getResultDefinition());
}
else if (resultClass != null)
{
rof = new ResultClassROF(resultClass, datastoreCompilation.getResultDefinitionForClass());
}
else
{
// Each result row is a candidate object
rof = storeMgr.newResultObjectFactory(acmd,
datastoreCompilation.getResultDefinitionForClass(),
RDBMSQueryUtils.useUpdateLockForQuery(this), getFetchPlan(),
candidateClass);
}
// Create the required type of QueryResult
String resultSetType = RDBMSQueryUtils.getResultSetTypeForQuery(this);
if (resultSetType.equals("scroll-insensitive") ||
resultSetType.equals("scroll-sensitive"))
{
qr = new ScrollableQueryResult(this, rof, rs,
getResultDistinct() ? null : candidateCollection);
}
else
{
qr = new ForwardQueryResult(this, rof, rs,
getResultDistinct() ? null : candidateCollection);
}
final QueryResult qr1 = qr;
final ManagedConnection mconn1 = mconn;
ManagedConnectionResourceListener listener =
new ManagedConnectionResourceListener()
{
public void transactionFlushed(){}
public void transactionPreClose()
{
// Disconnect the query from this ManagedConnection (read in unread rows etc)
qr1.disconnect();
}
public void managedConnectionPreClose(){}
public void managedConnectionPostClose(){}
public void resourcePostClose()
{
mconn1.removeListener(this);
}
};
mconn.addListener(listener);
((AbstractRDBMSQueryResult)qr).addConnectionListener(listener);
results = qr;
}
}
finally
{
if (qr == null)
{
rs.close();
}
}
}
else if (type == Query.BULK_UPDATE)
{
// Create PreparedStatement and apply parameters, result settings etc
ps = sqlControl.getStatementForUpdate(mconn, datastoreCompilation.getSQL(), false);
SQLStatementHelper.applyParametersToStatement(ps, ec,
datastoreCompilation.getStatementParameters(),
datastoreCompilation.getParameterNameByPosition(), parameters);
RDBMSQueryUtils.prepareStatementForExecution(ps, this, false);
int[] updateResults = sqlControl.executeStatementUpdate(mconn, toString(), ps, true);
try
{
// Evict all objects of this type from the cache
ec.getNucleusContext().getLevel2Cache().evictAll(candidateClass, subclasses);
}
catch (UnsupportedOperationException uoe)
{
// Do nothing
}
results = Long.valueOf(updateResults[0]);
}
else if (type == Query.BULK_DELETE)
{
// Create PreparedStatement and apply parameters, result settings etc
// TODO Cater for multiple DELETE statements
ps = sqlControl.getStatementForUpdate(mconn, datastoreCompilation.getSQL(), false);
SQLStatementHelper.applyParametersToStatement(ps, ec,
datastoreCompilation.getStatementParameters(),
datastoreCompilation.getParameterNameByPosition(), parameters);
RDBMSQueryUtils.prepareStatementForExecution(ps, this, false);
int[] deleteResults = sqlControl.executeStatementUpdate(mconn, toString(), ps, true);
try
{
// Evict all objects of this type from the cache
ec.getNucleusContext().getLevel2Cache().evictAll(candidateClass, subclasses);
}
catch (UnsupportedOperationException uoe)
{
// Do nothing
}
results = Long.valueOf(deleteResults[0]);
}
}
catch (SQLException sqle)
{
if (((RDBMSAdapter)storeMgr.getDatastoreAdapter()).isStatementCancel(sqle))
{
throw new QueryInterruptedException("Query has been interrupted", sqle);
}
else if (((RDBMSAdapter)storeMgr.getDatastoreAdapter()).isStatementTimeout(sqle))
{
throw new QueryTimeoutException("Query has been timed out", sqle);
}
throw new NucleusException(LOCALISER.msg("021042"), sqle);
}