Search in sources :

Example 6 with IteratorStatement

use of org.datanucleus.store.rdbms.scostore.IteratorStatement in project datanucleus-rdbms by datanucleus.

the class JPQLQuery method performExecute.

protected Object performExecute(Map parameters) {
    if (statementReturnsEmpty) {
        return Collections.EMPTY_LIST;
    }
    if (candidateCollection != null) {
        // Supplied collection of instances, so evaluate in-memory
        if (candidateCollection.isEmpty()) {
            return Collections.EMPTY_LIST;
        }
        List candidates = new ArrayList(candidateCollection);
        return new JPQLInMemoryEvaluator(this, candidates, 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;
    ManagedConnection mconn = getStoreManager().getConnectionManager().getConnection(ec);
    try {
        // Execute the query
        long startTime = System.currentTimeMillis();
        if (NucleusLogger.QUERY.isDebugEnabled()) {
            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 == QueryType.SELECT) {
                // Create PreparedStatement and apply parameters, result settings etc
                ps = RDBMSQueryUtils.getPreparedStatementForQuery(mconn, datastoreCompilation.getSQL(), this);
                SQLStatementHelper.applyParametersToStatement(ps, ec, datastoreCompilation.getStatementParameters(), null, 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 (evaluateInMemory()) {
                        // 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 JPQLInMemoryEvaluator(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("JPQL 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);
                                }
                            }
                        }
                        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();
                            }

                            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 || type == QueryType.BULK_INSERT) {
                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(), null, 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) JPQLInMemoryEvaluator(org.datanucleus.store.query.inmemory.JPQLInMemoryEvaluator) 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) 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)

Aggregations

IteratorStatement (org.datanucleus.store.rdbms.scostore.IteratorStatement)6 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)5 NucleusException (org.datanucleus.exceptions.NucleusException)4 SQLException (java.sql.SQLException)3 HashSet (java.util.HashSet)3 Iterator (java.util.Iterator)3 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)3 SelectStatement (org.datanucleus.store.rdbms.sql.SelectStatement)3 PreparedStatement (java.sql.PreparedStatement)2 ResultSet (java.sql.ResultSet)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 List (java.util.List)2 Map (java.util.Map)2 ExecutionContext (org.datanucleus.ExecutionContext)2 FetchPlanForClass (org.datanucleus.FetchPlanForClass)2 NucleusDataStoreException (org.datanucleus.exceptions.NucleusDataStoreException)2 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)2 RelationType (org.datanucleus.metadata.RelationType)2 ManagedConnection (org.datanucleus.store.connection.ManagedConnection)2