Search in sources :

Example 16 with SQLStatement

use of org.datanucleus.store.rdbms.sql.SQLStatement in project datanucleus-rdbms by datanucleus.

the class JPQLQuery method compileQueryUpdate.

/**
 * Method to compile the query for RDBMS for a bulk update.
 * @param parameterValues The parameter values (if any)
 * @param candidateCmd Meta-data for the candidate class
 */
protected void compileQueryUpdate(Map parameterValues, AbstractClassMetaData candidateCmd) {
    Expression[] updateExprs = compilation.getExprUpdate();
    if (updateExprs == null || updateExprs.length == 0) {
        // Nothing to update
        return;
    }
    // Generate statement for candidate and related classes in this inheritance tree
    RDBMSStoreManager storeMgr = (RDBMSStoreManager) getStoreManager();
    DatastoreClass candidateTbl = storeMgr.getDatastoreClass(candidateCmd.getFullClassName(), clr);
    if (candidateTbl == null) {
        // TODO Using subclass-table, so find the table(s) it can be persisted into
        throw new NucleusDataStoreException("Bulk update of " + candidateCmd.getFullClassName() + " not supported since candidate has no table of its own");
    }
    // Find tables potentially affected by this UPDATE statement
    List<BulkTable> tables = new ArrayList<>();
    tables.add(new BulkTable(candidateTbl, true));
    if (candidateTbl.getSuperDatastoreClass() != null) {
        DatastoreClass tbl = candidateTbl;
        while (tbl.getSuperDatastoreClass() != null) {
            tbl = tbl.getSuperDatastoreClass();
            tables.add(new BulkTable(tbl, false));
        }
    }
    List<SQLStatement> stmts = new ArrayList<>();
    List<Boolean> stmtCountFlags = new ArrayList<>();
    for (BulkTable bulkTable : tables) {
        // Generate statement for candidate
        DatastoreClass table = bulkTable.table;
        Map<String, Object> extensions = null;
        if (!storeMgr.getDatastoreAdapter().supportsOption(DatastoreAdapter.UPDATE_DELETE_STATEMENT_ALLOW_TABLE_ALIAS_IN_WHERE_CLAUSE)) {
            extensions = new HashMap<>();
            extensions.put(SQLStatement.EXTENSION_SQL_TABLE_NAMING_STRATEGY, "table-name");
        }
        UpdateStatement stmt = new UpdateStatement(storeMgr, table, null, null, extensions);
        stmt.setClassLoaderResolver(clr);
        stmt.setCandidateClassName(candidateCmd.getFullClassName());
        JavaTypeMapping multitenancyMapping = table.getSurrogateMapping(SurrogateColumnType.MULTITENANCY, false);
        if (multitenancyMapping != null) {
            // Multi-tenancy restriction
            SQLExpression tenantExpr = stmt.getSQLExpressionFactory().newExpression(stmt, stmt.getPrimaryTable(), multitenancyMapping);
            SQLExpression tenantVal = stmt.getSQLExpressionFactory().newLiteral(stmt, multitenancyMapping, ec.getNucleusContext().getMultiTenancyId(ec, candidateCmd));
            stmt.whereAnd(tenantExpr.eq(tenantVal), true);
        }
        // TODO Discriminator restriction?
        JavaTypeMapping softDeleteMapping = table.getSurrogateMapping(SurrogateColumnType.SOFTDELETE, false);
        if (softDeleteMapping != null) {
            // Soft-delete restriction
            SQLExpression softDeleteExpr = stmt.getSQLExpressionFactory().newExpression(stmt, stmt.getPrimaryTable(), softDeleteMapping);
            SQLExpression softDeleteVal = stmt.getSQLExpressionFactory().newLiteral(stmt, softDeleteMapping, Boolean.FALSE);
            stmt.whereAnd(softDeleteExpr.eq(softDeleteVal), true);
        }
        Set<String> options = new HashSet<>();
        options.add(QueryToSQLMapper.OPTION_CASE_INSENSITIVE);
        options.add(QueryToSQLMapper.OPTION_EXPLICIT_JOINS);
        if (// Default to false for "IS NULL" with null param
        getBooleanExtensionProperty(EXTENSION_USE_IS_NULL_WHEN_EQUALS_NULL_PARAM, false)) {
            options.add(QueryToSQLMapper.OPTION_NULL_PARAM_USE_IS_NULL);
        }
        QueryToSQLMapper sqlMapper = new QueryToSQLMapper(stmt, compilation, parameterValues, null, null, candidateCmd, subclasses, getFetchPlan(), ec, null, options, extensions);
        setMapperJoinTypes(sqlMapper);
        sqlMapper.compile();
        if (stmt.hasUpdates()) {
            stmts.add(stmt);
            stmtCountFlags.add(bulkTable.useInCount);
            datastoreCompilation.setStatementParameters(stmt.getSQLText().getParametersForStatement());
            datastoreCompilation.setPrecompilable(sqlMapper.isPrecompilable());
        }
    }
    datastoreCompilation.clearStatements();
    Iterator<SQLStatement> stmtIter = stmts.iterator();
    Iterator<Boolean> stmtCountFlagsIter = stmtCountFlags.iterator();
    while (stmtIter.hasNext()) {
        SQLStatement stmt = stmtIter.next();
        Boolean useInCount = stmtCountFlagsIter.next();
        if (stmts.size() == 1) {
            useInCount = true;
        }
        datastoreCompilation.addStatement(stmt, stmt.getSQLText().toSQL(), useInCount);
    }
}
Also used : UpdateStatement(org.datanucleus.store.rdbms.sql.UpdateStatement) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) ArrayList(java.util.ArrayList) SQLStatement(org.datanucleus.store.rdbms.sql.SQLStatement) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) Expression(org.datanucleus.query.expression.Expression) ColumnExpression(org.datanucleus.store.rdbms.sql.expression.ColumnExpression) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) HashSet(java.util.HashSet)

Aggregations

SQLStatement (org.datanucleus.store.rdbms.sql.SQLStatement)16 NucleusDataStoreException (org.datanucleus.exceptions.NucleusDataStoreException)10 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)10 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)8 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)7 ArrayList (java.util.ArrayList)6 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)6 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)6 ExecutionContext (org.datanucleus.ExecutionContext)5 Expression (org.datanucleus.query.expression.Expression)5 BooleanExpression (org.datanucleus.store.rdbms.sql.expression.BooleanExpression)5 PreparedStatement (java.sql.PreparedStatement)4 ResultSet (java.sql.ResultSet)4 SQLException (java.sql.SQLException)4 HashSet (java.util.HashSet)4 Transaction (org.datanucleus.Transaction)4 SubqueryExpression (org.datanucleus.query.expression.SubqueryExpression)4 ManagedConnection (org.datanucleus.store.connection.ManagedConnection)4 SQLController (org.datanucleus.store.rdbms.SQLController)4 StatementMappingIndex (org.datanucleus.store.rdbms.query.StatementMappingIndex)4