HHH-7472 - Introduce a "schema management" service
This commit is contained in:
parent
47f6360225
commit
2d82a57632
|
@ -640,4 +640,6 @@ public interface AvailableSettings {
|
|||
* @since 5.0
|
||||
*/
|
||||
public static final String SCHEMA_MANAGEMENT_TOOL = "hibernate.schema_management_tool";
|
||||
// todo : add to Environment
|
||||
String SCHEMA_NAME_RESOLVER = "hibernate.schema_name_resolver";
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ import org.hibernate.cache.internal.RegionFactoryInitiator;
|
|||
import org.hibernate.cache.internal.StandardQueryCacheFactory;
|
||||
import org.hibernate.cache.spi.QueryCacheFactory;
|
||||
import org.hibernate.cache.spi.RegionFactory;
|
||||
import org.hibernate.engine.jdbc.spi.ExtractedDatabaseMetaData;
|
||||
import org.hibernate.service.jdbc.env.spi.ExtractedDatabaseMetaData;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.transaction.spi.TransactionFactory;
|
||||
import org.hibernate.hql.spi.QueryTranslatorFactory;
|
||||
|
|
|
@ -1,202 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.env.internal;
|
||||
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.engine.jdbc.env.spi.SchemaCatalogSupport;
|
||||
import org.hibernate.engine.jdbc.env.spi.StandardSchemaCatalogSupportImpl;
|
||||
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||
import org.hibernate.exception.internal.SQLExceptionTypeDelegate;
|
||||
import org.hibernate.exception.internal.SQLStateConversionDelegate;
|
||||
import org.hibernate.exception.internal.StandardSQLExceptionConverter;
|
||||
import org.hibernate.exception.spi.SQLExceptionConverter;
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
import org.hibernate.service.schema.spi.ExistingSequenceMetadataExtractor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class JdbcEnvironmentImpl implements JdbcEnvironment {
|
||||
private final Dialect dialect;
|
||||
private final IdentifierHelper identifierHelper;
|
||||
private final Identifier currentCatalog;
|
||||
private final Identifier currentSchema;
|
||||
private final SchemaCatalogSupport schemaCatalogSupport;
|
||||
private ExistingSequenceMetadataExtractor sequenceMetadataExtractor;
|
||||
private final Set<String> reservedWords;
|
||||
private final SqlExceptionHelper sqlExceptionHelper;
|
||||
|
||||
public JdbcEnvironmentImpl(DatabaseMetaData dbmd, Dialect dialect, Map properties) throws SQLException {
|
||||
this.dialect = dialect;
|
||||
|
||||
Set<String> reservedWords = new HashSet<String>();
|
||||
reservedWords.addAll( dialect.getKeywords() );
|
||||
// todo : do we need to explicitly handle SQL:2003 keywords?
|
||||
reservedWords.addAll( Arrays.asList( dbmd.getSQLKeywords().split( "," ) ) );
|
||||
this.reservedWords = reservedWords;
|
||||
|
||||
this.identifierHelper = new NormalizingIdentifierHelperImpl(
|
||||
this,
|
||||
dbmd.storesMixedCaseQuotedIdentifiers(),
|
||||
dbmd.storesLowerCaseQuotedIdentifiers(),
|
||||
dbmd.storesUpperCaseQuotedIdentifiers(),
|
||||
dbmd.storesUpperCaseIdentifiers(),
|
||||
dbmd.storesLowerCaseIdentifiers()
|
||||
);
|
||||
|
||||
String currentCatalogName = dbmd.getConnection().getCatalog();
|
||||
if ( currentCatalogName != null ) {
|
||||
// intentionally using fromMetaDataObjectName rather than fromMetaDataCatalogName !!!
|
||||
currentCatalog = identifierHelper.fromMetaDataObjectName( currentCatalogName );
|
||||
}
|
||||
else {
|
||||
currentCatalogName = (String) properties.get( AvailableSettings.DEFAULT_CATALOG );
|
||||
currentCatalog = Identifier.toIdentifier( currentCatalogName );
|
||||
}
|
||||
|
||||
String currentSchemaName = TemporarySchemaNameResolver.INSTANCE.resolveSchemaName( dbmd.getConnection() );
|
||||
if ( currentSchemaName != null ) {
|
||||
// intentionally using fromMetaDataObjectName rather than fromMetaDataSchemaName !!!
|
||||
currentSchema = identifierHelper.fromMetaDataObjectName( currentSchemaName );
|
||||
}
|
||||
else {
|
||||
currentSchemaName = (String) properties.get( AvailableSettings.DEFAULT_SCHEMA );
|
||||
currentSchema = Identifier.toIdentifier( currentSchemaName );
|
||||
}
|
||||
|
||||
schemaCatalogSupport = new StandardSchemaCatalogSupportImpl(
|
||||
dbmd.getCatalogSeparator(),
|
||||
dbmd.isCatalogAtStart(),
|
||||
dialect.openQuote(),
|
||||
dialect.closeQuote()
|
||||
);
|
||||
|
||||
SQLExceptionConverter sqlExceptionConverter = dialect.buildSQLExceptionConverter();
|
||||
if ( sqlExceptionConverter == null ) {
|
||||
final StandardSQLExceptionConverter converter = new StandardSQLExceptionConverter();
|
||||
sqlExceptionConverter = converter;
|
||||
converter.addDelegate( dialect.buildSQLExceptionConversionDelegate() );
|
||||
converter.addDelegate( new SQLExceptionTypeDelegate( dialect ) );
|
||||
converter.addDelegate( new SQLStateConversionDelegate( dialect ) );
|
||||
}
|
||||
this.sqlExceptionHelper = new SqlExceptionHelper( sqlExceptionConverter );
|
||||
|
||||
this.sequenceMetadataExtractor = new TemporaryExistingSequenceMetadataExtractor( this );
|
||||
}
|
||||
|
||||
public JdbcEnvironmentImpl(Dialect dialect, Map properties) {
|
||||
this.dialect = dialect;
|
||||
|
||||
Set<String> reservedWords = new HashSet<String>();
|
||||
reservedWords.addAll( dialect.getKeywords() );
|
||||
// todo : do we need to explicitly handle SQL:2003 keywords?
|
||||
this.reservedWords = reservedWords;
|
||||
|
||||
// again, a simple temporary impl that works on H2
|
||||
this.identifierHelper = new NormalizingIdentifierHelperImpl(
|
||||
this,
|
||||
true, // storesMixedCaseQuotedIdentifiers
|
||||
false, // storesLowerCaseQuotedIdentifiers
|
||||
false, // storesUpperCaseQuotedIdentifiers
|
||||
true, // storesUpperCaseIdentifiers
|
||||
false // storesLowerCaseIdentifiers
|
||||
);
|
||||
|
||||
String currentCatalogName = (String) properties.get( AvailableSettings.DEFAULT_CATALOG );
|
||||
currentCatalog = Identifier.toIdentifier( currentCatalogName );
|
||||
|
||||
String currentSchemaName = (String) properties.get( AvailableSettings.DEFAULT_SCHEMA );
|
||||
currentSchema = Identifier.toIdentifier( currentSchemaName );
|
||||
|
||||
// again, a simple temporary impl that works on H2
|
||||
schemaCatalogSupport = new StandardSchemaCatalogSupportImpl(
|
||||
".",
|
||||
true,
|
||||
dialect.openQuote(),
|
||||
dialect.closeQuote()
|
||||
);
|
||||
|
||||
SQLExceptionConverter sqlExceptionConverter = dialect.buildSQLExceptionConverter();
|
||||
if ( sqlExceptionConverter == null ) {
|
||||
final StandardSQLExceptionConverter converter = new StandardSQLExceptionConverter();
|
||||
sqlExceptionConverter = converter;
|
||||
converter.addDelegate( dialect.buildSQLExceptionConversionDelegate() );
|
||||
converter.addDelegate( new SQLExceptionTypeDelegate( dialect ) );
|
||||
converter.addDelegate( new SQLStateConversionDelegate( dialect ) );
|
||||
}
|
||||
this.sqlExceptionHelper = new SqlExceptionHelper( sqlExceptionConverter );
|
||||
|
||||
this.sequenceMetadataExtractor = new TemporaryExistingSequenceMetadataExtractor( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialect getDialect() {
|
||||
return dialect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getCurrentCatalog() {
|
||||
return currentCatalog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getCurrentSchema() {
|
||||
return currentSchema;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SchemaCatalogSupport getSchemaCatalogSupport() {
|
||||
return schemaCatalogSupport;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IdentifierHelper getIdentifierHelper() {
|
||||
return identifierHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getReservedWords() {
|
||||
return reservedWords;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlExceptionHelper getSqlExceptionHelper() {
|
||||
return sqlExceptionHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExistingSequenceMetadataExtractor getExistingSequenceMetadataExtractor() {
|
||||
return sequenceMetadataExtractor;
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
package org.hibernate.engine.jdbc.env;
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.env.spi;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
import org.hibernate.service.schema.spi.ExistingSequenceMetadataExtractor;
|
||||
|
||||
/**
|
||||
* Initial look at this concept we keep talking about with merging information from {@link java.sql.DatabaseMetaData}
|
||||
* and {@link org.hibernate.dialect.Dialect}
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface JdbcEnvironment {
|
||||
public Dialect getDialect();
|
||||
|
||||
public Identifier getCurrentCatalog();
|
||||
|
||||
public Identifier getCurrentSchema();
|
||||
|
||||
public SchemaCatalogSupport getSchemaCatalogSupport();
|
||||
|
||||
public IdentifierHelper getIdentifierHelper();
|
||||
|
||||
public Set<String> getReservedWords();
|
||||
|
||||
public SqlExceptionHelper getSqlExceptionHelper();
|
||||
|
||||
public ExistingSequenceMetadataExtractor getExistingSequenceMetadataExtractor();
|
||||
}
|
|
@ -23,43 +23,20 @@
|
|||
*/
|
||||
package org.hibernate.engine.jdbc.internal;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.MultiTenancyStrategy;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.LobCreationContext;
|
||||
import org.hibernate.engine.jdbc.LobCreator;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.engine.jdbc.spi.ExtractedDatabaseMetaData;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.jdbc.spi.ResultSetWrapper;
|
||||
import org.hibernate.engine.jdbc.env.spi.SchemaNameResolver;
|
||||
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||
import org.hibernate.engine.jdbc.spi.SqlStatementLogger;
|
||||
import org.hibernate.exception.internal.SQLExceptionTypeDelegate;
|
||||
import org.hibernate.exception.internal.SQLStateConversionDelegate;
|
||||
import org.hibernate.exception.internal.StandardSQLExceptionConverter;
|
||||
import org.hibernate.exception.spi.SQLExceptionConverter;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.ReflectHelper;
|
||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.hibernate.service.jdbc.connections.spi.MultiTenantConnectionProvider;
|
||||
import org.hibernate.service.jdbc.cursor.internal.StandardRefCursorSupport;
|
||||
import org.hibernate.service.jdbc.dialect.spi.DialectFactory;
|
||||
import org.hibernate.service.jdbc.env.spi.ExtractedDatabaseMetaData;
|
||||
import org.hibernate.service.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.service.spi.Configurable;
|
||||
import org.hibernate.service.spi.ServiceRegistryAwareService;
|
||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
|
@ -70,16 +47,11 @@ import org.hibernate.service.spi.ServiceRegistryImplementor;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class JdbcServicesImpl implements JdbcServices, ServiceRegistryAwareService, Configurable {
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, JdbcServicesImpl.class.getName());
|
||||
|
||||
private ServiceRegistryImplementor serviceRegistry;
|
||||
private JdbcEnvironment jdbcEnvironment;
|
||||
|
||||
private Dialect dialect;
|
||||
private ConnectionProvider connectionProvider;
|
||||
private SqlStatementLogger sqlStatementLogger;
|
||||
private SqlExceptionHelper sqlExceptionHelper;
|
||||
private ExtractedDatabaseMetaData extractedMetaDataSupport;
|
||||
private LobCreatorBuilder lobCreatorBuilder;
|
||||
|
||||
@Override
|
||||
public void injectServices(ServiceRegistryImplementor serviceRegistry) {
|
||||
|
@ -88,359 +60,13 @@ public class JdbcServicesImpl implements JdbcServices, ServiceRegistryAwareServi
|
|||
|
||||
@Override
|
||||
public void configure(Map configValues) {
|
||||
final JdbcConnectionAccess jdbcConnectionAccess = buildJdbcConnectionAccess( configValues );
|
||||
final DialectFactory dialectFactory = serviceRegistry.getService( DialectFactory.class );
|
||||
this.jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class );
|
||||
|
||||
Dialect dialect = null;
|
||||
LobCreatorBuilder lobCreatorBuilder = null;
|
||||
|
||||
boolean metaSupportsRefCursors = false;
|
||||
boolean metaSupportsNamedParams = false;
|
||||
boolean metaSupportsScrollable = false;
|
||||
boolean metaSupportsGetGeneratedKeys = false;
|
||||
boolean metaSupportsBatchUpdates = false;
|
||||
boolean metaReportsDDLCausesTxnCommit = false;
|
||||
boolean metaReportsDDLInTxnSupported = true;
|
||||
String extraKeywordsString = "";
|
||||
int sqlStateType = -1;
|
||||
boolean lobLocatorUpdateCopy = false;
|
||||
String catalogName = null;
|
||||
String schemaName = null;
|
||||
LinkedHashSet<TypeInfo> typeInfoSet = new LinkedHashSet<TypeInfo>();
|
||||
|
||||
// 'hibernate.temp.use_jdbc_metadata_defaults' is a temporary magic value.
|
||||
// The need for it is intended to be alleviated with future development, thus it is
|
||||
// not defined as an Environment constant...
|
||||
//
|
||||
// it is used to control whether we should consult the JDBC metadata to determine
|
||||
// certain Settings default values; it is useful to *not* do this when the database
|
||||
// may not be available (mainly in tools usage).
|
||||
boolean useJdbcMetadata = ConfigurationHelper.getBoolean( "hibernate.temp.use_jdbc_metadata_defaults", configValues, true );
|
||||
if ( useJdbcMetadata ) {
|
||||
try {
|
||||
Connection connection = jdbcConnectionAccess.obtainConnection();
|
||||
try {
|
||||
DatabaseMetaData meta = connection.getMetaData();
|
||||
if(LOG.isDebugEnabled()) {
|
||||
LOG.debugf( "Database ->\n" + " name : %s\n" + " version : %s\n" + " major : %s\n" + " minor : %s",
|
||||
meta.getDatabaseProductName(),
|
||||
meta.getDatabaseProductVersion(),
|
||||
meta.getDatabaseMajorVersion(),
|
||||
meta.getDatabaseMinorVersion()
|
||||
);
|
||||
LOG.debugf( "Driver ->\n" + " name : %s\n" + " version : %s\n" + " major : %s\n" + " minor : %s",
|
||||
meta.getDriverName(),
|
||||
meta.getDriverVersion(),
|
||||
meta.getDriverMajorVersion(),
|
||||
meta.getDriverMinorVersion()
|
||||
);
|
||||
LOG.debugf( "JDBC version : %s.%s", meta.getJDBCMajorVersion(), meta.getJDBCMinorVersion() );
|
||||
}
|
||||
|
||||
metaSupportsRefCursors = StandardRefCursorSupport.supportsRefCursors( meta );
|
||||
metaSupportsNamedParams = meta.supportsNamedParameters();
|
||||
metaSupportsScrollable = meta.supportsResultSetType( ResultSet.TYPE_SCROLL_INSENSITIVE );
|
||||
metaSupportsBatchUpdates = meta.supportsBatchUpdates();
|
||||
metaReportsDDLCausesTxnCommit = meta.dataDefinitionCausesTransactionCommit();
|
||||
metaReportsDDLInTxnSupported = !meta.dataDefinitionIgnoredInTransactions();
|
||||
metaSupportsGetGeneratedKeys = meta.supportsGetGeneratedKeys();
|
||||
extraKeywordsString = meta.getSQLKeywords();
|
||||
sqlStateType = meta.getSQLStateType();
|
||||
lobLocatorUpdateCopy = meta.locatorsUpdateCopy();
|
||||
typeInfoSet.addAll( TypeInfoExtracter.extractTypeInfo( meta ) );
|
||||
|
||||
dialect = dialectFactory.buildDialect( configValues, connection );
|
||||
|
||||
catalogName = connection.getCatalog();
|
||||
SchemaNameResolver schemaNameResolver = determineExplicitSchemaNameResolver( configValues );
|
||||
if ( schemaNameResolver == null ) {
|
||||
// todo : add dialect method
|
||||
// schemaNameResolver = dialect.getSchemaNameResolver();
|
||||
}
|
||||
if ( schemaNameResolver != null ) {
|
||||
schemaName = schemaNameResolver.resolveSchemaName( connection );
|
||||
}
|
||||
lobCreatorBuilder = new LobCreatorBuilder( configValues, connection );
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
LOG.unableToObtainConnectionMetadata( sqle.getMessage() );
|
||||
}
|
||||
finally {
|
||||
if ( connection != null ) {
|
||||
jdbcConnectionAccess.releaseConnection( connection );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
LOG.unableToObtainConnectionToQueryMetadata( sqle.getMessage() );
|
||||
dialect = dialectFactory.buildDialect( configValues, null );
|
||||
}
|
||||
catch ( UnsupportedOperationException uoe ) {
|
||||
// user supplied JDBC connections
|
||||
dialect = dialectFactory.buildDialect( configValues, null );
|
||||
}
|
||||
}
|
||||
else {
|
||||
dialect = dialectFactory.buildDialect( configValues, null );
|
||||
}
|
||||
this.connectionProvider = serviceRegistry.getService( ConnectionProvider.class );
|
||||
|
||||
final boolean showSQL = ConfigurationHelper.getBoolean( Environment.SHOW_SQL, configValues, false );
|
||||
final boolean formatSQL = ConfigurationHelper.getBoolean( Environment.FORMAT_SQL, configValues, false );
|
||||
|
||||
this.dialect = dialect;
|
||||
this.lobCreatorBuilder = (
|
||||
lobCreatorBuilder == null ?
|
||||
new LobCreatorBuilder( configValues, null ) :
|
||||
lobCreatorBuilder
|
||||
);
|
||||
|
||||
this.sqlStatementLogger = new SqlStatementLogger( showSQL, formatSQL );
|
||||
|
||||
this.extractedMetaDataSupport = new ExtractedDatabaseMetaDataImpl(
|
||||
metaSupportsRefCursors,
|
||||
metaSupportsNamedParams,
|
||||
metaSupportsScrollable,
|
||||
metaSupportsGetGeneratedKeys,
|
||||
metaSupportsBatchUpdates,
|
||||
metaReportsDDLInTxnSupported,
|
||||
metaReportsDDLCausesTxnCommit,
|
||||
parseKeywords( extraKeywordsString ),
|
||||
parseSQLStateType( sqlStateType ),
|
||||
lobLocatorUpdateCopy,
|
||||
schemaName,
|
||||
catalogName,
|
||||
typeInfoSet
|
||||
);
|
||||
|
||||
SQLExceptionConverter sqlExceptionConverter = dialect.buildSQLExceptionConverter();
|
||||
if ( sqlExceptionConverter == null ) {
|
||||
final StandardSQLExceptionConverter converter = new StandardSQLExceptionConverter();
|
||||
sqlExceptionConverter = converter;
|
||||
converter.addDelegate( dialect.buildSQLExceptionConversionDelegate() );
|
||||
converter.addDelegate( new SQLExceptionTypeDelegate( dialect ) );
|
||||
// todo : vary this based on extractedMetaDataSupport.getSqlStateType()
|
||||
converter.addDelegate( new SQLStateConversionDelegate( dialect ) );
|
||||
}
|
||||
this.sqlExceptionHelper = new SqlExceptionHelper( sqlExceptionConverter );
|
||||
}
|
||||
|
||||
private JdbcConnectionAccess buildJdbcConnectionAccess(Map configValues) {
|
||||
final MultiTenancyStrategy multiTenancyStrategy = MultiTenancyStrategy.determineMultiTenancyStrategy( configValues );
|
||||
|
||||
if ( MultiTenancyStrategy.NONE == multiTenancyStrategy ) {
|
||||
connectionProvider = serviceRegistry.getService( ConnectionProvider.class );
|
||||
return new ConnectionProviderJdbcConnectionAccess( connectionProvider );
|
||||
}
|
||||
else {
|
||||
connectionProvider = null;
|
||||
final MultiTenantConnectionProvider multiTenantConnectionProvider = serviceRegistry.getService( MultiTenantConnectionProvider.class );
|
||||
return new MultiTenantConnectionProviderJdbcConnectionAccess( multiTenantConnectionProvider );
|
||||
}
|
||||
}
|
||||
|
||||
private static class ConnectionProviderJdbcConnectionAccess implements JdbcConnectionAccess {
|
||||
private final ConnectionProvider connectionProvider;
|
||||
|
||||
public ConnectionProviderJdbcConnectionAccess(ConnectionProvider connectionProvider) {
|
||||
this.connectionProvider = connectionProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection obtainConnection() throws SQLException {
|
||||
return connectionProvider.getConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseConnection(Connection connection) throws SQLException {
|
||||
connectionProvider.closeConnection( connection );
|
||||
}
|
||||
}
|
||||
|
||||
private static class MultiTenantConnectionProviderJdbcConnectionAccess implements JdbcConnectionAccess {
|
||||
private final MultiTenantConnectionProvider connectionProvider;
|
||||
|
||||
public MultiTenantConnectionProviderJdbcConnectionAccess(MultiTenantConnectionProvider connectionProvider) {
|
||||
this.connectionProvider = connectionProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection obtainConnection() throws SQLException {
|
||||
return connectionProvider.getAnyConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseConnection(Connection connection) throws SQLException {
|
||||
connectionProvider.releaseAnyConnection( connection );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// todo : add to Environment
|
||||
public static final String SCHEMA_NAME_RESOLVER = "hibernate.schema_name_resolver";
|
||||
|
||||
private SchemaNameResolver determineExplicitSchemaNameResolver(Map configValues) {
|
||||
Object setting = configValues.get( SCHEMA_NAME_RESOLVER );
|
||||
if ( SchemaNameResolver.class.isInstance( setting ) ) {
|
||||
return (SchemaNameResolver) setting;
|
||||
}
|
||||
|
||||
String resolverClassName = (String) setting;
|
||||
if ( resolverClassName != null ) {
|
||||
try {
|
||||
Class resolverClass = ReflectHelper.classForName( resolverClassName, getClass() );
|
||||
return (SchemaNameResolver) ReflectHelper.getDefaultConstructor( resolverClass ).newInstance();
|
||||
}
|
||||
catch ( ClassNotFoundException e ) {
|
||||
LOG.unableToLocateConfiguredSchemaNameResolver( resolverClassName, e.toString() );
|
||||
}
|
||||
catch ( InvocationTargetException e ) {
|
||||
LOG.unableToInstantiateConfiguredSchemaNameResolver( resolverClassName, e.getTargetException().toString() );
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
LOG.unableToInstantiateConfiguredSchemaNameResolver( resolverClassName, e.toString() );
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Set<String> parseKeywords(String extraKeywordsString) {
|
||||
Set<String> keywordSet = new HashSet<String>();
|
||||
keywordSet.addAll( Arrays.asList( extraKeywordsString.split( "," ) ) );
|
||||
return keywordSet;
|
||||
}
|
||||
|
||||
private ExtractedDatabaseMetaData.SQLStateType parseSQLStateType(int sqlStateType) {
|
||||
switch ( sqlStateType ) {
|
||||
case DatabaseMetaData.sqlStateSQL99 : {
|
||||
return ExtractedDatabaseMetaData.SQLStateType.SQL99;
|
||||
}
|
||||
case DatabaseMetaData.sqlStateXOpen : {
|
||||
return ExtractedDatabaseMetaData.SQLStateType.XOpen;
|
||||
}
|
||||
default : {
|
||||
return ExtractedDatabaseMetaData.SQLStateType.UNKOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData {
|
||||
private final boolean supportsRefCursors;
|
||||
private final boolean supportsNamedParameters;
|
||||
private final boolean supportsScrollableResults;
|
||||
private final boolean supportsGetGeneratedKeys;
|
||||
private final boolean supportsBatchUpdates;
|
||||
private final boolean supportsDataDefinitionInTransaction;
|
||||
private final boolean doesDataDefinitionCauseTransactionCommit;
|
||||
private final Set<String> extraKeywords;
|
||||
private final SQLStateType sqlStateType;
|
||||
private final boolean lobLocatorUpdateCopy;
|
||||
private final String connectionSchemaName;
|
||||
private final String connectionCatalogName;
|
||||
private final LinkedHashSet<TypeInfo> typeInfoSet;
|
||||
|
||||
private ExtractedDatabaseMetaDataImpl(
|
||||
boolean supportsRefCursors,
|
||||
boolean supportsNamedParameters,
|
||||
boolean supportsScrollableResults,
|
||||
boolean supportsGetGeneratedKeys,
|
||||
boolean supportsBatchUpdates,
|
||||
boolean supportsDataDefinitionInTransaction,
|
||||
boolean doesDataDefinitionCauseTransactionCommit,
|
||||
Set<String> extraKeywords,
|
||||
SQLStateType sqlStateType,
|
||||
boolean lobLocatorUpdateCopy,
|
||||
String connectionSchemaName,
|
||||
String connectionCatalogName,
|
||||
LinkedHashSet<TypeInfo> typeInfoSet) {
|
||||
this.supportsRefCursors = supportsRefCursors;
|
||||
this.supportsNamedParameters = supportsNamedParameters;
|
||||
this.supportsScrollableResults = supportsScrollableResults;
|
||||
this.supportsGetGeneratedKeys = supportsGetGeneratedKeys;
|
||||
this.supportsBatchUpdates = supportsBatchUpdates;
|
||||
this.supportsDataDefinitionInTransaction = supportsDataDefinitionInTransaction;
|
||||
this.doesDataDefinitionCauseTransactionCommit = doesDataDefinitionCauseTransactionCommit;
|
||||
this.extraKeywords = extraKeywords;
|
||||
this.sqlStateType = sqlStateType;
|
||||
this.lobLocatorUpdateCopy = lobLocatorUpdateCopy;
|
||||
this.connectionSchemaName = connectionSchemaName;
|
||||
this.connectionCatalogName = connectionCatalogName;
|
||||
this.typeInfoSet = typeInfoSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsRefCursors() {
|
||||
return supportsRefCursors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsNamedParameters() {
|
||||
return supportsNamedParameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsScrollableResults() {
|
||||
return supportsScrollableResults;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsGetGeneratedKeys() {
|
||||
return supportsGetGeneratedKeys;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsBatchUpdates() {
|
||||
return supportsBatchUpdates;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsDataDefinitionInTransaction() {
|
||||
return supportsDataDefinitionInTransaction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesDataDefinitionCauseTransactionCommit() {
|
||||
return doesDataDefinitionCauseTransactionCommit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getExtraKeywords() {
|
||||
return extraKeywords;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLStateType getSqlStateType() {
|
||||
return sqlStateType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesLobLocatorUpdateCopy() {
|
||||
return lobLocatorUpdateCopy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConnectionSchemaName() {
|
||||
return connectionSchemaName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConnectionCatalogName() {
|
||||
return connectionCatalogName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LinkedHashSet<TypeInfo> getTypeInfoSet() {
|
||||
return typeInfoSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeInfo getTypeInfoForJdbcCode(int jdbcTypeCode) {
|
||||
for ( TypeInfo typeInfo : typeInfoSet ) {
|
||||
if ( typeInfo.getJdbcTypeCode() == jdbcTypeCode ) {
|
||||
return typeInfo;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -455,22 +81,22 @@ public class JdbcServicesImpl implements JdbcServices, ServiceRegistryAwareServi
|
|||
|
||||
@Override
|
||||
public SqlExceptionHelper getSqlExceptionHelper() {
|
||||
return sqlExceptionHelper;
|
||||
return jdbcEnvironment.getSqlExceptionHelper();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialect getDialect() {
|
||||
return dialect;
|
||||
return jdbcEnvironment.getDialect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtractedDatabaseMetaData getExtractedMetaDataSupport() {
|
||||
return extractedMetaDataSupport;
|
||||
return jdbcEnvironment.getExtractedDatabaseMetaData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LobCreator getLobCreator(LobCreationContext lobCreationContext) {
|
||||
return lobCreatorBuilder.buildLobCreator( lobCreationContext );
|
||||
return jdbcEnvironment.getLobCreatorBuilder().buildLobCreator( lobCreationContext );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -480,6 +106,6 @@ public class JdbcServicesImpl implements JdbcServices, ServiceRegistryAwareServi
|
|||
|
||||
@Override
|
||||
public JdbcEnvironment getJdbcEnvironment() {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
return jdbcEnvironment;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ import org.hibernate.HibernateException;
|
|||
import org.hibernate.JDBCException;
|
||||
import org.hibernate.engine.jdbc.internal.proxy.ProxyBuilder;
|
||||
import org.hibernate.engine.jdbc.spi.ConnectionObserver;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.service.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcResourceRegistry;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.jdbc.spi.LogicalConnectionImplementor;
|
||||
|
|
|
@ -29,7 +29,8 @@ import java.sql.ResultSet;
|
|||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.LobCreationContext;
|
||||
import org.hibernate.engine.jdbc.LobCreator;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.service.jdbc.env.spi.ExtractedDatabaseMetaData;
|
||||
import org.hibernate.service.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.service.Service;
|
||||
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
|
||||
|
||||
|
@ -44,6 +45,7 @@ public interface JdbcServices extends Service {
|
|||
*
|
||||
* @return The connection provider.
|
||||
*/
|
||||
@Deprecated
|
||||
public ConnectionProvider getConnectionProvider();
|
||||
|
||||
/**
|
||||
|
|
|
@ -39,7 +39,7 @@ import org.hibernate.ScrollableResults;
|
|||
import org.hibernate.cache.spi.CacheKey;
|
||||
import org.hibernate.collection.spi.PersistentCollection;
|
||||
import org.hibernate.engine.jdbc.LobCreationContext;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.service.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.query.spi.sql.NativeSQLQuerySpecification;
|
||||
import org.hibernate.engine.transaction.spi.TransactionCoordinator;
|
||||
import org.hibernate.internal.CriteriaImpl;
|
||||
|
|
|
@ -26,7 +26,7 @@ package org.hibernate.engine.transaction.spi;
|
|||
import java.io.Serializable;
|
||||
|
||||
import org.hibernate.ConnectionReleaseMode;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.service.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
|
||||
/**
|
||||
* Access to services needed in the context of processing transaction requests.
|
||||
|
|
|
@ -39,7 +39,7 @@ import org.hibernate.SharedSessionContract;
|
|||
import org.hibernate.StoredProcedureCall;
|
||||
import org.hibernate.cache.spi.CacheKey;
|
||||
import org.hibernate.engine.jdbc.LobCreationContext;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.service.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.query.spi.HQLQueryPlan;
|
||||
import org.hibernate.engine.query.spi.NativeSQLQueryPlan;
|
||||
import org.hibernate.engine.query.spi.ParameterMetadata;
|
||||
|
@ -333,6 +333,11 @@ public abstract class AbstractSessionImpl implements Serializable, SharedSession
|
|||
public void releaseConnection(Connection connection) throws SQLException {
|
||||
connectionProvider.closeConnection( connection );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsAggressiveRelease() {
|
||||
return connectionProvider.supportsAggressiveRelease();
|
||||
}
|
||||
}
|
||||
|
||||
private class ContextualJdbcConnectionAccess implements JdbcConnectionAccess, Serializable {
|
||||
|
@ -357,5 +362,10 @@ public abstract class AbstractSessionImpl implements Serializable, SharedSession
|
|||
}
|
||||
connectionProvider.releaseConnection( tenantIdentifier, connection );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsAggressiveRelease() {
|
||||
return connectionProvider.supportsAggressiveRelease();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ import org.hibernate.StoredProcedureCall;
|
|||
import org.hibernate.StoredProcedureOutputs;
|
||||
import org.hibernate.cfg.NotYetImplementedException;
|
||||
import org.hibernate.engine.ResultSetMappingDefinition;
|
||||
import org.hibernate.engine.jdbc.spi.ExtractedDatabaseMetaData;
|
||||
import org.hibernate.service.jdbc.env.spi.ExtractedDatabaseMetaData;
|
||||
import org.hibernate.engine.query.spi.sql.NativeSQLQueryReturn;
|
||||
import org.hibernate.engine.query.spi.sql.NativeSQLQueryRootReturn;
|
||||
import org.hibernate.engine.spi.QueryParameters;
|
||||
|
|
|
@ -34,7 +34,7 @@ import java.util.Set;
|
|||
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.service.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||
import org.hibernate.metamodel.Metadata;
|
||||
|
|
|
@ -47,7 +47,7 @@ public class ObjectName {
|
|||
/**
|
||||
* Tries to create an {@code ObjectName} from a name. This form explicitly looks for the form
|
||||
* {@code catalog.schema.name}. If you need db specific parsing use
|
||||
* {@link org.hibernate.engine.jdbc.env.spi.SchemaCatalogSupport#parseName} instead
|
||||
* {@link org.hibernate.service.jdbc.env.spi.QualifiedObjectNameSupport#parseName} instead
|
||||
*
|
||||
* @param text simple or qualified name of the database object.
|
||||
*/
|
||||
|
|
|
@ -41,9 +41,11 @@ import org.hibernate.service.jdbc.connections.internal.MultiTenantConnectionProv
|
|||
import org.hibernate.service.jdbc.cursor.internal.RefCursorSupportInitiator;
|
||||
import org.hibernate.service.jdbc.dialect.internal.DialectFactoryInitiator;
|
||||
import org.hibernate.service.jdbc.dialect.internal.DialectResolverInitiator;
|
||||
import org.hibernate.service.jdbc.env.internal.JdbcEnvironmentInitiator;
|
||||
import org.hibernate.service.jmx.internal.JmxServiceInitiator;
|
||||
import org.hibernate.service.jndi.internal.JndiServiceInitiator;
|
||||
import org.hibernate.service.jta.platform.internal.JtaPlatformInitiator;
|
||||
import org.hibernate.service.schema.internal.SchemaManagementToolInitiator;
|
||||
import org.hibernate.service.spi.BasicServiceInitiator;
|
||||
import org.hibernate.tool.hbm2ddl.ImportSqlCommandExtractorInitiator;
|
||||
|
||||
|
@ -72,9 +74,12 @@ public class StandardServiceInitiators {
|
|||
serviceInitiators.add( DialectResolverInitiator.INSTANCE );
|
||||
serviceInitiators.add( DialectFactoryInitiator.INSTANCE );
|
||||
serviceInitiators.add( BatchBuilderInitiator.INSTANCE );
|
||||
serviceInitiators.add( JdbcEnvironmentInitiator.INSTANCE );
|
||||
serviceInitiators.add( JdbcServicesInitiator.INSTANCE );
|
||||
serviceInitiators.add( RefCursorSupportInitiator.INSTANCE );
|
||||
|
||||
serviceInitiators.add( SchemaManagementToolInitiator.INSTANCE );
|
||||
|
||||
serviceInitiators.add( MutableIdentifierGeneratorFactoryInitiator.INSTANCE);
|
||||
|
||||
serviceInitiators.add( JtaPlatformInitiator.INSTANCE );
|
||||
|
|
|
@ -21,15 +21,15 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.service.schema.spi;
|
||||
package org.hibernate.service.jdbc.connections.internal;
|
||||
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
import org.hibernate.HibernateException;
|
||||
|
||||
/**
|
||||
* Because JDBC (at least up to an including Java 7, JDBC 4) still does not have a notion of
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ExistingSequenceMetadataExtractor {
|
||||
public Iterable<ExistingSequenceMetadata> extractMetadata(DatabaseMetaData databaseMetaData) throws SQLException;
|
||||
public class UserSuppliedConnectionException extends HibernateException {
|
||||
public UserSuppliedConnectionException() {
|
||||
super( "The application must supply JDBC connections" );
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.service.jdbc.connections.internal;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
|
@ -55,23 +56,17 @@ public class UserSuppliedConnectionProviderImpl implements ConnectionProvider {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Connection getConnection() throws SQLException {
|
||||
throw new UnsupportedOperationException( "The application must supply JDBC connections" );
|
||||
throw new UserSuppliedConnectionException();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void closeConnection(Connection conn) throws SQLException {
|
||||
throw new UnsupportedOperationException( "The application must supply JDBC connections" );
|
||||
throw new UserSuppliedConnectionException();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsAggressiveRelease() {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.spi;
|
||||
package org.hibernate.service.jdbc.connections.spi;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.Connection;
|
||||
|
@ -34,6 +34,30 @@ import java.sql.SQLException;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface JdbcConnectionAccess extends Serializable {
|
||||
/**
|
||||
* Obtain a JDBC connection
|
||||
*
|
||||
* @return The obtained connection
|
||||
*
|
||||
* @throws SQLException Indicates a problem getting the connection
|
||||
*/
|
||||
public Connection obtainConnection() throws SQLException;
|
||||
|
||||
/**
|
||||
* Release a previously obtained connection
|
||||
*
|
||||
* @param connection The connection to release
|
||||
*
|
||||
* @throws SQLException Indicates a problem releasing the connection
|
||||
*/
|
||||
public void releaseConnection(Connection connection) throws SQLException;
|
||||
|
||||
/**
|
||||
* Does the underlying provider of connections support aggressive releasing of connections (and re-acquisition
|
||||
* of those connections later, if need be) in JTA environments?
|
||||
*
|
||||
* @see ConnectionProvider#supportsAggressiveRelease()
|
||||
* @see MultiTenantConnectionProvider#supportsAggressiveRelease()
|
||||
*/
|
||||
public boolean supportsAggressiveRelease();
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.service.jdbc.env.internal;
|
||||
|
||||
import org.hibernate.service.jdbc.env.spi.ExtractedDatabaseMetaData;
|
||||
import org.hibernate.service.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.service.jdbc.env.spi.SQLStateType;
|
||||
|
||||
/**
|
||||
* Standard implementation of ExtractedDatabaseMetaData
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData {
|
||||
private final JdbcEnvironment jdbcEnvironment;
|
||||
|
||||
private final boolean supportsRefCursors;
|
||||
private final boolean supportsNamedParameters;
|
||||
private final boolean supportsScrollableResults;
|
||||
private final boolean supportsGetGeneratedKeys;
|
||||
private final boolean supportsBatchUpdates;
|
||||
private final boolean supportsDataDefinitionInTransaction;
|
||||
private final boolean doesDataDefinitionCauseTransactionCommit;
|
||||
private final SQLStateType sqlStateType;
|
||||
private final boolean lobLocatorUpdateCopy;
|
||||
|
||||
/**
|
||||
* Form used when {@link java.sql.DatabaseMetaData} is not available.
|
||||
*
|
||||
* @param jdbcEnvironment The JDBC environment containing this metadata.
|
||||
*/
|
||||
public ExtractedDatabaseMetaDataImpl(JdbcEnvironment jdbcEnvironment) {
|
||||
this.jdbcEnvironment = jdbcEnvironment;
|
||||
|
||||
// if possible, set values that will allow things to still work....
|
||||
this.supportsRefCursors = false; // Java 8 feature, safest to say not.
|
||||
this.supportsNamedParameters = false;
|
||||
this.supportsScrollableResults = true;
|
||||
this.supportsGetGeneratedKeys = false;
|
||||
this.supportsBatchUpdates = true;
|
||||
this.sqlStateType = SQLStateType.UNKNOWN;
|
||||
this.lobLocatorUpdateCopy = true;
|
||||
|
||||
// ugh my favorites...
|
||||
this.supportsDataDefinitionInTransaction = false;
|
||||
this.doesDataDefinitionCauseTransactionCommit = false;
|
||||
}
|
||||
|
||||
public ExtractedDatabaseMetaDataImpl(
|
||||
JdbcEnvironmentImpl jdbcEnvironment,
|
||||
boolean supportsRefCursors,
|
||||
boolean supportsNamedParameters,
|
||||
boolean supportsScrollableResults,
|
||||
boolean supportsGetGeneratedKeys,
|
||||
boolean supportsBatchUpdates,
|
||||
boolean supportsDataDefinitionInTransaction,
|
||||
boolean doesDataDefinitionCauseTransactionCommit,
|
||||
SQLStateType sqlStateType,
|
||||
boolean lobLocatorUpdateCopy) {
|
||||
this.jdbcEnvironment = jdbcEnvironment;
|
||||
this.supportsRefCursors = supportsRefCursors;
|
||||
this.supportsNamedParameters = supportsNamedParameters;
|
||||
this.supportsScrollableResults = supportsScrollableResults;
|
||||
this.supportsGetGeneratedKeys = supportsGetGeneratedKeys;
|
||||
this.supportsBatchUpdates = supportsBatchUpdates;
|
||||
this.supportsDataDefinitionInTransaction = supportsDataDefinitionInTransaction;
|
||||
this.doesDataDefinitionCauseTransactionCommit = doesDataDefinitionCauseTransactionCommit;
|
||||
this.sqlStateType = sqlStateType;
|
||||
this.lobLocatorUpdateCopy = lobLocatorUpdateCopy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdbcEnvironment getJdbcEnvironment() {
|
||||
return jdbcEnvironment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsRefCursors() {
|
||||
return supportsRefCursors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsNamedParameters() {
|
||||
return supportsNamedParameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsScrollableResults() {
|
||||
return supportsScrollableResults;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsGetGeneratedKeys() {
|
||||
return supportsGetGeneratedKeys;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsBatchUpdates() {
|
||||
return supportsBatchUpdates;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsDataDefinitionInTransaction() {
|
||||
return supportsDataDefinitionInTransaction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesDataDefinitionCauseTransactionCommit() {
|
||||
return doesDataDefinitionCauseTransactionCommit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLStateType getSqlStateType() {
|
||||
return sqlStateType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesLobLocatorUpdateCopy() {
|
||||
return lobLocatorUpdateCopy;
|
||||
}
|
||||
}
|
117
hibernate-core/src/main/java/org/hibernate/service/jdbc/env/internal/JdbcEnvironment.java
vendored
Normal file
117
hibernate-core/src/main/java/org/hibernate/service/jdbc/env/internal/JdbcEnvironment.java
vendored
Normal file
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.service.jdbc.env.internal;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.internal.TypeInfo;
|
||||
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
import org.hibernate.service.Service;
|
||||
import org.hibernate.service.jdbc.env.spi.ExtractedDatabaseMetaData;
|
||||
import org.hibernate.service.jdbc.env.spi.IdentifierHelper;
|
||||
import org.hibernate.service.jdbc.env.spi.QualifiedObjectNameSupport;
|
||||
|
||||
/**
|
||||
* Initial look at this concept we keep talking about with merging information from {@link java.sql.DatabaseMetaData}
|
||||
* and {@link org.hibernate.dialect.Dialect}
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface JdbcEnvironment extends Service {
|
||||
/**
|
||||
* Get the dialect for this environment.
|
||||
*
|
||||
* @return The dialect.
|
||||
*/
|
||||
public Dialect getDialect();
|
||||
|
||||
/**
|
||||
* Access to the bits of information we pulled off the JDBC {@link java.sql.DatabaseMetaData} (that did not get
|
||||
* "interpreted" into the helpers/delegates available here).
|
||||
*
|
||||
* @return The values extracted from JDBC DatabaseMetaData
|
||||
*/
|
||||
public ExtractedDatabaseMetaData getExtractedDatabaseMetaData();
|
||||
|
||||
/**
|
||||
* Get the current database catalog. Typically will come from either {@link java.sql.Connection#getCatalog()}
|
||||
* or {@link org.hibernate.cfg.AvailableSettings#DEFAULT_CATALOG}.
|
||||
*
|
||||
* @return The current catalog.
|
||||
*/
|
||||
public Identifier getCurrentCatalog();
|
||||
|
||||
/**
|
||||
* Get the current database catalog. Typically will come from either
|
||||
* {@link org.hibernate.service.jdbc.env.spi.SchemaNameResolver#resolveSchemaName(java.sql.Connection)} or
|
||||
* {@link org.hibernate.cfg.AvailableSettings#DEFAULT_CATALOG}.
|
||||
*
|
||||
* @return The current schema
|
||||
*/
|
||||
public Identifier getCurrentSchema();
|
||||
|
||||
/**
|
||||
* Obtain support for reading and writing qualified object names.
|
||||
*
|
||||
* @return Qualified name support.
|
||||
*/
|
||||
public QualifiedObjectNameSupport getQualifiedObjectNameSupport();
|
||||
|
||||
/**
|
||||
* Obtain the helper for dealing with identifiers in this environment.
|
||||
*
|
||||
* @return The identifier helper.
|
||||
*/
|
||||
public IdentifierHelper getIdentifierHelper();
|
||||
|
||||
/**
|
||||
* Get the complete set of reserved words for this environment. These are significant because they represent
|
||||
* the complete set of terms that MUST BE quoted if used as identifiers. This allows us to apply auto-quoting
|
||||
* in the metamodel based on these terms.
|
||||
*
|
||||
* Note that the standard IdentifierHelper returned by {@link #getIdentifierHelper()} already accounts for
|
||||
* auto-quoting :) yaay!
|
||||
*
|
||||
* @return Reserved words
|
||||
*/
|
||||
public Set<String> getReservedWords();
|
||||
|
||||
/**
|
||||
* Obtain the helper for dealing with JDBC {@link java.sql.SQLException} faults.
|
||||
*
|
||||
* @return This environment's helper.
|
||||
*/
|
||||
public SqlExceptionHelper getSqlExceptionHelper();
|
||||
|
||||
/**
|
||||
* Find type information for the type identified by the given "JDBC type code".
|
||||
*
|
||||
* @param jdbcTypeCode The JDBC type code.
|
||||
*
|
||||
* @return The corresponding type info.
|
||||
*/
|
||||
public TypeInfo getTypeInfoForJdbcCode(int jdbcTypeCode);
|
||||
}
|
294
hibernate-core/src/main/java/org/hibernate/service/jdbc/env/internal/JdbcEnvironmentImpl.java
vendored
Normal file
294
hibernate-core/src/main/java/org/hibernate/service/jdbc/env/internal/JdbcEnvironmentImpl.java
vendored
Normal file
|
@ -0,0 +1,294 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.service.jdbc.env.internal;
|
||||
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.internal.TypeInfo;
|
||||
import org.hibernate.engine.jdbc.internal.TypeInfoExtracter;
|
||||
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||
import org.hibernate.exception.internal.SQLExceptionTypeDelegate;
|
||||
import org.hibernate.exception.internal.SQLStateConversionDelegate;
|
||||
import org.hibernate.exception.internal.StandardSQLExceptionConverter;
|
||||
import org.hibernate.exception.spi.SQLExceptionConverter;
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.service.config.spi.ConfigurationService;
|
||||
import org.hibernate.service.config.spi.StandardConverters;
|
||||
import org.hibernate.service.jdbc.cursor.internal.StandardRefCursorSupport;
|
||||
import org.hibernate.service.jdbc.env.spi.ExtractedDatabaseMetaData;
|
||||
import org.hibernate.service.jdbc.env.spi.IdentifierHelper;
|
||||
import org.hibernate.service.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.service.jdbc.env.spi.LobCreatorBuilder;
|
||||
import org.hibernate.service.jdbc.env.spi.QualifiedObjectNameSupport;
|
||||
import org.hibernate.service.jdbc.env.spi.SQLStateType;
|
||||
import org.hibernate.service.jdbc.env.spi.SchemaNameResolver;
|
||||
import org.hibernate.service.jdbc.env.spi.StandardQualifiedObjectNameSupportImpl;
|
||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class JdbcEnvironmentImpl implements JdbcEnvironment {
|
||||
private final ServiceRegistryImplementor serviceRegistry;
|
||||
private final Dialect dialect;
|
||||
|
||||
private final SqlExceptionHelper sqlExceptionHelper;
|
||||
private final ExtractedDatabaseMetaData extractedMetaDataSupport;
|
||||
private final Set<String> reservedWords;
|
||||
private final Identifier currentCatalog;
|
||||
private final Identifier currentSchema;
|
||||
private final IdentifierHelper identifierHelper;
|
||||
private final QualifiedObjectNameSupport qualifiedObjectNameSupport;
|
||||
private final LobCreatorBuilderImpl lobCreatorBuilder;
|
||||
private final LinkedHashSet<TypeInfo> typeInfoSet = new LinkedHashSet<TypeInfo>();
|
||||
|
||||
/**
|
||||
* Constructor form used when the JDBC {@link DatabaseMetaData} is not available.
|
||||
*
|
||||
* @param serviceRegistry The service registry
|
||||
* @param dialect The resolved dialect.
|
||||
*/
|
||||
public JdbcEnvironmentImpl(ServiceRegistryImplementor serviceRegistry, Dialect dialect) {
|
||||
this.serviceRegistry = serviceRegistry;
|
||||
this.dialect = dialect;
|
||||
|
||||
this.sqlExceptionHelper = buildSqlExceptionHelper( dialect );
|
||||
this.extractedMetaDataSupport = new ExtractedDatabaseMetaDataImpl( this );
|
||||
|
||||
// make sure reserved-words, current-catalog and current-schema happen before the identifier-helper!
|
||||
this.reservedWords = dialect.getKeywords();
|
||||
this.currentCatalog = Identifier.toIdentifier(
|
||||
serviceRegistry.getService( ConfigurationService.class )
|
||||
.getSetting( AvailableSettings.DEFAULT_CATALOG, StandardConverters.STRING )
|
||||
);
|
||||
this.currentSchema = Identifier.toIdentifier(
|
||||
serviceRegistry.getService( ConfigurationService.class )
|
||||
.getSetting( AvailableSettings.DEFAULT_SCHEMA, StandardConverters.STRING )
|
||||
);
|
||||
|
||||
// a simple temporary impl that works on H2
|
||||
this.identifierHelper = new NormalizingIdentifierHelperImpl(
|
||||
this,
|
||||
true, // storesMixedCaseQuotedIdentifiers
|
||||
false, // storesLowerCaseQuotedIdentifiers
|
||||
false, // storesUpperCaseQuotedIdentifiers
|
||||
true, // storesUpperCaseIdentifiers
|
||||
false // storesLowerCaseIdentifiers
|
||||
);
|
||||
|
||||
// again, a simple temporary impl that works on H2
|
||||
this.qualifiedObjectNameSupport = new StandardQualifiedObjectNameSupportImpl(
|
||||
".",
|
||||
true,
|
||||
dialect.openQuote(),
|
||||
dialect.closeQuote()
|
||||
);
|
||||
|
||||
this.lobCreatorBuilder = LobCreatorBuilderImpl.makeLobCreatorBuilder();
|
||||
}
|
||||
|
||||
public JdbcEnvironmentImpl(ServiceRegistryImplementor serviceRegistry, Dialect dialect, DatabaseMetaData dbmd) throws SQLException {
|
||||
this.serviceRegistry = serviceRegistry;
|
||||
this.dialect = dialect;
|
||||
|
||||
this.sqlExceptionHelper = buildSqlExceptionHelper( dialect );
|
||||
|
||||
this.extractedMetaDataSupport = new ExtractedDatabaseMetaDataImpl(
|
||||
this,
|
||||
StandardRefCursorSupport.supportsRefCursors( dbmd ),
|
||||
dbmd.supportsNamedParameters(),
|
||||
dbmd.supportsResultSetType( ResultSet.TYPE_SCROLL_INSENSITIVE ),
|
||||
dbmd.supportsGetGeneratedKeys(),
|
||||
dbmd.supportsBatchUpdates(),
|
||||
!dbmd.dataDefinitionIgnoredInTransactions(),
|
||||
dbmd.dataDefinitionCausesTransactionCommit(),
|
||||
parseSQLStateType( dbmd.getSQLStateType() ),
|
||||
dbmd.locatorsUpdateCopy()
|
||||
);
|
||||
|
||||
// make sure reserved-words happen before the identifier-helper!
|
||||
this.reservedWords = buildMergedReservedWords( dialect, dbmd );
|
||||
|
||||
this.identifierHelper = new NormalizingIdentifierHelperImpl(
|
||||
this,
|
||||
dbmd.storesMixedCaseQuotedIdentifiers(),
|
||||
dbmd.storesLowerCaseQuotedIdentifiers(),
|
||||
dbmd.storesUpperCaseQuotedIdentifiers(),
|
||||
dbmd.storesUpperCaseIdentifiers(),
|
||||
dbmd.storesLowerCaseIdentifiers()
|
||||
);
|
||||
|
||||
// and that current-catalog and current-schema happen after it
|
||||
this.currentCatalog = determineCurrentCatalog( dbmd );
|
||||
this.currentSchema = determineCurrentSchema( dbmd );
|
||||
|
||||
this.qualifiedObjectNameSupport = new StandardQualifiedObjectNameSupportImpl(
|
||||
dbmd.getCatalogSeparator(),
|
||||
dbmd.isCatalogAtStart(),
|
||||
dialect.openQuote(),
|
||||
dialect.closeQuote()
|
||||
);
|
||||
|
||||
this.typeInfoSet.addAll( TypeInfoExtracter.extractTypeInfo( dbmd ) );
|
||||
|
||||
this.lobCreatorBuilder = LobCreatorBuilderImpl.makeLobCreatorBuilder(
|
||||
serviceRegistry.getService( ConfigurationService.class ).getSettings(),
|
||||
dbmd.getConnection()
|
||||
);
|
||||
}
|
||||
|
||||
private SQLStateType parseSQLStateType(int sqlStateType) {
|
||||
switch ( sqlStateType ) {
|
||||
case DatabaseMetaData.sqlStateSQL99 : {
|
||||
return SQLStateType.SQL99;
|
||||
}
|
||||
case DatabaseMetaData.sqlStateXOpen : {
|
||||
return SQLStateType.XOpen;
|
||||
}
|
||||
default : {
|
||||
return SQLStateType.UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private SqlExceptionHelper buildSqlExceptionHelper(Dialect dialect) {
|
||||
SQLExceptionConverter sqlExceptionConverter = dialect.buildSQLExceptionConverter();
|
||||
if ( sqlExceptionConverter == null ) {
|
||||
final StandardSQLExceptionConverter converter = new StandardSQLExceptionConverter();
|
||||
sqlExceptionConverter = converter;
|
||||
converter.addDelegate( dialect.buildSQLExceptionConversionDelegate() );
|
||||
converter.addDelegate( new SQLExceptionTypeDelegate( dialect ) );
|
||||
converter.addDelegate( new SQLStateConversionDelegate( dialect ) );
|
||||
}
|
||||
return new SqlExceptionHelper( sqlExceptionConverter );
|
||||
}
|
||||
|
||||
private Identifier determineCurrentCatalog(DatabaseMetaData dbmd) throws SQLException {
|
||||
String currentCatalogName = dbmd.getConnection().getCatalog();
|
||||
if ( currentCatalogName != null ) {
|
||||
// intentionally using fromMetaDataObjectName rather than fromMetaDataCatalogName !!!
|
||||
return identifierHelper.fromMetaDataObjectName( currentCatalogName );
|
||||
}
|
||||
else {
|
||||
currentCatalogName = serviceRegistry.getService( ConfigurationService.class )
|
||||
.getSetting( AvailableSettings.DEFAULT_CATALOG, StandardConverters.STRING );
|
||||
return Identifier.toIdentifier( currentCatalogName );
|
||||
}
|
||||
}
|
||||
|
||||
private Identifier determineCurrentSchema(DatabaseMetaData dbmd) throws SQLException {
|
||||
String currentSchemaName = locateSchemaNameResolver().resolveSchemaName( dbmd.getConnection() );
|
||||
if ( currentSchemaName != null ) {
|
||||
// intentionally using fromMetaDataObjectName rather than fromMetaDataSchemaName !!!
|
||||
return identifierHelper.fromMetaDataObjectName( currentSchemaName );
|
||||
}
|
||||
else {
|
||||
currentSchemaName = serviceRegistry.getService( ConfigurationService.class )
|
||||
.getSetting( AvailableSettings.DEFAULT_SCHEMA, StandardConverters.STRING );
|
||||
return Identifier.toIdentifier( currentSchemaName );
|
||||
}
|
||||
}
|
||||
|
||||
private SchemaNameResolver locateSchemaNameResolver() {
|
||||
final Object setting = serviceRegistry.getService( ConfigurationService.class )
|
||||
.getSettings()
|
||||
.get( AvailableSettings.SCHEMA_NAME_RESOLVER );
|
||||
return serviceRegistry.getService( ClassLoaderService.class )
|
||||
.getStrategyInstanceResolver()
|
||||
.resolveDefaultableStrategyInstance( setting, SchemaNameResolver.class, TemporarySchemaNameResolver.INSTANCE );
|
||||
}
|
||||
|
||||
private Set<String> buildMergedReservedWords(Dialect dialect, DatabaseMetaData dbmd) throws SQLException {
|
||||
Set<String> reservedWords = new HashSet<String>();
|
||||
reservedWords.addAll( dialect.getKeywords() );
|
||||
// todo : do we need to explicitly handle SQL:2003 keywords?
|
||||
reservedWords.addAll( Arrays.asList( dbmd.getSQLKeywords().split( "," ) ) );
|
||||
return reservedWords;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialect getDialect() {
|
||||
return dialect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtractedDatabaseMetaData getExtractedDatabaseMetaData() {
|
||||
return extractedMetaDataSupport;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getCurrentCatalog() {
|
||||
return currentCatalog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getCurrentSchema() {
|
||||
return currentSchema;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QualifiedObjectNameSupport getQualifiedObjectNameSupport() {
|
||||
return qualifiedObjectNameSupport;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IdentifierHelper getIdentifierHelper() {
|
||||
return identifierHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getReservedWords() {
|
||||
return reservedWords;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqlExceptionHelper getSqlExceptionHelper() {
|
||||
return sqlExceptionHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LobCreatorBuilder getLobCreatorBuilder() {
|
||||
return lobCreatorBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeInfo getTypeInfoForJdbcCode(int jdbcTypeCode) {
|
||||
for ( TypeInfo typeInfo : typeInfoSet ) {
|
||||
if ( typeInfo.getJdbcTypeCode() == jdbcTypeCode ) {
|
||||
return typeInfo;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
186
hibernate-core/src/main/java/org/hibernate/service/jdbc/env/internal/JdbcEnvironmentInitiator.java
vendored
Normal file
186
hibernate-core/src/main/java/org/hibernate/service/jdbc/env/internal/JdbcEnvironmentInitiator.java
vendored
Normal file
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.service.jdbc.env.internal;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.MultiTenancyStrategy;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||
import org.hibernate.service.jdbc.connections.internal.UserSuppliedConnectionException;
|
||||
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.hibernate.service.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.service.jdbc.connections.spi.MultiTenantConnectionProvider;
|
||||
import org.hibernate.service.jdbc.dialect.spi.DialectFactory;
|
||||
import org.hibernate.service.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.service.spi.BasicServiceInitiator;
|
||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class JdbcEnvironmentInitiator implements BasicServiceInitiator<JdbcEnvironment> {
|
||||
private static final CoreMessageLogger log = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
JdbcEnvironmentInitiator.class.getName()
|
||||
);
|
||||
|
||||
public static final JdbcEnvironmentInitiator INSTANCE = new JdbcEnvironmentInitiator();
|
||||
|
||||
@Override
|
||||
public Class<JdbcEnvironment> getServiceInitiated() {
|
||||
return JdbcEnvironment.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdbcEnvironment initiateService(Map configurationValues, ServiceRegistryImplementor registry) {
|
||||
final DialectFactory dialectFactory = registry.getService( DialectFactory.class );
|
||||
|
||||
boolean useJdbcMetadata = ConfigurationHelper.getBoolean(
|
||||
"hibernate.temp.use_jdbc_metadata_defaults",
|
||||
configurationValues,
|
||||
true
|
||||
);
|
||||
|
||||
if ( useJdbcMetadata ) {
|
||||
final JdbcConnectionAccess jdbcConnectionAccess = buildJdbcConnectionAccess( configurationValues, registry );
|
||||
try {
|
||||
final Connection connection = jdbcConnectionAccess.obtainConnection();
|
||||
try {
|
||||
final DatabaseMetaData dbmd = connection.getMetaData();
|
||||
if ( log.isDebugEnabled() ) {
|
||||
log.debugf(
|
||||
"Database ->\n"
|
||||
+ " name : %s\n"
|
||||
+ " version : %s\n"
|
||||
+ " major : %s\n"
|
||||
+ " minor : %s",
|
||||
dbmd.getDatabaseProductName(),
|
||||
dbmd.getDatabaseProductVersion(),
|
||||
dbmd.getDatabaseMajorVersion(),
|
||||
dbmd.getDatabaseMinorVersion()
|
||||
);
|
||||
log.debugf(
|
||||
"Driver ->\n"
|
||||
+ " name : %s\n"
|
||||
+ " version : %s\n"
|
||||
+ " major : %s\n"
|
||||
+ " minor : %s",
|
||||
dbmd.getDriverName(),
|
||||
dbmd.getDriverVersion(),
|
||||
dbmd.getDriverMajorVersion(),
|
||||
dbmd.getDriverMinorVersion()
|
||||
);
|
||||
log.debugf( "JDBC version : %s.%s", dbmd.getJDBCMajorVersion(), dbmd.getJDBCMinorVersion() );
|
||||
}
|
||||
|
||||
return new JdbcEnvironmentImpl(
|
||||
registry,
|
||||
dialectFactory.buildDialect( configurationValues, connection ),
|
||||
dbmd
|
||||
);
|
||||
}
|
||||
catch (SQLException e) {
|
||||
log.unableToObtainConnectionMetadata( e.getMessage() );
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
jdbcConnectionAccess.releaseConnection( connection );
|
||||
}
|
||||
catch (SQLException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.unableToObtainConnectionToQueryMetadata( e.getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
// if we get here, either we were asked to not use JDBC metadata or accessing the JDBC metadata failed.
|
||||
return new JdbcEnvironmentImpl( registry, dialectFactory.buildDialect( configurationValues, null ) );
|
||||
}
|
||||
|
||||
private JdbcConnectionAccess buildJdbcConnectionAccess(Map configValues, ServiceRegistryImplementor registry) {
|
||||
final MultiTenancyStrategy multiTenancyStrategy = MultiTenancyStrategy.determineMultiTenancyStrategy( configValues );
|
||||
if ( MultiTenancyStrategy.NONE == multiTenancyStrategy ) {
|
||||
ConnectionProvider connectionProvider = registry.getService( ConnectionProvider.class );
|
||||
return new ConnectionProviderJdbcConnectionAccess( connectionProvider );
|
||||
}
|
||||
else {
|
||||
final MultiTenantConnectionProvider multiTenantConnectionProvider = registry.getService( MultiTenantConnectionProvider.class );
|
||||
return new MultiTenantConnectionProviderJdbcConnectionAccess( multiTenantConnectionProvider );
|
||||
}
|
||||
}
|
||||
|
||||
private static class ConnectionProviderJdbcConnectionAccess implements JdbcConnectionAccess {
|
||||
private final ConnectionProvider connectionProvider;
|
||||
|
||||
public ConnectionProviderJdbcConnectionAccess(ConnectionProvider connectionProvider) {
|
||||
this.connectionProvider = connectionProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection obtainConnection() throws SQLException {
|
||||
return connectionProvider.getConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseConnection(Connection connection) throws SQLException {
|
||||
connectionProvider.closeConnection( connection );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsAggressiveRelease() {
|
||||
return connectionProvider.supportsAggressiveRelease();
|
||||
}
|
||||
}
|
||||
|
||||
private static class MultiTenantConnectionProviderJdbcConnectionAccess implements JdbcConnectionAccess {
|
||||
private final MultiTenantConnectionProvider connectionProvider;
|
||||
|
||||
public MultiTenantConnectionProviderJdbcConnectionAccess(MultiTenantConnectionProvider connectionProvider) {
|
||||
this.connectionProvider = connectionProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection obtainConnection() throws SQLException {
|
||||
return connectionProvider.getAnyConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseConnection(Connection connection) throws SQLException {
|
||||
connectionProvider.releaseAnyConnection( connection );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsAggressiveRelease() {
|
||||
return connectionProvider.supportsAggressiveRelease();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,7 +21,7 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.internal;
|
||||
package org.hibernate.service.jdbc.env.internal;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.Connection;
|
||||
|
@ -38,49 +38,70 @@ import org.hibernate.engine.jdbc.LobCreator;
|
|||
import org.hibernate.engine.jdbc.NonContextualLobCreator;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||
import org.hibernate.service.jdbc.env.spi.LobCreatorBuilder;
|
||||
|
||||
/**
|
||||
* Builds {@link LobCreator} instances based on the capabilities of the environment.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class LobCreatorBuilder {
|
||||
public class LobCreatorBuilderImpl implements LobCreatorBuilder {
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, LobCreatorBuilderImpl.class.getName());
|
||||
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, LobCreatorBuilder.class.getName());
|
||||
private final boolean useContextualLobCreation;
|
||||
|
||||
private boolean useContextualLobCreation;
|
||||
private LobCreatorBuilderImpl(boolean useContextualLobCreation) {
|
||||
this.useContextualLobCreation = useContextualLobCreation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LobCreator buildLobCreator(LobCreationContext lobCreationContext) {
|
||||
return useContextualLobCreation
|
||||
? new ContextualLobCreator( lobCreationContext )
|
||||
: NonContextualLobCreator.INSTANCE;
|
||||
}
|
||||
|
||||
|
||||
// factory methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/**
|
||||
* The public factory method for obtaining the appropriate (according to given JDBC {@link java.sql.Connection}.
|
||||
*
|
||||
* The public factory method for obtaining the appropriate LOB creator (according to given
|
||||
* JDBC {@link java.sql.Connection}).
|
||||
*
|
||||
* @param jdbcConnection A JDBC {@link java.sql.Connection} which can be used to gauge the drivers level of support,
|
||||
* specifically for creating LOB references.
|
||||
*/
|
||||
public LobCreatorBuilder(Map configValues, Connection jdbcConnection) {
|
||||
this.useContextualLobCreation = useContextualLobCreation( configValues, jdbcConnection );
|
||||
public static LobCreatorBuilderImpl makeLobCreatorBuilder(Map configValues, Connection jdbcConnection) {
|
||||
return new LobCreatorBuilderImpl( useContextualLobCreation( configValues, jdbcConnection ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* For used when JDBC Connection is not available.
|
||||
*
|
||||
* @return Appropriate LobCreatorBuilder
|
||||
*/
|
||||
public static LobCreatorBuilderImpl makeLobCreatorBuilder() {
|
||||
LOG.disablingContextualLOBCreationSinceConnectionNull();
|
||||
return new LobCreatorBuilderImpl( false );
|
||||
}
|
||||
|
||||
private static final Class[] NO_ARG_SIG = new Class[0];
|
||||
private static final Object[] NO_ARGS = new Object[0];
|
||||
|
||||
/**
|
||||
* Basically here we are simply checking whether we can call the {@link Connection} methods for
|
||||
* LOB creation added in JDBC 4. We not only check whether the {@link Connection} declares these methods,
|
||||
* but also whether the actual {@link Connection} instance implements them (i.e. can be called without simply
|
||||
* throwing an exception).
|
||||
*
|
||||
* @param jdbcConnection The connection which can be used in level-of-support testing.
|
||||
*
|
||||
* @return True if the connection can be used to create LOBs; false otherwise.
|
||||
*/
|
||||
private static boolean useContextualLobCreation(Map configValues, Connection jdbcConnection) {
|
||||
// Basically here we are simply checking whether we can call the {@link Connection} methods for
|
||||
// LOB creation added in JDBC 4. We not only check whether the {@link Connection} declares these methods,
|
||||
// but also whether the actual {@link Connection} instance implements them (i.e. can be called without simply
|
||||
// throwing an exception).
|
||||
|
||||
// First, did the user explicitly configure to use non-contextual creation?
|
||||
boolean isNonContextualLobCreationRequired =
|
||||
ConfigurationHelper.getBoolean( Environment.NON_CONTEXTUAL_LOB_CREATION, configValues );
|
||||
if ( isNonContextualLobCreationRequired ) {
|
||||
LOG.disablingContextualLOBCreation( Environment.NON_CONTEXTUAL_LOB_CREATION );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( jdbcConnection == null ) {
|
||||
LOG.disablingContextualLOBCreationSinceConnectionNull();
|
||||
return false;
|
||||
|
@ -126,10 +147,4 @@ public class LobCreatorBuilder {
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
public LobCreator buildLobCreator(LobCreationContext lobCreationContext) {
|
||||
return useContextualLobCreation
|
||||
? new ContextualLobCreator( lobCreationContext )
|
||||
: NonContextualLobCreator.INSTANCE;
|
||||
}
|
||||
}
|
|
@ -21,12 +21,12 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.env.internal;
|
||||
package org.hibernate.service.jdbc.env.internal;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.service.jdbc.env.spi.IdentifierHelper;
|
||||
import org.hibernate.service.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
|
|
@ -21,14 +21,14 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.env.internal;
|
||||
package org.hibernate.service.jdbc.env.internal;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
import org.hibernate.engine.jdbc.env.spi.SchemaNameResolver;
|
||||
import org.hibernate.service.jdbc.env.spi.SchemaNameResolver;
|
||||
|
||||
/**
|
||||
* Temporary implementation that works for H2.
|
1
hibernate-core/src/main/java/org/hibernate/service/jdbc/env/package-info.java
vendored
Normal file
1
hibernate-core/src/main/java/org/hibernate/service/jdbc/env/package-info.java
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
package org.hibernate.service.jdbc.env;
|
|
@ -21,7 +21,7 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.spi;
|
||||
package org.hibernate.service.jdbc.env.spi;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
@ -37,12 +37,12 @@ import org.hibernate.engine.jdbc.internal.TypeInfo;
|
|||
*/
|
||||
@SuppressWarnings( {"UnusedDeclaration"})
|
||||
public interface ExtractedDatabaseMetaData {
|
||||
|
||||
public enum SQLStateType {
|
||||
XOpen,
|
||||
SQL99,
|
||||
UNKOWN
|
||||
}
|
||||
/**
|
||||
* Obtain the JDBC Environment from which this metadata came.
|
||||
*
|
||||
* @return The JDBC environment
|
||||
*/
|
||||
public JdbcEnvironment getJdbcEnvironment();
|
||||
|
||||
/**
|
||||
* Does the driver report supporting named parameters?
|
||||
|
@ -107,15 +107,6 @@ public interface ExtractedDatabaseMetaData {
|
|||
*/
|
||||
public boolean doesDataDefinitionCauseTransactionCommit();
|
||||
|
||||
/**
|
||||
* Get the list of extra keywords (beyond standard SQL92 keywords) reported by the driver.
|
||||
*
|
||||
* @return The extra keywords used by this database.
|
||||
*
|
||||
* @see java.sql.DatabaseMetaData#getSQLKeywords()
|
||||
*/
|
||||
public Set<String> getExtraKeywords();
|
||||
|
||||
/**
|
||||
* Retrieve the type of codes the driver says it uses for {@code SQLState}. They might follow either
|
||||
* the X/Open standard or the SQL92 standard.
|
||||
|
@ -134,36 +125,4 @@ public interface ExtractedDatabaseMetaData {
|
|||
* @see java.sql.DatabaseMetaData#locatorsUpdateCopy()
|
||||
*/
|
||||
public boolean doesLobLocatorUpdateCopy();
|
||||
|
||||
/**
|
||||
* Retrieve the name of the schema in effect when we connected to the database.
|
||||
*
|
||||
* @return The schema name
|
||||
*/
|
||||
public String getConnectionSchemaName();
|
||||
|
||||
/**
|
||||
* Retrieve the name of the catalog in effect when we connected to the database.
|
||||
*
|
||||
* @return The catalog name
|
||||
*/
|
||||
public String getConnectionCatalogName();
|
||||
|
||||
/**
|
||||
* Set of type info reported by the driver.
|
||||
*
|
||||
* @return The type information obtained from the driver.
|
||||
*
|
||||
* @see java.sql.DatabaseMetaData#getTypeInfo()
|
||||
*/
|
||||
public LinkedHashSet<TypeInfo> getTypeInfoSet();
|
||||
|
||||
/**
|
||||
* Set of type info reported by the driver.
|
||||
*
|
||||
* @return The type information obtained from the driver.
|
||||
*
|
||||
* @see java.sql.DatabaseMetaData#getTypeInfo()
|
||||
*/
|
||||
public TypeInfo getTypeInfoForJdbcCode(int jdbcTypeCode);
|
||||
}
|
|
@ -21,7 +21,7 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.env.spi;
|
||||
package org.hibernate.service.jdbc.env.spi;
|
||||
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
|
121
hibernate-core/src/main/java/org/hibernate/service/jdbc/env/spi/JdbcEnvironment.java
vendored
Normal file
121
hibernate-core/src/main/java/org/hibernate/service/jdbc/env/spi/JdbcEnvironment.java
vendored
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.service.jdbc.env.spi;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.internal.TypeInfo;
|
||||
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
import org.hibernate.service.Service;
|
||||
|
||||
/**
|
||||
* Initial look at this concept we keep talking about with merging information from {@link java.sql.DatabaseMetaData}
|
||||
* and {@link org.hibernate.dialect.Dialect}
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface JdbcEnvironment extends Service {
|
||||
/**
|
||||
* Get the dialect for this environment.
|
||||
*
|
||||
* @return The dialect.
|
||||
*/
|
||||
public Dialect getDialect();
|
||||
|
||||
/**
|
||||
* Access to the bits of information we pulled off the JDBC {@link java.sql.DatabaseMetaData} (that did not get
|
||||
* "interpreted" into the helpers/delegates available here).
|
||||
*
|
||||
* @return The values extracted from JDBC DatabaseMetaData
|
||||
*/
|
||||
public ExtractedDatabaseMetaData getExtractedDatabaseMetaData();
|
||||
|
||||
/**
|
||||
* Get the current database catalog. Typically will come from either {@link java.sql.Connection#getCatalog()}
|
||||
* or {@link org.hibernate.cfg.AvailableSettings#DEFAULT_CATALOG}.
|
||||
*
|
||||
* @return The current catalog.
|
||||
*/
|
||||
public Identifier getCurrentCatalog();
|
||||
|
||||
/**
|
||||
* Get the current database catalog. Typically will come from either
|
||||
* {@link SchemaNameResolver#resolveSchemaName(java.sql.Connection)} or
|
||||
* {@link org.hibernate.cfg.AvailableSettings#DEFAULT_CATALOG}.
|
||||
*
|
||||
* @return The current schema
|
||||
*/
|
||||
public Identifier getCurrentSchema();
|
||||
|
||||
/**
|
||||
* Obtain support for reading and writing qualified object names.
|
||||
*
|
||||
* @return Qualified name support.
|
||||
*/
|
||||
public QualifiedObjectNameSupport getQualifiedObjectNameSupport();
|
||||
|
||||
/**
|
||||
* Obtain the helper for dealing with identifiers in this environment.
|
||||
*
|
||||
* @return The identifier helper.
|
||||
*/
|
||||
public IdentifierHelper getIdentifierHelper();
|
||||
|
||||
/**
|
||||
* Get the complete set of reserved words for this environment. These are significant because they represent
|
||||
* the complete set of terms that MUST BE quoted if used as identifiers. This allows us to apply auto-quoting
|
||||
* in the metamodel based on these terms.
|
||||
*
|
||||
* Note that the standard IdentifierHelper returned by {@link #getIdentifierHelper()} already accounts for
|
||||
* auto-quoting :) yaay!
|
||||
*
|
||||
* @return Reserved words
|
||||
*/
|
||||
public Set<String> getReservedWords();
|
||||
|
||||
/**
|
||||
* Obtain the helper for dealing with JDBC {@link java.sql.SQLException} faults.
|
||||
*
|
||||
* @return This environment's helper.
|
||||
*/
|
||||
public SqlExceptionHelper getSqlExceptionHelper();
|
||||
|
||||
/**
|
||||
* Retrieve the delegate for building {@link org.hibernate.engine.jdbc.LobCreator} instances.
|
||||
*
|
||||
* @return The LobCreator builder.
|
||||
*/
|
||||
public LobCreatorBuilder getLobCreatorBuilder();
|
||||
|
||||
/**
|
||||
* Find type information for the type identified by the given "JDBC type code".
|
||||
*
|
||||
* @param jdbcTypeCode The JDBC type code.
|
||||
*
|
||||
* @return The corresponding type info.
|
||||
*/
|
||||
public TypeInfo getTypeInfoForJdbcCode(int jdbcTypeCode);
|
||||
}
|
|
@ -21,35 +21,14 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.service.schema.spi;
|
||||
package org.hibernate.service.jdbc.env.spi;
|
||||
|
||||
import org.hibernate.TruthValue;
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
import org.hibernate.engine.jdbc.LobCreationContext;
|
||||
import org.hibernate.engine.jdbc.LobCreator;
|
||||
|
||||
/**
|
||||
* Information about existing columns
|
||||
*
|
||||
* @author Christoph Sturm
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ExistingColumnMetadata {
|
||||
public ExistingTableMetadata getContainingTableMetadata();
|
||||
|
||||
public Identifier getColumnIdentifier();
|
||||
|
||||
public TruthValue getNullable();
|
||||
|
||||
public int getTypeCode();
|
||||
|
||||
public String getTypeName();
|
||||
|
||||
public int getColumnSize();
|
||||
|
||||
public int getDecimalDigits();
|
||||
public interface LobCreatorBuilder {
|
||||
LobCreator buildLobCreator(LobCreationContext lobCreationContext);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -21,16 +21,18 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.env.spi;
|
||||
package org.hibernate.service.jdbc.env.spi;
|
||||
|
||||
import org.hibernate.metamodel.spi.relational.ObjectName;
|
||||
|
||||
/**
|
||||
* Defines the support for dealing with schemas and catalogs
|
||||
* Defines support for reading and writing qualified object names to and from the database. Generally speaking
|
||||
* Hibernate itself only uses {@link #formatName}. Most times when it is "parsing" object names it is coming from
|
||||
* mappings, in which case we expect simple dot-separated syntax and apply {@link ObjectName#parse}
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface SchemaCatalogSupport {
|
||||
public interface QualifiedObjectNameSupport {
|
||||
/**
|
||||
* Performs formatting of an ObjectName to its String representation
|
||||
*
|
|
@ -21,15 +21,15 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.service.schema.spi;
|
||||
|
||||
import org.hibernate.metamodel.spi.relational.ObjectName;
|
||||
package org.hibernate.service.jdbc.env.spi;
|
||||
|
||||
/**
|
||||
* Access to information about existing sequences
|
||||
* Enum interpretation of the valid values from {@link java.sql.DatabaseMetaData#getSQLStateType()}
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ExistingSequenceMetadata {
|
||||
public ObjectName getSequenceName();
|
||||
public enum SQLStateType {
|
||||
XOpen,
|
||||
SQL99,
|
||||
UNKNOWN
|
||||
}
|
|
@ -21,7 +21,7 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.env.spi;
|
||||
package org.hibernate.service.jdbc.env.spi;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
|
@ -21,7 +21,7 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.env.spi;
|
||||
package org.hibernate.service.jdbc.env.spi;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -33,7 +33,7 @@ import org.hibernate.metamodel.spi.relational.ObjectName;
|
|||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class StandardSchemaCatalogSupportImpl implements SchemaCatalogSupport {
|
||||
public class StandardQualifiedObjectNameSupportImpl implements QualifiedObjectNameSupport {
|
||||
public static final char DEFAULT_QUOTE_START = '\'';
|
||||
public static final char DEFAULT_QUOTE_END = '\'';
|
||||
public static final String DEFAULT_CATALOG_SEPARATOR = ".";
|
||||
|
@ -45,7 +45,7 @@ public class StandardSchemaCatalogSupportImpl implements SchemaCatalogSupport {
|
|||
|
||||
private final Pattern splitPattern;
|
||||
|
||||
public StandardSchemaCatalogSupportImpl(
|
||||
public StandardQualifiedObjectNameSupportImpl(
|
||||
String catalogSeparator,
|
||||
boolean catalogAfterName,
|
||||
char quotedStart,
|
||||
|
@ -60,19 +60,19 @@ public class StandardSchemaCatalogSupportImpl implements SchemaCatalogSupport {
|
|||
: Pattern.compile( "[\\." + catalogSeparator + "]" );
|
||||
}
|
||||
|
||||
public StandardSchemaCatalogSupportImpl() {
|
||||
public StandardQualifiedObjectNameSupportImpl() {
|
||||
this( DEFAULT_CATALOG_SEPARATOR, false, DEFAULT_QUOTE_START, DEFAULT_QUOTE_END );
|
||||
}
|
||||
|
||||
public StandardSchemaCatalogSupportImpl(String catalogSeparator, boolean catalogAfterName, Dialect dialect) {
|
||||
public StandardQualifiedObjectNameSupportImpl(String catalogSeparator, boolean catalogAfterName, Dialect dialect) {
|
||||
this( catalogSeparator, catalogAfterName, dialect.openQuote(), dialect.closeQuote() );
|
||||
}
|
||||
|
||||
public StandardSchemaCatalogSupportImpl(Dialect dialect) {
|
||||
public StandardQualifiedObjectNameSupportImpl(Dialect dialect) {
|
||||
this( DEFAULT_CATALOG_SEPARATOR, false, dialect );
|
||||
}
|
||||
|
||||
public StandardSchemaCatalogSupportImpl(String catalogSeparator, boolean catalogAfterName) {
|
||||
public StandardQualifiedObjectNameSupportImpl(String catalogSeparator, boolean catalogAfterName) {
|
||||
this( catalogSeparator, catalogAfterName, DEFAULT_QUOTE_START, DEFAULT_QUOTE_END );
|
||||
}
|
||||
|
|
@ -25,15 +25,17 @@ package org.hibernate.service.schema.internal;
|
|||
|
||||
import org.hibernate.TruthValue;
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
import org.hibernate.service.schema.spi.ExistingColumnMetadata;
|
||||
import org.hibernate.service.schema.spi.ExistingTableMetadata;
|
||||
import org.hibernate.service.schema.spi.ColumnInformation;
|
||||
import org.hibernate.service.schema.spi.TableInformation;
|
||||
|
||||
/**
|
||||
* JDBC column metadata
|
||||
*
|
||||
* @author Christoph Sturm
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ExistingColumnMetadataImpl implements ExistingColumnMetadata {
|
||||
private final ExistingTableMetadata containingTableMetadata;
|
||||
public class ColumnInformationImpl implements ColumnInformation {
|
||||
private final TableInformation containingTableInformation;
|
||||
private final Identifier columnIdentifier;
|
||||
|
||||
private final int typeCode;
|
||||
|
@ -42,15 +44,15 @@ public class ExistingColumnMetadataImpl implements ExistingColumnMetadata {
|
|||
private final int decimalDigits;
|
||||
private final TruthValue nullable;
|
||||
|
||||
public ExistingColumnMetadataImpl(
|
||||
ExistingTableMetadata containingTableMetadata,
|
||||
public ColumnInformationImpl(
|
||||
TableInformation containingTableInformation,
|
||||
Identifier columnIdentifier,
|
||||
int typeCode,
|
||||
String typeName,
|
||||
int columnSize,
|
||||
int decimalDigits,
|
||||
TruthValue nullable) {
|
||||
this.containingTableMetadata = containingTableMetadata;
|
||||
this.containingTableInformation = containingTableInformation;
|
||||
this.columnIdentifier = columnIdentifier;
|
||||
this.typeCode = typeCode;
|
||||
this.typeName = typeName;
|
||||
|
@ -60,8 +62,8 @@ public class ExistingColumnMetadataImpl implements ExistingColumnMetadata {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ExistingTableMetadata getContainingTableMetadata() {
|
||||
return containingTableMetadata;
|
||||
public TableInformation getContainingTableInformation() {
|
||||
return containingTableInformation;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -95,7 +97,7 @@ public class ExistingColumnMetadataImpl implements ExistingColumnMetadata {
|
|||
}
|
||||
|
||||
public String toString() {
|
||||
return "ExistingColumnMetadata(" + columnIdentifier + ')';
|
||||
return "ColumnInformation(" + columnIdentifier + ')';
|
||||
}
|
||||
|
||||
}
|
|
@ -31,25 +31,25 @@ import java.util.Map;
|
|||
import java.util.StringTokenizer;
|
||||
|
||||
import org.hibernate.TruthValue;
|
||||
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.service.jdbc.env.spi.IdentifierHelper;
|
||||
import org.hibernate.service.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
import org.hibernate.metamodel.spi.relational.ObjectName;
|
||||
import org.hibernate.metamodel.spi.relational.Schema;
|
||||
import org.hibernate.service.schema.spi.ExistingColumnMetadata;
|
||||
import org.hibernate.service.schema.spi.ExistingDatabaseMetaData;
|
||||
import org.hibernate.service.schema.spi.ExistingSequenceMetadata;
|
||||
import org.hibernate.service.schema.spi.ExistingTableMetadata;
|
||||
import org.hibernate.service.schema.spi.ColumnInformation;
|
||||
import org.hibernate.service.schema.spi.DatabaseInformation;
|
||||
import org.hibernate.service.schema.spi.SequenceInformation;
|
||||
import org.hibernate.service.schema.spi.TableInformation;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ExistingDatabaseMetaDataImpl implements ExistingDatabaseMetaData {
|
||||
public class DatabaseInformationImpl implements DatabaseInformation {
|
||||
private final JdbcEnvironment jdbcEnvironment;
|
||||
private final DatabaseMetaData databaseMetaData;
|
||||
|
||||
private final Map<ObjectName,ExistingTableMetadataImpl> tables = new HashMap<ObjectName, ExistingTableMetadataImpl>();
|
||||
private final Map<ObjectName,ExistingSequenceMetadata> sequences;
|
||||
private final Map<ObjectName,TableInformationImpl> tables = new HashMap<ObjectName, TableInformationImpl>();
|
||||
private final Map<ObjectName,SequenceInformation> sequences;
|
||||
|
||||
public static Builder builder(JdbcEnvironment jdbcEnvironment, DatabaseMetaData databaseMetaData) {
|
||||
try {
|
||||
|
@ -60,7 +60,7 @@ public class ExistingDatabaseMetaDataImpl implements ExistingDatabaseMetaData {
|
|||
}
|
||||
}
|
||||
|
||||
private ExistingDatabaseMetaDataImpl(JdbcEnvironment jdbcEnvironment, DatabaseMetaData databaseMetaData) throws SQLException {
|
||||
private DatabaseInformationImpl(JdbcEnvironment jdbcEnvironment, DatabaseMetaData databaseMetaData) throws SQLException {
|
||||
this.jdbcEnvironment = jdbcEnvironment;
|
||||
this.databaseMetaData = databaseMetaData;
|
||||
this.sequences = loadSequenceMetadataMap();
|
||||
|
@ -91,30 +91,31 @@ public class ExistingDatabaseMetaDataImpl implements ExistingDatabaseMetaData {
|
|||
);
|
||||
final ObjectName tableName = new ObjectName( catalogIdentifier, schemaIdentifier, tableIdentifier );
|
||||
// make sure it does not already exist...
|
||||
ExistingTableMetadataImpl tableMetadata = tables.get( tableName );
|
||||
TableInformationImpl tableMetadata = tables.get( tableName );
|
||||
if ( tableMetadata != null ) {
|
||||
throw new IllegalStateException( "Table already found on parsing database metadata [" + tableName + "]" );
|
||||
}
|
||||
|
||||
tableMetadata = new ExistingTableMetadataImpl( this, tableName );
|
||||
tableMetadata = new TableInformationImpl( this, tableName );
|
||||
tables.put( toMapKey( tableName ), tableMetadata );
|
||||
}
|
||||
}
|
||||
|
||||
private Map<ObjectName,ExistingSequenceMetadata> loadSequenceMetadataMap() throws SQLException {
|
||||
Map<ObjectName,ExistingSequenceMetadata> sequences = new HashMap<ObjectName, ExistingSequenceMetadata>();
|
||||
final Iterable<ExistingSequenceMetadata> sequenceMetadatas =
|
||||
jdbcEnvironment.getExistingSequenceMetadataExtractor().extractMetadata( databaseMetaData );
|
||||
private Map<ObjectName,SequenceInformation> loadSequenceMetadataMap() throws SQLException {
|
||||
Map<ObjectName,SequenceInformation> sequences = new HashMap<ObjectName, SequenceInformation>();
|
||||
// todo : temporary impl!
|
||||
final Iterable<SequenceInformation> sequenceMetadatas =
|
||||
new TemporarySequenceInformationExtractor( jdbcEnvironment ).extractMetadata( databaseMetaData );
|
||||
if ( sequenceMetadatas != null ) {
|
||||
for ( ExistingSequenceMetadata sequenceMetadata :sequenceMetadatas ) {
|
||||
sequences.put( toMapKey( sequenceMetadata.getSequenceName() ), sequenceMetadata );
|
||||
for ( SequenceInformation sequenceInformation :sequenceMetadatas ) {
|
||||
sequences.put( toMapKey( sequenceInformation.getSequenceName() ), sequenceInformation );
|
||||
}
|
||||
}
|
||||
return sequences;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExistingTableMetadata getTableMetadata(ObjectName tableName) {
|
||||
public TableInformation getTableInformation(ObjectName tableName) {
|
||||
return tables.get( toMapKey( tableName ) );
|
||||
}
|
||||
|
||||
|
@ -144,18 +145,18 @@ public class ExistingDatabaseMetaDataImpl implements ExistingDatabaseMetaData {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ExistingSequenceMetadata getSequenceMetadata(ObjectName sequenceName) {
|
||||
public SequenceInformation getSequenceInformation(ObjectName sequenceName) {
|
||||
return sequences.get( toMapKey( sequenceName ) );
|
||||
}
|
||||
|
||||
public Map<Identifier, ExistingColumnMetadata> getColumnMetadata(ExistingTableMetadata tableMetadata) {
|
||||
final Map<Identifier, ExistingColumnMetadata> results = new HashMap<Identifier, ExistingColumnMetadata>();
|
||||
public Map<Identifier, ColumnInformation> getColumnMetadata(TableInformation tableInformation) {
|
||||
final Map<Identifier, ColumnInformation> results = new HashMap<Identifier, ColumnInformation>();
|
||||
|
||||
try {
|
||||
ResultSet resultSet = databaseMetaData.getColumns(
|
||||
identifierHelper().toMetaDataCatalogName( tableMetadata.getName().getCatalog() ),
|
||||
identifierHelper().toMetaDataSchemaName( tableMetadata.getName().getSchema() ),
|
||||
identifierHelper().toMetaDataObjectName( tableMetadata.getName().getName() ),
|
||||
identifierHelper().toMetaDataCatalogName( tableInformation.getName().getCatalog() ),
|
||||
identifierHelper().toMetaDataSchemaName( tableInformation.getName().getSchema() ),
|
||||
identifierHelper().toMetaDataObjectName( tableInformation.getName().getName() ),
|
||||
"%"
|
||||
);
|
||||
|
||||
|
@ -171,8 +172,8 @@ public class ExistingDatabaseMetaDataImpl implements ExistingDatabaseMetaData {
|
|||
continue;
|
||||
}
|
||||
|
||||
final ExistingColumnMetadataImpl meta = new ExistingColumnMetadataImpl(
|
||||
tableMetadata,
|
||||
final ColumnInformationImpl meta = new ColumnInformationImpl(
|
||||
tableInformation,
|
||||
columnIdentifier,
|
||||
resultSet.getInt( "DATA_TYPE" ),
|
||||
new StringTokenizer( resultSet.getString( "TYPE_NAME" ), "() " ).nextToken(),
|
||||
|
@ -190,16 +191,16 @@ public class ExistingDatabaseMetaDataImpl implements ExistingDatabaseMetaData {
|
|||
catch (SQLException e) {
|
||||
throw jdbcEnvironment.getSqlExceptionHelper().convert(
|
||||
e,
|
||||
"Error accessing column metadata: " + tableMetadata.getName().toString()
|
||||
"Error accessing column metadata: " + tableInformation.getName().toString()
|
||||
);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public Map<Identifier, ExistingForeignKeyMetadataImpl> getForeignKeyMetadata(ExistingTableMetadataImpl tableMetadata) {
|
||||
final Map<Identifier, ExistingForeignKeyMetadataImpl.Builder> fkBuilders
|
||||
= new HashMap<Identifier, ExistingForeignKeyMetadataImpl.Builder>();
|
||||
public Map<Identifier, ForeignKeyInformationImpl> getForeignKeyMetadata(TableInformationImpl tableMetadata) {
|
||||
final Map<Identifier, ForeignKeyInformationImpl.Builder> fkBuilders
|
||||
= new HashMap<Identifier, ForeignKeyInformationImpl.Builder>();
|
||||
|
||||
try {
|
||||
ResultSet resultSet = databaseMetaData.getImportedKeys(
|
||||
|
@ -214,15 +215,15 @@ public class ExistingDatabaseMetaDataImpl implements ExistingDatabaseMetaData {
|
|||
while ( resultSet.next() ) {
|
||||
// IMPL NOTE : intentionally build the builder early!
|
||||
final Identifier fkIdentifier = Identifier.toIdentifier( resultSet.getString( "FK_NAME" ) );
|
||||
ExistingForeignKeyMetadataImpl.Builder fkBuilder = fkBuilders.get( fkIdentifier );
|
||||
ForeignKeyInformationImpl.Builder fkBuilder = fkBuilders.get( fkIdentifier );
|
||||
if ( fkBuilder == null ) {
|
||||
fkBuilder = ExistingForeignKeyMetadataImpl.builder( fkIdentifier );
|
||||
fkBuilder = ForeignKeyInformationImpl.builder( fkIdentifier );
|
||||
fkBuilders.put( fkIdentifier, fkBuilder );
|
||||
}
|
||||
|
||||
final ObjectName incomingPkTableName = extractKeyTableName( resultSet, "PK" );
|
||||
|
||||
final ExistingTableMetadataImpl pkTableMetadata = tables.get( incomingPkTableName );
|
||||
final TableInformationImpl pkTableMetadata = tables.get( incomingPkTableName );
|
||||
if ( pkTableMetadata == 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
|
||||
|
@ -235,8 +236,8 @@ public class ExistingDatabaseMetaDataImpl implements ExistingDatabaseMetaData {
|
|||
final Identifier pkColumnIdentifier = Identifier.toIdentifier( resultSet.getString( "PKCOLUMN_NAME" ) );
|
||||
|
||||
fkBuilder.addColumnMapping(
|
||||
tableMetadata.getColumnMetadata( fkColumnIdentifier ),
|
||||
pkTableMetadata.getColumnMetadata( pkColumnIdentifier )
|
||||
tableMetadata.getColumnInformation( fkColumnIdentifier ),
|
||||
pkTableMetadata.getColumnInformation( pkColumnIdentifier )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -251,9 +252,9 @@ public class ExistingDatabaseMetaDataImpl implements ExistingDatabaseMetaData {
|
|||
);
|
||||
}
|
||||
|
||||
final Map<Identifier, ExistingForeignKeyMetadataImpl> fks = new HashMap<Identifier, ExistingForeignKeyMetadataImpl>();
|
||||
for ( ExistingForeignKeyMetadataImpl.Builder fkBuilder : fkBuilders.values() ) {
|
||||
ExistingForeignKeyMetadataImpl fk = fkBuilder.build();
|
||||
final Map<Identifier, ForeignKeyInformationImpl> fks = new HashMap<Identifier, ForeignKeyInformationImpl>();
|
||||
for ( ForeignKeyInformationImpl.Builder fkBuilder : fkBuilders.values() ) {
|
||||
ForeignKeyInformationImpl fk = fkBuilder.build();
|
||||
fks.put( fk.getForeignKeyIdentifier(), fk );
|
||||
}
|
||||
return fks;
|
||||
|
@ -285,14 +286,14 @@ public class ExistingDatabaseMetaDataImpl implements ExistingDatabaseMetaData {
|
|||
public Builder prepareCatalogAndSchema(Schema.Name schemaName);
|
||||
public Builder prepareCatalog(Identifier catalog);
|
||||
public Builder prepareSchema(Identifier schema);
|
||||
public ExistingDatabaseMetaData build();
|
||||
public DatabaseInformation build();
|
||||
}
|
||||
|
||||
private static class BuilderImpl implements Builder {
|
||||
private final ExistingDatabaseMetaDataImpl it;
|
||||
private final DatabaseInformationImpl it;
|
||||
|
||||
public BuilderImpl(JdbcEnvironment jdbcEnvironment, DatabaseMetaData databaseMetaData) throws SQLException {
|
||||
it = new ExistingDatabaseMetaDataImpl( jdbcEnvironment, databaseMetaData );
|
||||
it = new DatabaseInformationImpl( jdbcEnvironment, databaseMetaData );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -355,7 +356,7 @@ public class ExistingDatabaseMetaDataImpl implements ExistingDatabaseMetaData {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ExistingDatabaseMetaData build() {
|
||||
public DatabaseInformation build() {
|
||||
return it;
|
||||
}
|
||||
}
|
|
@ -27,18 +27,18 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
import org.hibernate.service.schema.spi.ExistingColumnMetadata;
|
||||
import org.hibernate.service.schema.spi.ExistingForeignKeyMetadata;
|
||||
import org.hibernate.service.schema.spi.ColumnInformation;
|
||||
import org.hibernate.service.schema.spi.ForeignKeyInformation;
|
||||
import org.hibernate.service.schema.spi.SchemaManagementException;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ExistingForeignKeyMetadataImpl implements ExistingForeignKeyMetadata {
|
||||
public class ForeignKeyInformationImpl implements ForeignKeyInformation {
|
||||
private final Identifier fkIdentifier;
|
||||
private final List<ColumnReferenceMapping> columnMappingList;
|
||||
|
||||
public ExistingForeignKeyMetadataImpl(
|
||||
public ForeignKeyInformationImpl(
|
||||
Identifier fkIdentifier,
|
||||
List<ColumnReferenceMapping> columnMappingList) {
|
||||
this.fkIdentifier = fkIdentifier;
|
||||
|
@ -67,38 +67,38 @@ public class ExistingForeignKeyMetadataImpl implements ExistingForeignKeyMetadat
|
|||
this.fkIdentifier = fkIdentifier;
|
||||
}
|
||||
|
||||
public Builder addColumnMapping(ExistingColumnMetadata referencing, ExistingColumnMetadata referenced) {
|
||||
public Builder addColumnMapping(ColumnInformation referencing, ColumnInformation referenced) {
|
||||
columnMappingList.add( new ColumnReferenceMappingImpl( referencing, referenced ) );
|
||||
return this;
|
||||
}
|
||||
|
||||
public ExistingForeignKeyMetadataImpl build() {
|
||||
public ForeignKeyInformationImpl build() {
|
||||
if ( columnMappingList.isEmpty() ) {
|
||||
throw new SchemaManagementException(
|
||||
"Attempt to resolve foreign key metadata from JDBC metadata failed to find " +
|
||||
"column mappings for foreign key named [" + fkIdentifier.getText() + "]"
|
||||
);
|
||||
}
|
||||
return new ExistingForeignKeyMetadataImpl( fkIdentifier, columnMappingList );
|
||||
return new ForeignKeyInformationImpl( fkIdentifier, columnMappingList );
|
||||
}
|
||||
}
|
||||
|
||||
public static class ColumnReferenceMappingImpl implements ColumnReferenceMapping {
|
||||
private final ExistingColumnMetadata referencing;
|
||||
private final ExistingColumnMetadata referenced;
|
||||
private final ColumnInformation referencing;
|
||||
private final ColumnInformation referenced;
|
||||
|
||||
public ColumnReferenceMappingImpl(ExistingColumnMetadata referencing, ExistingColumnMetadata referenced) {
|
||||
public ColumnReferenceMappingImpl(ColumnInformation referencing, ColumnInformation referenced) {
|
||||
this.referencing = referencing;
|
||||
this.referenced = referenced;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExistingColumnMetadata getReferencingColumnMetadata() {
|
||||
public ColumnInformation getReferencingColumnMetadata() {
|
||||
return referencing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExistingColumnMetadata getReferencedColumnMetadata() {
|
||||
public ColumnInformation getReferencedColumnMetadata() {
|
||||
return referenced;
|
||||
}
|
||||
}
|
|
@ -27,9 +27,9 @@ import org.hibernate.metamodel.spi.relational.Database;
|
|||
import org.hibernate.metamodel.spi.relational.Schema;
|
||||
import org.hibernate.metamodel.spi.relational.Sequence;
|
||||
import org.hibernate.metamodel.spi.relational.Table;
|
||||
import org.hibernate.service.schema.spi.ExistingDatabaseMetaData;
|
||||
import org.hibernate.service.schema.spi.ExistingSequenceMetadata;
|
||||
import org.hibernate.service.schema.spi.ExistingTableMetadata;
|
||||
import org.hibernate.service.schema.spi.DatabaseInformation;
|
||||
import org.hibernate.service.schema.spi.SequenceInformation;
|
||||
import org.hibernate.service.schema.spi.TableInformation;
|
||||
import org.hibernate.service.schema.spi.SchemaValidator;
|
||||
|
||||
/**
|
||||
|
@ -37,31 +37,31 @@ import org.hibernate.service.schema.spi.SchemaValidator;
|
|||
*/
|
||||
public class SchemaValidatorImpl implements SchemaValidator {
|
||||
@Override
|
||||
public void doValidation(Database database, ExistingDatabaseMetaData existingDatabaseMetaData) {
|
||||
public void doValidation(Database database, DatabaseInformation databaseInformation) {
|
||||
for ( Schema schema : database.getSchemas() ) {
|
||||
for ( Table table : schema.getTables() ) {
|
||||
final ExistingTableMetadata existingTableMetadata = existingDatabaseMetaData.getTableMetadata(
|
||||
final TableInformation tableInformation = databaseInformation.getTableInformation(
|
||||
table.getTableName()
|
||||
);
|
||||
validateTable( table, existingTableMetadata );
|
||||
validateTable( table, tableInformation );
|
||||
}
|
||||
}
|
||||
|
||||
for ( Schema schema : database.getSchemas() ) {
|
||||
for ( Sequence sequence : schema.getSequences() ) {
|
||||
final ExistingSequenceMetadata existingSequenceMetadata = existingDatabaseMetaData.getSequenceMetadata(
|
||||
final SequenceInformation sequenceInformation = databaseInformation.getSequenceInformation(
|
||||
sequence.getName()
|
||||
);
|
||||
validateSequence( sequence, existingSequenceMetadata );
|
||||
validateSequence( sequence, sequenceInformation );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void validateTable(Table table, ExistingTableMetadata existingTableMetadata) {
|
||||
private void validateTable(Table table, TableInformation tableInformation) {
|
||||
//To change body of created methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
private void validateSequence(Sequence sequence, ExistingSequenceMetadata existingSequenceMetadata) {
|
||||
private void validateSequence(Sequence sequence, SequenceInformation sequenceInformation) {
|
||||
//To change body of created methods use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,17 +24,17 @@
|
|||
package org.hibernate.service.schema.internal;
|
||||
|
||||
import org.hibernate.metamodel.spi.relational.ObjectName;
|
||||
import org.hibernate.service.schema.spi.ExistingSequenceMetadata;
|
||||
import org.hibernate.service.schema.spi.SequenceInformation;
|
||||
|
||||
/**
|
||||
* For now we only collect sequence name. If all databases support it, would really like to see INCREMENT here as well.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ExistingSequenceMetadataImpl implements ExistingSequenceMetadata {
|
||||
public class SequenceInformationImpl implements SequenceInformation {
|
||||
private ObjectName sequenceName;
|
||||
|
||||
public ExistingSequenceMetadataImpl(ObjectName sequenceName) {
|
||||
public SequenceInformationImpl(ObjectName sequenceName) {
|
||||
this.sequenceName = sequenceName;
|
||||
}
|
||||
|
|
@ -25,12 +25,11 @@ package org.hibernate.service.schema.internal;
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.metamodel.spi.relational.ForeignKey;
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
import org.hibernate.metamodel.spi.relational.ObjectName;
|
||||
import org.hibernate.service.schema.spi.ExistingColumnMetadata;
|
||||
import org.hibernate.service.schema.spi.ExistingForeignKeyMetadata;
|
||||
import org.hibernate.service.schema.spi.ExistingTableMetadata;
|
||||
import org.hibernate.service.schema.spi.ColumnInformation;
|
||||
import org.hibernate.service.schema.spi.ForeignKeyInformation;
|
||||
import org.hibernate.service.schema.spi.TableInformation;
|
||||
import org.hibernate.tool.hbm2ddl.IndexMetadata;
|
||||
|
||||
/**
|
||||
|
@ -40,14 +39,14 @@ import org.hibernate.tool.hbm2ddl.IndexMetadata;
|
|||
* @author Max Rydahl Andersen
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ExistingTableMetadataImpl implements ExistingTableMetadata {
|
||||
private final ExistingDatabaseMetaDataImpl database;
|
||||
public class TableInformationImpl implements TableInformation {
|
||||
private final DatabaseInformationImpl database;
|
||||
private final ObjectName tableName;
|
||||
private final Map<Identifier, ExistingColumnMetadata> columns;
|
||||
private final Map<Identifier, ColumnInformation> columns;
|
||||
|
||||
private Map<Identifier, ExistingForeignKeyMetadataImpl> foreignKeys;
|
||||
private Map<Identifier, ForeignKeyInformationImpl> foreignKeys;
|
||||
|
||||
public ExistingTableMetadataImpl(ExistingDatabaseMetaDataImpl database, ObjectName tableName) {
|
||||
public TableInformationImpl(DatabaseInformationImpl database, ObjectName tableName) {
|
||||
this.database = database;
|
||||
this.tableName = tableName;
|
||||
this.columns = database.getColumnMetadata( this );
|
||||
|
@ -59,12 +58,12 @@ public class ExistingTableMetadataImpl implements ExistingTableMetadata {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ExistingColumnMetadata getColumnMetadata(Identifier columnIdentifier) {
|
||||
public ColumnInformation getColumnInformation(Identifier columnIdentifier) {
|
||||
return columns.get( columnIdentifier );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExistingForeignKeyMetadata getForeignKeyMetadata(Identifier fkIdentifier) {
|
||||
public ForeignKeyInformation getForeignKeyInformation(Identifier fkIdentifier) {
|
||||
if ( foreignKeys == null ) {
|
||||
foreignKeys = database.getForeignKeyMetadata( this );
|
||||
}
|
||||
|
@ -72,20 +71,14 @@ public class ExistingTableMetadataImpl implements ExistingTableMetadata {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ExistingForeignKeyMetadata getForeignKeyMetadata(ForeignKey fk) {
|
||||
// Iterator it = foreignKeys.values().iterator();
|
||||
// while ( it.hasNext() ) {
|
||||
// ForeignKeyMetadata existingFk = ( ForeignKeyMetadata ) it.next();
|
||||
// if ( existingFk.matches( fk ) ) {
|
||||
// return existingFk;
|
||||
// }
|
||||
// }
|
||||
return null;
|
||||
@SuppressWarnings("unchecked")
|
||||
public Iterable getForeignKeyInformations() {
|
||||
return foreignKeys.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ExistingTableMetadataImpl(" + tableName.toString() + ')';
|
||||
return "TableInformationImpl(" + tableName.toString() + ')';
|
||||
}
|
||||
|
||||
@Override
|
|
@ -21,7 +21,7 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.env.internal;
|
||||
package org.hibernate.service.schema.internal;
|
||||
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.ResultSet;
|
||||
|
@ -31,24 +31,24 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import org.hibernate.metamodel.spi.relational.ObjectName;
|
||||
import org.hibernate.service.schema.internal.ExistingSequenceMetadataImpl;
|
||||
import org.hibernate.service.schema.spi.ExistingSequenceMetadata;
|
||||
import org.hibernate.service.schema.spi.ExistingSequenceMetadataExtractor;
|
||||
import org.hibernate.service.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.service.schema.spi.SequenceInformation;
|
||||
import org.hibernate.service.schema.spi.SequenceInformationExtractor;
|
||||
|
||||
/**
|
||||
* Temporary implementation that works for H2.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class TemporaryExistingSequenceMetadataExtractor implements ExistingSequenceMetadataExtractor {
|
||||
private final JdbcEnvironmentImpl jdbcEnvironment;
|
||||
public class TemporarySequenceInformationExtractor implements SequenceInformationExtractor {
|
||||
private final JdbcEnvironment jdbcEnvironment;
|
||||
|
||||
public TemporaryExistingSequenceMetadataExtractor(JdbcEnvironmentImpl jdbcEnvironment) {
|
||||
public TemporarySequenceInformationExtractor(JdbcEnvironment jdbcEnvironment) {
|
||||
this.jdbcEnvironment = jdbcEnvironment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<ExistingSequenceMetadata> extractMetadata(DatabaseMetaData databaseMetaData) throws SQLException {
|
||||
public Iterable<SequenceInformation> extractMetadata(DatabaseMetaData databaseMetaData) throws SQLException {
|
||||
Statement statement = databaseMetaData.getConnection().createStatement();
|
||||
try {
|
||||
ResultSet resultSet = statement.executeQuery(
|
||||
|
@ -56,10 +56,10 @@ public class TemporaryExistingSequenceMetadataExtractor implements ExistingSeque
|
|||
"from information_schema.sequences"
|
||||
);
|
||||
try {
|
||||
final List<ExistingSequenceMetadata> sequenceMetadataList = new ArrayList<ExistingSequenceMetadata>();
|
||||
final List<SequenceInformation> sequenceInformationList = new ArrayList<SequenceInformation>();
|
||||
while ( resultSet.next() ) {
|
||||
sequenceMetadataList.add(
|
||||
new ExistingSequenceMetadataImpl(
|
||||
sequenceInformationList.add(
|
||||
new SequenceInformationImpl(
|
||||
new ObjectName(
|
||||
jdbcEnvironment.getIdentifierHelper().fromMetaDataCatalogName(
|
||||
resultSet.getString(
|
||||
|
@ -80,7 +80,7 @@ public class TemporaryExistingSequenceMetadataExtractor implements ExistingSeque
|
|||
)
|
||||
);
|
||||
}
|
||||
return sequenceMetadataList;
|
||||
return sequenceInformationList;
|
||||
}
|
||||
finally {
|
||||
try {
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.service.schema.spi;
|
||||
|
||||
import org.hibernate.TruthValue;
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
|
||||
/**
|
||||
* Provides access to information about existing table columns
|
||||
*
|
||||
* @author Christoph Sturm
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ColumnInformation {
|
||||
/**
|
||||
* Access to the containing table.
|
||||
*
|
||||
* @return The containing table information
|
||||
*/
|
||||
public TableInformation getContainingTableInformation();
|
||||
|
||||
/**
|
||||
* The simple (not qualified) column name.
|
||||
*
|
||||
* @return The column simple identifier.
|
||||
*/
|
||||
public Identifier getColumnIdentifier();
|
||||
|
||||
/**
|
||||
* Is the column nullable. The database is allowed to report unknown, hence the use of TruthValue
|
||||
*
|
||||
* @return nullability.
|
||||
*/
|
||||
public TruthValue getNullable();
|
||||
|
||||
/**
|
||||
* The JDBC type-code.
|
||||
*
|
||||
* @return JDBC type-code
|
||||
*/
|
||||
public int getTypeCode();
|
||||
|
||||
/**
|
||||
* The database specific type name.
|
||||
*
|
||||
* @return Type name
|
||||
*/
|
||||
public String getTypeName();
|
||||
|
||||
// todo : wrap these in org.hibernate.metamodel.spi.relational.Size ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/**
|
||||
* The column size (length).
|
||||
*
|
||||
* @return The column length
|
||||
*/
|
||||
public int getColumnSize();
|
||||
|
||||
/**
|
||||
* The precision, for numeric types
|
||||
*
|
||||
* @return The numeric precision
|
||||
*/
|
||||
public int getDecimalDigits();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -23,27 +23,31 @@
|
|||
*/
|
||||
package org.hibernate.service.schema.spi;
|
||||
|
||||
import org.hibernate.metamodel.spi.relational.ForeignKey;
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
import org.hibernate.metamodel.spi.relational.ObjectName;
|
||||
import org.hibernate.tool.hbm2ddl.ForeignKeyMetadata;
|
||||
import org.hibernate.tool.hbm2ddl.IndexMetadata;
|
||||
|
||||
/**
|
||||
* Provides access to information about existing schema objects (tables, sequences etc) of existing database.
|
||||
*
|
||||
* @author Christoph Sturm
|
||||
* @author Max Rydahl Andersen
|
||||
* @author Teodor Danciu
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ExistingTableMetadata {
|
||||
public ObjectName getName();
|
||||
public interface DatabaseInformation {
|
||||
/**
|
||||
* Obtain reference to the named TableInformation
|
||||
*
|
||||
* @param tableName The qualified table name
|
||||
*
|
||||
* @return The table information. May return {@code null} if not found.
|
||||
*/
|
||||
public TableInformation getTableInformation(ObjectName tableName);
|
||||
|
||||
public ExistingColumnMetadata getColumnMetadata(Identifier columnIdentifier);
|
||||
|
||||
public ExistingForeignKeyMetadata getForeignKeyMetadata(Identifier keyName);
|
||||
|
||||
public ExistingForeignKeyMetadata getForeignKeyMetadata(ForeignKey fk);
|
||||
|
||||
public IndexMetadata getIndexMetadata(Identifier indexName);
|
||||
/**
|
||||
* Obtain reference to the named SequenceInformation
|
||||
*
|
||||
* @param sequenceName The qualified sequence name
|
||||
*
|
||||
* @return The sequence information. May return {@code null} if not found.
|
||||
*/
|
||||
public SequenceInformation getSequenceInformation(ObjectName sequenceName);
|
||||
}
|
|
@ -30,7 +30,7 @@ import org.hibernate.metamodel.spi.relational.Identifier;
|
|||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ExistingForeignKeyMetadata {
|
||||
public interface ForeignKeyInformation {
|
||||
/**
|
||||
* Obtain the identifier for this FK.
|
||||
*
|
||||
|
@ -52,13 +52,13 @@ public interface ExistingForeignKeyMetadata {
|
|||
*
|
||||
* @return The referencing column.
|
||||
*/
|
||||
public ExistingColumnMetadata getReferencingColumnMetadata();
|
||||
public ColumnInformation getReferencingColumnMetadata();
|
||||
|
||||
/**
|
||||
* Obtain the information about the referenced column (the target side).
|
||||
*
|
||||
* @return The referenced column
|
||||
*/
|
||||
public ExistingColumnMetadata getReferencedColumnMetadata();
|
||||
public ColumnInformation getReferencedColumnMetadata();
|
||||
}
|
||||
}
|
|
@ -42,5 +42,5 @@ public interface SchemaMigrator {
|
|||
*
|
||||
* @throws SchemaManagementException
|
||||
*/
|
||||
public void doMigration(Database database, ExistingDatabaseMetaData existingDatabase, List<Target> targets) throws SchemaManagementException;
|
||||
public void doMigration(Database database, DatabaseInformation existingDatabase, List<Target> targets) throws SchemaManagementException;
|
||||
}
|
||||
|
|
|
@ -35,9 +35,9 @@ public interface SchemaValidator {
|
|||
* Handle schema validation requests
|
||||
*
|
||||
* @param database The current Hibernate relational model
|
||||
* @param existingDatabaseMetaData Access to the existing database information.
|
||||
* @param databaseInformation Access to the existing database information.
|
||||
*
|
||||
* @throws SchemaManagementException
|
||||
*/
|
||||
public void doValidation(Database database, ExistingDatabaseMetaData existingDatabaseMetaData) throws SchemaManagementException;
|
||||
public void doValidation(Database database, DatabaseInformation databaseInformation) throws SchemaManagementException;
|
||||
}
|
||||
|
|
|
@ -26,13 +26,18 @@ package org.hibernate.service.schema.spi;
|
|||
import org.hibernate.metamodel.spi.relational.ObjectName;
|
||||
|
||||
/**
|
||||
* Provides access to information about existing schema objects (tables, sequences etc) of existing database.
|
||||
* Access to information about existing sequences.
|
||||
*
|
||||
* For now we only support retrieving the names (for existence checking from validation). However,
|
||||
* at least INCREMENT would be valuable as well. Just need to make sure all dbs support that.
|
||||
*
|
||||
* @author Christoph Sturm
|
||||
* @author Teodor Danciu
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ExistingDatabaseMetaData {
|
||||
public ExistingTableMetadata getTableMetadata(ObjectName tableName);
|
||||
public ExistingSequenceMetadata getSequenceMetadata(ObjectName sequenceName);
|
||||
public interface SequenceInformation {
|
||||
/**
|
||||
* The qualified sequence name.
|
||||
*
|
||||
* @return The sequence name
|
||||
*/
|
||||
public ObjectName getSequenceName();
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.service.schema.spi;
|
||||
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Because JDBC (at least up to an including Java 7, JDBC 4) still does not have support for obtaining information
|
||||
* about sequences from DatabaseMetaData.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface SequenceInformationExtractor {
|
||||
/**
|
||||
* Get the information about sequences.
|
||||
*
|
||||
* @param databaseMetaData The JDBC DatabaseMetadata
|
||||
*
|
||||
* @return The extracted information about existing sequences.
|
||||
*
|
||||
* @throws SQLException Don't bother handling SQLExceptions (unless you want to), we will deal with them in the
|
||||
* caller.
|
||||
*/
|
||||
public Iterable<SequenceInformation> extractMetadata(DatabaseMetaData databaseMetaData) throws SQLException;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.service.schema.spi;
|
||||
|
||||
import org.hibernate.metamodel.spi.relational.ForeignKey;
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
import org.hibernate.metamodel.spi.relational.ObjectName;
|
||||
import org.hibernate.tool.hbm2ddl.IndexMetadata;
|
||||
|
||||
/**
|
||||
* Provides access to information about existing tables in the database
|
||||
*
|
||||
* @author Christoph Sturm
|
||||
* @author Max Rydahl Andersen
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface TableInformation {
|
||||
/**
|
||||
* Get the qualified name of the table.
|
||||
*
|
||||
* @return The qualified table name
|
||||
*/
|
||||
public ObjectName getName();
|
||||
|
||||
/**
|
||||
* Retrieve the named ColumnInformation
|
||||
*
|
||||
* @param columnIdentifier The column identifier (simple name)
|
||||
*
|
||||
* @return The matching column information. May return {@code null}
|
||||
*/
|
||||
public ColumnInformation getColumnInformation(Identifier columnIdentifier);
|
||||
|
||||
/**
|
||||
* Retrieve the named ForeignKeyInformation
|
||||
*
|
||||
* @param keyName The foreign key identifier (simple name)
|
||||
*
|
||||
* @return The matching foreign key information. May return {@code null}
|
||||
*/
|
||||
public ForeignKeyInformation getForeignKeyInformation(Identifier keyName);
|
||||
|
||||
/**
|
||||
* Obtain an iterable over all the table's defined foreign keys.
|
||||
*
|
||||
* @return The iterable.
|
||||
*/
|
||||
public Iterable<ForeignKeyInformation> getForeignKeyInformations();
|
||||
|
||||
/**
|
||||
* todo : create an IndexInformation...
|
||||
*/
|
||||
public IndexMetadata getIndexMetadata(Identifier indexName);
|
||||
}
|
|
@ -50,7 +50,7 @@ import org.hibernate.engine.jdbc.NClobImplementer;
|
|||
import org.hibernate.engine.jdbc.NonContextualLobCreator;
|
||||
import org.hibernate.engine.jdbc.WrappedBlob;
|
||||
import org.hibernate.engine.jdbc.WrappedClob;
|
||||
import org.hibernate.engine.jdbc.internal.LobCreatorBuilder;
|
||||
import org.hibernate.service.jdbc.env.internal.LobCreatorBuilderImpl;
|
||||
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
@ -65,8 +65,7 @@ public class LobCreatorTest extends org.hibernate.testing.junit4.BaseUnitTestCas
|
|||
final Connection connection = createConnectionProxy( 4, new JdbcLobBuilderImpl( true ) );
|
||||
LobCreationContext lobCreationContext = new LobCreationContextImpl( connection );
|
||||
|
||||
LobCreator lobCreator =
|
||||
new LobCreatorBuilder( new Properties(), connection )
|
||||
LobCreator lobCreator = LobCreatorBuilderImpl.makeLobCreatorBuilder( new Properties(), connection )
|
||||
.buildLobCreator( lobCreationContext );
|
||||
assertTrue( lobCreator instanceof ContextualLobCreator );
|
||||
testLobCreation( lobCreator );
|
||||
|
@ -78,8 +77,7 @@ public class LobCreatorTest extends org.hibernate.testing.junit4.BaseUnitTestCas
|
|||
final Connection connection = createConnectionProxy( 3, new JdbcLobBuilderImpl( false) );
|
||||
LobCreationContext lobCreationContext = new LobCreationContextImpl( connection );
|
||||
|
||||
LobCreator lobCreator =
|
||||
new LobCreatorBuilder( new Properties(), connection )
|
||||
LobCreator lobCreator = LobCreatorBuilderImpl.makeLobCreatorBuilder( new Properties(), connection )
|
||||
.buildLobCreator( lobCreationContext );
|
||||
assertSame( NonContextualLobCreator.INSTANCE, lobCreator );
|
||||
|
||||
|
@ -91,8 +89,7 @@ public class LobCreatorTest extends org.hibernate.testing.junit4.BaseUnitTestCas
|
|||
final Connection connection = createConnectionProxy( 4, new JdbcLobBuilderImpl( false ) );
|
||||
LobCreationContext lobCreationContext = new LobCreationContextImpl( connection );
|
||||
|
||||
LobCreator lobCreator =
|
||||
new LobCreatorBuilder( new Properties(), connection )
|
||||
LobCreator lobCreator = LobCreatorBuilderImpl.makeLobCreatorBuilder( new Properties(), connection )
|
||||
.buildLobCreator( lobCreationContext );
|
||||
assertSame( NonContextualLobCreator.INSTANCE, lobCreator );
|
||||
|
||||
|
@ -106,8 +103,7 @@ public class LobCreatorTest extends org.hibernate.testing.junit4.BaseUnitTestCas
|
|||
|
||||
Properties props = new Properties();
|
||||
props.setProperty( Environment.NON_CONTEXTUAL_LOB_CREATION, "true" );
|
||||
LobCreator lobCreator =
|
||||
new LobCreatorBuilder( props, connection )
|
||||
LobCreator lobCreator = LobCreatorBuilderImpl.makeLobCreatorBuilder( props, connection )
|
||||
.buildLobCreator( lobCreationContext );
|
||||
assertSame( NonContextualLobCreator.INSTANCE, lobCreator );
|
||||
|
||||
|
|
|
@ -24,22 +24,28 @@
|
|||
package org.hibernate.test.common;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.LobCreationContext;
|
||||
import org.hibernate.engine.jdbc.LobCreator;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.engine.jdbc.internal.ResultSetWrapperImpl;
|
||||
import org.hibernate.engine.jdbc.internal.TypeInfo;
|
||||
import org.hibernate.engine.jdbc.spi.ExtractedDatabaseMetaData;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.jdbc.spi.ResultSetWrapper;
|
||||
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||
import org.hibernate.engine.jdbc.spi.SqlStatementLogger;
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.hibernate.service.jdbc.env.internal.ExtractedDatabaseMetaDataImpl;
|
||||
import org.hibernate.service.jdbc.env.internal.LobCreatorBuilderImpl;
|
||||
import org.hibernate.service.jdbc.env.spi.ExtractedDatabaseMetaData;
|
||||
import org.hibernate.service.jdbc.env.spi.IdentifierHelper;
|
||||
import org.hibernate.service.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.service.jdbc.env.spi.LobCreatorBuilder;
|
||||
import org.hibernate.service.jdbc.env.spi.QualifiedObjectNameSupport;
|
||||
import org.hibernate.service.spi.Stoppable;
|
||||
|
||||
import org.hibernate.testing.env.ConnectionProviderBuilder;
|
||||
|
||||
|
||||
|
@ -50,11 +56,9 @@ import org.hibernate.testing.env.ConnectionProviderBuilder;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class BasicTestingJdbcServiceImpl implements JdbcServices {
|
||||
private ConnectionProvider connectionProvider;
|
||||
private Dialect dialect;
|
||||
private SqlStatementLogger sqlStatementLogger;
|
||||
private SqlExceptionHelper exceptionHelper;
|
||||
private final ExtractedDatabaseMetaData metaDataSupport = new MetaDataSupportImpl();
|
||||
private TestingJdbcEnvironmentImpl jdbcEnvironment;
|
||||
|
||||
private final SqlStatementLogger sqlStatementLogger = new SqlStatementLogger( true, false );
|
||||
private final ResultSetWrapper resultSetWrapper = ResultSetWrapperImpl.INSTANCE;
|
||||
|
||||
public void start() {
|
||||
|
@ -65,38 +69,34 @@ public class BasicTestingJdbcServiceImpl implements JdbcServices {
|
|||
}
|
||||
|
||||
public void prepare(boolean allowAggressiveRelease) {
|
||||
connectionProvider = ConnectionProviderBuilder.buildConnectionProvider( allowAggressiveRelease );
|
||||
dialect = ConnectionProviderBuilder.getCorrespondingDialect();
|
||||
sqlStatementLogger = new SqlStatementLogger( true, false );
|
||||
exceptionHelper = new SqlExceptionHelper();
|
||||
|
||||
jdbcEnvironment = new TestingJdbcEnvironmentImpl( allowAggressiveRelease );
|
||||
}
|
||||
|
||||
public void release() {
|
||||
if ( connectionProvider instanceof Stoppable ) {
|
||||
( (Stoppable) connectionProvider ).stop();
|
||||
if ( jdbcEnvironment.connectionProvider instanceof Stoppable ) {
|
||||
( (Stoppable) jdbcEnvironment.connectionProvider ).stop();
|
||||
}
|
||||
}
|
||||
|
||||
public ConnectionProvider getConnectionProvider() {
|
||||
return connectionProvider;
|
||||
return jdbcEnvironment.connectionProvider;
|
||||
}
|
||||
|
||||
public Dialect getDialect() {
|
||||
return dialect;
|
||||
return jdbcEnvironment.dialect;
|
||||
}
|
||||
|
||||
public LobCreator getLobCreator(LobCreationContext lobCreationContext) {
|
||||
return null;
|
||||
return jdbcEnvironment.getLobCreatorBuilder().buildLobCreator( lobCreationContext );
|
||||
}
|
||||
|
||||
public ResultSetWrapper getResultSetWrapper() {
|
||||
return null;
|
||||
return resultSetWrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdbcEnvironment getJdbcEnvironment() {
|
||||
return null;
|
||||
return jdbcEnvironment;
|
||||
}
|
||||
|
||||
public SqlStatementLogger getSqlStatementLogger() {
|
||||
|
@ -104,68 +104,72 @@ public class BasicTestingJdbcServiceImpl implements JdbcServices {
|
|||
}
|
||||
|
||||
public SqlExceptionHelper getSqlExceptionHelper() {
|
||||
return exceptionHelper;
|
||||
return jdbcEnvironment.exceptionHelper;
|
||||
}
|
||||
|
||||
public ExtractedDatabaseMetaData getExtractedMetaDataSupport() {
|
||||
return metaDataSupport;
|
||||
return jdbcEnvironment.extractedDatabaseMetaData;
|
||||
}
|
||||
|
||||
private static class MetaDataSupportImpl implements ExtractedDatabaseMetaData {
|
||||
@Override
|
||||
public boolean supportsRefCursors() {
|
||||
return false;
|
||||
private static class TestingJdbcEnvironmentImpl implements JdbcEnvironment {
|
||||
private final ExtractedDatabaseMetaData extractedDatabaseMetaData = new ExtractedDatabaseMetaDataImpl( this );
|
||||
private final SqlExceptionHelper exceptionHelper = new SqlExceptionHelper();
|
||||
private final LobCreatorBuilder lobCreatorBuilder = LobCreatorBuilderImpl.makeLobCreatorBuilder();
|
||||
|
||||
private ConnectionProvider connectionProvider;
|
||||
private Dialect dialect;
|
||||
|
||||
private TestingJdbcEnvironmentImpl(boolean allowAggressiveRelease) {
|
||||
connectionProvider = ConnectionProviderBuilder.buildConnectionProvider( allowAggressiveRelease );
|
||||
dialect = ConnectionProviderBuilder.getCorrespondingDialect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsNamedParameters() {
|
||||
return false;
|
||||
public Dialect getDialect() {
|
||||
return dialect;
|
||||
}
|
||||
|
||||
public boolean supportsScrollableResults() {
|
||||
return false;
|
||||
@Override
|
||||
public ExtractedDatabaseMetaData getExtractedDatabaseMetaData() {
|
||||
return extractedDatabaseMetaData;
|
||||
}
|
||||
|
||||
public boolean supportsGetGeneratedKeys() {
|
||||
return false;
|
||||
@Override
|
||||
public Identifier getCurrentCatalog() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean supportsBatchUpdates() {
|
||||
return false;
|
||||
@Override
|
||||
public Identifier getCurrentSchema() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean supportsDataDefinitionInTransaction() {
|
||||
return false;
|
||||
@Override
|
||||
public QualifiedObjectNameSupport getQualifiedObjectNameSupport() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean doesDataDefinitionCauseTransactionCommit() {
|
||||
return false;
|
||||
@Override
|
||||
public IdentifierHelper getIdentifierHelper() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Set<String> getExtraKeywords() {
|
||||
@Override
|
||||
public Set<String> getReservedWords() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
public SQLStateType getSqlStateType() {
|
||||
return SQLStateType.UNKOWN;
|
||||
@Override
|
||||
public SqlExceptionHelper getSqlExceptionHelper() {
|
||||
return exceptionHelper;
|
||||
}
|
||||
|
||||
public boolean doesLobLocatorUpdateCopy() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getConnectionSchemaName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getConnectionCatalogName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public LinkedHashSet<TypeInfo> getTypeInfoSet() {
|
||||
return null;
|
||||
@Override
|
||||
public LobCreatorBuilder getLobCreatorBuilder() {
|
||||
return lobCreatorBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeInfo getTypeInfoForJdbcCode(int jdbcTypeCode) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ package org.hibernate.test.common;
|
|||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.engine.jdbc.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.service.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.transaction.spi.TransactionEnvironment;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
|
||||
|
@ -58,4 +58,9 @@ public class JdbcConnectionAccessImpl implements JdbcConnectionAccess {
|
|||
public void releaseConnection(Connection connection) throws SQLException {
|
||||
connectionProvider.closeConnection( connection );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsAggressiveRelease() {
|
||||
return connectionProvider.supportsAggressiveRelease();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
package org.hibernate.test.common;
|
||||
|
||||
import org.hibernate.ConnectionReleaseMode;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.service.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.transaction.spi.TransactionContext;
|
||||
import org.hibernate.engine.transaction.spi.TransactionEnvironment;
|
||||
import org.hibernate.engine.transaction.spi.TransactionImplementor;
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
*/
|
||||
package org.hibernate.test.engine.jdbc.env;
|
||||
|
||||
import org.hibernate.engine.jdbc.env.spi.StandardSchemaCatalogSupportImpl;
|
||||
import org.hibernate.service.jdbc.env.spi.StandardQualifiedObjectNameSupportImpl;
|
||||
import org.hibernate.metamodel.spi.relational.ObjectName;
|
||||
|
||||
import org.junit.Test;
|
||||
|
@ -37,8 +37,8 @@ import static org.junit.Assert.assertNull;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class StandardSchemaCatalogSupportImplTest extends BaseUnitTestCase {
|
||||
private final StandardSchemaCatalogSupportImpl basic = new StandardSchemaCatalogSupportImpl();
|
||||
private final StandardSchemaCatalogSupportImpl oracle = new StandardSchemaCatalogSupportImpl( "@", true );
|
||||
private final StandardQualifiedObjectNameSupportImpl basic = new StandardQualifiedObjectNameSupportImpl();
|
||||
private final StandardQualifiedObjectNameSupportImpl oracle = new StandardQualifiedObjectNameSupportImpl( "@", true );
|
||||
|
||||
@Test
|
||||
public void testFormatName() throws Exception {
|
||||
|
|
|
@ -30,11 +30,13 @@ import java.util.Properties;
|
|||
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentImpl;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.service.ServiceRegistryBuilder;
|
||||
import org.hibernate.service.jdbc.env.internal.JdbcEnvironmentImpl;
|
||||
import org.hibernate.service.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.metamodel.spi.relational.ObjectName;
|
||||
import org.hibernate.service.schema.internal.ExistingDatabaseMetaDataImpl;
|
||||
import org.hibernate.service.schema.spi.ExistingDatabaseMetaData;
|
||||
import org.hibernate.service.schema.internal.DatabaseInformationImpl;
|
||||
import org.hibernate.service.schema.spi.DatabaseInformation;
|
||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
@ -48,12 +50,14 @@ import static org.junit.Assert.assertNotNull;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ExistingDatabaseMetaDataImplTest extends BaseUnitTestCase {
|
||||
private ServiceRegistryImplementor serviceRegistry;
|
||||
private JdbcEnvironment jdbcEnvironment;
|
||||
private Connection connection;
|
||||
|
||||
@Before
|
||||
public void prepare() throws SQLException {
|
||||
Properties props = Environment.getProperties();
|
||||
serviceRegistry = (ServiceRegistryImplementor) new ServiceRegistryBuilder().applySettings( props ).buildServiceRegistry();
|
||||
connection = DriverManager.getConnection(
|
||||
props.getProperty( Environment.URL ),
|
||||
props.getProperty( Environment.USER ),
|
||||
|
@ -67,7 +71,7 @@ public class ExistingDatabaseMetaDataImplTest extends BaseUnitTestCase {
|
|||
connection.createStatement().execute( "CREATE SEQUENCE seq1" );
|
||||
connection.createStatement().execute( "CREATE SEQUENCE db1.another_schema.seq2" );
|
||||
|
||||
jdbcEnvironment = new JdbcEnvironmentImpl( connection.getMetaData(), Dialect.getDialect( props ), props );
|
||||
jdbcEnvironment = new JdbcEnvironmentImpl( serviceRegistry, Dialect.getDialect( props ), connection.getMetaData() );
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -79,27 +83,30 @@ public class ExistingDatabaseMetaDataImplTest extends BaseUnitTestCase {
|
|||
catch (SQLException ignore) {
|
||||
}
|
||||
}
|
||||
if ( serviceRegistry != null ) {
|
||||
ServiceRegistryBuilder.destroy( serviceRegistry );
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTableMetadata() throws Exception {
|
||||
ExistingDatabaseMetaData databaseMetaData =
|
||||
ExistingDatabaseMetaDataImpl.builder( jdbcEnvironment, connection.getMetaData() ).prepareAll().build();
|
||||
DatabaseInformation databaseMetaData =
|
||||
DatabaseInformationImpl.builder( jdbcEnvironment, connection.getMetaData() ).prepareAll().build();
|
||||
|
||||
ObjectName name = new ObjectName( null, null, "t1" );
|
||||
assertNotNull( databaseMetaData.getTableMetadata( name ) );
|
||||
assertNotNull( databaseMetaData.getTableInformation( name ) );
|
||||
|
||||
name = new ObjectName( null, "another_schema", "t2" );
|
||||
assertNotNull( databaseMetaData.getTableMetadata( name ) );
|
||||
assertNotNull( databaseMetaData.getTableInformation( name ) );
|
||||
|
||||
name = new ObjectName( null, null, "seq1" );
|
||||
assertNotNull( databaseMetaData.getSequenceMetadata( name ) );
|
||||
assertNotNull( databaseMetaData.getSequenceInformation( name ) );
|
||||
|
||||
name = new ObjectName( null, "another_schema", "seq2" );
|
||||
assertNotNull( databaseMetaData.getSequenceMetadata( name ) );
|
||||
assertNotNull( databaseMetaData.getSequenceInformation( name ) );
|
||||
|
||||
// knowing if identifiers coming back from the database are quoted is all dicked up...
|
||||
// see org.hibernate.engine.jdbc.env.internal.NormalizingIdentifierHelperImpl
|
||||
// see org.hibernate.service.jdbc.env.internal.NormalizingIdentifierHelperImpl
|
||||
//
|
||||
// surely JDBC has a better way to determine this right?
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ import org.hibernate.ScrollMode;
|
|||
import org.hibernate.ScrollableResults;
|
||||
import org.hibernate.cache.spi.CacheKey;
|
||||
import org.hibernate.collection.spi.PersistentCollection;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.service.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.query.spi.sql.NativeSQLQuerySpecification;
|
||||
import org.hibernate.engine.spi.EntityKey;
|
||||
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||
|
|
Loading…
Reference in New Issue