use of org.datanucleus.store.query.QueryResult in project datanucleus-rdbms by datanucleus.
the class JDOQLQuery method performExecute.
protected Object performExecute(Map parameters) {
if (statementReturnsEmpty) {
return Collections.EMPTY_LIST;
}
boolean inMemory = evaluateInMemory();
if (candidateCollection != null) {
// Supplied collection of instances, so evaluate in-memory
if (candidateCollection.isEmpty()) {
return Collections.EMPTY_LIST;
} else if (inMemory) {
return new JDOQLInMemoryEvaluator(this, new ArrayList(candidateCollection), compilation, parameters, clr).execute(true, true, true, true, true);
}
} else if (type == QueryType.SELECT) {
// Query results are cached, so return those
List<Object> cachedResults = getQueryManager().getQueryResult(this, parameters);
if (cachedResults != null) {
return new CandidateIdsQueryResult(this, cachedResults);
}
}
Object results = null;
RDBMSStoreManager storeMgr = (RDBMSStoreManager) getStoreManager();
ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
try {
// Execute the query
long startTime = System.currentTimeMillis();
if (NucleusLogger.QUERY.isDebugEnabled()) {
NucleusLogger.QUERY.debug(Localiser.msg("021046", getLanguage(), getSingleStringQuery(), null));
}
AbstractClassMetaData acmd = ec.getMetaDataManager().getMetaDataForClass(candidateClass, clr);
SQLController sqlControl = storeMgr.getSQLController();
PreparedStatement ps = null;
try {
if (type == QueryType.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(ec, mconn, datastoreCompilation.getSQL(), ps);
} finally {
deregisterTask();
}
AbstractRDBMSQueryResult qr = null;
try {
if (inMemory) {
// IN-MEMORY EVALUATION
ResultObjectFactory rof = new PersistentClassROF(ec, rs, ignoreCache, getFetchPlan(), datastoreCompilation.getResultDefinitionForClass(), acmd, 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());
}
// Perform in-memory filter/result/order etc
results = new JDOQLInMemoryEvaluator(this, candidates, compilation, parameters, clr).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(ec, rs, ignoreCache, getFetchPlan(), resultClass, datastoreCompilation.getResultDefinition());
} else if (resultClass != null && resultClass != candidateClass) {
rof = new ResultClassROF(ec, rs, resultClass, datastoreCompilation.getResultDefinitionForClass());
} else {
// Each result row is a candidate object
rof = new PersistentClassROF(ec, rs, ignoreCache, getFetchPlan(), datastoreCompilation.getResultDefinitionForClass(), acmd, candidateClass);
}
// Create the required type of QueryResult
qr = RDBMSQueryUtils.getQueryResultForQuery(this, rof, rs, getResultDistinct() ? null : candidateCollection);
// Register any bulk loaded member resultSets that need loading
Map<String, IteratorStatement> scoIterStmts = datastoreCompilation.getSCOIteratorStatements();
if (scoIterStmts != null) {
Iterator<Map.Entry<String, IteratorStatement>> scoStmtIter = scoIterStmts.entrySet().iterator();
while (scoStmtIter.hasNext()) {
Map.Entry<String, IteratorStatement> stmtIterEntry = scoStmtIter.next();
IteratorStatement iterStmt = stmtIterEntry.getValue();
String iterStmtSQL = iterStmt.getSelectStatement().getSQLText().toSQL();
NucleusLogger.DATASTORE_RETRIEVE.debug("JDOQL Bulk-Fetch of " + iterStmt.getBackingStore().getOwnerMemberMetaData().getFullFieldName());
try {
PreparedStatement psSco = sqlControl.getStatementForQuery(mconn, iterStmtSQL);
if (datastoreCompilation.getStatementParameters() != null) {
BulkFetchHandler.applyParametersToStatement(ec, psSco, datastoreCompilation, iterStmt.getSelectStatement(), parameters);
}
ResultSet rsSCO = sqlControl.executeStatementQuery(ec, mconn, iterStmtSQL, psSco);
qr.registerMemberBulkResultSet(iterStmt, rsSCO);
} catch (SQLException e) {
throw new NucleusDataStoreException(Localiser.msg("056006", iterStmtSQL), e);
}
}
}
// Initialise the QueryResult for use
qr.initialise();
// Add hooks for closing query resources
final QueryResult qr1 = qr;
final ManagedConnection mconn1 = mconn;
ManagedConnectionResourceListener listener = new ManagedConnectionResourceListener() {
public void transactionFlushed() {
}
public void transactionPreClose() {
// Tx : disconnect query from ManagedConnection (read in unread rows etc)
qr1.disconnect();
}
public void managedConnectionPreClose() {
if (!ec.getTransaction().isActive()) {
// Non-Tx : disconnect query from ManagedConnection (read in unread rows etc)
qr1.disconnect();
}
}
public void managedConnectionPostClose() {
}
public void resourcePostClose() {
mconn1.removeListener(this);
}
};
mconn.addListener(listener);
qr.addConnectionListener(listener);
results = qr;
}
} finally {
if (qr == null) {
rs.close();
}
}
} else if (type == QueryType.BULK_UPDATE || type == QueryType.BULK_DELETE) {
long bulkResult = 0;
List<StatementCompilation> stmtCompilations = datastoreCompilation.getStatementCompilations();
Iterator<StatementCompilation> stmtCompileIter = stmtCompilations.iterator();
while (stmtCompileIter.hasNext()) {
StatementCompilation stmtCompile = stmtCompileIter.next();
ps = sqlControl.getStatementForUpdate(mconn, stmtCompile.getSQL(), false);
SQLStatementHelper.applyParametersToStatement(ps, ec, datastoreCompilation.getStatementParameters(), datastoreCompilation.getParameterNameByPosition(), parameters);
RDBMSQueryUtils.prepareStatementForExecution(ps, this, false);
int[] execResults = sqlControl.executeStatementUpdate(ec, mconn, toString(), ps, true);
if (stmtCompile.useInCount()) {
bulkResult += execResults[0];
}
}
try {
// Evict all objects of this type from the cache
ec.getNucleusContext().getLevel2Cache().evictAll(candidateClass, subclasses);
} catch (UnsupportedOperationException uoe) {
// Do nothing
}
results = bulkResult;
}
} catch (SQLException sqle) {
if (storeMgr.getDatastoreAdapter().isStatementCancel(sqle)) {
throw new QueryInterruptedException("Query has been interrupted", sqle);
} else if (storeMgr.getDatastoreAdapter().isStatementTimeout(sqle)) {
throw new QueryTimeoutException("Query has been timed out", sqle);
}
throw new NucleusException(Localiser.msg("021042", datastoreCompilation.getSQL()), sqle);
}
if (NucleusLogger.QUERY.isDebugEnabled()) {
NucleusLogger.QUERY.debug(Localiser.msg("021074", getLanguage(), "" + (System.currentTimeMillis() - startTime)));
}
return results;
} finally {
mconn.release();
}
}
use of org.datanucleus.store.query.QueryResult in project datanucleus-rdbms by datanucleus.
the class SQLQuery method performExecute.
/**
* Execute the query and return the result.
* For a SELECT query this will be the QueryResult.
* For an UPDATE/DELETE it will be the row count for the update statement.
* @param parameters the Map containing all of the parameters (positional parameters) (not null)
* @return the result of the query
*/
protected Object performExecute(Map parameters) {
if (parameters.size() != (parameterNames != null ? parameterNames.length : 0)) {
throw new NucleusUserException(Localiser.msg("059019", (parameterNames != null) ? "" + parameterNames.length : 0, "" + parameters.size()));
}
if (type == QueryType.BULK_DELETE || type == QueryType.BULK_UPDATE || type == QueryType.BULK_INSERT) {
// Update/Delete statement (INSERT/UPDATE/DELETE/MERGE)
try {
RDBMSStoreManager storeMgr = (RDBMSStoreManager) getStoreManager();
ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
SQLController sqlControl = storeMgr.getSQLController();
try {
PreparedStatement ps = sqlControl.getStatementForUpdate(mconn, compiledSQL, false);
try {
// Set the values of any parameters
for (int i = 0; i < parameters.size(); i++) {
ps.setObject((i + 1), parameters.get(Integer.valueOf(i + 1)));
}
// Execute the update statement
int[] rcs = sqlControl.executeStatementUpdate(ec, mconn, compiledSQL, ps, true);
// Return a single Long with the number of records updated
return Long.valueOf(rcs[0]);
} finally {
sqlControl.closeStatement(mconn, ps);
}
} finally {
mconn.release();
}
} catch (SQLException e) {
throw new NucleusDataStoreException(Localiser.msg("059025", compiledSQL), e);
}
} else if (type == QueryType.SELECT) {
// Query statement (SELECT, stored-procedure)
AbstractRDBMSQueryResult qr = null;
try {
RDBMSStoreManager storeMgr = (RDBMSStoreManager) getStoreManager();
ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
SQLController sqlControl = storeMgr.getSQLController();
try {
PreparedStatement ps = RDBMSQueryUtils.getPreparedStatementForQuery(mconn, compiledSQL, this);
try {
// Set the values of any parameters
for (int i = 0; i < parameters.size(); i++) {
ps.setObject((i + 1), parameters.get(Integer.valueOf(i + 1)));
}
// Apply any user-specified constraints over timeouts and ResultSet
RDBMSQueryUtils.prepareStatementForExecution(ps, this, true);
ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, compiledSQL, ps);
try {
// Generate a ResultObjectFactory
ResultObjectFactory rof = null;
if (resultMetaData != null) {
// Each row of the ResultSet is defined by MetaData
rof = new ResultMetaDataROF(ec, rs, ignoreCache, getFetchPlan(), resultMetaData);
} else if (resultClass != null || candidateClass == null) {
// Each row of the ResultSet is either an instance of resultClass, or Object[]
rof = RDBMSQueryUtils.getResultObjectFactoryForNoCandidateClass(ec, rs, resultClass);
} else {
// Each row of the ResultSet is an instance of the candidate class
rof = getResultObjectFactoryForCandidateClass(rs);
}
// Return the associated type of results depending on whether scrollable or not
qr = RDBMSQueryUtils.getQueryResultForQuery(this, rof, rs, null);
qr.initialise();
final QueryResult qr1 = qr;
final ManagedConnection mconn1 = mconn;
mconn.addListener(new ManagedConnectionResourceListener() {
public void transactionFlushed() {
}
public void transactionPreClose() {
// Disconnect the query from this ManagedConnection (read in unread rows etc)
qr1.disconnect();
}
public void managedConnectionPreClose() {
if (!ec.getTransaction().isActive()) {
// Disconnect the query from this ManagedConnection (read in unread rows etc)
qr1.disconnect();
}
}
public void managedConnectionPostClose() {
}
public void resourcePostClose() {
mconn1.removeListener(this);
}
});
} finally {
if (qr == null) {
rs.close();
}
}
} catch (QueryInterruptedException qie) {
// Execution was cancelled so cancel the PreparedStatement
ps.cancel();
throw qie;
} finally {
if (qr == null) {
sqlControl.closeStatement(mconn, ps);
}
}
} finally {
mconn.release();
}
} catch (SQLException e) {
throw new NucleusDataStoreException(Localiser.msg("059025", compiledSQL), e);
}
return qr;
} else {
// 'Other' statement (manually invoked stored-procedure?, CREATE?, DROP?, or similar)
try {
RDBMSStoreManager storeMgr = (RDBMSStoreManager) getStoreManager();
ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
SQLController sqlControl = storeMgr.getSQLController();
try {
PreparedStatement ps = RDBMSQueryUtils.getPreparedStatementForQuery(mconn, compiledSQL, this);
try {
// Set the values of any parameters
for (int i = 0; i < parameters.size(); i++) {
ps.setObject((i + 1), parameters.get(Integer.valueOf(i + 1)));
}
// Apply any user-specified constraints over timeouts etc
RDBMSQueryUtils.prepareStatementForExecution(ps, this, false);
sqlControl.executeStatement(ec, mconn, compiledSQL, ps);
} catch (QueryInterruptedException qie) {
// Execution was cancelled so cancel the PreparedStatement
ps.cancel();
throw qie;
} finally {
sqlControl.closeStatement(mconn, ps);
}
} finally {
mconn.release();
}
} catch (SQLException e) {
throw new NucleusDataStoreException(Localiser.msg("059025", compiledSQL), e);
}
return true;
}
}
use of org.datanucleus.store.query.QueryResult in project datanucleus-core by datanucleus.
the class DefaultCandidateExtent method iterator.
public Iterator<T> iterator() {
Object results = query.execute();
Iterator iter = null;
if (results instanceof QueryResult) {
QueryResult qr = (QueryResult) results;
iter = qr.iterator();
queryResultsByIterator.put(iter, qr);
} else {
iter = ((Collection) results).iterator();
}
return iter;
}
use of org.datanucleus.store.query.QueryResult in project datanucleus-rdbms by datanucleus.
the class StoredProcedureQuery method getResultsForResultSet.
protected QueryResult getResultsForResultSet(RDBMSStoreManager storeMgr, ResultSet rs, ManagedConnection mconn) throws SQLException {
ResultObjectFactory rof = null;
if (resultMetaDatas != null) {
// Each row of the ResultSet is defined by MetaData
rof = new ResultMetaDataROF(ec, rs, ignoreCache, getFetchPlan(), resultMetaDatas[resultSetNumber]);
} else {
// Each row of the ResultSet is either an instance of resultClass, or Object[]
rof = RDBMSQueryUtils.getResultObjectFactoryForNoCandidateClass(ec, rs, resultClasses != null ? resultClasses[resultSetNumber] : null);
}
// Create the required type of QueryResult
AbstractRDBMSQueryResult qr = RDBMSQueryUtils.getQueryResultForQuery(this, rof, rs, null);
// In case there are multiple result sets
qr.setCloseStatementWithResultSet(false);
qr.initialise();
final QueryResult qr1 = qr;
final ManagedConnection mconn1 = mconn;
ManagedConnectionResourceListener listener = new ManagedConnectionResourceListener() {
public void transactionFlushed() {
}
public void transactionPreClose() {
// Tx : disconnect query from ManagedConnection (read in unread rows etc)
qr1.disconnect();
try {
if (stmt != null) {
stmt.close();
}
} catch (SQLException e) {
}
}
public void managedConnectionPreClose() {
if (!ec.getTransaction().isActive()) {
// Non-Tx : disconnect query from ManagedConnection (read in unread rows etc)
qr1.disconnect();
try {
if (stmt != null) {
stmt.close();
}
} catch (SQLException e) {
}
}
}
public void managedConnectionPostClose() {
}
public void resourcePostClose() {
mconn1.removeListener(this);
}
};
mconn.addListener(listener);
qr.addConnectionListener(listener);
return qr;
}
use of org.datanucleus.store.query.QueryResult in project datanucleus-rdbms by datanucleus.
the class StoredProcedureQuery method getNextResults.
@Override
public Object getNextResults() {
if (stmt == null) {
throw new NucleusUserException("Cannot check for more results until the stored procedure has been executed");
}
ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
try {
resultSetNumber++;
ResultSet rs = stmt.getResultSet();
QueryResult qr = getResultsForResultSet((RDBMSStoreManager) storeMgr, rs, mconn);
if (shouldReturnSingleRow()) {
// Single row only needed so just take first row
try {
if (qr == null || qr.size() == 0) {
throw new NoQueryResultsException("No query results were returned");
}
Iterator qrIter = qr.iterator();
Object firstRow = qrIter.next();
if (qrIter.hasNext()) {
throw new QueryNotUniqueException();
}
return firstRow;
} finally {
// can close results right now because we don't return it
close(qr);
}
}
// Apply range?
return qr;
} catch (SQLException sqle) {
throw new NucleusDataStoreException("Exception from CallableStatement.getResultSet", sqle);
} finally {
mconn.release();
}
}
Aggregations