HHH-10934 - Initial unit test
This commit is contained in:
parent
6307a47c13
commit
736da3247c
|
@ -0,0 +1,357 @@
|
|||
package org.hibernate.test.tool.schema.internal;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.boot.Metadata;
|
||||
import org.hibernate.boot.model.TruthValue;
|
||||
import org.hibernate.boot.model.naming.Identifier;
|
||||
import org.hibernate.boot.model.relational.Namespace;
|
||||
import org.hibernate.boot.model.relational.Namespace.Name;
|
||||
import org.hibernate.boot.model.relational.QualifiedTableName;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
|
||||
import org.hibernate.engine.jdbc.internal.Formatter;
|
||||
import org.hibernate.mapping.Column;
|
||||
import org.hibernate.mapping.ForeignKey;
|
||||
import org.hibernate.mapping.Table;
|
||||
import org.hibernate.tool.schema.extract.internal.ColumnInformationImpl;
|
||||
import org.hibernate.tool.schema.extract.internal.ForeignKeyInformationImpl;
|
||||
import org.hibernate.tool.schema.extract.internal.TableInformationImpl;
|
||||
import org.hibernate.tool.schema.extract.spi.ColumnInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.DatabaseInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.ForeignKeyInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.ForeignKeyInformation.ColumnReferenceMapping;
|
||||
import org.hibernate.tool.schema.extract.spi.InformationExtractor;
|
||||
import org.hibernate.tool.schema.extract.spi.NameSpaceTablesInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.TableInformation;
|
||||
import org.hibernate.tool.schema.internal.AbstractSchemaMigrator;
|
||||
import org.hibernate.tool.schema.internal.exec.GenerationTarget;
|
||||
import org.hibernate.tool.schema.spi.ExecutionOptions;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
/**
|
||||
* @author Milo van der Zee
|
||||
*/
|
||||
public class CheckForExistingForeignKeyTest {
|
||||
|
||||
private class SchemaMigrator extends AbstractSchemaMigrator {
|
||||
|
||||
/**
|
||||
* Needed constructor.
|
||||
*/
|
||||
public SchemaMigrator() {
|
||||
super( null, null );
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed implementation. Not used in test.
|
||||
*/
|
||||
@Override
|
||||
protected NameSpaceTablesInformation performTablesMigration(Metadata metadata, DatabaseInformation existingDatabase, ExecutionOptions options,
|
||||
Dialect dialect,
|
||||
Formatter formatter, Set<String> exportIdentifiers, boolean tryToCreateCatalogs, boolean tryToCreateSchemas,
|
||||
Set<Identifier> exportedCatalogs, Namespace namespace, GenerationTarget[] targets) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private class ColumnReferenceMappingImpl implements ColumnReferenceMapping {
|
||||
|
||||
private ColumnInformation referencingColumnMetadata;
|
||||
private ColumnInformation referencedColumnMetadata;
|
||||
|
||||
public ColumnReferenceMappingImpl(ColumnInformation referencingColumnMetadata, ColumnInformation referencedColumnMetadata) {
|
||||
this.referencingColumnMetadata = referencingColumnMetadata;
|
||||
this.referencedColumnMetadata = referencedColumnMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColumnInformation getReferencingColumnMetadata() {
|
||||
return referencingColumnMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColumnInformation getReferencedColumnMetadata() {
|
||||
return referencedColumnMetadata;
|
||||
}
|
||||
}
|
||||
|
||||
private class IdentifierHelperImpl implements IdentifierHelper {
|
||||
|
||||
@Override
|
||||
public Identifier normalizeQuoting(Identifier identifier) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier toIdentifier(String text) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier toIdentifier(String text, boolean quoted) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier applyGlobalQuoting(String text) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReservedWord(String word) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toMetaDataCatalogName(Identifier catalogIdentifier) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toMetaDataSchemaName(Identifier schemaIdentifier) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toMetaDataObjectName(Identifier identifier) {
|
||||
return identifier.getText();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the key has no name it should never be found. Result is that those keys are always recreated. But keys always
|
||||
* have a name so this is no problem.
|
||||
*
|
||||
* @throws NoSuchMethodException - error
|
||||
* @throws SecurityException - error
|
||||
* @throws IllegalAccessException - error
|
||||
* @throws IllegalArgumentException - error
|
||||
* @throws InvocationTargetException - error
|
||||
*/
|
||||
@Test
|
||||
public void testForeignKeyWithoutName()
|
||||
throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||
// Get the private method
|
||||
Method method = AbstractSchemaMigrator.class.getDeclaredMethod( "checkForExistingForeignKey", ForeignKey.class, TableInformation.class );
|
||||
method.setAccessible( true );
|
||||
|
||||
// foreignKey name with same name should match
|
||||
ForeignKey foreignKey = new ForeignKey();
|
||||
TableInformation tableInformation = new TableInformationImpl( null, null, null, false, null );
|
||||
boolean found = (boolean) method.invoke( new SchemaMigrator(), foreignKey, tableInformation );
|
||||
Assert.assertFalse( "Key should not be found", found );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test key not found if tableinformation is missing.
|
||||
*
|
||||
* @throws NoSuchMethodException - error
|
||||
* @throws SecurityException - error
|
||||
* @throws IllegalAccessException - error
|
||||
* @throws IllegalArgumentException - error
|
||||
* @throws InvocationTargetException - error
|
||||
*/
|
||||
@Test
|
||||
public void testMissingTableInformation()
|
||||
throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||
// Get the private method
|
||||
Method method = AbstractSchemaMigrator.class.getDeclaredMethod( "checkForExistingForeignKey", ForeignKey.class, TableInformation.class );
|
||||
method.setAccessible( true );
|
||||
|
||||
// foreignKey name with same name should match
|
||||
ForeignKey foreignKey = new ForeignKey();
|
||||
foreignKey.setName( "objectId2id" );
|
||||
boolean found = (boolean) method.invoke( new SchemaMigrator(), foreignKey, null );
|
||||
Assert.assertFalse( "Key should not be found", found );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check detection of existing foreign keys with the same name exists.
|
||||
*
|
||||
* @throws SecurityException - error
|
||||
* @throws NoSuchMethodException - error
|
||||
* @throws InvocationTargetException - error
|
||||
* @throws IllegalArgumentException - error
|
||||
* @throws IllegalAccessException - error
|
||||
* @throws NoSuchFieldException - error
|
||||
*/
|
||||
@Test
|
||||
public void testKeyWithSameNameExists()
|
||||
throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException,
|
||||
NoSuchFieldException {
|
||||
// Get the private method
|
||||
Method method = AbstractSchemaMigrator.class.getDeclaredMethod( "checkForExistingForeignKey", ForeignKey.class, TableInformation.class );
|
||||
method.setAccessible( true );
|
||||
|
||||
ForeignKey foreignKey = new ForeignKey();
|
||||
foreignKey.setName( "objectId2id" );
|
||||
foreignKey.addColumn( new Column( "id" ) );
|
||||
foreignKey.setReferencedTable( new Table( "table2" ) );
|
||||
|
||||
InformationExtractor informationExtractor = Mockito.mock( InformationExtractor.class );
|
||||
IdentifierHelper identifierHelper = new IdentifierHelperImpl();
|
||||
List<ForeignKeyInformation> fks = new ArrayList<>();
|
||||
fks.add( new ForeignKeyInformationImpl( new Identifier( "objectId2id", false ), new ArrayList<>() ) );
|
||||
Mockito.when( informationExtractor.getForeignKeys( Mockito.any() ) ).thenReturn( fks );
|
||||
Name schemaName = new Name( new Identifier( "-", false ), new Identifier( "-", false ) );
|
||||
QualifiedTableName tableName = new QualifiedTableName( schemaName, new Identifier( "-", false ) );
|
||||
TableInformation tableInformation = new TableInformationImpl( informationExtractor, identifierHelper, tableName, false, null );
|
||||
|
||||
// foreignKey name with same name should match
|
||||
boolean found = (boolean) method.invoke( new SchemaMigrator(), foreignKey, tableInformation );
|
||||
Assert.assertTrue( "Key should be found", found );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check detection of existing foreign keys with the same name exists.
|
||||
*
|
||||
* @throws SecurityException - error
|
||||
* @throws NoSuchMethodException - error
|
||||
* @throws InvocationTargetException - error
|
||||
* @throws IllegalArgumentException - error
|
||||
* @throws IllegalAccessException - error
|
||||
* @throws NoSuchFieldException - error
|
||||
*/
|
||||
@Test
|
||||
public void testKeyWithSameNameNotExists()
|
||||
throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException,
|
||||
NoSuchFieldException {
|
||||
// Get the private method
|
||||
Method method = AbstractSchemaMigrator.class.getDeclaredMethod( "checkForExistingForeignKey", ForeignKey.class, TableInformation.class );
|
||||
method.setAccessible( true );
|
||||
|
||||
ForeignKey foreignKey = new ForeignKey();
|
||||
foreignKey.setName( "objectId2id_1" );
|
||||
foreignKey.addColumn( new Column( "id" ) );
|
||||
foreignKey.setReferencedTable( new Table( "table2" ) );
|
||||
|
||||
InformationExtractor informationExtractor = Mockito.mock( InformationExtractor.class );
|
||||
IdentifierHelper identifierHelper = new IdentifierHelperImpl();
|
||||
List<ForeignKeyInformation> fks = new ArrayList<>();
|
||||
fks.add( new ForeignKeyInformationImpl( new Identifier( "objectId2id_2", false ), new ArrayList<>() ) );
|
||||
Mockito.when( informationExtractor.getForeignKeys( Mockito.any() ) ).thenReturn( fks );
|
||||
Name schemaName = new Name( new Identifier( "-", false ), new Identifier( "-", false ) );
|
||||
QualifiedTableName tableName = new QualifiedTableName( schemaName, new Identifier( "-", false ) );
|
||||
TableInformation tableInformation = new TableInformationImpl( informationExtractor, identifierHelper, tableName, false, null );
|
||||
|
||||
// foreignKey name with same name should match
|
||||
boolean found = (boolean) method.invoke( new SchemaMigrator(), foreignKey, tableInformation );
|
||||
Assert.assertFalse( "Key should not be found", found );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check detection of existing foreign key with the same mappings for a simple mapping (table1.objectId =>
|
||||
* table2.id).
|
||||
*
|
||||
* @throws SecurityException - error
|
||||
* @throws NoSuchMethodException - error
|
||||
* @throws InvocationTargetException - error
|
||||
* @throws IllegalArgumentException - error
|
||||
* @throws IllegalAccessException - error
|
||||
* @throws NoSuchFieldException - error
|
||||
*/
|
||||
@Test
|
||||
public void testCheckForExistingForeignKeyOne2One() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
|
||||
InvocationTargetException, NoSuchFieldException {
|
||||
// Get the private method
|
||||
Method method = AbstractSchemaMigrator.class.getDeclaredMethod( "checkForExistingForeignKey", ForeignKey.class, TableInformation.class );
|
||||
method.setAccessible( true );
|
||||
|
||||
ForeignKey foreignKey = new ForeignKey();
|
||||
foreignKey.setName( "objectId2id_1" ); // Make sure the match is not successful based on key name
|
||||
foreignKey.addColumn( new Column( "id" ) );
|
||||
foreignKey.setReferencedTable( new Table( "table2" ) );
|
||||
|
||||
Name schemaName = new Name( new Identifier( "-", false ), new Identifier( "-", false ) );
|
||||
InformationExtractor informationExtractor = Mockito.mock( InformationExtractor.class );
|
||||
IdentifierHelper identifierHelper = new IdentifierHelperImpl();
|
||||
List<ForeignKeyInformation> fks = new ArrayList<>();
|
||||
fks.add( getForeignKeyInformation( "table2", "id", "object2Id_2" ) );
|
||||
Mockito.when( informationExtractor.getForeignKeys( Mockito.any() ) ).thenReturn( fks );
|
||||
QualifiedTableName tableName = new QualifiedTableName( schemaName, new Identifier( "-", false ) );
|
||||
TableInformation tableInformation = new TableInformationImpl( informationExtractor, identifierHelper, tableName, false, null );
|
||||
AbstractSchemaMigrator schemaMigrator = new SchemaMigrator();
|
||||
|
||||
// Check single-column-key to single-column-key, existing (table1.objectId => table2.id)
|
||||
boolean found = (boolean) method.invoke( schemaMigrator, foreignKey, tableInformation );
|
||||
Assert.assertTrue( "Key should be found", found );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check detection of not existing foreign key with the same mappings for a simple mapping (table1.objectId =>
|
||||
* table2.id).
|
||||
*
|
||||
* @throws SecurityException - error
|
||||
* @throws NoSuchMethodException - error
|
||||
* @throws InvocationTargetException - error
|
||||
* @throws IllegalArgumentException - error
|
||||
* @throws IllegalAccessException - error
|
||||
* @throws NoSuchFieldException - error
|
||||
*/
|
||||
@Test
|
||||
public void testCheckForNotExistingForeignKeyOne2One() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
|
||||
InvocationTargetException, NoSuchFieldException {
|
||||
// Get the private method
|
||||
Method method = AbstractSchemaMigrator.class.getDeclaredMethod( "checkForExistingForeignKey", ForeignKey.class, TableInformation.class );
|
||||
method.setAccessible( true );
|
||||
|
||||
ForeignKey foreignKey = new ForeignKey();
|
||||
foreignKey.setName( "objectId2id_1" ); // Make sure the match is not successful based on key name
|
||||
foreignKey.addColumn( new Column( "id" ) );
|
||||
foreignKey.setReferencedTable( new Table( "table2" ) );
|
||||
|
||||
Name schemaName = new Name( new Identifier( "-", false ), new Identifier( "-", false ) );
|
||||
InformationExtractor informationExtractor = Mockito.mock( InformationExtractor.class );
|
||||
IdentifierHelper identifierHelper = new IdentifierHelperImpl();
|
||||
List<ForeignKeyInformation> fks = new ArrayList<>();
|
||||
fks.add( getForeignKeyInformation( "table2", "blah", "blahKey_001" ) );
|
||||
fks.add( getForeignKeyInformation( "table3", "id", "blahKey_002" ) );
|
||||
fks.add( getForeignKeyInformation( "table3", "blah", "blahKey_003" ) );
|
||||
Mockito.when( informationExtractor.getForeignKeys( Mockito.any() ) ).thenReturn( fks );
|
||||
QualifiedTableName tableName = new QualifiedTableName( schemaName, new Identifier( "-", false ) );
|
||||
TableInformation tableInformation = new TableInformationImpl( informationExtractor, identifierHelper, tableName, false, null );
|
||||
AbstractSchemaMigrator schemaMigrator = new SchemaMigrator();
|
||||
|
||||
// Check single-column-key to single-column-key, existing (table1.objectId => table2.id)
|
||||
boolean found = (boolean) method.invoke( schemaMigrator, foreignKey, tableInformation );
|
||||
Assert.assertFalse( "Key should not be found", found );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param referencedTableName - String
|
||||
* @param referencingColumnName - String
|
||||
* @param keyName - String
|
||||
* @return ForeignKeyInformation
|
||||
*/
|
||||
private ForeignKeyInformation getForeignKeyInformation(String referencedTableName, String referencingColumnName, String keyName) {
|
||||
List<ColumnReferenceMapping> columnMappingList = new ArrayList<>();
|
||||
ColumnInformation referencingColumnMetadata = getColumnInformation( "-", referencingColumnName );
|
||||
ColumnInformation referencedColumnMetadata = getColumnInformation( referencedTableName, "-" );
|
||||
ColumnReferenceMapping columnReferenceMapping = new ColumnReferenceMappingImpl( referencingColumnMetadata, referencedColumnMetadata );
|
||||
columnMappingList.add( columnReferenceMapping );
|
||||
ForeignKeyInformationImpl foreignKeyInformation = new ForeignKeyInformationImpl( new Identifier( keyName, false ), columnMappingList );
|
||||
return foreignKeyInformation;
|
||||
}
|
||||
|
||||
private ColumnInformation getColumnInformation(String tableName, String columnName) {
|
||||
Name schemaName = new Name( new Identifier( "-", false ), new Identifier( "-", false ) );
|
||||
TableInformation containingTableInformation = new TableInformationImpl( null, null,
|
||||
new QualifiedTableName( schemaName, new Identifier( tableName, false ) ), false, null );
|
||||
Identifier columnIdentifier = new Identifier( columnName, false );
|
||||
int typeCode = 0;
|
||||
String typeName = null;
|
||||
int columnSize = 0;
|
||||
int decimalDigits = 0;
|
||||
TruthValue nullable = null;
|
||||
ColumnInformationImpl columnInformation = new ColumnInformationImpl( containingTableInformation, columnIdentifier, typeCode, typeName, columnSize,
|
||||
decimalDigits, nullable );
|
||||
return columnInformation;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue