/******************************************************************************* * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * Oracle - initial API and implementation from Oracle TopLink ******************************************************************************/ package org.eclipse.persistence.tools.workbench.test.mappingsmodel.db; import java.util.Collection; import java.util.Iterator; import java.util.List; import junit.framework.Test; import junit.framework.TestSuite; import org.eclipse.persistence.tools.workbench.mappingsio.ProjectIOManager; import org.eclipse.persistence.tools.workbench.mappingsmodel.ProblemConstants; import org.eclipse.persistence.tools.workbench.mappingsmodel.db.MWColumn; import org.eclipse.persistence.tools.workbench.mappingsmodel.db.MWColumnPair; import org.eclipse.persistence.tools.workbench.mappingsmodel.db.MWReference; import org.eclipse.persistence.tools.workbench.mappingsmodel.db.MWTable; import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.MWInheritancePolicy; import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.MWLockingPolicy; import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.relational.MWDescriptorMultiTableInfoPolicy; import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.relational.MWRelationalClassIndicatorFieldPolicy; import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.relational.MWSecondaryTableHolder; import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.relational.MWTableDescriptorLockingPolicy; import org.eclipse.persistence.tools.workbench.mappingsmodel.mapping.MWFieldTransformerAssociation; import org.eclipse.persistence.tools.workbench.mappingsmodel.mapping.relational.MWAbstractTableReferenceMapping; import org.eclipse.persistence.tools.workbench.mappingsmodel.mapping.relational.MWDirectToFieldMapping; import org.eclipse.persistence.tools.workbench.mappingsmodel.mapping.relational.MWManyToManyMapping; import org.eclipse.persistence.tools.workbench.mappingsmodel.mapping.relational.MWRelationalDirectCollectionMapping; import org.eclipse.persistence.tools.workbench.mappingsmodel.mapping.relational.MWRelationalTransformationMapping; import org.eclipse.persistence.tools.workbench.mappingsmodel.project.relational.MWRelationalProject; import org.eclipse.persistence.tools.workbench.test.mappingsmodel.ModelProblemsTestCase; import org.eclipse.persistence.tools.workbench.utility.ClassTools; import org.eclipse.persistence.tools.workbench.utility.CollectionTools; import org.eclipse.persistence.tools.workbench.utility.NullPreferences; import org.eclipse.persistence.tools.workbench.utility.io.FileTools; public class MWTableTests extends ModelProblemsTestCase { public MWTableTests(String name) { super(name); } public static Test suite() { return new TestSuite(MWTableTests.class); } public void checkThatMappingsHaveNoMWReferences() { Iterator mappings = null; // check table reference mappings Collection tableReferenceMappings = getMappingsForClass( MWAbstractTableReferenceMapping.class, getCrimeSceneProject()); assertTrue( "there are no table reference mappings to test.", tableReferenceMappings.size() > 0); mappings = tableReferenceMappings.iterator(); while (mappings.hasNext()) { MWAbstractTableReferenceMapping mapping = (MWAbstractTableReferenceMapping) mappings.next(); assertTrue("TableRef mapping " + mapping.getName() + " in " + mapping.getParentDescriptor().getName() + " should not have a table reference.", mapping.getReference() == null); } // check many to many mappings Collection manyToManyMappings = getMappingsForClass( MWManyToManyMapping.class, getCrimeSceneProject()); assertTrue( "there are no MtoM mappings to test.", manyToManyMappings.size() > 0); mappings = manyToManyMappings.iterator(); while (mappings.hasNext()) { MWManyToManyMapping mapping = (MWManyToManyMapping) mappings.next(); assertTrue("MtoM mapping " + mapping.getName() + " in " + mapping.getParentDescriptor().getName() + " should not have a table reference.", mapping.getSourceReference() == null && mapping.getTargetReference() == null); } } public void checkThatMappingsHaveNoFieldReferences() { Iterator mappings = null; // check direct collection mappings Collection directCollectionMappings = getMappingsForClass(MWRelationalDirectCollectionMapping.class, getCrimeSceneProject()); assertTrue( "there are no direct collection mappings to test.", directCollectionMappings.size() > 0); mappings = directCollectionMappings.iterator(); while(mappings.hasNext()) { MWRelationalDirectCollectionMapping mapping = (MWRelationalDirectCollectionMapping) mappings.next(); assertTrue("mapping " + mapping.getName() + " in " + mapping.getParentDescriptor().getName() + " should not have a direct field.", mapping.getDirectValueColumn() == null); } // check direct to field mappings Collection directToFieldMappings = getMappingsForClass(MWDirectToFieldMapping.class, getCrimeSceneProject()); assertTrue( "there are no DtoD mappings to test.", directToFieldMappings.size() > 0); mappings = directToFieldMappings.iterator(); while (mappings.hasNext()) { MWDirectToFieldMapping mapping = (MWDirectToFieldMapping) mappings.next(); assertTrue("DtoF mapping " + mapping.getName() + " in " + mapping.getParentDescriptor().getName() + " should not have a field.", mapping.getColumn() == null); } // check transformation mappings Collection transformationMappings = getMappingsForClass(MWRelationalTransformationMapping.class, getCrimeSceneProject()); assertTrue( "there are no transformation mappings to test.", transformationMappings.size() > 0); mappings = transformationMappings.iterator(); while (mappings.hasNext()) { MWRelationalTransformationMapping mapping = (MWRelationalTransformationMapping) mappings.next(); boolean hasField = false; Iterator fieldMethodPairs = mapping.fieldTransformerAssociations(); while (fieldMethodPairs.hasNext()) { MWFieldTransformerAssociation fieldMethodPair = (MWFieldTransformerAssociation) fieldMethodPairs.next(); if (fieldMethodPair.getField() != null) { hasField = true; } } assertTrue("transformation mapping " + mapping.getName() + " in " + mapping.getParentDescriptor().getName() + " should not have any fields.", ! hasField); } } public void checkThatMappingsHaveNoTableReferences() { checkThatMappingsHaveNoMWReferences(); checkThatMappingsHaveNoFieldReferences(); } public void testAddField() { MWTable table = getTableNamed("PERSON"); MWColumn field = table.addColumn("NEWFIELD"); assertTrue("The field was not added.", table.columnNamed("NEWFIELD") != null); table.removeColumn(field); assertTrue("The field was not removed.", table.columnNamed("NEWFIELD") == null); } public void testAddReference() { MWTable crimeSceneTable = getTableNamed("CRIME_SCENE"); MWTable csToSuspectTable = getTableNamed("CS_SUSPECT"); MWReference reference = csToSuspectTable.addReference("CS_SUSPECT_TO_CRIME_SCENE", crimeSceneTable); reference.addColumnPair(csToSuspectTable.columnNamed("CS_ID"), crimeSceneTable.columnNamed("ID") ); assertTrue("The reference was not added.", csToSuspectTable.referenceNamed("CS_SUSPECT_TO_CRIME_SCENE") != null); csToSuspectTable.removeReference(reference); assertTrue("The reference was not removed.", csToSuspectTable.referenceNamed("CS_SUSPECT_TO_CRIME_SCENE") == null); } public void testGetReferenceConvenienceMethods() { MWTable personTable = getTableNamed("PERSON"); MWTable csSuspectTable = getTableNamed("CS_SUSPECT"); Collection references = CollectionTools.collection(personTable.referencesBetween(csSuspectTable)); assertTrue("getReferencesBetweenSelfAnd() failed.", references.size() == 1); } /** * this is an extensive test to make sure that all references to a databaseField are cleaned * up when a field is removed from a table. */ public void testRemoveField() { MWTable csToSuspectTable = getTableNamed("CS_SUSPECT"); MWTable personTable = getTableNamed("PERSON"); MWTable evidenceTable = getTableNamed("EVIDENCE"); // add a locking policy MWTableDescriptorLockingPolicy lockPolicy = (MWTableDescriptorLockingPolicy) getPersonDescriptor().getLockingPolicy(); lockPolicy.setLockingType(MWLockingPolicy.OPTIMISTIC_LOCKING); lockPolicy.setVersionLockField(personTable.columnNamed("F_NAME")); assertTrue("failed to set lock field", lockPolicy.getVersionLockField() != null); // add a primary key field assertTrue("there should be one primary key in Person descriptor.", getPersonDescriptor().primaryKeyPolicy().primaryKeysSize() == 1); assertTrue("there should be one virtual primary key in Person descriptor.", getPersonDescriptor().primaryKeyPolicy().primaryKeysSize() == 1); getPersonDescriptor().primaryKeyPolicy().addPrimaryKey(personTable.columnNamed("F_NAME")); assertTrue("failed to add a primary key field to Person descriptor.", getPersonDescriptor().primaryKeyPolicy().primaryKeysSize() == 2); // add a secondary table getPersonDescriptor().addMultiTableInfoPolicy(); getPersonDescriptor().addAssociatedTable(evidenceTable); assertTrue("failed to add a secondary table", getPersonDescriptor().associatedTablesSize() > 1); // add a secondary table association MWDescriptorMultiTableInfoPolicy tablePolicy = (MWDescriptorMultiTableInfoPolicy) getPersonDescriptor().getMultiTableInfoPolicy(); tablePolicy.secondaryTableHolderFor(evidenceTable).setPrimaryKeysHaveSameName(false); tablePolicy.secondaryTableHolderFor(evidenceTable).setReference(evidenceTable.referenceNamed("EVIDENCE_CRIME_SCENE")); assertTrue( "failed to add a secondary table association", tablePolicy.secondaryTableHoldersSize() > 0); // make sure that person has class indicator field MWInheritancePolicy inheritPolicy = getPersonDescriptor().getInheritancePolicy(); assertTrue("person does not have an inheritance policy.", inheritPolicy.isActive()); MWRelationalClassIndicatorFieldPolicy indicatorPolicy = (MWRelationalClassIndicatorFieldPolicy) inheritPolicy.getClassIndicatorPolicy(); assertTrue("person does not have a class indicator policy", indicatorPolicy != null); assertTrue("person does not have a class indicator field", indicatorPolicy.getField() != null); // test if I remove a field, then it is removed from all MWReferences. assertTrue("The reference CSSUS_SUS does not exist.", csToSuspectTable.columnNamed("SUSPECT_ID") != null); csToSuspectTable.removeColumn(csToSuspectTable.columnNamed("SUSPECT_ID") ); assertTrue("the SUSPECT_ID was not removed from the CSSUS_CS reference", ((MWColumnPair) csToSuspectTable.referenceNamed("CS_SUSPECT_PERSON").columnPairs().next()).getSourceColumn() == null ); // remove all the fields for (Iterator tables = getDatabase().tables(); tables.hasNext(); ) { MWTable table = (MWTable) tables.next(); for (Iterator columns = table.columns(); columns.hasNext(); ) { columns.next(); columns.remove(); } } // at this point, all tables have been deleted, so nobody should still have a reference // to a MWDatabaseField // check the multi-table info policy MWReference assoc = ((MWSecondaryTableHolder) tablePolicy.secondaryTableHolders().next()).getReference(); MWColumnPair ffAssoc = (MWColumnPair) assoc.columnPairs().next(); assertTrue("all fields are gone, but multi table info policy still has a field.", ffAssoc.getSourceColumn() == null && ffAssoc.getTargetColumn() == null ); // check locking policy assertTrue("all tables are gone, but locking policy still has a lock field.", lockPolicy.getVersionLockField() == null ); // check primary keys of descriptor assertTrue("descriptor primary keys not cleaned up properly", getPersonDescriptor().primaryKeyPolicy().primaryKeysSize() == 0); // check class indicator policy assertTrue("Person should not have have a class indicator field.", indicatorPolicy.getField() == null); checkThatMappingsHaveNoFieldReferences(); } /** this is an extensive test to make sure that all references to a MWReference are cleaned up when a reference is removed from a table. */ public void testRemoveReference() { MWTable evidenceTable = getTableNamed("EVIDENCE"); // add a secondary table getPersonDescriptor().addMultiTableInfoPolicy(); getPersonDescriptor().addAssociatedTable(evidenceTable); assertTrue("failed to add a secondary table", getPersonDescriptor().associatedTablesSize() > 1); // add a secondary table association MWDescriptorMultiTableInfoPolicy tablePolicy = (MWDescriptorMultiTableInfoPolicy) getPersonDescriptor().getMultiTableInfoPolicy(); tablePolicy.secondaryTableHolderFor(evidenceTable).setPrimaryKeysHaveSameName(false); tablePolicy.secondaryTableHolderFor(evidenceTable).setReference(evidenceTable.referenceNamed("EVIDENCE_CRIME_SCENE")); assertTrue( "failed to add a secondary table association", tablePolicy.secondaryTableHoldersSize() > 0); // remove all references for (Iterator tables = getDatabase().tables(); tables.hasNext(); ) { MWTable table = (MWTable) tables.next(); for (Iterator references = table.references(); references.hasNext(); ) { references.next(); references.remove(); } } // at this point, all references have been deleted, so nobody should still have a reference // to a MWReference // check the multi-table info policy assertTrue("all references are gone, but multi table info policy still has a table association.", ((MWSecondaryTableHolder) tablePolicy.secondaryTableHolders().next()).getReference() == null); checkThatMappingsHaveNoMWReferences(); } /** this is an extensive test to make sure that all references to a table are cleaned up when the table is removed from the database. */ public void testRemoveTable() { MWTable crimeSceneTable = getTableNamed("CRIME_SCENE"); MWTable csToSuspectTable = getTableNamed("CS_SUSPECT"); MWTable personTable = getTableNamed("PERSON"); MWTable evidenceTable = getTableNamed("EVIDENCE"); // add a locking policy MWTableDescriptorLockingPolicy lockPolicy = (MWTableDescriptorLockingPolicy) getPersonDescriptor().getLockingPolicy(); lockPolicy.setLockingType(MWLockingPolicy.OPTIMISTIC_LOCKING); lockPolicy.setVersionLockField(personTable.columnNamed("F_NAME")); assertTrue("failed to set lock field", lockPolicy.getVersionLockField() != null); // add a primary key field assertTrue("there should be one primary key in Person descriptor.", getPersonDescriptor().primaryKeyPolicy().primaryKeysSize() == 1); assertTrue("there should be one virtual primary key in Person descriptor.", getPersonDescriptor().primaryKeyPolicy().primaryKeysSize() == 1); getPersonDescriptor().primaryKeyPolicy().addPrimaryKey(personTable.columnNamed("F_NAME")); assertTrue("failed to add a primary key field to Person descriptor.", getPersonDescriptor().primaryKeyPolicy().primaryKeysSize() == 2); // add a secondary table getPersonDescriptor().addMultiTableInfoPolicy(); getPersonDescriptor().addAssociatedTable(evidenceTable); assertTrue("failed to add a secondary table", getPersonDescriptor().associatedTablesSize() > 1); // add a secondary table association MWDescriptorMultiTableInfoPolicy tablePolicy = (MWDescriptorMultiTableInfoPolicy) getPersonDescriptor().getMultiTableInfoPolicy(); tablePolicy.secondaryTableHolderFor(evidenceTable).setPrimaryKeysHaveSameName(false); tablePolicy.secondaryTableHolderFor(evidenceTable).setReference(evidenceTable.referenceNamed("EVIDENCE_CRIME_SCENE")); assertTrue( "failed to add a secondary table association", tablePolicy.secondaryTableHoldersSize() > 0); // make sure that person has class indicator field MWInheritancePolicy inheritPolicy = getPersonDescriptor().getInheritancePolicy(); assertTrue("person does not have an inheritance policy.", inheritPolicy.isActive()); MWRelationalClassIndicatorFieldPolicy indicatorPolicy = (MWRelationalClassIndicatorFieldPolicy) inheritPolicy.getClassIndicatorPolicy(); assertTrue("person does not have a class indicator policy", indicatorPolicy != null); assertTrue("person does not have a class indicator field", indicatorPolicy.getField() != null); // make sure that all many-to-many mappings have relation tables Collection manyToManyMappings = getMappingsForClass( MWManyToManyMapping.class, getCrimeSceneProject()); assertTrue( "there are no MtoM mappings to test.", manyToManyMappings.size() > 0); Iterator mappings = manyToManyMappings.iterator(); while (mappings.hasNext()) { MWManyToManyMapping mapping = (MWManyToManyMapping) mappings.next(); assertTrue("MtoM mapping " + mapping.getName() + " in " + mapping.getParentDescriptor().getName() + " should have relation table.", mapping.getRelationTable() != null); } // test if I remove a table, then all MWReferences to it are removed. assertTrue("The reference CSSUS_CS does not exist.", csToSuspectTable.referenceNamed("CS_SUSPECT_CRIME_SCENE") != null); getDatabase().removeTable(crimeSceneTable); assertTrue("the reference CSSUS_CS was not removed when CRIME_SCENE table was removed", csToSuspectTable.referenceNamed("CSSUSPECT_CRIME_SCENE") == null); // remove all the tables for (Iterator stream = getDatabase().tables(); stream.hasNext(); ) { stream.next(); stream.remove(); } // at this point, all tables have been deleted, so nobody should still have a reference // to a MWReference or MWTable assertTrue("the database should have no tables", getDatabase().tablesSize() == 0); // check the multi-table info policy assertTrue("all tables are gone, but multi table info policy still has a table association.", tablePolicy.secondaryTableHoldersSize() == 0); // check associated tables assertTrue("all tables are gone, but Person descriptor still has an associated table.", getPersonDescriptor().associatedTablesSize() == 0); assertTrue("all tables are gone, but Person descriptor still has a primary table.", getPersonDescriptor().getPrimaryTable() == null); assertTrue("secondary table associations should be gone in Person.tablePolicy", tablePolicy.secondaryTableHoldersSize() == 0); // check locking policy assertTrue("all tables are gone, but locking policy still has a lock field.", lockPolicy.getVersionLockField() == null ); // check primary keys of descriptor assertTrue("descriptor primary keys not cleaned up properly", getPersonDescriptor().primaryKeyPolicy().primaryKeysSize() == 0); assertTrue("descriptor virtual primary keys not good", getPersonDescriptor().primaryKeyPolicy().primaryKeysSize() == 0); // check class indicator policy assertTrue("Person should not have have a class indicator field.", indicatorPolicy.getField() == null); // check many-to-many relation table manyToManyMappings = getMappingsForClass( MWManyToManyMapping.class, getCrimeSceneProject()); assertTrue( "there are no MtoM mappings to test.", manyToManyMappings.size() > 0); mappings = manyToManyMappings.iterator(); while (mappings.hasNext()) { MWManyToManyMapping mapping = (MWManyToManyMapping) mappings.next(); assertTrue("MtoM mapping " + mapping.getName() + " in " + mapping.getParentDescriptor().getName() + " should not have relation table.", mapping.getRelationTable() == null ); } checkThatMappingsHaveNoTableReferences(); } public void testkeyPairsSpecifiedForReferencesProblem() { String errorName = ProblemConstants.INCOMPLETE_COLUMN_PAIR; MWTable table = getTableNamed("EVIDENCE"); MWReference reference = table.referenceNamed("EVIDENCE_CRIME_SCENE"); List associations = CollectionTools.list(reference.columnPairs()); ((MWColumnPair) associations.get(0)).setSourceColumn(null); assertTrue( "EVIDENCE table should have problem", hasProblem(errorName, table)); } /** * test renaming a table in an existing project and saving it; * the table would not be read back in */ public void testRenameIO() throws Exception { MWRelationalProject project0 = this.getCrimeSceneProject(); MWTable table0 = project0.getDatabase().tableNamed("EVIDENCE"); assertNotNull(table0); project0.setSaveDirectory(FileTools.emptyTemporaryDirectory(ClassTools.shortClassNameForObject(this) + "." + this.getName())); ProjectIOManager ioMgr = new ProjectIOManager(); ioMgr.write(project0); MWRelationalProject project1 = (MWRelationalProject) ioMgr.read(project0.saveFile(), NullPreferences.instance()); MWTable table1 = project1.getDatabase().tableNamed("EVIDENCE"); assertNotNull(table1); table1.rename(table1.getCatalog(), table1.getSchema(), table1.getShortName().toLowerCase()); ioMgr.write(project1); MWRelationalProject project2 = (MWRelationalProject) ioMgr.read(project1.saveFile(), NullPreferences.instance()); MWTable table2 = project2.getDatabase().tableNamed("EVIDENCE"); assertNull(table2); table2 = project2.getDatabase().tableNamed("evidence"); assertNotNull(table2); } }