Search in sources :

Example 1 with SQLDeleteAllStatementForTempTable

use of org.eclipse.persistence.internal.expressions.SQLDeleteAllStatementForTempTable in project eclipselink by eclipse-ee4j.

the class ExpressionQueryMechanism method buildDeleteAllStatementForTempTable.

/**
 * Build SQL delete statement which delete from target table using temporary table.
 * @return SQLDeleteAllStatementForTempTable
 */
private SQLDeleteAllStatementForTempTable buildDeleteAllStatementForTempTable(DatabaseTable rootTable, List<DatabaseField> rootTablePrimaryKeyFields, DatabaseTable targetTable, List<DatabaseField> targetTablePrimaryKeyFields) {
    SQLDeleteAllStatementForTempTable deleteStatement = new SQLDeleteAllStatementForTempTable();
    deleteStatement.setMode(SQLModifyAllStatementForTempTable.UPDATE_ORIGINAL_TABLE);
    deleteStatement.setTable(rootTable);
    deleteStatement.setPrimaryKeyFields(rootTablePrimaryKeyFields);
    deleteStatement.setTargetTable(targetTable);
    deleteStatement.setTargetPrimaryKeyFields(targetTablePrimaryKeyFields);
    return deleteStatement;
}
Also used : SQLDeleteAllStatementForTempTable(org.eclipse.persistence.internal.expressions.SQLDeleteAllStatementForTempTable)

Example 2 with SQLDeleteAllStatementForTempTable

use of org.eclipse.persistence.internal.expressions.SQLDeleteAllStatementForTempTable in project eclipselink by eclipse-ee4j.

the class ExpressionQueryMechanism method buildDeleteAllStatementsForMappingsWithTempTable.

/**
 * Build delete statements with temporary table for ManyToMany and DirectCollection mappings.
 *
 * NOTE: A similar pattern also used in method buildDeleteAllStatementsForMappings():
 *  if you are updating this method consider applying a similar update to that method as well.
 *
 * @return {@code Vector<SQLDeleteAllStatementForTempTable>}
 */
protected Vector buildDeleteAllStatementsForMappingsWithTempTable(ClassDescriptor descriptor, DatabaseTable rootTable, boolean dontCheckDescriptor) {
    Vector deleteStatements = new Vector();
    for (DatabaseMapping mapping : descriptor.getMappings()) {
        if (mapping.isForeignReferenceMapping()) {
            List<DatabaseField> sourceFields = null;
            List<DatabaseField> targetFields = null;
            if (mapping.isDirectCollectionMapping()) {
                if (shouldBuildDeleteStatementForMapping((DirectCollectionMapping) mapping, dontCheckDescriptor, descriptor)) {
                    sourceFields = ((DirectCollectionMapping) mapping).getSourceKeyFields();
                    targetFields = ((DirectCollectionMapping) mapping).getReferenceKeyFields();
                }
            } else if (mapping.isAggregateCollectionMapping()) {
                if (shouldBuildDeleteStatementForMapping((AggregateCollectionMapping) mapping, dontCheckDescriptor, descriptor)) {
                    sourceFields = ((AggregateCollectionMapping) mapping).getSourceKeyFields();
                    targetFields = ((AggregateCollectionMapping) mapping).getTargetForeignKeyFields();
                }
            } else if (mapping.isManyToManyMapping()) {
                if (shouldBuildDeleteStatementForMapping((ManyToManyMapping) mapping, dontCheckDescriptor, descriptor)) {
                    RelationTableMechanism relationTableMechanism = ((ManyToManyMapping) mapping).getRelationTableMechanism();
                    sourceFields = relationTableMechanism.getSourceKeyFields();
                    targetFields = relationTableMechanism.getSourceRelationKeyFields();
                }
            } else if (mapping.isOneToOneMapping()) {
                RelationTableMechanism relationTableMechanism = ((OneToOneMapping) mapping).getRelationTableMechanism();
                if (relationTableMechanism != null) {
                    if (shouldBuildDeleteStatementForMapping((OneToOneMapping) mapping, dontCheckDescriptor, descriptor)) {
                        sourceFields = relationTableMechanism.getSourceKeyFields();
                        targetFields = relationTableMechanism.getSourceRelationKeyFields();
                    }
                }
            }
            if (sourceFields != null) {
                DatabaseTable targetTable = targetFields.get(0).getTable();
                SQLDeleteAllStatementForTempTable deleteStatement = buildDeleteAllStatementForTempTable(rootTable, sourceFields, targetTable, targetFields);
                deleteStatements.addElement(deleteStatement);
            }
        }
    }
    return deleteStatements;
}
Also used : ManyToManyMapping(org.eclipse.persistence.mappings.ManyToManyMapping) AggregateCollectionMapping(org.eclipse.persistence.mappings.AggregateCollectionMapping) DatabaseField(org.eclipse.persistence.internal.helper.DatabaseField) DatabaseTable(org.eclipse.persistence.internal.helper.DatabaseTable) DatabaseMapping(org.eclipse.persistence.mappings.DatabaseMapping) Vector(java.util.Vector) NonSynchronizedVector(org.eclipse.persistence.internal.helper.NonSynchronizedVector) RelationTableMechanism(org.eclipse.persistence.mappings.RelationTableMechanism) OneToOneMapping(org.eclipse.persistence.mappings.OneToOneMapping) SQLDeleteAllStatementForTempTable(org.eclipse.persistence.internal.expressions.SQLDeleteAllStatementForTempTable)

Example 3 with SQLDeleteAllStatementForTempTable

use of org.eclipse.persistence.internal.expressions.SQLDeleteAllStatementForTempTable in project eclipselink by eclipse-ee4j.

the class ExpressionQueryMechanism method buildDeleteAllStatementsForTempTable.

/**
 * Build delete all SQLStatements using temporary table.
 * This is recursively called for multiple table child descriptors.
 *
 * NOTE: A similar pattern also used in method prepareDeleteAll():
 *  if you are updating this method consider applying a similar update to that method as well.
 *
 * @return {@code Vector<SQLDeleteAllStatementForTempTable>}
 */
private Vector buildDeleteAllStatementsForTempTable(ClassDescriptor descriptor, DatabaseTable rootTable, List<DatabaseField> rootTablePrimaryKeyFields, Vector tablesToIgnore) {
    Vector statements = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance();
    List<DatabaseTable> tablesInInsertOrder;
    if (tablesToIgnore == null) {
        // It's original (not a nested) method call.
        tablesInInsertOrder = descriptor.getMultipleTableInsertOrder();
    } else {
        // It's a nested method call: tableInInsertOrder filled with descriptor's tables (in insert order),
        // the tables found in tablesToIgnore are thrown away -
        // they have already been taken care of by the caller.
        // In Employee example, query with reference class Project gets here
        // to handle LPROJECT table; tablesToIgnore contains PROJECT table.
        tablesInInsertOrder = new ArrayList(descriptor.getMultipleTableInsertOrder().size());
        for (DatabaseTable table : descriptor.getMultipleTableInsertOrder()) {
            if (!tablesToIgnore.contains(table)) {
                tablesInInsertOrder.add(table);
            }
        }
    }
    if (!tablesInInsertOrder.isEmpty()) {
        for (DatabaseTable table : tablesInInsertOrder) {
            SQLDeleteAllStatementForTempTable deleteStatement = buildDeleteAllStatementForTempTable(rootTable, rootTablePrimaryKeyFields, table, getPrimaryKeyFieldsForTable(descriptor, table));
            statements.add(deleteStatement);
            // Most databases support delete cascade constraints by specifying a ON DELETE CASCADE option when defining foreign key constraints.
            // However some databases which don't support foreign key constraints cannot use delete cascade constraints.
            // Therefore each delete operation should be executed in such a database platform instead of delegating delete cascade constraints.
            boolean supportForeignKeyConstraints = getSession().getPlatform().supportsForeignKeyConstraints();
            boolean supportCascadeOnDelete = supportForeignKeyConstraints && descriptor.isCascadeOnDeleteSetOnDatabaseOnSecondaryTables();
            // Only delete from first table if delete is cascaded on the database.
            if (supportCascadeOnDelete) {
                break;
            }
        }
        // Add statements for ManyToMany and DirectCollection mappings
        Vector deleteStatementsForMappings = buildDeleteAllStatementsForMappingsWithTempTable(descriptor, rootTable, tablesToIgnore == null);
        statements.addAll(deleteStatementsForMappings);
    }
    // Indicates whether the descriptor has children using extra tables.
    boolean hasChildrenWithExtraTables = descriptor.hasInheritance() && descriptor.getInheritancePolicy().hasChildren() && descriptor.getInheritancePolicy().hasMultipleTableChild();
    // TBD: should we ignore subclasses in case descriptor doesn't want us to read them in?
    // ** Currently in this code we do ignore.
    // ** If it will be decided that we need to handle children in all cases
    // ** the following statement should be changed to: boolean shouldHandleChildren = hasChildrenWithExtraTables;
    boolean shouldHandleChildren = hasChildrenWithExtraTables && descriptor.getInheritancePolicy().shouldReadSubclasses();
    // Perform a nested method call for each child
    if (shouldHandleChildren) {
        // In Employee example: query for Project will make nested calls to
        // LargeProject and SmallProject and ask them to ignore PROJECT table
        Vector tablesToIgnoreForChildren = new Vector();
        // The tables this descriptor has ignored, its children also should ignore.
        if (tablesToIgnore != null) {
            tablesToIgnoreForChildren.addAll(tablesToIgnore);
        }
        // subclasses to process its tables for the second time.
        if (descriptor.getInheritancePolicy().shouldReadSubclasses()) {
            tablesToIgnoreForChildren.addAll(tablesInInsertOrder);
        }
        Iterator<ClassDescriptor> it = descriptor.getInheritancePolicy().getChildDescriptors().iterator();
        while (it.hasNext()) {
            ClassDescriptor childDescriptor = it.next();
            // Need to process only "multiple tables" child descriptors
            if ((childDescriptor.getTables().size() > descriptor.getTables().size()) || (childDescriptor.getInheritancePolicy().hasMultipleTableChild())) {
                // recursively build for child desciptors
                Vector childStatements = buildDeleteAllStatementsForTempTable(childDescriptor, rootTable, rootTablePrimaryKeyFields, tablesToIgnoreForChildren);
                statements.addAll(childStatements);
            }
        }
    }
    return statements;
}
Also used : ClassDescriptor(org.eclipse.persistence.descriptors.ClassDescriptor) ArrayList(java.util.ArrayList) DatabaseTable(org.eclipse.persistence.internal.helper.DatabaseTable) Vector(java.util.Vector) NonSynchronizedVector(org.eclipse.persistence.internal.helper.NonSynchronizedVector) SQLDeleteAllStatementForTempTable(org.eclipse.persistence.internal.expressions.SQLDeleteAllStatementForTempTable)

Example 4 with SQLDeleteAllStatementForTempTable

use of org.eclipse.persistence.internal.expressions.SQLDeleteAllStatementForTempTable in project eclipselink by eclipse-ee4j.

the class ExpressionQueryMechanism method buildStatementsForDeleteAllForTempTables.

/**
 * Build SQLStatements for delete all using temporary table.
 * @return {@code Vector<SQLStatement>}
 */
protected Vector buildStatementsForDeleteAllForTempTables() {
    Vector statements = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance();
    // retrieve rootTable and its primary key fields for composing temporary table
    DatabaseTable rootTable = getDescriptor().getMultipleTableInsertOrder().get(0);
    List<DatabaseField> rootTablePrimaryKeyFields = getPrimaryKeyFieldsForTable(rootTable);
    ClassDescriptor rootDescriptor = getDescriptor();
    if (getDescriptor().hasInheritance()) {
        rootDescriptor = rootDescriptor.getInheritancePolicy().getRootParentDescriptor();
    }
    Vector allFields = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance();
    Iterator<DatabaseField> it = rootDescriptor.getFields().iterator();
    while (it.hasNext()) {
        DatabaseField field = it.next();
        if (rootTable.equals(field.getTable())) {
            allFields.add(field);
        }
    }
    // statements will be executed in reverse order
    // statement for temporary table cleanup (Drop table or Delete from temp_table)
    SQLDeleteAllStatementForTempTable cleanupStatement = new SQLDeleteAllStatementForTempTable();
    cleanupStatement.setMode(SQLModifyAllStatementForTempTable.CLEANUP_TEMP_TABLE);
    cleanupStatement.setTable(rootTable);
    statements.addElement(cleanupStatement);
    // delete statements using temporary table
    Vector deleteStatements = buildDeleteAllStatementsForTempTable(getDescriptor(), rootTable, rootTablePrimaryKeyFields, null);
    statements.addAll(deleteStatements);
    // Insert statement populating temporary table with criteria
    SQLSelectStatement selectStatement = createSQLSelectStatementForModifyAllForTempTable(null);
    SQLCall selectCall = (SQLCall) selectStatement.buildCall(getSession());
    SQLDeleteAllStatementForTempTable insertStatement = new SQLDeleteAllStatementForTempTable();
    insertStatement.setMode(SQLModifyAllStatementForTempTable.INSERT_INTO_TEMP_TABLE);
    insertStatement.setTable(rootTable);
    insertStatement.setTranslationRow(getTranslationRow());
    insertStatement.setSelectCall(selectCall);
    insertStatement.setPrimaryKeyFields(rootTablePrimaryKeyFields);
    statements.addElement(insertStatement);
    // Create temporary table statement
    SQLDeleteAllStatementForTempTable createTempTableStatement = new SQLDeleteAllStatementForTempTable();
    createTempTableStatement.setMode(SQLModifyAllStatementForTempTable.CREATE_TEMP_TABLE);
    createTempTableStatement.setTable(rootTable);
    createTempTableStatement.setAllFields(allFields);
    createTempTableStatement.setPrimaryKeyFields(rootTablePrimaryKeyFields);
    statements.addElement(createTempTableStatement);
    return statements;
}
Also used : SQLCall(org.eclipse.persistence.queries.SQLCall) ClassDescriptor(org.eclipse.persistence.descriptors.ClassDescriptor) DatabaseField(org.eclipse.persistence.internal.helper.DatabaseField) DatabaseTable(org.eclipse.persistence.internal.helper.DatabaseTable) SQLSelectStatement(org.eclipse.persistence.internal.expressions.SQLSelectStatement) Vector(java.util.Vector) NonSynchronizedVector(org.eclipse.persistence.internal.helper.NonSynchronizedVector) SQLDeleteAllStatementForTempTable(org.eclipse.persistence.internal.expressions.SQLDeleteAllStatementForTempTable)

Aggregations

SQLDeleteAllStatementForTempTable (org.eclipse.persistence.internal.expressions.SQLDeleteAllStatementForTempTable)4 Vector (java.util.Vector)3 DatabaseTable (org.eclipse.persistence.internal.helper.DatabaseTable)3 NonSynchronizedVector (org.eclipse.persistence.internal.helper.NonSynchronizedVector)3 ClassDescriptor (org.eclipse.persistence.descriptors.ClassDescriptor)2 DatabaseField (org.eclipse.persistence.internal.helper.DatabaseField)2 ArrayList (java.util.ArrayList)1 SQLSelectStatement (org.eclipse.persistence.internal.expressions.SQLSelectStatement)1 AggregateCollectionMapping (org.eclipse.persistence.mappings.AggregateCollectionMapping)1 DatabaseMapping (org.eclipse.persistence.mappings.DatabaseMapping)1 ManyToManyMapping (org.eclipse.persistence.mappings.ManyToManyMapping)1 OneToOneMapping (org.eclipse.persistence.mappings.OneToOneMapping)1 RelationTableMechanism (org.eclipse.persistence.mappings.RelationTableMechanism)1 SQLCall (org.eclipse.persistence.queries.SQLCall)1