Search in sources :

Example 1 with QueryResult

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();
    }
}
Also used : SQLException(java.sql.SQLException) ArrayList(java.util.ArrayList) IteratorStatement(org.datanucleus.store.rdbms.scostore.IteratorStatement) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) SQLController(org.datanucleus.store.rdbms.SQLController) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) QueryTimeoutException(org.datanucleus.store.query.QueryTimeoutException) QueryResult(org.datanucleus.store.query.QueryResult) CandidateIdsQueryResult(org.datanucleus.store.query.CandidateIdsQueryResult) ResultSet(java.sql.ResultSet) Iterator(java.util.Iterator) List(java.util.List) ArrayList(java.util.ArrayList) ManagedConnection(org.datanucleus.store.connection.ManagedConnection) CandidateIdsQueryResult(org.datanucleus.store.query.CandidateIdsQueryResult) QueryInterruptedException(org.datanucleus.store.query.QueryInterruptedException) StatementCompilation(org.datanucleus.store.rdbms.query.RDBMSQueryCompilation.StatementCompilation) JDOQLInMemoryEvaluator(org.datanucleus.store.query.inmemory.JDOQLInMemoryEvaluator) PreparedStatement(java.sql.PreparedStatement) ManagedConnectionResourceListener(org.datanucleus.store.connection.ManagedConnectionResourceListener) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) NucleusException(org.datanucleus.exceptions.NucleusException) Map(java.util.Map) HashMap(java.util.HashMap)

Example 2 with QueryResult

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;
    }
}
Also used : SQLException(java.sql.SQLException) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) PreparedStatement(java.sql.PreparedStatement) ManagedConnectionResourceListener(org.datanucleus.store.connection.ManagedConnectionResourceListener) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) SQLController(org.datanucleus.store.rdbms.SQLController) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) QueryResult(org.datanucleus.store.query.QueryResult) ResultSet(java.sql.ResultSet) ManagedConnection(org.datanucleus.store.connection.ManagedConnection) QueryInterruptedException(org.datanucleus.store.query.QueryInterruptedException)

Example 3 with QueryResult

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;
}
Also used : QueryResult(org.datanucleus.store.query.QueryResult) Iterator(java.util.Iterator)

Example 4 with QueryResult

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;
}
Also used : QueryResult(org.datanucleus.store.query.QueryResult) SQLException(java.sql.SQLException) ManagedConnection(org.datanucleus.store.connection.ManagedConnection) ManagedConnectionResourceListener(org.datanucleus.store.connection.ManagedConnectionResourceListener)

Example 5 with QueryResult

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();
    }
}
Also used : NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) QueryResult(org.datanucleus.store.query.QueryResult) SQLException(java.sql.SQLException) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) QueryNotUniqueException(org.datanucleus.store.query.QueryNotUniqueException) ResultSet(java.sql.ResultSet) Iterator(java.util.Iterator) ManagedConnection(org.datanucleus.store.connection.ManagedConnection) NoQueryResultsException(org.datanucleus.store.query.NoQueryResultsException)

Aggregations

QueryResult (org.datanucleus.store.query.QueryResult)6 SQLException (java.sql.SQLException)5 ManagedConnection (org.datanucleus.store.connection.ManagedConnection)5 ResultSet (java.sql.ResultSet)4 Iterator (java.util.Iterator)4 NucleusDataStoreException (org.datanucleus.exceptions.NucleusDataStoreException)4 ManagedConnectionResourceListener (org.datanucleus.store.connection.ManagedConnectionResourceListener)4 PreparedStatement (java.sql.PreparedStatement)3 QueryInterruptedException (org.datanucleus.store.query.QueryInterruptedException)3 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)3 SQLController (org.datanucleus.store.rdbms.SQLController)3 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 List (java.util.List)2 Map (java.util.Map)2 NucleusException (org.datanucleus.exceptions.NucleusException)2 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)2 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)2 CandidateIdsQueryResult (org.datanucleus.store.query.CandidateIdsQueryResult)2 QueryTimeoutException (org.datanucleus.store.query.QueryTimeoutException)2