some cleanups to AbstractInformationExtractorImpl

This commit is contained in:
Gavin King 2024-11-14 10:35:35 +01:00
parent 26cd62ff6d
commit 12e17ed870
3 changed files with 225 additions and 324 deletions

View File

@ -203,6 +203,7 @@ import jakarta.xml.bind.Marshaller;
import static org.hibernate.boot.jaxb.hbm.transform.HbmTransformationLogging.TRANSFORMATION_LOGGER; import static org.hibernate.boot.jaxb.hbm.transform.HbmTransformationLogging.TRANSFORMATION_LOGGER;
import static org.hibernate.internal.util.StringHelper.isNotEmpty; import static org.hibernate.internal.util.StringHelper.isNotEmpty;
import static org.hibernate.internal.util.StringHelper.nullIfEmpty;
/** /**
* Transforms {@code hbm.xml} {@linkplain JaxbHbmHibernateMapping JAXB} bindings into * Transforms {@code hbm.xml} {@linkplain JaxbHbmHibernateMapping JAXB} bindings into
@ -1205,7 +1206,7 @@ public class HbmXmlTransformer {
} }
} }
} }
else if ( StringHelper.isNotEmpty( tableName ) ) { else if ( isNotEmpty( tableName ) ) {
// this is the case of transforming a <join/> where the property did not specify columns or formula. // this is the case of transforming a <join/> where the property did not specify columns or formula.
// we need to create a column still to pass along the secondary table name // we need to create a column still to pass along the secondary table name
final TargetColumnAdapter column = target.makeColumnAdapter( columnDefaults ); final TargetColumnAdapter column = target.makeColumnAdapter( columnDefaults );
@ -1590,7 +1591,7 @@ public class HbmXmlTransformer {
} }
private JaxbUserTypeImpl interpretBasicType(String typeName, JaxbHbmConfigParameterContainer typeLocalParams, JaxbHbmTypeDefinitionType typeDef) { private JaxbUserTypeImpl interpretBasicType(String typeName, JaxbHbmConfigParameterContainer typeLocalParams, JaxbHbmTypeDefinitionType typeDef) {
assert StringHelper.isNotEmpty( typeName ); assert isNotEmpty( typeName );
final JaxbUserTypeImpl typeNode = new JaxbUserTypeImpl(); final JaxbUserTypeImpl typeNode = new JaxbUserTypeImpl();
@ -1624,7 +1625,7 @@ public class HbmXmlTransformer {
JaxbHbmCompositeAttributeType hbmComponent, JaxbHbmCompositeAttributeType hbmComponent,
ComponentTypeInfo componentTypeInfo) { ComponentTypeInfo componentTypeInfo) {
final String embeddableClassName = componentTypeInfo.getComponent().getComponentClassName(); final String embeddableClassName = componentTypeInfo.getComponent().getComponentClassName();
if ( StringHelper.isNotEmpty( embeddableClassName ) ) { if ( isNotEmpty( embeddableClassName ) ) {
final JaxbEmbeddableImpl existing = jaxbEmbeddableByClassName.get( embeddableClassName ); final JaxbEmbeddableImpl existing = jaxbEmbeddableByClassName.get( embeddableClassName );
if ( existing != null ) { if ( existing != null ) {
return existing; return existing;
@ -1641,7 +1642,7 @@ public class HbmXmlTransformer {
); );
mappingXmlBinding.getRoot().getEmbeddables().add( jaxbEmbeddable ); mappingXmlBinding.getRoot().getEmbeddables().add( jaxbEmbeddable );
if ( StringHelper.isNotEmpty( embeddableClassName ) ) { if ( isNotEmpty( embeddableClassName ) ) {
jaxbEmbeddableByClassName.put( embeddableClassName, jaxbEmbeddable ); jaxbEmbeddableByClassName.put( embeddableClassName, jaxbEmbeddable );
} }
@ -1668,7 +1669,7 @@ public class HbmXmlTransformer {
private int counter = 1; private int counter = 1;
private String determineEmbeddableName(String componentClassName, String attributeName) { private String determineEmbeddableName(String componentClassName, String attributeName) {
if ( StringHelper.isNotEmpty( componentClassName ) ) { if ( isNotEmpty( componentClassName ) ) {
return componentClassName; return componentClassName;
} }
return attributeName + "_" + counter++; return attributeName + "_" + counter++;
@ -1692,7 +1693,7 @@ public class HbmXmlTransformer {
oneToOne.setOrphanRemoval( isOrphanRemoval( hbmOneToOne.getCascade() ) ); oneToOne.setOrphanRemoval( isOrphanRemoval( hbmOneToOne.getCascade() ) );
oneToOne.setForeignKey( new JaxbForeignKeyImpl() ); oneToOne.setForeignKey( new JaxbForeignKeyImpl() );
oneToOne.getForeignKey().setName( hbmOneToOne.getForeignKey() ); oneToOne.getForeignKey().setName( hbmOneToOne.getForeignKey() );
if ( StringHelper.isNotEmpty( hbmOneToOne.getPropertyRef() ) ) { if ( isNotEmpty( hbmOneToOne.getPropertyRef() ) ) {
oneToOne.setPropertyRef( new JaxbPropertyRefImpl() ); oneToOne.setPropertyRef( new JaxbPropertyRefImpl() );
oneToOne.getPropertyRef().setName( hbmOneToOne.getPropertyRef() ); oneToOne.getPropertyRef().setName( hbmOneToOne.getPropertyRef() );
} }
@ -1736,7 +1737,7 @@ public class HbmXmlTransformer {
jaxbManyToOne.setAttributeAccessor( hbmNode.getAccess() ); jaxbManyToOne.setAttributeAccessor( hbmNode.getAccess() );
jaxbManyToOne.setCascade( convertCascadeType( hbmNode.getCascade() ) ); jaxbManyToOne.setCascade( convertCascadeType( hbmNode.getCascade() ) );
if ( StringHelper.isNotEmpty( hbmNode.getPropertyRef() ) ) { if ( isNotEmpty( hbmNode.getPropertyRef() ) ) {
jaxbManyToOne.setPropertyRef( new JaxbPropertyRefImpl() ); jaxbManyToOne.setPropertyRef( new JaxbPropertyRefImpl() );
jaxbManyToOne.getPropertyRef().setName( hbmNode.getPropertyRef() ); jaxbManyToOne.getPropertyRef().setName( hbmNode.getPropertyRef() );
} }
@ -1905,7 +1906,7 @@ public class HbmXmlTransformer {
target.setFetchMode( convert( source.getFetch() ) ); target.setFetchMode( convert( source.getFetch() ) );
target.setFetch( convert( source.getLazy() ) ); target.setFetch( convert( source.getLazy() ) );
if ( StringHelper.isNotEmpty( source.getCollectionType() ) ) { if ( isNotEmpty( source.getCollectionType() ) ) {
final JaxbCollectionUserTypeImpl jaxbCollectionUserType = new JaxbCollectionUserTypeImpl(); final JaxbCollectionUserTypeImpl jaxbCollectionUserType = new JaxbCollectionUserTypeImpl();
target.setCollectionType( jaxbCollectionUserType ); target.setCollectionType( jaxbCollectionUserType );
jaxbCollectionUserType.setType( source.getCollectionType() ); jaxbCollectionUserType.setType( source.getCollectionType() );
@ -1913,7 +1914,7 @@ public class HbmXmlTransformer {
if ( source instanceof JaxbHbmSetType set ) { if ( source instanceof JaxbHbmSetType set ) {
final String sort = set.getSort(); final String sort = set.getSort();
if ( StringHelper.isNotEmpty( sort ) && !"unsorted".equals( sort ) ) { if ( isNotEmpty( sort ) && !"unsorted".equals( sort ) ) {
target.setSort( sort ); target.setSort( sort );
} }
target.setOrderBy( set.getOrderBy() ); target.setOrderBy( set.getOrderBy() );
@ -1921,7 +1922,7 @@ public class HbmXmlTransformer {
} }
else if ( source instanceof JaxbHbmMapType map ) { else if ( source instanceof JaxbHbmMapType map ) {
final String sort = map.getSort(); final String sort = map.getSort();
if ( StringHelper.isNotEmpty( sort ) && !"unsorted".equals( sort ) ) { if ( isNotEmpty( sort ) && !"unsorted".equals( sort ) ) {
target.setSort( sort ); target.setSort( sort );
} }
target.setOrderBy( map.getOrderBy() ); target.setOrderBy( map.getOrderBy() );
@ -2025,7 +2026,7 @@ public class HbmXmlTransformer {
return; return;
} }
if ( StringHelper.isNotEmpty( source.getMapKey().getNode() ) ) { if ( isNotEmpty( source.getMapKey().getNode() ) ) {
handleUnsupported( handleUnsupported(
"Transformation of `node` attribute is not supported - %s", "Transformation of `node` attribute is not supported - %s",
origin() origin()
@ -2040,7 +2041,7 @@ public class HbmXmlTransformer {
jaxbMapKeyType.setValue( mapKeyType ); jaxbMapKeyType.setValue( mapKeyType );
} }
if ( StringHelper.isNotEmpty( source.getMapKey().getColumnAttribute() ) ) { if ( isNotEmpty( source.getMapKey().getColumnAttribute() ) ) {
final JaxbMapKeyColumnImpl mapKeyColumn = new JaxbMapKeyColumnImpl(); final JaxbMapKeyColumnImpl mapKeyColumn = new JaxbMapKeyColumnImpl();
mapKeyColumn.setName( source.getMapKey().getColumnAttribute() ); mapKeyColumn.setName( source.getMapKey().getColumnAttribute() );
target.setMapKeyColumn( mapKeyColumn ); target.setMapKeyColumn( mapKeyColumn );
@ -2049,38 +2050,32 @@ public class HbmXmlTransformer {
} }
private String resolveMapKeyType(JaxbHbmMapKeyBasicType mapKey) { private String resolveMapKeyType(JaxbHbmMapKeyBasicType mapKey) {
if ( StringHelper.isNotEmpty( mapKey.getTypeAttribute() ) ) { if ( isNotEmpty( mapKey.getTypeAttribute() ) ) {
return mapKey.getTypeAttribute(); return mapKey.getTypeAttribute();
} }
else if ( mapKey.getType() != null ) {
if ( mapKey.getType() != null ) { return nullIfEmpty( mapKey.getType().getName() );
return StringHelper.nullIfEmpty( mapKey.getType().getName() );
} }
else {
return null; return null;
} }
}
private Boolean invert(Boolean value) { private Boolean invert(Boolean value) {
return invert( value, null ); return value == null ? null : !value;
}
private Boolean invert(Boolean value, Boolean defaultValue) {
if ( value == null ) {
return defaultValue;
}
return !value;
} }
private JaxbPluralFetchModeImpl convert(JaxbHbmFetchStyleWithSubselectEnum fetch) { private JaxbPluralFetchModeImpl convert(JaxbHbmFetchStyleWithSubselectEnum fetch) {
if ( fetch != null ) { if ( fetch == null ) {
return null;
}
else {
return switch ( fetch ) { return switch ( fetch ) {
case SELECT -> JaxbPluralFetchModeImpl.SELECT; case SELECT -> JaxbPluralFetchModeImpl.SELECT;
case JOIN -> JaxbPluralFetchModeImpl.JOIN; case JOIN -> JaxbPluralFetchModeImpl.JOIN;
case SUBSELECT -> JaxbPluralFetchModeImpl.SUBSELECT; case SUBSELECT -> JaxbPluralFetchModeImpl.SUBSELECT;
}; };
} }
return null;
} }
@ -2181,7 +2176,7 @@ public class HbmXmlTransformer {
final ComponentTypeInfo componentTypeInfo = transformationState.getEmbeddableInfoByRole().get( partRole ); final ComponentTypeInfo componentTypeInfo = transformationState.getEmbeddableInfoByRole().get( partRole );
target.setTarget( embeddableName ); target.setTarget( embeddableName );
if ( StringHelper.isNotEmpty( embeddableClassName ) ) { if ( isNotEmpty( embeddableClassName ) ) {
target.setTargetClass( embeddableClassName ); target.setTargetClass( embeddableClassName );
} }
@ -2217,7 +2212,7 @@ public class HbmXmlTransformer {
} }
transferCollectionCommonInfo( hbmAttributeInfo, target ); transferCollectionCommonInfo( hbmAttributeInfo, target );
target.setTargetEntity( StringHelper.isNotEmpty( hbmOneToMany.getClazz() ) ? hbmOneToMany.getClazz() : hbmOneToMany.getEntityName() ); target.setTargetEntity( isNotEmpty( hbmOneToMany.getClazz() ) ? hbmOneToMany.getClazz() : hbmOneToMany.getEntityName() );
final Property bootModelProperty = propertyInfo.bootModelProperty(); final Property bootModelProperty = propertyInfo.bootModelProperty();
final Collection bootModelValue = (Collection) bootModelProperty.getValue(); final Collection bootModelValue = (Collection) bootModelProperty.getValue();
@ -2291,7 +2286,7 @@ public class HbmXmlTransformer {
target.getFilters().add( convert( hbmFilter ) ); target.getFilters().add( convert( hbmFilter ) );
} }
if ( StringHelper.isNotEmpty( hbmAttributeInfo.getWhere() ) ) { if ( isNotEmpty( hbmAttributeInfo.getWhere() ) ) {
target.setSqlRestriction( hbmAttributeInfo.getWhere() ); target.setSqlRestriction( hbmAttributeInfo.getWhere() );
} }
if ( hbmAttributeInfo.getSqlInsert() != null ) { if ( hbmAttributeInfo.getSqlInsert() != null ) {
@ -2320,7 +2315,7 @@ public class HbmXmlTransformer {
PluralAttributeInfo hbmAttributeInfo, PluralAttributeInfo hbmAttributeInfo,
Property bootModelProperty, Property bootModelProperty,
Collection bootModelValue) { Collection bootModelValue) {
if ( StringHelper.isNotEmpty( bootModelValue.getMappedByProperty() ) ) { if ( isNotEmpty( bootModelValue.getMappedByProperty() ) ) {
return bootModelValue.getMappedByProperty(); return bootModelValue.getMappedByProperty();
} }
@ -2369,8 +2364,8 @@ public class HbmXmlTransformer {
final Column collectionKeyColumn = (Column) collectionKeySelectable; final Column collectionKeyColumn = (Column) collectionKeySelectable;
final Column candidateColumn = (Column) candidateSelectable; final Column candidateColumn = (Column) candidateSelectable;
assert StringHelper.isNotEmpty( collectionKeyColumn.getCanonicalName() ); assert isNotEmpty( collectionKeyColumn.getCanonicalName() );
assert StringHelper.isNotEmpty( candidateColumn.getCanonicalName() ); assert isNotEmpty( candidateColumn.getCanonicalName() );
if ( !collectionKeyColumn.getCanonicalName().equals( candidateColumn.getCanonicalName() ) ) { if ( !collectionKeyColumn.getCanonicalName().equals( candidateColumn.getCanonicalName() ) ) {
return false; return false;
} }
@ -2400,7 +2395,7 @@ public class HbmXmlTransformer {
if ( manyToMany.isEmbedXml() != null ) { if ( manyToMany.isEmbedXml() != null ) {
handleUnsupported( "`embed-xml` no longer supported" ); handleUnsupported( "`embed-xml` no longer supported" );
} }
if ( StringHelper.isNotEmpty( manyToMany.getNode() ) ) { if ( isNotEmpty( manyToMany.getNode() ) ) {
handleUnsupported( "`node` no longer supported" ); handleUnsupported( "`node` no longer supported" );
} }
@ -2409,7 +2404,7 @@ public class HbmXmlTransformer {
final JaxbJoinTableImpl joinTable = new JaxbJoinTableImpl(); final JaxbJoinTableImpl joinTable = new JaxbJoinTableImpl();
final String tableName = hbmCollection.getTable(); final String tableName = hbmCollection.getTable();
if ( StringHelper.isNotEmpty( tableName ) ) { if ( isNotEmpty( tableName ) ) {
joinTable.setName( tableName ); joinTable.setName( tableName );
} }
target.setJoinTable( joinTable ); target.setJoinTable( joinTable );
@ -2503,7 +2498,7 @@ public class HbmXmlTransformer {
); );
transferCollectionCommonInfo( hbmCollection, target ); transferCollectionCommonInfo( hbmCollection, target );
target.setTargetEntity( StringHelper.isNotEmpty( manyToMany.getClazz() ) ? manyToMany.getClazz() : manyToMany.getEntityName() ); target.setTargetEntity( isNotEmpty( manyToMany.getClazz() ) ? manyToMany.getClazz() : manyToMany.getEntityName() );
if ( manyToMany.getNotFound() == JaxbHbmNotFoundEnum.IGNORE ) { if ( manyToMany.getNotFound() == JaxbHbmNotFoundEnum.IGNORE ) {
target.setNotFound( NotFoundAction.IGNORE ); target.setNotFound( NotFoundAction.IGNORE );
@ -2513,7 +2508,7 @@ public class HbmXmlTransformer {
target.getFilters().add( convert( hbmFilter ) ); target.getFilters().add( convert( hbmFilter ) );
} }
if ( StringHelper.isNotEmpty( hbmCollection.getWhere() ) ) { if ( isNotEmpty( hbmCollection.getWhere() ) ) {
target.setSqlRestriction( hbmCollection.getWhere() ); target.setSqlRestriction( hbmCollection.getWhere() );
} }
if ( hbmCollection.getSqlInsert() != null ) { if ( hbmCollection.getSqlInsert() != null ) {
@ -2664,7 +2659,7 @@ public class HbmXmlTransformer {
EntityTypeInfo bootEntityInfo, EntityTypeInfo bootEntityInfo,
Property idProperty) { Property idProperty) {
final String embeddableClassName = hbmCompositeId.getClazz(); final String embeddableClassName = hbmCompositeId.getClazz();
if ( StringHelper.isNotEmpty( embeddableClassName ) ) { if ( isNotEmpty( embeddableClassName ) ) {
final JaxbEmbeddableImpl existing = jaxbEmbeddableByClassName.get( embeddableClassName ); final JaxbEmbeddableImpl existing = jaxbEmbeddableByClassName.get( embeddableClassName );
if ( existing != null ) { if ( existing != null ) {
return existing; return existing;

View File

@ -9,7 +9,6 @@ import java.sql.ResultSet;
import java.sql.ResultSetMetaData; import java.sql.ResultSetMetaData;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -18,7 +17,6 @@ import java.util.Objects;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import org.hibernate.JDBCException; import org.hibernate.JDBCException;
import org.hibernate.boot.model.naming.DatabaseIdentifier;
import org.hibernate.boot.model.naming.Identifier; import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.relational.QualifiedTableName; import org.hibernate.boot.model.relational.QualifiedTableName;
import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.AvailableSettings;
@ -31,8 +29,6 @@ import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.engine.jdbc.env.spi.NameQualifierSupport; import org.hibernate.engine.jdbc.env.spi.NameQualifierSupport;
import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.tool.schema.extract.spi.ColumnInformation; import org.hibernate.tool.schema.extract.spi.ColumnInformation;
import org.hibernate.tool.schema.extract.spi.ExtractionContext; import org.hibernate.tool.schema.extract.spi.ExtractionContext;
import org.hibernate.tool.schema.extract.spi.ForeignKeyInformation; import org.hibernate.tool.schema.extract.spi.ForeignKeyInformation;
@ -44,6 +40,12 @@ import org.hibernate.tool.schema.extract.spi.SchemaExtractionException;
import org.hibernate.tool.schema.extract.spi.TableInformation; import org.hibernate.tool.schema.extract.spi.TableInformation;
import org.hibernate.tool.schema.spi.SchemaManagementException; import org.hibernate.tool.schema.spi.SchemaManagementException;
import static java.util.Collections.addAll;
import static org.hibernate.boot.model.naming.DatabaseIdentifier.toIdentifier;
import static org.hibernate.internal.util.StringHelper.isBlank;
import static org.hibernate.internal.util.StringHelper.splitTrimmingTokens;
import static org.hibernate.internal.util.config.ConfigurationHelper.getBoolean;
public abstract class AbstractInformationExtractorImpl implements InformationExtractor { public abstract class AbstractInformationExtractorImpl implements InformationExtractor {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( AbstractInformationExtractorImpl.class ); private static final CoreMessageLogger LOG = CoreLogging.messageLogger( AbstractInformationExtractorImpl.class );
@ -65,7 +67,7 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
public AbstractInformationExtractorImpl(ExtractionContext extractionContext) { public AbstractInformationExtractorImpl(ExtractionContext extractionContext) {
this.extractionContext = extractionContext; this.extractionContext = extractionContext;
ConfigurationService configService = final ConfigurationService configService =
extractionContext.getServiceRegistry().requireService( ConfigurationService.class ); extractionContext.getServiceRegistry().requireService( ConfigurationService.class );
useJdbcMetadataDefaultsSetting = configService.getSetting( useJdbcMetadataDefaultsSetting = configService.getSetting(
@ -84,15 +86,8 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
) )
); );
final List<String> physicalTableTypesList = new ArrayList<>(); final List<String> physicalTableTypesList = new ArrayList<>();
if ( ! StringHelper.isBlank( extraPhysicalTableTypesConfig ) ) { if ( !isBlank( extraPhysicalTableTypesConfig ) ) {
Collections.addAll( addAll( physicalTableTypesList, splitTrimmingTokens( ",;", extraPhysicalTableTypesConfig, false ) );
physicalTableTypesList,
StringHelper.splitTrimmingTokens(
",;",
extraPhysicalTableTypesConfig,
false
)
);
} }
final Dialect dialect = extractionContext.getJdbcEnvironment().getDialect(); final Dialect dialect = extractionContext.getJdbcEnvironment().getDialect();
dialect.augmentPhysicalTableTypes( physicalTableTypesList ); dialect.augmentPhysicalTableTypes( physicalTableTypesList );
@ -101,34 +96,38 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
final List<String> tableTypesList = new ArrayList<>(); final List<String> tableTypesList = new ArrayList<>();
tableTypesList.add( "TABLE" ); tableTypesList.add( "TABLE" );
tableTypesList.add( "VIEW" ); tableTypesList.add( "VIEW" );
if ( ConfigurationHelper.getBoolean( AvailableSettings.ENABLE_SYNONYMS, configService.getSettings() ) ) { if ( getBoolean( AvailableSettings.ENABLE_SYNONYMS, configService.getSettings() ) ) {
if ( dialect instanceof DB2Dialect ) { if ( dialect instanceof DB2Dialect ) {
tableTypesList.add( "ALIAS" ); tableTypesList.add( "ALIAS" );
} }
tableTypesList.add( "SYNONYM" ); tableTypesList.add( "SYNONYM" );
} }
Collections.addAll( tableTypesList, extraPhysicalTableTypes ); addAll( tableTypesList, extraPhysicalTableTypes );
dialect.augmentRecognizedTableTypes( tableTypesList ); dialect.augmentRecognizedTableTypes( tableTypesList );
this.tableTypes = tableTypesList.toArray( new String[0] ); this.tableTypes = tableTypesList.toArray( new String[0] );
} }
protected IdentifierHelper identifierHelper() { protected IdentifierHelper identifierHelper() {
return extractionContext.getJdbcEnvironment().getIdentifierHelper(); return getIdentifierHelper();
} }
protected JDBCException convertSQLException(SQLException sqlException, String message) { protected JDBCException convertSQLException(SQLException sqlException, String message) {
return extractionContext.getJdbcEnvironment().getSqlExceptionHelper().convert( sqlException, message ); return getJdbcEnvironment().getSqlExceptionHelper().convert( sqlException, message );
} }
protected String toMetaDataObjectName(Identifier identifier) { protected String toMetaDataObjectName(Identifier identifier) {
return extractionContext.getJdbcEnvironment().getIdentifierHelper().toMetaDataObjectName( identifier ); return getIdentifierHelper().toMetaDataObjectName( identifier );
} }
protected ExtractionContext getExtractionContext() { protected ExtractionContext getExtractionContext() {
return extractionContext; return extractionContext;
} }
protected JdbcEnvironment getJdbcEnvironment() {
return extractionContext.getJdbcEnvironment();
}
// The following methods purposely return the column labels that are defined by // The following methods purposely return the column labels that are defined by
// DatabaseMetaData methods that return a ResultSet. Subclasses that do not rely // DatabaseMetaData methods that return a ResultSet. Subclasses that do not rely
// on DatabaseMetaData may override these methods to use different column labels. // on DatabaseMetaData may override these methods to use different column labels.
@ -222,20 +221,16 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
public boolean catalogExists(Identifier catalog) { public boolean catalogExists(Identifier catalog) {
try { try {
return processCatalogsResultSet( resultSet -> { return processCatalogsResultSet( resultSet -> {
while ( resultSet.next() ) { while ( resultSet.next() ) {
final String existingCatalogName = resultSet.getString( getResultSetCatalogLabel() ); final String existingCatalogName = resultSet.getString( getResultSetCatalogLabel() );
// todo : hmm.. case sensitive or insensitive match... // todo : hmm.. case sensitive or insensitive match...
// for now, match any case... // for now, match any case...
if ( catalog.getText().equalsIgnoreCase( existingCatalogName ) ) { if ( catalog.getText().equalsIgnoreCase( existingCatalogName ) ) {
return true; return true;
} }
} }
return false; return false;
}); } );
} }
catch (SQLException sqlException) { catch (SQLException sqlException) {
throw convertSQLException( sqlException, "Unable to query ResultSet for existing catalogs" ); throw convertSQLException( sqlException, "Unable to query ResultSet for existing catalogs" );
@ -313,13 +308,17 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
} }
} }
private IdentifierHelper getIdentifierHelper() {
return getJdbcEnvironment().getIdentifierHelper();
}
protected String determineCatalogFilter(Identifier catalog) { protected String determineCatalogFilter(Identifier catalog) {
Identifier identifierToUse = catalog; Identifier identifierToUse = catalog;
if ( identifierToUse == null ) { if ( identifierToUse == null ) {
identifierToUse = extractionContext.getDefaultCatalog(); identifierToUse = extractionContext.getDefaultCatalog();
} }
return extractionContext.getJdbcEnvironment().getIdentifierHelper().toMetaDataCatalogName( identifierToUse ); return getIdentifierHelper().toMetaDataCatalogName( identifierToUse );
} }
protected String determineSchemaFilter(Identifier schema) { protected String determineSchemaFilter(Identifier schema) {
@ -328,16 +327,14 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
identifierToUse = extractionContext.getDefaultSchema(); identifierToUse = extractionContext.getDefaultSchema();
} }
return extractionContext.getJdbcEnvironment().getIdentifierHelper().toMetaDataSchemaName( identifierToUse ); return getIdentifierHelper().toMetaDataSchemaName( identifierToUse );
} }
private TableInformation extractTableInformation(ResultSet resultSet) throws SQLException { private TableInformation extractTableInformation(ResultSet resultSet) throws SQLException {
final QualifiedTableName tableName = extractTableName( resultSet );
return new TableInformationImpl( return new TableInformationImpl(
this, this,
identifierHelper(), identifierHelper(),
tableName, extractTableName( resultSet ),
isPhysicalTableType( resultSet.getString( getResultSetTableTypeLabel() ) ), isPhysicalTableType( resultSet.getString( getResultSetTableTypeLabel() ) ),
resultSet.getString( getResultSetRemarksLabel() ) resultSet.getString( getResultSetRemarksLabel() )
); );
@ -357,33 +354,24 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
// 2) look in default namespace // 2) look in default namespace
// 3) look in all namespaces - multiple hits is considered an error // 3) look in all namespaces - multiple hits is considered an error
TableInformation tableInfo;
// 1) look in current namespace // 1) look in current namespace
final JdbcEnvironment jdbcEnvironment = extractionContext.getJdbcEnvironment(); final Identifier currentSchema = getCurrentSchema();
final Identifier currentSchema = getCurrentSchema( jdbcEnvironment ); final Identifier currentCatalog = getCurrentCatalog();
final Identifier currentCatalog = getCurrentCatalog( jdbcEnvironment ); if ( currentCatalog != null || currentSchema != null ) {
if ( currentCatalog != null final TableInformation tableInfo =
|| currentSchema != null ) { locateTableInNamespace( currentCatalog, currentSchema, tableName );
tableInfo = locateTableInNamespace(
currentCatalog,
currentSchema,
tableName
);
if ( tableInfo != null ) { if ( tableInfo != null ) {
return tableInfo; return tableInfo;
} }
} }
// 2) look in default namespace // 2) look in default namespace
if ( extractionContext.getDefaultCatalog() != null || extractionContext.getDefaultSchema() != null ) { final Identifier defaultCatalog = extractionContext.getDefaultCatalog();
tableInfo = locateTableInNamespace( final Identifier defaultSchema = extractionContext.getDefaultSchema();
extractionContext.getDefaultCatalog(), if ( defaultCatalog != null
extractionContext.getDefaultSchema(), || defaultSchema != null ) {
tableName final TableInformation tableInfo =
); locateTableInNamespace( defaultCatalog, defaultSchema, tableName );
if ( tableInfo != null ) { if ( tableInfo != null ) {
return tableInfo; return tableInfo;
} }
@ -391,19 +379,12 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
// 3) look in all namespaces // 3) look in all namespaces
try { try {
final String tableNameFilter = toMetaDataObjectName( tableName );
return processTableResultSet( return processTableResultSet(
null, null,
null, null,
tableNameFilter, toMetaDataObjectName( tableName ),
tableTypes, tableTypes,
resultSet -> extractTableInformation( resultSet -> extractTableInformation( null, null, tableName, resultSet )
null,
null,
tableName,
resultSet
)
); );
} }
catch (SQLException sqlException) { catch (SQLException sqlException) {
@ -412,21 +393,20 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
} }
} }
private Identifier getCurrentSchema(JdbcEnvironment jdbcEnvironment) { private Identifier getCurrentSchema() {
if ( jdbcEnvironment.getNameQualifierSupport() == NameQualifierSupport.CATALOG ) { if ( getNameQualifierSupport() == NameQualifierSupport.CATALOG ) {
return null; return null;
} }
if ( currentSchema != null ) { if ( currentSchema != null ) {
return currentSchema; return currentSchema;
} }
final Identifier schema = jdbcEnvironment.getCurrentSchema(); final Identifier schema = getJdbcEnvironment().getCurrentSchema();
if ( schema != null ) { if ( schema != null ) {
currentSchema = schema; currentSchema = schema;
} }
if ( !useJdbcMetadataDefaultsSetting ) { if ( !useJdbcMetadataDefaultsSetting ) {
try { try {
currentSchema = extractionContext.getJdbcEnvironment() currentSchema = getIdentifierHelper()
.getIdentifierHelper()
.toIdentifier( extractionContext.getJdbcConnection().getSchema() ); .toIdentifier( extractionContext.getJdbcConnection().getSchema() );
} }
catch (SQLException sqle) { catch (SQLException sqle) {
@ -439,25 +419,24 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
return currentSchema; return currentSchema;
} }
private Identifier getCurrentCatalog(JdbcEnvironment jdbcEnvironment) { private Identifier getCurrentCatalog() {
if ( jdbcEnvironment.getNameQualifierSupport() == NameQualifierSupport.SCHEMA ) { if ( getNameQualifierSupport() == NameQualifierSupport.SCHEMA ) {
return null; return null;
} }
if ( currentCatalog != null ) { if ( currentCatalog != null ) {
return currentCatalog; return currentCatalog;
} }
final Identifier catalog = jdbcEnvironment.getCurrentCatalog(); final Identifier catalog = getJdbcEnvironment().getCurrentCatalog();
if ( catalog != null ) { if ( catalog != null ) {
currentCatalog = catalog; currentCatalog = catalog;
} }
if ( !useJdbcMetadataDefaultsSetting ) { if ( !useJdbcMetadataDefaultsSetting ) {
try { try {
currentCatalog = extractionContext.getJdbcEnvironment() currentCatalog = getIdentifierHelper()
.getIdentifierHelper()
.toIdentifier( extractionContext.getJdbcConnection().getCatalog() ); .toIdentifier( extractionContext.getJdbcConnection().getCatalog() );
} }
catch (SQLException ignore) { catch (SQLException sqle) {
LOG.sqlWarning( ignore.getErrorCode(), ignore.getSQLState() ); LOG.sqlWarning( sqle.getErrorCode(), sqle.getSQLState() );
} }
} }
return currentCatalog; return currentCatalog;
@ -475,8 +454,8 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
try { try {
currentCatalogFilter = extractionContext.getJdbcConnection().getCatalog(); currentCatalogFilter = extractionContext.getJdbcConnection().getCatalog();
} }
catch (SQLException ignore) { catch (SQLException sqle) {
LOG.sqlWarning( ignore.getErrorCode(), ignore.getSQLState() ); LOG.sqlWarning( sqle.getErrorCode(), sqle.getSQLState() );
} }
} }
return currentCatalogFilter; return currentCatalogFilter;
@ -495,8 +474,8 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
try { try {
currentSchemaFilter = extractionContext.getJdbcConnection().getSchema(); currentSchemaFilter = extractionContext.getJdbcConnection().getSchema();
} }
catch (SQLException ignore) { catch (SQLException sqle) {
LOG.sqlWarning( ignore.getErrorCode(), ignore.getSQLState() ); LOG.sqlWarning( sqle.getErrorCode(), sqle.getSQLState() );
} }
catch (AbstractMethodError ignore) { catch (AbstractMethodError ignore) {
// jConnect and jTDS report that they "support" schemas, but they don't really // jConnect and jTDS report that they "support" schemas, but they don't really
@ -511,12 +490,12 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
final String catalogFilter; final String catalogFilter;
final String schemaFilter; final String schemaFilter;
final JdbcEnvironment jdbcEnvironment = extractionContext.getJdbcEnvironment(); final NameQualifierSupport nameQualifierSupport = getNameQualifierSupport();
final NameQualifierSupport nameQualifierSupport = jdbcEnvironment.getNameQualifierSupport();
if ( nameQualifierSupport.supportsCatalogs() ) { if ( nameQualifierSupport.supportsCatalogs() ) {
if ( catalog == null ) { if ( catalog == null ) {
// look in the current namespace // look in the current namespace
final String currentCatalogFilter = getCurrentCatalogFilter(jdbcEnvironment); final String currentCatalogFilter = getCurrentCatalogFilter( getJdbcEnvironment() );
if ( currentCatalogFilter != null ) { if ( currentCatalogFilter != null ) {
catalogFilter = currentCatalogFilter; catalogFilter = currentCatalogFilter;
} }
@ -541,7 +520,7 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
if ( nameQualifierSupport.supportsSchemas() ) { if ( nameQualifierSupport.supportsSchemas() ) {
if ( schema == null ) { if ( schema == null ) {
// 1) look in current namespace // 1) look in current namespace
final String currentSchemaFilter = getCurrentSchemaFilter( jdbcEnvironment ); final String currentSchemaFilter = getCurrentSchemaFilter( getJdbcEnvironment() );
if ( currentSchemaFilter != null ) { if ( currentSchemaFilter != null ) {
schemaFilter = currentSchemaFilter; schemaFilter = currentSchemaFilter;
} }
@ -570,7 +549,8 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
"%", "%",
tableTypes, tableTypes,
resultSet -> { resultSet -> {
final NameSpaceTablesInformation tablesInformation = extractNameSpaceTablesInformation( resultSet ); final NameSpaceTablesInformation tablesInformation =
extractNameSpaceTablesInformation( resultSet );
populateTablesWithColumns( catalogFilter, schemaFilter, tablesInformation ); populateTablesWithColumns( catalogFilter, schemaFilter, tablesInformation );
return tablesInformation; return tablesInformation;
} ); } );
@ -665,10 +645,7 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
); );
} }
catch (SQLException e) { catch (SQLException e) {
throw convertSQLException( throw convertSQLException( e, "Error accessing tables metadata" );
e,
"Error accessing tables metadata"
);
} }
} }
@ -676,7 +653,7 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
throws SQLException { throws SQLException {
final ColumnInformation columnInformation = new ColumnInformationImpl( final ColumnInformation columnInformation = new ColumnInformationImpl(
tableInformation, tableInformation,
DatabaseIdentifier.toIdentifier( resultSet.getString( getResultSetColumnNameLabel() ) ), toIdentifier( resultSet.getString( getResultSetColumnNameLabel() ) ),
resultSet.getInt( getResultSetSqlTypeCodeLabel() ), resultSet.getInt( getResultSetSqlTypeCodeLabel() ),
new StringTokenizer( resultSet.getString( getResultSetTypeNameLabel() ), "()" ).nextToken(), new StringTokenizer( resultSet.getString( getResultSetTypeNameLabel() ), "()" ).nextToken(),
resultSet.getInt( getResultSetColumnSizeLabel() ), resultSet.getInt( getResultSetColumnSizeLabel() ),
@ -687,7 +664,7 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
} }
private NameSpaceTablesInformation extractNameSpaceTablesInformation(ResultSet resultSet) throws SQLException { private NameSpaceTablesInformation extractNameSpaceTablesInformation(ResultSet resultSet) throws SQLException {
NameSpaceTablesInformation tables = new NameSpaceTablesInformation(identifierHelper()); final NameSpaceTablesInformation tables = new NameSpaceTablesInformation( identifierHelper() );
while ( resultSet.next() ) { while ( resultSet.next() ) {
final TableInformation tableInformation = extractTableInformation( resultSet ); final TableInformation tableInformation = extractTableInformation( resultSet );
tables.addTableInformation( tableInformation ); tables.addTableInformation( tableInformation );
@ -757,15 +734,15 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
final String catalogFilter; final String catalogFilter;
final String schemaFilter; final String schemaFilter;
if ( extractionContext.getJdbcEnvironment().getNameQualifierSupport().supportsCatalogs() ) { final NameQualifierSupport nameQualifierSupport = getNameQualifierSupport();
if ( nameQualifierSupport.supportsCatalogs() ) {
if ( catalog == null ) { if ( catalog == null ) {
String defaultCatalog = ""; String defaultCatalog;
if ( extractionContext.getJdbcEnvironment().getNameQualifierSupport().supportsCatalogs() ) {
try { try {
defaultCatalog = extractionContext.getJdbcConnection().getCatalog(); defaultCatalog = extractionContext.getJdbcConnection().getCatalog();
} }
catch (SQLException ignore) { catch (SQLException ignore) {
} defaultCatalog = "";
} }
catalogToUse = null; catalogToUse = null;
catalogFilter = defaultCatalog; catalogFilter = defaultCatalog;
@ -780,7 +757,7 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
catalogFilter = null; catalogFilter = null;
} }
if ( extractionContext.getJdbcEnvironment().getNameQualifierSupport().supportsSchemas() ) { if ( nameQualifierSupport.supportsSchemas() ) {
if ( schema == null ) { if ( schema == null ) {
schemaToUse = null; schemaToUse = null;
schemaFilter = ""; schemaFilter = "";
@ -817,6 +794,10 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
} }
} }
private NameQualifierSupport getNameQualifierSupport() {
return getJdbcEnvironment().getNameQualifierSupport();
}
private TableInformation extractTableInformation( private TableInformation extractTableInformation(
Identifier catalog, Identifier catalog,
Identifier schema, Identifier schema,
@ -825,23 +806,19 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
boolean found = false; boolean found = false;
TableInformation tableInformation = null; TableInformation tableInformation = null;
while ( resultSet.next() ) { while ( resultSet.next() ) {
if ( tableName.equals( Identifier.toIdentifier( if ( tableName.equals( Identifier.toIdentifier(
resultSet.getString( getResultSetTableNameLabel() ), resultSet.getString( getResultSetTableNameLabel() ),
tableName.isQuoted() tableName.isQuoted()
) ) ) { ) ) ) {
if ( found ) { if ( found ) {
LOG.multipleTablesFound( tableName.render() ); LOG.multipleTablesFound( tableName.render() );
final String catalogName = catalog == null ? "" : catalog.render();
final String schemaName = schema == null ? "" : schema.render();
throw new SchemaExtractionException( throw new SchemaExtractionException(
String.format( String.format(
Locale.ENGLISH, Locale.ENGLISH,
"More than one table found in namespace (%s, %s) : %s", "More than one table found in namespace (%s, %s) : %s",
catalogName, catalog == null ? "" : catalog.render(),
schemaName, schema == null ? "" : schema.render(),
tableName.render() tableName.render()
) )
); );
@ -882,18 +859,13 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
final QualifiedTableName tableName = tableInformation.getName(); final QualifiedTableName tableName = tableInformation.getName();
final Identifier catalog = tableName.getCatalogName(); final Identifier catalog = tableName.getCatalogName();
final Identifier schema = tableName.getSchemaName(); final Identifier schema = tableName.getSchemaName();
final String catalogFilter = catalog == null ? "" : catalog.getText();
final String schemaFilter = schema == null ? "" : schema.getText();
try { try {
processColumnsResultSet( processColumnsResultSet(
catalogFilter, catalog == null ? "" : catalog.getText(),
schemaFilter, schema == null ? "" : schema.getText(),
tableName.getTableName().getText(), tableName.getTableName().getText(),
"%", "%",
resultSet -> { resultSet -> {
while ( resultSet.next() ) { while ( resultSet.next() ) {
addExtractedColumnInformation( tableInformation, resultSet ); addExtractedColumnInformation( tableInformation, resultSet );
} }
@ -903,10 +875,7 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
} }
catch (SQLException e) { catch (SQLException e) {
throw convertSQLException( throw convertSQLException( e, "Error accessing tables metadata" );
e,
"Error accessing tables metadata"
);
} }
} }
@ -942,34 +911,18 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
final QualifiedTableName tableName = tableInformation.getName(); final QualifiedTableName tableName = tableInformation.getName();
final Identifier catalog = tableName.getCatalogName(); final Identifier catalog = tableName.getCatalogName();
final Identifier schema = tableName.getSchemaName(); final Identifier schema = tableName.getSchemaName();
final String catalogFilter;
final String schemaFilter;
if ( catalog == null ) {
catalogFilter = "";
}
else {
catalogFilter = catalog.getText();
}
if ( schema == null ) {
schemaFilter = "";
}
else {
schemaFilter = schema.getText();
}
try { try {
return processPrimaryKeysResultSet( return processPrimaryKeysResultSet(
catalogFilter, catalog == null ? "" : catalog.getText(),
schemaFilter, schema == null ? "" : schema.getText(),
tableInformation.getName().getTableName(), tableInformation.getName().getTableName(),
resultSet -> extractPrimaryKeyInformation( tableInformation, resultSet ) resultSet -> extractPrimaryKeyInformation( tableInformation, resultSet )
); );
} }
catch (SQLException e) { catch (SQLException e) {
throw convertSQLException( e, "Error while reading primary key meta data for " + tableInformation.getName().toString() ); throw convertSQLException( e,
"Error while reading primary key meta data for "
+ tableInformation.getName() );
} }
} }
@ -984,9 +937,7 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
while ( resultSet.next() ) { while ( resultSet.next() ) {
final String currentPkName = resultSet.getString( getResultSetPrimaryKeyNameLabel() ); final String currentPkName = resultSet.getString( getResultSetPrimaryKeyNameLabel() );
final Identifier currentPkIdentifier = currentPkName == null final Identifier currentPkIdentifier = currentPkName == null ? null : toIdentifier( currentPkName );
? null
: DatabaseIdentifier.toIdentifier( currentPkName );
if ( firstPass ) { if ( firstPass ) {
pkIdentifier = currentPkIdentifier; pkIdentifier = currentPkIdentifier;
firstPass = false; firstPass = false;
@ -1003,15 +954,13 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
} }
final int columnPosition = resultSet.getInt( getResultSetColumnPositionColumn() ); final int columnPosition = resultSet.getInt( getResultSetColumnPositionColumn() );
final int index = columnPosition - 1; final int index = columnPosition - 1;
// Fill up the array list with nulls up to the desired index, because some JDBC drivers don't return results ordered by column position // Fill up the array list with nulls up to the desired index, because some JDBC drivers don't return results ordered by column position
while ( pkColumns.size() <= index ) { while ( pkColumns.size() <= index ) {
pkColumns.add( null ); pkColumns.add( null );
} }
final Identifier columnIdentifier = DatabaseIdentifier.toIdentifier( final Identifier columnIdentifier =
resultSet.getString( getResultSetColumnNameLabel() ) toIdentifier( resultSet.getString( getResultSetColumnNameLabel() ) );
);
pkColumns.set( index, tableInformation.getColumn( columnIdentifier ) ); pkColumns.set( index, tableInformation.getColumn( columnIdentifier ) );
} }
if ( firstPass ) { if ( firstPass ) {
@ -1025,7 +974,6 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
throw new SchemaExtractionException( "Primary Key information was missing for KEY_SEQ = " + ( i+1) ); throw new SchemaExtractionException( "Primary Key information was missing for KEY_SEQ = " + ( i+1) );
} }
} }
// build the return // build the return
return new PrimaryKeyInformationImpl( pkIdentifier, pkColumns ); return new PrimaryKeyInformationImpl( pkIdentifier, pkColumns );
} }
@ -1110,54 +1058,34 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
@Override @Override
public Iterable<IndexInformation> getIndexes(TableInformation tableInformation) { public Iterable<IndexInformation> getIndexes(TableInformation tableInformation) {
final Map<Identifier, IndexInformationImpl.Builder> builders = new HashMap<>();
final QualifiedTableName tableName = tableInformation.getName(); final QualifiedTableName tableName = tableInformation.getName();
final Identifier catalog = tableName.getCatalogName(); final Identifier catalog = tableName.getCatalogName();
final Identifier schema = tableName.getSchemaName(); final Identifier schema = tableName.getSchemaName();
final String catalogFilter; final Map<Identifier, IndexInformationImpl.Builder> builders = new HashMap<>();
final String schemaFilter;
if ( catalog == null ) {
catalogFilter = "";
}
else {
catalogFilter = catalog.getText();
}
if ( schema == null ) {
schemaFilter = "";
}
else {
schemaFilter = schema.getText();
}
try { try {
processIndexInfoResultSet( processIndexInfoResultSet(
catalogFilter, catalog == null ? "" : catalog.getText(),
schemaFilter, schema == null ? "" : schema.getText(),
tableName.getTableName().getText(), tableName.getTableName().getText(),
false, // DO NOT limit to just unique false, // DO NOT limit to just unique
true, // DO require up-to-date results true, // DO require up-to-date results
resultSet -> { resultSet -> {
while ( resultSet.next() ) { while ( resultSet.next() ) {
if ( resultSet.getShort( getResultSetIndexTypeLabel() ) == DatabaseMetaData.tableIndexStatistic ) { if ( resultSet.getShort( getResultSetIndexTypeLabel() )
continue; != DatabaseMetaData.tableIndexStatistic ) {
} final Identifier indexIdentifier =
toIdentifier( resultSet.getString( getResultSetIndexNameLabel() ) );
final Identifier indexIdentifier = DatabaseIdentifier.toIdentifier(
resultSet.getString( getResultSetIndexNameLabel() )
);
IndexInformationImpl.Builder builder = builders.get( indexIdentifier ); IndexInformationImpl.Builder builder = builders.get( indexIdentifier );
if ( builder == null ) { if ( builder == null ) {
builder = IndexInformationImpl.builder( indexIdentifier ); builder = IndexInformationImpl.builder( indexIdentifier );
builders.put( indexIdentifier, builder ); builders.put( indexIdentifier, builder );
} }
final Identifier columnIdentifier = DatabaseIdentifier.toIdentifier( final Identifier columnIdentifier =
resultSet.getString( getResultSetColumnNameLabel() ) toIdentifier( resultSet.getString( getResultSetColumnNameLabel() ) );
); final ColumnInformation columnInformation =
final ColumnInformation columnInformation = tableInformation.getColumn( columnIdentifier ); tableInformation.getColumn( columnIdentifier );
if ( columnInformation == null ) { if ( columnInformation == null ) {
// See HHH-10191: this may happen when dealing with Oracle/PostgreSQL function indexes // See HHH-10191: this may happen when dealing with Oracle/PostgreSQL function indexes
LOG.logCannotLocateIndexColumnInformation( LOG.logCannotLocateIndexColumnInformation(
@ -1167,16 +1095,17 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
} }
builder.addColumn( columnInformation ); builder.addColumn( columnInformation );
} }
}
return null; return null;
} }
); );
} }
catch (SQLException e) { catch (SQLException e) {
throw convertSQLException( throw convertSQLException( e,
e, "Error accessing index information: "
"Error accessing index information: " + tableInformation.getName().toString() + tableInformation.getName() );
);
} }
final List<IndexInformation> indexes = new ArrayList<>(); final List<IndexInformation> indexes = new ArrayList<>();
@ -1348,91 +1277,41 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
@Override @Override
public Iterable<ForeignKeyInformation> getForeignKeys(TableInformation tableInformation) { public Iterable<ForeignKeyInformation> getForeignKeys(TableInformation tableInformation) {
final Map<Identifier, ForeignKeyBuilder> fkBuilders = new HashMap<>();
final QualifiedTableName tableName = tableInformation.getName(); final QualifiedTableName tableName = tableInformation.getName();
final Identifier catalog = tableName.getCatalogName(); final Identifier catalog = tableName.getCatalogName();
final Identifier schema = tableName.getSchemaName(); final Identifier schema = tableName.getSchemaName();
final String catalogFilter; final String catalogFilter = catalog == null ? "" : catalog.getText();
final String schemaFilter; final String schemaFilter = schema == null ? "" : schema.getText();
if ( catalog == null ) {
catalogFilter = "";
}
else {
catalogFilter = catalog.getText();
}
if ( schema == null ) {
schemaFilter = "";
}
else {
schemaFilter = schema.getText();
}
final Map<Identifier, ForeignKeyBuilder> fkBuilders = new HashMap<>();
try { try {
ExtractionContext.ResultSetProcessor<Void> processor = resultSet -> { final String table = tableInformation.getName().getTableName().getText();
while ( resultSet.next() ) { processImportedKeysResultSet( catalogFilter, schemaFilter, table,
// IMPL NOTE : The builder is mainly used to collect the column reference mappings resultSet -> {
final Identifier fkIdentifier = DatabaseIdentifier.toIdentifier( process( tableInformation, resultSet, fkBuilders );
resultSet.getString( getResultSetForeignKeyLabel() )
);
ForeignKeyBuilder fkBuilder = fkBuilders.get( fkIdentifier );
if ( fkBuilder == null ) {
fkBuilder = generateForeignKeyBuilder( fkIdentifier );
fkBuilders.put( fkIdentifier, fkBuilder );
}
final QualifiedTableName incomingPkTableName = extractPrimaryKeyTableName( resultSet );
final TableInformation pkTableInformation = extractionContext.getDatabaseObjectAccess()
.locateTableInformation( incomingPkTableName );
if ( pkTableInformation == null ) {
// the assumption here is that we have not seen this table already based on fully-qualified name
// during previous step of building all table metadata so most likely this is
// not a match based solely on schema/catalog and that another row in this result set
// should match.
continue;
}
final Identifier fkColumnIdentifier = DatabaseIdentifier.toIdentifier(
resultSet.getString( getResultSetForeignKeyColumnNameLabel() )
);
final Identifier pkColumnIdentifier = DatabaseIdentifier.toIdentifier(
resultSet.getString( getResultSetPrimaryKeyColumnNameLabel() )
);
fkBuilder.addColumnMapping(
tableInformation.getColumn( fkColumnIdentifier ),
pkTableInformation.getColumn( pkColumnIdentifier )
);
}
return null; return null;
}; } );
processImportedKeysResultSet( final Dialect dialect = getJdbcEnvironment().getDialect();
catalogFilter, if ( dialect.useCrossReferenceForeignKeys() ) {
schemaFilter,
tableInformation.getName().getTableName().getText(),
processor);
final Dialect dialect = extractionContext.getJdbcEnvironment().getDialect();
if (dialect.useCrossReferenceForeignKeys()) {
processCrossReferenceResultSet( processCrossReferenceResultSet(
null, null,
null, null,
dialect.getCrossReferenceParentTableFilter(), dialect.getCrossReferenceParentTableFilter(),
catalogFilter, catalogFilter,
schemaFilter, schemaFilter,
tableInformation.getName().getTableName().getText(), table,
processor resultSet -> {
process( tableInformation, resultSet, fkBuilders );
return null;
}
); );
} }
} }
catch (SQLException e) { catch (SQLException e) {
throw convertSQLException( throw convertSQLException( e,
e, "Error accessing column metadata: "
"Error accessing column metadata: " + tableInformation.getName().toString() + tableInformation.getName() );
);
} }
final List<ForeignKeyInformation> fks = new ArrayList<>(); final List<ForeignKeyInformation> fks = new ArrayList<>();
@ -1443,6 +1322,37 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
return fks; return fks;
} }
private void process(TableInformation tableInformation, ResultSet resultSet, Map<Identifier, ForeignKeyBuilder> fkBuilders)
throws SQLException {
while ( resultSet.next() ) {
// IMPL NOTE : The builder is mainly used to collect the column reference mappings
final Identifier fkIdentifier = toIdentifier( resultSet.getString( getResultSetForeignKeyLabel() ) );
ForeignKeyBuilder fkBuilder = fkBuilders.get( fkIdentifier );
if ( fkBuilder == null ) {
fkBuilder = generateForeignKeyBuilder( fkIdentifier );
fkBuilders.put( fkIdentifier, fkBuilder );
}
final TableInformation pkTableInformation = extractionContext.getDatabaseObjectAccess()
.locateTableInformation( extractPrimaryKeyTableName( resultSet ) );
if ( pkTableInformation != null ) {
// the assumption here is that we have not seen this table already based on fully-qualified name
// during previous step of building all table metadata so most likely this is
// not a match based solely on schema/catalog and that another row in this result set
// should match.
final Identifier fkColumnIdentifier =
toIdentifier( resultSet.getString( getResultSetForeignKeyColumnNameLabel() ) );
final Identifier pkColumnIdentifier =
toIdentifier( resultSet.getString( getResultSetPrimaryKeyColumnNameLabel() ) );
fkBuilder.addColumnMapping(
tableInformation.getColumn( fkColumnIdentifier ),
pkTableInformation.getColumn( pkColumnIdentifier )
);
}
}
}
private ForeignKeyBuilder generateForeignKeyBuilder(Identifier fkIdentifier) { private ForeignKeyBuilder generateForeignKeyBuilder(Identifier fkIdentifier) {
return new ForeignKeyBuilderImpl( fkIdentifier ); return new ForeignKeyBuilderImpl( fkIdentifier );
} }
@ -1480,27 +1390,18 @@ public abstract class AbstractInformationExtractorImpl implements InformationExt
} }
private QualifiedTableName extractPrimaryKeyTableName(ResultSet resultSet) throws SQLException { private QualifiedTableName extractPrimaryKeyTableName(ResultSet resultSet) throws SQLException {
final String incomingCatalogName = resultSet.getString( getResultSetPrimaryKeyCatalogLabel() ); return new QualifiedTableName(
final String incomingSchemaName = resultSet.getString( getResultSetPrimaryKeySchemaLabel() ); toIdentifier( resultSet.getString( getResultSetPrimaryKeyCatalogLabel() ) ),
final String incomingTableName = resultSet.getString( getResultSetPrimaryKeyTableLabel() ); toIdentifier( resultSet.getString( getResultSetPrimaryKeySchemaLabel() ) ),
toIdentifier( resultSet.getString( getResultSetPrimaryKeyTableLabel() ) ) );
final DatabaseIdentifier catalog = DatabaseIdentifier.toIdentifier( incomingCatalogName );
final DatabaseIdentifier schema = DatabaseIdentifier.toIdentifier( incomingSchemaName );
final DatabaseIdentifier table = DatabaseIdentifier.toIdentifier( incomingTableName );
return new QualifiedTableName( catalog, schema, table );
} }
private QualifiedTableName extractTableName(ResultSet resultSet) throws SQLException { private QualifiedTableName extractTableName(ResultSet resultSet) throws SQLException {
final String incomingCatalogName = resultSet.getString( getResultSetCatalogLabel() ); return new QualifiedTableName(
final String incomingSchemaName = resultSet.getString( getResultSetSchemaLabel() ); toIdentifier( resultSet.getString( getResultSetCatalogLabel() ) ),
final String incomingTableName = resultSet.getString( getResultSetTableNameLabel() ); toIdentifier( resultSet.getString( getResultSetSchemaLabel() ) ),
toIdentifier( resultSet.getString( getResultSetTableNameLabel() ) )
final DatabaseIdentifier catalog = DatabaseIdentifier.toIdentifier( incomingCatalogName ); );
final DatabaseIdentifier schema = DatabaseIdentifier.toIdentifier( incomingSchemaName );
final DatabaseIdentifier table = DatabaseIdentifier.toIdentifier( incomingTableName );
return new QualifiedTableName( catalog, schema, table );
} }
} }

View File

@ -4,6 +4,7 @@
*/ */
package org.hibernate.tool.schema.extract.internal; package org.hibernate.tool.schema.extract.internal;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.ResultSetMetaData; import java.sql.ResultSetMetaData;
import java.sql.SQLException; import java.sql.SQLException;
@ -28,6 +29,10 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl extends AbstractInform
super( extractionContext ); super( extractionContext );
} }
private DatabaseMetaData getJdbcDatabaseMetaData() {
return getExtractionContext().getJdbcDatabaseMetaData();
}
@Override @Override
protected String getResultSetTableTypesPhysicalTableConstant() { protected String getResultSetTableTypesPhysicalTableConstant() {
return "TABLE"; return "TABLE";
@ -35,7 +40,7 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl extends AbstractInform
@Override @Override
public <T> T processCatalogsResultSet(ExtractionContext.ResultSetProcessor<T> processor) throws SQLException { public <T> T processCatalogsResultSet(ExtractionContext.ResultSetProcessor<T> processor) throws SQLException {
try (ResultSet resultSet = getExtractionContext().getJdbcDatabaseMetaData().getCatalogs() ) { try (ResultSet resultSet = getJdbcDatabaseMetaData().getCatalogs() ) {
return processor.process( resultSet ); return processor.process( resultSet );
} }
} }
@ -45,7 +50,7 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl extends AbstractInform
String catalog, String catalog,
String schemaPattern, String schemaPattern,
ExtractionContext.ResultSetProcessor<T> processor) throws SQLException { ExtractionContext.ResultSetProcessor<T> processor) throws SQLException {
try (ResultSet resultSet = getExtractionContext().getJdbcDatabaseMetaData().getSchemas( try (ResultSet resultSet = getJdbcDatabaseMetaData().getSchemas(
catalog, catalog,
schemaPattern ) ) { schemaPattern ) ) {
return processor.process( resultSet ); return processor.process( resultSet );
@ -60,7 +65,7 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl extends AbstractInform
String[] types, String[] types,
ExtractionContext.ResultSetProcessor<T> processor ExtractionContext.ResultSetProcessor<T> processor
) throws SQLException { ) throws SQLException {
try (ResultSet resultSet = getExtractionContext().getJdbcDatabaseMetaData().getTables( try (ResultSet resultSet = getJdbcDatabaseMetaData().getTables(
catalog, catalog,
schemaPattern, schemaPattern,
tableNamePattern, tableNamePattern,
@ -76,7 +81,7 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl extends AbstractInform
String tableNamePattern, String tableNamePattern,
String columnNamePattern, String columnNamePattern,
ExtractionContext.ResultSetProcessor<T> processor) throws SQLException { ExtractionContext.ResultSetProcessor<T> processor) throws SQLException {
try (ResultSet resultSet = getExtractionContext().getJdbcDatabaseMetaData().getColumns( try (ResultSet resultSet = getJdbcDatabaseMetaData().getColumns(
catalog, catalog,
schemaPattern, schemaPattern,
tableNamePattern, tableNamePattern,
@ -91,7 +96,7 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl extends AbstractInform
String schemaFilter, String schemaFilter,
Identifier tableName, Identifier tableName,
ExtractionContext.ResultSetProcessor<T> processor) throws SQLException { ExtractionContext.ResultSetProcessor<T> processor) throws SQLException {
try( ResultSet resultSet = getExtractionContext().getJdbcDatabaseMetaData().getPrimaryKeys( try( ResultSet resultSet = getJdbcDatabaseMetaData().getPrimaryKeys(
catalogFilter, catalogFilter,
schemaFilter, schemaFilter,
tableName.getText() ) ) { tableName.getText() ) ) {
@ -108,7 +113,7 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl extends AbstractInform
boolean approximate, boolean approximate,
ExtractionContext.ResultSetProcessor<T> processor) throws SQLException { ExtractionContext.ResultSetProcessor<T> processor) throws SQLException {
try (ResultSet resultSet = getExtractionContext().getJdbcDatabaseMetaData().getIndexInfo( try (ResultSet resultSet = getJdbcDatabaseMetaData().getIndexInfo(
catalog, catalog,
schema, schema,
table, table,
@ -124,7 +129,7 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl extends AbstractInform
String schema, String schema,
String table, String table,
ExtractionContext.ResultSetProcessor<T> processor) throws SQLException { ExtractionContext.ResultSetProcessor<T> processor) throws SQLException {
try (ResultSet resultSet = getExtractionContext().getJdbcDatabaseMetaData().getImportedKeys( try (ResultSet resultSet = getJdbcDatabaseMetaData().getImportedKeys(
catalog, catalog,
schema, schema,
table ) ) { table ) ) {
@ -141,7 +146,7 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl extends AbstractInform
String foreignSchema, String foreignSchema,
String foreignTable, String foreignTable,
ExtractionContext.ResultSetProcessor<T> processor) throws SQLException { ExtractionContext.ResultSetProcessor<T> processor) throws SQLException {
try (ResultSet resultSet = getExtractionContext().getJdbcDatabaseMetaData().getCrossReference( try (ResultSet resultSet = getJdbcDatabaseMetaData().getCrossReference(
parentCatalog, parentCatalog,
parentSchema, parentSchema,
parentTable, parentTable,
@ -153,9 +158,9 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl extends AbstractInform
} }
protected void addColumns(TableInformation tableInformation) { protected void addColumns(TableInformation tableInformation) {
final Dialect dialect = getExtractionContext().getJdbcEnvironment().getDialect(); final Dialect dialect = getJdbcEnvironment().getDialect();
final ExtractionContext extractionContext = getExtractionContext(); final ExtractionContext extractionContext = getExtractionContext();
// We use this dummy query to retrieve the table information through the ResultSetMetaData // We use this dummy query to retrieve the table information through the ResultSetMetaData
// This is significantly better than to use the DatabaseMetaData especially on Oracle with synonyms enabled // This is significantly better than to use the DatabaseMetaData especially on Oracle with synonyms enabled
final String tableName = extractionContext.getSqlStringGenerationContext().format( final String tableName = extractionContext.getSqlStringGenerationContext().format(