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;
}
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;
}
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;
}
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;
}
Aggregations