HHH-9910 - Schema migration (update) problems with catalog/schema restrictions
yes, in oracle
This commit is contained in:
parent
6af89449f2
commit
ce54660cdb
|
@ -53,6 +53,7 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
|
||||||
private final LobCreatorBuilderImpl lobCreatorBuilder;
|
private final LobCreatorBuilderImpl lobCreatorBuilder;
|
||||||
|
|
||||||
private final LinkedHashSet<TypeInfo> typeInfoSet = new LinkedHashSet<TypeInfo>();
|
private final LinkedHashSet<TypeInfo> typeInfoSet = new LinkedHashSet<TypeInfo>();
|
||||||
|
private final NameQualifierSupport nameQualifierSupport;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor form used when the JDBC {@link java.sql.DatabaseMetaData} is not available.
|
* Constructor form used when the JDBC {@link java.sql.DatabaseMetaData} is not available.
|
||||||
|
@ -70,6 +71,7 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
|
||||||
// assume both catalogs and schemas are supported
|
// assume both catalogs and schemas are supported
|
||||||
nameQualifierSupport = NameQualifierSupport.BOTH;
|
nameQualifierSupport = NameQualifierSupport.BOTH;
|
||||||
}
|
}
|
||||||
|
this.nameQualifierSupport = nameQualifierSupport;
|
||||||
|
|
||||||
this.sqlExceptionHelper = buildSqlExceptionHelper( dialect );
|
this.sqlExceptionHelper = buildSqlExceptionHelper( dialect );
|
||||||
this.extractedMetaDataSupport = new ExtractedDatabaseMetaDataImpl.Builder( this ).build();
|
this.extractedMetaDataSupport = new ExtractedDatabaseMetaDataImpl.Builder( this ).build();
|
||||||
|
@ -138,6 +140,7 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
|
||||||
if ( nameQualifierSupport == null ) {
|
if ( nameQualifierSupport == null ) {
|
||||||
nameQualifierSupport = determineNameQualifierSupport( databaseMetaData );
|
nameQualifierSupport = determineNameQualifierSupport( databaseMetaData );
|
||||||
}
|
}
|
||||||
|
this.nameQualifierSupport = nameQualifierSupport;
|
||||||
|
|
||||||
final IdentifierHelperBuilder identifierHelperBuilder = IdentifierHelperBuilder.from( this );
|
final IdentifierHelperBuilder identifierHelperBuilder = IdentifierHelperBuilder.from( this );
|
||||||
identifierHelperBuilder.setNameQualifierSupport( nameQualifierSupport );
|
identifierHelperBuilder.setNameQualifierSupport( nameQualifierSupport );
|
||||||
|
@ -211,6 +214,7 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
|
||||||
if ( nameQualifierSupport == null ) {
|
if ( nameQualifierSupport == null ) {
|
||||||
nameQualifierSupport = determineNameQualifierSupport( databaseMetaData );
|
nameQualifierSupport = determineNameQualifierSupport( databaseMetaData );
|
||||||
}
|
}
|
||||||
|
this.nameQualifierSupport = nameQualifierSupport;
|
||||||
|
|
||||||
final IdentifierHelperBuilder identifierHelperBuilder = IdentifierHelperBuilder.from( this );
|
final IdentifierHelperBuilder identifierHelperBuilder = IdentifierHelperBuilder.from( this );
|
||||||
identifierHelperBuilder.setGloballyQuoteIdentifiers( globalQuoting( cfgService ) );
|
identifierHelperBuilder.setGloballyQuoteIdentifiers( globalQuoting( cfgService ) );
|
||||||
|
@ -323,6 +327,11 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
|
||||||
return identifierHelper;
|
return identifierHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NameQualifierSupport getNameQualifierSupport() {
|
||||||
|
return nameQualifierSupport;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlExceptionHelper getSqlExceptionHelper() {
|
public SqlExceptionHelper getSqlExceptionHelper() {
|
||||||
return sqlExceptionHelper;
|
return sqlExceptionHelper;
|
||||||
|
|
|
@ -68,6 +68,13 @@ public interface JdbcEnvironment extends Service {
|
||||||
*/
|
*/
|
||||||
IdentifierHelper getIdentifierHelper();
|
IdentifierHelper getIdentifierHelper();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the level of support for qualified names.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
NameQualifierSupport getNameQualifierSupport();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain the helper for dealing with JDBC {@link java.sql.SQLException} faults.
|
* Obtain the helper for dealing with JDBC {@link java.sql.SQLException} faults.
|
||||||
*
|
*
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
|
@ -70,6 +71,42 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl implements Information
|
||||||
return extractionContext.getJdbcEnvironment().getSqlExceptionHelper().convert( sqlException, message );
|
return extractionContext.getJdbcEnvironment().getSqlExceptionHelper().convert( sqlException, message );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String toMetaDataObjectName(Identifier identifier) {
|
||||||
|
return extractionContext.getJdbcEnvironment().getIdentifierHelper().toMetaDataObjectName( identifier );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean catalogExists(Identifier catalog) {
|
||||||
|
try {
|
||||||
|
final ResultSet resultSet = extractionContext.getJdbcDatabaseMetaData().getCatalogs();
|
||||||
|
|
||||||
|
try {
|
||||||
|
while ( resultSet.next() ) {
|
||||||
|
final String existingCatalogName = resultSet.getString( "TABLE_CAT" );
|
||||||
|
|
||||||
|
// todo : hmm.. case sensitive or insensitive match...
|
||||||
|
// for now, match any case...
|
||||||
|
|
||||||
|
if ( catalog.getText().equalsIgnoreCase( existingCatalogName ) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
try {
|
||||||
|
resultSet.close();
|
||||||
|
}
|
||||||
|
catch (SQLException ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (SQLException sqlException) {
|
||||||
|
throw convertSQLException( sqlException, "Unable to query DatabaseMetaData for existing catalogs" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean schemaExists(Identifier catalog, Identifier schema) {
|
public boolean schemaExists(Identifier catalog, Identifier schema) {
|
||||||
try {
|
try {
|
||||||
|
@ -150,17 +187,140 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl implements Information
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TableInformation getTable(Identifier catalog, Identifier schema, Identifier tableName) {
|
public TableInformation getTable(Identifier catalog, Identifier schema, Identifier tableName) {
|
||||||
try {
|
if ( catalog != null || schema != null ) {
|
||||||
final String catalogFilter = determineCatalogFilter( catalog );
|
// The table defined an explicit namespace. In such cases we only ever want to look
|
||||||
final String schemaFilter = determineSchemaFilter( schema );
|
// in the identified namespace
|
||||||
|
|
||||||
ResultSet resultSet = extractionContext.getJdbcDatabaseMetaData().getTables(
|
return locateTableInNamespace( catalog, schema, tableName );
|
||||||
catalogFilter,
|
}
|
||||||
schemaFilter,
|
else {
|
||||||
extractionContext.getJdbcEnvironment().getIdentifierHelper().toMetaDataObjectName( tableName ),
|
// The table did not define an explicit namespace:
|
||||||
|
// 1) look in current namespace
|
||||||
|
// 2) look in default namespace
|
||||||
|
// 3) look in all namespaces - multiple hits is considered an error
|
||||||
|
|
||||||
|
TableInformation tableInfo = null;
|
||||||
|
|
||||||
|
// 1) look in current namespace
|
||||||
|
if ( extractionContext.getJdbcEnvironment().getCurrentCatalog() != null
|
||||||
|
|| extractionContext.getJdbcEnvironment().getCurrentSchema() != null ) {
|
||||||
|
tableInfo = locateTableInNamespace(
|
||||||
|
extractionContext.getJdbcEnvironment().getCurrentCatalog(),
|
||||||
|
extractionContext.getJdbcEnvironment().getCurrentSchema(),
|
||||||
|
tableName
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( tableInfo != null ) {
|
||||||
|
return tableInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 2) look in default namespace
|
||||||
|
if ( extractionContext.getDefaultCatalog() != null || extractionContext.getDefaultSchema() != null ) {
|
||||||
|
tableInfo = locateTableInNamespace(
|
||||||
|
extractionContext.getJdbcEnvironment().getCurrentCatalog(),
|
||||||
|
extractionContext.getJdbcEnvironment().getCurrentSchema(),
|
||||||
|
tableName
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( tableInfo != null ) {
|
||||||
|
return tableInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 3) look in all namespaces
|
||||||
|
try {
|
||||||
|
final String tableNameFilter = toMetaDataObjectName( tableName );
|
||||||
|
|
||||||
|
final ResultSet resultSet = extractionContext.getJdbcDatabaseMetaData().getTables(
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
tableNameFilter,
|
||||||
tableTypes
|
tableTypes
|
||||||
);
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
return processGetTableResults(
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
tableName,
|
||||||
|
resultSet
|
||||||
|
);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
try {
|
||||||
|
resultSet.close();
|
||||||
|
}
|
||||||
|
catch (SQLException ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (SQLException sqlException) {
|
||||||
|
throw convertSQLException( sqlException, "Error accessing table metadata" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private TableInformation locateTableInNamespace(
|
||||||
|
Identifier catalog,
|
||||||
|
Identifier schema,
|
||||||
|
Identifier tableName) {
|
||||||
|
final String catalogFilter;
|
||||||
|
final String schemaFilter;
|
||||||
|
|
||||||
|
if ( extractionContext.getJdbcEnvironment().getNameQualifierSupport().supportsCatalogs() ) {
|
||||||
|
if ( catalog == null ) {
|
||||||
|
catalogFilter = "";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
catalogFilter = toMetaDataObjectName( catalog );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
catalogFilter = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( extractionContext.getJdbcEnvironment().getNameQualifierSupport().supportsSchemas() ) {
|
||||||
|
if ( schema == null ) {
|
||||||
|
schemaFilter = "";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
schemaFilter = toMetaDataObjectName( schema );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
schemaFilter = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String tableNameFilter = toMetaDataObjectName( tableName );
|
||||||
|
|
||||||
|
try {
|
||||||
|
ResultSet resultSet = extractionContext.getJdbcDatabaseMetaData().getTables(
|
||||||
|
catalogFilter,
|
||||||
|
schemaFilter,
|
||||||
|
tableNameFilter,
|
||||||
|
tableTypes
|
||||||
|
);
|
||||||
|
|
||||||
|
return processGetTableResults(
|
||||||
|
catalog,
|
||||||
|
schema,
|
||||||
|
tableName,
|
||||||
|
resultSet
|
||||||
|
);
|
||||||
|
}
|
||||||
|
catch (SQLException sqlException) {
|
||||||
|
throw convertSQLException( sqlException, "Error accessing table metadata" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private TableInformation processGetTableResults(
|
||||||
|
Identifier catalog,
|
||||||
|
Identifier schema,
|
||||||
|
Identifier tableName,
|
||||||
|
ResultSet resultSet) throws SQLException {
|
||||||
try {
|
try {
|
||||||
if ( !resultSet.next() ) {
|
if ( !resultSet.next() ) {
|
||||||
log.tableNotFound( tableName.render() );
|
log.tableNotFound( tableName.render() );
|
||||||
|
@ -176,6 +336,15 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl implements Information
|
||||||
|
|
||||||
if ( resultSet.next() ) {
|
if ( resultSet.next() ) {
|
||||||
log.multipleTablesFound( tableName.render() );
|
log.multipleTablesFound( tableName.render() );
|
||||||
|
throw new SchemaExtractionException(
|
||||||
|
String.format(
|
||||||
|
Locale.ENGLISH,
|
||||||
|
"More than one table found in namespace (%s, %s) : %s",
|
||||||
|
catalog.render(),
|
||||||
|
schema.render(),
|
||||||
|
tableName.render()
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tableInformation;
|
return tableInformation;
|
||||||
|
@ -188,10 +357,6 @@ public class InformationExtractorJdbcDatabaseMetaDataImpl implements Information
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (SQLException sqlException) {
|
|
||||||
throw convertSQLException( sqlException, "Error accessing table metadata" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean isPhysicalTableType(String tableType) {
|
protected boolean isPhysicalTableType(String tableType) {
|
||||||
return "TABLE".equalsIgnoreCase( tableType );
|
return "TABLE".equalsIgnoreCase( tableType );
|
||||||
|
|
|
@ -23,6 +23,23 @@ import org.hibernate.tool.schema.extract.internal.TableInformationImpl;
|
||||||
*/
|
*/
|
||||||
public interface InformationExtractor {
|
public interface InformationExtractor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does the given catalog exist yet?
|
||||||
|
*
|
||||||
|
* @param catalog The name of the catalog to look for.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the catalog does exist; {@code false} otherwise
|
||||||
|
*/
|
||||||
|
boolean catalogExists(Identifier catalog);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The the given schema exist yet?
|
||||||
|
*
|
||||||
|
* @param catalog The name of the catalog to look in.
|
||||||
|
* @param schema The name of the schema to look for.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the schema does exist; {@code false} otherwise
|
||||||
|
*/
|
||||||
boolean schemaExists(Identifier catalog, Identifier schema);
|
boolean schemaExists(Identifier catalog, Identifier schema);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue