Search in sources :

Example 1 with InheritanceStrategy

use of org.datanucleus.metadata.InheritanceStrategy in project datanucleus-rdbms by datanucleus.

the class JPQLQuery method compileQueryDelete.

/**
 * Method to compile the query for RDBMS for a bulk delete.
 * @param parameterValues The parameter values (if any)
 * @param candidateCmd Meta-data for the candidate class
 */
protected void compileQueryDelete(Map parameterValues, AbstractClassMetaData candidateCmd) {
    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 delete of " + candidateCmd.getFullClassName() + " not supported since candidate has no table of its own");
    }
    InheritanceStrategy inhStr = candidateCmd.getBaseAbstractClassMetaData().getInheritanceMetaData().getStrategy();
    List<BulkTable> tables = new ArrayList<>();
    tables.add(new BulkTable(candidateTbl, true));
    if (inhStr != InheritanceStrategy.COMPLETE_TABLE) {
        // Add deletion from superclass tables since we will have an entry there
        while (candidateTbl.getSuperDatastoreClass() != null) {
            candidateTbl = candidateTbl.getSuperDatastoreClass();
            tables.add(new BulkTable(candidateTbl, false));
        }
    }
    Collection<String> subclassNames = storeMgr.getSubClassesForClass(candidateCmd.getFullClassName(), true, clr);
    if (subclassNames != null && !subclassNames.isEmpty()) {
        // Check for subclasses having their own tables and hence needing multiple DELETEs
        Iterator<String> iter = subclassNames.iterator();
        while (iter.hasNext()) {
            String subclassName = iter.next();
            DatastoreClass subclassTbl = storeMgr.getDatastoreClass(subclassName, clr);
            if (candidateTbl != subclassTbl) {
                // Only include BulkTable in count if using COMPLETE_TABLE strategy
                tables.add(0, new BulkTable(subclassTbl, inhStr == InheritanceStrategy.COMPLETE_TABLE));
            }
        }
    }
    List<SQLStatement> stmts = new ArrayList<>();
    List<Boolean> stmtCountFlags = new ArrayList<>();
    for (BulkTable bulkTable : tables) {
        // Generate statement for candidate
        DatastoreClass table = bulkTable.table;
        JavaTypeMapping softDeleteMapping = table.getSurrogateMapping(SurrogateColumnType.SOFTDELETE, false);
        if (softDeleteMapping != null) {
            throw new NucleusUserException("Cannot use BulkDelete queries when using SoftDelete on an affected table (" + 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");
        }
        SQLStatement stmt = new DeleteStatement(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
            SQLTable tenantSqlTbl = stmt.getPrimaryTable();
            SQLExpression tenantExpr = stmt.getSQLExpressionFactory().newExpression(stmt, tenantSqlTbl, multitenancyMapping);
            SQLExpression tenantVal = stmt.getSQLExpressionFactory().newLiteral(stmt, multitenancyMapping, ec.getNucleusContext().getMultiTenancyId(ec, candidateCmd));
            stmt.whereAnd(tenantExpr.eq(tenantVal), true);
        }
        // TODO Discriminator restriction?
        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();
        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 : 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) DeleteStatement(org.datanucleus.store.rdbms.sql.DeleteStatement) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) HashSet(java.util.HashSet) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) InheritanceStrategy(org.datanucleus.metadata.InheritanceStrategy) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass)

Example 2 with InheritanceStrategy

use of org.datanucleus.metadata.InheritanceStrategy in project datanucleus-rdbms by datanucleus.

the class JDOQLQuery method compileQueryDelete.

/**
 * Method to compile the query for RDBMS for a bulk delete.
 * @param parameterValues The parameter values (if any)
 * @param candidateCmd Meta-data for the candidate class
 */
protected void compileQueryDelete(Map parameterValues, AbstractClassMetaData candidateCmd) {
    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 delete of " + candidateCmd.getFullClassName() + " not supported since candidate has no table of its own");
    }
    InheritanceStrategy inhStr = candidateCmd.getBaseAbstractClassMetaData().getInheritanceMetaData().getStrategy();
    List<BulkTable> tables = new ArrayList<>();
    tables.add(new BulkTable(candidateTbl, true));
    if (inhStr != InheritanceStrategy.COMPLETE_TABLE) {
        // Add deletion from superclass tables since we will have an entry there
        while (candidateTbl.getSuperDatastoreClass() != null) {
            candidateTbl = candidateTbl.getSuperDatastoreClass();
            tables.add(new BulkTable(candidateTbl, false));
        }
    }
    Collection<String> subclassNames = storeMgr.getSubClassesForClass(candidateCmd.getFullClassName(), true, clr);
    if (subclassNames != null && !subclassNames.isEmpty()) {
        // Check for subclasses having their own tables and hence needing multiple DELETEs
        Iterator<String> iter = subclassNames.iterator();
        while (iter.hasNext()) {
            String subclassName = iter.next();
            DatastoreClass subclassTbl = storeMgr.getDatastoreClass(subclassName, clr);
            if (candidateTbl != subclassTbl) {
                // Only include BulkTable in count if using COMPLETE_TABLE strategy
                tables.add(0, new BulkTable(subclassTbl, inhStr == InheritanceStrategy.COMPLETE_TABLE));
            }
        }
    }
    List<SQLStatement> stmts = new ArrayList<>();
    List<Boolean> stmtCountFlags = new ArrayList<>();
    for (BulkTable bulkTable : tables) {
        // Generate statement for candidate
        DatastoreClass table = bulkTable.table;
        JavaTypeMapping softDeleteMapping = table.getSurrogateMapping(SurrogateColumnType.SOFTDELETE, false);
        if (softDeleteMapping != null) {
            throw new NucleusUserException("Cannot use BulkDelete queries when using SoftDelete on an affected table (" + 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");
        }
        SQLStatement stmt = new DeleteStatement(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
            SQLTable tenantSqlTbl = stmt.getPrimaryTable();
            SQLExpression tenantExpr = stmt.getSQLExpressionFactory().newExpression(stmt, tenantSqlTbl, multitenancyMapping);
            SQLExpression tenantVal = stmt.getSQLExpressionFactory().newLiteral(stmt, multitenancyMapping, ec.getNucleusContext().getMultiTenancyId(ec, candidateCmd));
            stmt.whereAnd(tenantExpr.eq(tenantVal), true);
        }
        // TODO Discriminator restriction?
        Set<String> options = new HashSet<>();
        if (getBooleanExtensionProperty(EXTENSION_USE_IS_NULL_WHEN_EQUALS_NULL_PARAM, true)) {
            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();
        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 : 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) DeleteStatement(org.datanucleus.store.rdbms.sql.DeleteStatement) NucleusDataStoreException(org.datanucleus.exceptions.NucleusDataStoreException) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) HashSet(java.util.HashSet) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) RDBMSStoreManager(org.datanucleus.store.rdbms.RDBMSStoreManager) InheritanceStrategy(org.datanucleus.metadata.InheritanceStrategy) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass)

Aggregations

ArrayList (java.util.ArrayList)2 HashSet (java.util.HashSet)2 NucleusDataStoreException (org.datanucleus.exceptions.NucleusDataStoreException)2 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)2 InheritanceStrategy (org.datanucleus.metadata.InheritanceStrategy)2 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)2 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)2 DeleteStatement (org.datanucleus.store.rdbms.sql.DeleteStatement)2 SQLStatement (org.datanucleus.store.rdbms.sql.SQLStatement)2 SQLTable (org.datanucleus.store.rdbms.sql.SQLTable)2 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)2 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)2