HHH-7616 - Integrate hibernate-tools JDBCBinder into hibernate-orm
This commit is contained in:
parent
9914b17010
commit
5dd5e251ba
|
@ -179,11 +179,11 @@ public class Identifier {
|
|||
Identifier that = (Identifier) o;
|
||||
|
||||
return isQuoted == that.isQuoted
|
||||
&& text.equals( that.text );
|
||||
&& isQuoted ? text.equals( that.text ) : text.equalsIgnoreCase( that.text );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return text.hashCode();
|
||||
return isQuoted ? text.hashCode() : text.toUpperCase().hashCode();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,8 +31,8 @@ import java.util.Set;
|
|||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.tool.schema.spi.ColumnInformation;
|
||||
import org.hibernate.tool.schema.spi.TableInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.ColumnInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.TableInformation;
|
||||
|
||||
/**
|
||||
* Models the concept of a relational <tt>TABLE</tt> (or <tt>VIEW</tt>).
|
||||
|
@ -201,7 +201,7 @@ public class Table extends AbstractTableSpecification implements Exportable {
|
|||
}
|
||||
|
||||
final Column column = (Column) value;
|
||||
final ColumnInformation columnInformation = tableInformation.getColumnInformation( column.getColumnName() );
|
||||
final ColumnInformation columnInformation = tableInformation.getColumn( column.getColumnName() );
|
||||
|
||||
if ( columnInformation != null ) {
|
||||
continue;
|
||||
|
|
|
@ -21,12 +21,12 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.tool.schema.internal;
|
||||
package org.hibernate.tool.schema.extract.internal;
|
||||
|
||||
import org.hibernate.TruthValue;
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
import org.hibernate.tool.schema.spi.ColumnInformation;
|
||||
import org.hibernate.tool.schema.spi.TableInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.ColumnInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.TableInformation;
|
||||
|
||||
/**
|
||||
* JDBC column metadata
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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.tool.schema.extract.internal;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.metamodel.spi.relational.ObjectName;
|
||||
import org.hibernate.tool.schema.extract.spi.DatabaseInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.ExtractionContext;
|
||||
import org.hibernate.tool.schema.extract.spi.SequenceInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.TableInformation;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class DatabaseInformationImpl implements DatabaseInformation, ExtractionContext.RegisteredObjectAccess {
|
||||
private final Map<ObjectName,TableInformation> tables = new HashMap<ObjectName, TableInformation>();
|
||||
private final Map<ObjectName,SequenceInformation> sequences = new HashMap<ObjectName, SequenceInformation>();
|
||||
|
||||
public DatabaseInformationImpl() {
|
||||
}
|
||||
|
||||
// DatabaseInformation implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public TableInformation getTableInformation(ObjectName tableName) {
|
||||
return locateRegisteredTableInformation( tableName );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SequenceInformation getSequenceInformation(ObjectName sequenceName) {
|
||||
return locateRegisteredSequenceInformation( sequenceName );
|
||||
}
|
||||
|
||||
|
||||
// RegisteredObjectAccess implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public TableInformation locateRegisteredTableInformation(ObjectName tableName) {
|
||||
return tables.get( tableName );
|
||||
}
|
||||
|
||||
public void registerTableInformation(TableInformation tableInformation) {
|
||||
tables.put( tableInformation.getName(), tableInformation );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SequenceInformation locateRegisteredSequenceInformation(ObjectName sequenceName) {
|
||||
return sequences.get( sequenceName );
|
||||
}
|
||||
|
||||
public void registerSequenceInformation(SequenceInformation sequenceInformation) {
|
||||
sequences.put( sequenceInformation.getSequenceName(), sequenceInformation );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* 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.tool.schema.extract.internal;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.tool.schema.extract.spi.ExtractionContext;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ExtractionContextImpl implements ExtractionContext {
|
||||
private final JdbcEnvironment jdbcEnvironment;
|
||||
private final JdbcConnectionAccess jdbcConnectionAccess;
|
||||
private final RegisteredObjectAccess registeredTableAccess;
|
||||
|
||||
private Connection jdbcConnection;
|
||||
private DatabaseMetaData jdbcDatabaseMetaData;
|
||||
|
||||
public ExtractionContextImpl(
|
||||
JdbcEnvironment jdbcEnvironment,
|
||||
JdbcConnectionAccess jdbcConnectionAccess,
|
||||
RegisteredObjectAccess registeredTableAccess) {
|
||||
this.jdbcEnvironment = jdbcEnvironment;
|
||||
this.jdbcConnectionAccess = jdbcConnectionAccess;
|
||||
this.registeredTableAccess = registeredTableAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdbcEnvironment getJdbcEnvironment() {
|
||||
return jdbcEnvironment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getJdbcConnection() {
|
||||
if ( jdbcConnection == null ) {
|
||||
try {
|
||||
jdbcConnection = jdbcConnectionAccess.obtainConnection();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw jdbcEnvironment.getSqlExceptionHelper().convert( e, "Unable to obtain JDBC Connection" );
|
||||
}
|
||||
}
|
||||
return jdbcConnection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DatabaseMetaData getJdbcDatabaseMetaData() {
|
||||
if ( jdbcDatabaseMetaData == null ) {
|
||||
try {
|
||||
jdbcDatabaseMetaData = getJdbcConnection().getMetaData();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw jdbcEnvironment.getSqlExceptionHelper().convert( e, "Unable to obtain JDBC DatabaseMetaData" );
|
||||
}
|
||||
}
|
||||
return jdbcDatabaseMetaData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegisteredObjectAccess getRegisteredObjectAccess() {
|
||||
return registeredTableAccess;
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
if ( jdbcDatabaseMetaData != null ) {
|
||||
jdbcDatabaseMetaData = null;
|
||||
}
|
||||
|
||||
if ( jdbcConnection != null ) {
|
||||
try {
|
||||
jdbcConnectionAccess.releaseConnection( jdbcConnection );
|
||||
}
|
||||
catch (SQLException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,15 +21,13 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.tool.schema.internal;
|
||||
package org.hibernate.tool.schema.extract.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
import org.hibernate.tool.schema.spi.ColumnInformation;
|
||||
import org.hibernate.tool.schema.spi.ForeignKeyInformation;
|
||||
import org.hibernate.tool.schema.spi.SchemaManagementException;
|
||||
import org.hibernate.tool.schema.extract.spi.ColumnInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.ForeignKeyInformation;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
|
@ -38,7 +36,7 @@ public class ForeignKeyInformationImpl implements ForeignKeyInformation {
|
|||
private final Identifier fkIdentifier;
|
||||
private final List<ColumnReferenceMapping> columnMappingList;
|
||||
|
||||
private ForeignKeyInformationImpl(
|
||||
public ForeignKeyInformationImpl(
|
||||
Identifier fkIdentifier,
|
||||
List<ColumnReferenceMapping> columnMappingList) {
|
||||
this.fkIdentifier = fkIdentifier;
|
||||
|
@ -51,37 +49,9 @@ public class ForeignKeyInformationImpl implements ForeignKeyInformation {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<ColumnReferenceMapping> getColumnReferenceMappingList() {
|
||||
public Iterable<ColumnReferenceMapping> getColumnReferenceMappings() {
|
||||
return columnMappingList;
|
||||
}
|
||||
|
||||
public static Builder builder(Identifier fkIdentifier) {
|
||||
return new Builder( fkIdentifier );
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private final Identifier fkIdentifier;
|
||||
private final List<ColumnReferenceMapping> columnMappingList = new ArrayList<ColumnReferenceMapping>();
|
||||
|
||||
public Builder(Identifier fkIdentifier) {
|
||||
this.fkIdentifier = fkIdentifier;
|
||||
}
|
||||
|
||||
public Builder addColumnMapping(ColumnInformation referencing, ColumnInformation referenced) {
|
||||
columnMappingList.add( new ColumnReferenceMappingImpl( referencing, referenced ) );
|
||||
return this;
|
||||
}
|
||||
|
||||
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 ForeignKeyInformationImpl( fkIdentifier, columnMappingList );
|
||||
}
|
||||
}
|
||||
|
||||
public static class ColumnReferenceMappingImpl implements ColumnReferenceMapping {
|
||||
private final ColumnInformation referencing;
|
|
@ -21,15 +21,15 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.tool.schema.internal;
|
||||
package org.hibernate.tool.schema.extract.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
import org.hibernate.tool.schema.spi.ColumnInformation;
|
||||
import org.hibernate.tool.schema.spi.IndexInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.ColumnInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.IndexInformation;
|
||||
import org.hibernate.tool.schema.spi.SchemaManagementException;
|
||||
|
||||
/**
|
|
@ -21,10 +21,10 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.tool.schema.internal;
|
||||
package org.hibernate.tool.schema.extract.internal;
|
||||
|
||||
import org.hibernate.metamodel.spi.relational.ObjectName;
|
||||
import org.hibernate.tool.schema.spi.SequenceInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.SequenceInformation;
|
||||
|
||||
/**
|
||||
* For now we only collect sequence name. If all databases support it, would really like to see INCREMENT here as well.
|
|
@ -0,0 +1,347 @@
|
|||
/*
|
||||
* 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.tool.schema.extract.internal;
|
||||
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.hibernate.JDBCException;
|
||||
import org.hibernate.TruthValue;
|
||||
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
import org.hibernate.metamodel.spi.relational.ObjectName;
|
||||
import org.hibernate.tool.schema.extract.spi.ColumnInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.ExtractionContext;
|
||||
import org.hibernate.tool.schema.extract.spi.ForeignKeyInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.IndexInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.SchemaMetaDataExtractor;
|
||||
import org.hibernate.tool.schema.extract.spi.TableInformation;
|
||||
import org.hibernate.tool.schema.spi.SchemaManagementException;
|
||||
|
||||
/**
|
||||
* Implementation of the SchemaMetaDataExtractor contract which uses the standard JDBC {@link java.sql.DatabaseMetaData}
|
||||
* API for extraction.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class StandardJdbcDatabaseMetaDataExtractor implements SchemaMetaDataExtractor {
|
||||
private static final String[] TABLE_TYPES = new String[] { "TABLE", "VIEW" };
|
||||
|
||||
private final ExtractionContext extractionContext;
|
||||
|
||||
public StandardJdbcDatabaseMetaDataExtractor(ExtractionContext extractionContext) {
|
||||
this.extractionContext = extractionContext;
|
||||
}
|
||||
|
||||
protected IdentifierHelper identifierHelper() {
|
||||
return extractionContext.getJdbcEnvironment().getIdentifierHelper();
|
||||
}
|
||||
|
||||
protected JDBCException convertSQLException(SQLException sqlException, String message) {
|
||||
return extractionContext.getJdbcEnvironment().getSqlExceptionHelper().convert( sqlException, message );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<TableInformation> getTables(String catalogFilter, String schemaFilter) {
|
||||
try {
|
||||
ResultSet resultSet = extractionContext.getJdbcDatabaseMetaData().getTables(
|
||||
catalogFilter,
|
||||
schemaFilter,
|
||||
null,
|
||||
TABLE_TYPES
|
||||
);
|
||||
|
||||
final List<TableInformation> results = new ArrayList<TableInformation>();
|
||||
|
||||
try {
|
||||
while ( resultSet.next() ) {
|
||||
final Identifier catalogIdentifier = identifierHelper().fromMetaDataCatalogName(
|
||||
resultSet.getString(
|
||||
"TABLE_CAT"
|
||||
)
|
||||
);
|
||||
final Identifier schemaIdentifier = identifierHelper().fromMetaDataSchemaName(
|
||||
resultSet.getString(
|
||||
"TABLE_SCHEM"
|
||||
)
|
||||
);
|
||||
final Identifier tableIdentifier = identifierHelper().fromMetaDataObjectName(
|
||||
resultSet.getString(
|
||||
"TABLE_NAME"
|
||||
)
|
||||
);
|
||||
final ObjectName tableName = new ObjectName( catalogIdentifier, schemaIdentifier, tableIdentifier );
|
||||
TableInformation tableInformation = new TableInformationImpl(
|
||||
this,
|
||||
tableName,
|
||||
isPhysicalTableType( resultSet.getString( "TABLE_TYPE" ) ),
|
||||
resultSet.getString( "REMARKS" )
|
||||
);
|
||||
results.add( tableInformation );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
resultSet.close();
|
||||
}
|
||||
catch (SQLException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
catch (SQLException sqlException) {
|
||||
throw convertSQLException( sqlException, "Error accessing table metadata" );
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isPhysicalTableType(String tableType) {
|
||||
return "TABLE".equalsIgnoreCase( tableType );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<ColumnInformation> getColumns(TableInformation tableInformation) {
|
||||
final List<ColumnInformation> results = new ArrayList<ColumnInformation>();
|
||||
|
||||
try {
|
||||
ResultSet resultSet = extractionContext.getJdbcDatabaseMetaData().getColumns(
|
||||
identifierHelper().toMetaDataCatalogName( tableInformation.getName().getCatalog() ),
|
||||
identifierHelper().toMetaDataSchemaName( tableInformation.getName().getSchema() ),
|
||||
identifierHelper().toMetaDataObjectName( tableInformation.getName().getName() ),
|
||||
"%"
|
||||
);
|
||||
|
||||
try {
|
||||
while ( resultSet.next() ) {
|
||||
final String columnName = resultSet.getString( "COLUMN_NAME" );
|
||||
if ( columnName == null ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
results.add(
|
||||
new ColumnInformationImpl(
|
||||
tableInformation,
|
||||
Identifier.toIdentifier( columnName ),
|
||||
resultSet.getInt( "DATA_TYPE" ),
|
||||
new StringTokenizer( resultSet.getString( "TYPE_NAME" ), "() " ).nextToken(),
|
||||
resultSet.getInt( "COLUMN_SIZE" ),
|
||||
resultSet.getInt("DECIMAL_DIGITS"),
|
||||
interpretTruthValue( resultSet.getString( "IS_NULLABLE" ) )
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
resultSet.close();
|
||||
}
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw convertSQLException( e, "Error accessing column metadata: " + tableInformation.getName().toString() );
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private TruthValue interpretTruthValue(String nullable) {
|
||||
if ( "yes".equalsIgnoreCase( nullable ) ) {
|
||||
return TruthValue.TRUE;
|
||||
}
|
||||
else if ( "no".equalsIgnoreCase( nullable ) ) {
|
||||
return TruthValue.FALSE;
|
||||
}
|
||||
return TruthValue.UNKNOWN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<IndexInformation> getIndexes(TableInformation tableInformation) {
|
||||
final Map<Identifier, IndexInformationImpl.Builder> builders = new HashMap<Identifier, IndexInformationImpl.Builder>();
|
||||
|
||||
try {
|
||||
ResultSet resultSet = extractionContext.getJdbcDatabaseMetaData().getIndexInfo(
|
||||
identifierHelper().toMetaDataCatalogName( tableInformation.getName().getCatalog() ),
|
||||
identifierHelper().toMetaDataSchemaName( tableInformation.getName().getSchema() ),
|
||||
identifierHelper().toMetaDataObjectName( tableInformation.getName().getName() ),
|
||||
false, // DO NOT limit to just unique
|
||||
true // DO require up-to-date results
|
||||
);
|
||||
|
||||
try {
|
||||
while ( resultSet.next() ) {
|
||||
if ( resultSet.getShort("TYPE") == DatabaseMetaData.tableIndexStatistic ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final Identifier indexIdentifier = Identifier.toIdentifier( resultSet.getString( "INDEX_NAME" ) );
|
||||
IndexInformationImpl.Builder builder = builders.get( indexIdentifier );
|
||||
if ( builder == null ) {
|
||||
builder = IndexInformationImpl.builder( indexIdentifier );
|
||||
builders.put( indexIdentifier, builder );
|
||||
}
|
||||
|
||||
final Identifier columnIdentifier = Identifier.toIdentifier( resultSet.getString( "COLUMN_NAME" ) );
|
||||
final ColumnInformation columnInformation = tableInformation.getColumn( columnIdentifier );
|
||||
if ( columnInformation == null ) {
|
||||
throw new SchemaManagementException(
|
||||
"Could not locate column information using identifier [" + columnIdentifier.getText() + "]"
|
||||
);
|
||||
}
|
||||
builder.addColumn( columnInformation );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
resultSet.close();
|
||||
}
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw convertSQLException(
|
||||
e,
|
||||
"Error accessing index information: " + tableInformation.getName().toString()
|
||||
);
|
||||
}
|
||||
|
||||
final List<IndexInformation> indexes = new ArrayList<IndexInformation>();
|
||||
for ( IndexInformationImpl.Builder builder : builders.values() ) {
|
||||
IndexInformationImpl index = builder.build();
|
||||
indexes.add( index );
|
||||
}
|
||||
return indexes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<ForeignKeyInformation> getForeignKeys(TableInformation tableInformation) {
|
||||
final Map<Identifier, ForeignKeyBuilder> fkBuilders = new HashMap<Identifier, ForeignKeyBuilder>();
|
||||
|
||||
try {
|
||||
ResultSet resultSet = extractionContext.getJdbcDatabaseMetaData().getImportedKeys(
|
||||
identifierHelper().toMetaDataCatalogName( tableInformation.getName().getCatalog() ),
|
||||
identifierHelper().toMetaDataSchemaName( tableInformation.getName().getSchema() ),
|
||||
identifierHelper().toMetaDataObjectName( tableInformation.getName().getName() )
|
||||
);
|
||||
|
||||
// todo : need to account for getCrossReference() as well...
|
||||
|
||||
try {
|
||||
while ( resultSet.next() ) {
|
||||
// IMPL NOTE : The builder is mainly used to collect the column reference mappings
|
||||
final Identifier fkIdentifier = Identifier.toIdentifier( resultSet.getString( "FK_NAME" ) );
|
||||
ForeignKeyBuilder fkBuilder = fkBuilders.get( fkIdentifier );
|
||||
if ( fkBuilder == null ) {
|
||||
fkBuilder = generateForeignKeyBuilder( fkIdentifier );
|
||||
fkBuilders.put( fkIdentifier, fkBuilder );
|
||||
}
|
||||
|
||||
final ObjectName incomingPkTableName = extractKeyTableName( resultSet, "PK" );
|
||||
|
||||
final TableInformation pkTableInformation = extractionContext.getRegisteredObjectAccess()
|
||||
.locateRegisteredTableInformation( incomingPkTableName );
|
||||
|
||||
if ( pkTableInformation == null ) {
|
||||
// the assumption here is that we have not seen this table already based on fully-qualified name
|
||||
// during previous step of building all table metadata so most likely this is
|
||||
// not a match based solely on schema/catalog and that another row in this result set
|
||||
// should match.
|
||||
continue;
|
||||
}
|
||||
|
||||
final Identifier fkColumnIdentifier = Identifier.toIdentifier( resultSet.getString( "FKCOLUMN_NAME" ) );
|
||||
final Identifier pkColumnIdentifier = Identifier.toIdentifier( resultSet.getString( "PKCOLUMN_NAME" ) );
|
||||
|
||||
fkBuilder.addColumnMapping(
|
||||
tableInformation.getColumn( fkColumnIdentifier ),
|
||||
pkTableInformation.getColumn( pkColumnIdentifier )
|
||||
);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
resultSet.close();
|
||||
}
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw convertSQLException(
|
||||
e,
|
||||
"Error accessing column metadata: " + tableInformation.getName().toString()
|
||||
);
|
||||
}
|
||||
|
||||
final List<ForeignKeyInformation> fks = new ArrayList<ForeignKeyInformation>();
|
||||
for ( ForeignKeyBuilder fkBuilder : fkBuilders.values() ) {
|
||||
ForeignKeyInformation fk = fkBuilder.build();
|
||||
fks.add( fk );
|
||||
}
|
||||
return fks;
|
||||
}
|
||||
|
||||
private ForeignKeyBuilder generateForeignKeyBuilder(Identifier fkIdentifier) {
|
||||
return new ForeignKeyBuilderImpl( fkIdentifier );
|
||||
}
|
||||
|
||||
protected static interface ForeignKeyBuilder {
|
||||
public ForeignKeyBuilder addColumnMapping(ColumnInformation referencing, ColumnInformation referenced);
|
||||
|
||||
public ForeignKeyInformation build();
|
||||
}
|
||||
|
||||
protected static class ForeignKeyBuilderImpl implements ForeignKeyBuilder {
|
||||
private final Identifier fkIdentifier;
|
||||
private final List<ForeignKeyInformation.ColumnReferenceMapping> columnMappingList = new ArrayList<ForeignKeyInformation.ColumnReferenceMapping>();
|
||||
|
||||
public ForeignKeyBuilderImpl(Identifier fkIdentifier) {
|
||||
this.fkIdentifier = fkIdentifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ForeignKeyBuilder addColumnMapping(ColumnInformation referencing, ColumnInformation referenced) {
|
||||
columnMappingList.add( new ForeignKeyInformationImpl.ColumnReferenceMappingImpl( referencing, referenced ) );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
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 ForeignKeyInformationImpl( fkIdentifier, columnMappingList );
|
||||
}
|
||||
}
|
||||
|
||||
private ObjectName extractKeyTableName(ResultSet resultSet, String prefix) throws SQLException {
|
||||
final String incomingCatalogName = resultSet.getString( prefix + "TABLE_SCHEM" );
|
||||
final String incomingSchemaName = resultSet.getString( prefix + "TABLE_CATALOG" );
|
||||
final String incomingTableName = resultSet.getString( prefix + "TABLE_NAME" );
|
||||
|
||||
return new ObjectName(
|
||||
Identifier.toIdentifier( incomingCatalogName ), Identifier.toIdentifier( incomingSchemaName ),
|
||||
Identifier.toIdentifier( incomingTableName )
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* 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.tool.schema.extract.internal;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
import org.hibernate.metamodel.spi.relational.ObjectName;
|
||||
import org.hibernate.tool.schema.extract.spi.ColumnInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.ForeignKeyInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.IndexInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.SchemaMetaDataExtractor;
|
||||
import org.hibernate.tool.schema.extract.spi.TableInformation;
|
||||
|
||||
/**
|
||||
* Provides access to information about existing schema objects (tables, sequences etc) of existing database.
|
||||
*
|
||||
* @author Christoph Sturm
|
||||
* @author Max Rydahl Andersen
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class TableInformationImpl implements TableInformation {
|
||||
private final SchemaMetaDataExtractor metaDataExtractor;
|
||||
private final ObjectName tableName;
|
||||
private final boolean physicalTable;
|
||||
private final String comment;
|
||||
|
||||
private Map<Identifier, ColumnInformation> columns;
|
||||
private Map<Identifier, ForeignKeyInformation> foreignKeys;
|
||||
private Map<Identifier, IndexInformation> indexes;
|
||||
|
||||
public TableInformationImpl(
|
||||
SchemaMetaDataExtractor metaDataExtractor,
|
||||
ObjectName tableName,
|
||||
boolean physicalTable,
|
||||
String comment) {
|
||||
this.metaDataExtractor = metaDataExtractor;
|
||||
this.tableName = tableName;
|
||||
this.physicalTable = physicalTable;
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectName getName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPhysicalTable() {
|
||||
return physicalTable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<ColumnInformation> getColumns() {
|
||||
return columns().values();
|
||||
}
|
||||
|
||||
protected Map<Identifier, ColumnInformation> columns() {
|
||||
if ( this.columns == null ) {
|
||||
final Map<Identifier, ColumnInformation> columnMap = new HashMap<Identifier, ColumnInformation>();
|
||||
final Iterable<ColumnInformation> columnInformationItr = metaDataExtractor.getColumns( this );
|
||||
for ( ColumnInformation columnInformation : columnInformationItr ) {
|
||||
columnMap.put( columnInformation.getColumnIdentifier(), columnInformation );
|
||||
}
|
||||
this.columns = columnMap;
|
||||
}
|
||||
return this.columns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColumnInformation getColumn(Identifier columnIdentifier) {
|
||||
return columns().get( columnIdentifier );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<ForeignKeyInformation> getForeignKeys() {
|
||||
return foreignKeys().values();
|
||||
}
|
||||
|
||||
protected Map<Identifier, ForeignKeyInformation> foreignKeys() {
|
||||
if ( foreignKeys == null ) {
|
||||
final Map<Identifier, ForeignKeyInformation> fkMap = new HashMap<Identifier, ForeignKeyInformation>();
|
||||
final Iterable<ForeignKeyInformation> fks = metaDataExtractor.getForeignKeys( this );
|
||||
for ( ForeignKeyInformation fk : fks ) {
|
||||
fkMap.put( fk.getForeignKeyIdentifier(), fk );
|
||||
}
|
||||
this.foreignKeys = fkMap;
|
||||
}
|
||||
return foreignKeys;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ForeignKeyInformation getForeignKey(Identifier fkIdentifier) {
|
||||
return foreignKeys().get( fkIdentifier );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<IndexInformation> getIndexes() {
|
||||
return indexes().values();
|
||||
}
|
||||
|
||||
protected Map<Identifier, IndexInformation> indexes() {
|
||||
if ( indexes == null ) {
|
||||
final Map<Identifier, IndexInformation> indexMap = new HashMap<Identifier, IndexInformation>();
|
||||
final Iterable<IndexInformation> indexes = metaDataExtractor.getIndexes( this );
|
||||
for ( IndexInformation index : indexes ) {
|
||||
indexMap.put( index.getIndexIdentifier(), index );
|
||||
}
|
||||
this.indexes = indexMap;
|
||||
}
|
||||
return indexes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IndexInformation getIndex(Identifier indexName) {
|
||||
return indexes().get( indexName );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TableInformationImpl(" + tableName.toString() + ')';
|
||||
}
|
||||
}
|
|
@ -21,19 +21,19 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.tool.schema.internal;
|
||||
package org.hibernate.tool.schema.extract.internal;
|
||||
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
|
||||
import org.hibernate.metamodel.spi.relational.ObjectName;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.tool.schema.spi.SequenceInformation;
|
||||
import org.hibernate.tool.schema.spi.SequenceInformationExtractor;
|
||||
import org.hibernate.tool.schema.extract.spi.ExtractionContext;
|
||||
import org.hibernate.tool.schema.extract.spi.SequenceInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
||||
|
||||
/**
|
||||
* Temporary implementation that works for H2.
|
||||
|
@ -41,15 +41,10 @@ import org.hibernate.tool.schema.spi.SequenceInformationExtractor;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class TemporarySequenceInformationExtractor implements SequenceInformationExtractor {
|
||||
private final JdbcEnvironment jdbcEnvironment;
|
||||
|
||||
public TemporarySequenceInformationExtractor(JdbcEnvironment jdbcEnvironment) {
|
||||
this.jdbcEnvironment = jdbcEnvironment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<SequenceInformation> extractMetadata(DatabaseMetaData databaseMetaData) throws SQLException {
|
||||
Statement statement = databaseMetaData.getConnection().createStatement();
|
||||
public Iterable<SequenceInformation> extractMetadata(ExtractionContext extractionContext) throws SQLException {
|
||||
final IdentifierHelper identifierHelper = extractionContext.getJdbcEnvironment().getIdentifierHelper();
|
||||
final Statement statement = extractionContext.getJdbcConnection().createStatement();
|
||||
try {
|
||||
ResultSet resultSet = statement.executeQuery(
|
||||
"select SEQUENCE_CATALOG, SEQUENCE_SCHEMA, SEQUENCE_NAME, INCREMENT " +
|
||||
|
@ -61,20 +56,14 @@ public class TemporarySequenceInformationExtractor implements SequenceInformatio
|
|||
sequenceInformationList.add(
|
||||
new SequenceInformationImpl(
|
||||
new ObjectName(
|
||||
jdbcEnvironment.getIdentifierHelper().fromMetaDataCatalogName(
|
||||
resultSet.getString(
|
||||
"SEQUENCE_CATALOG"
|
||||
)
|
||||
identifierHelper.fromMetaDataCatalogName(
|
||||
resultSet.getString( "SEQUENCE_CATALOG" )
|
||||
),
|
||||
jdbcEnvironment.getIdentifierHelper().fromMetaDataSchemaName(
|
||||
resultSet.getString(
|
||||
"SEQUENCE_SCHEMA"
|
||||
)
|
||||
identifierHelper.fromMetaDataSchemaName(
|
||||
resultSet.getString( "SEQUENCE_SCHEMA" )
|
||||
),
|
||||
jdbcEnvironment.getIdentifierHelper().fromMetaDataCatalogName(
|
||||
resultSet.getString(
|
||||
"SEQUENCE_NAME"
|
||||
)
|
||||
identifierHelper.fromMetaDataCatalogName(
|
||||
resultSet.getString( "SEQUENCE_NAME" )
|
||||
)
|
||||
),
|
||||
resultSet.getInt( "INCREMENT" )
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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.tool.schema.extract;
|
||||
|
||||
/**
|
||||
* Defines a model of schema information extracted from the database through JDBC.
|
||||
*/
|
|
@ -21,7 +21,7 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.tool.schema.spi;
|
||||
package org.hibernate.tool.schema.extract.spi;
|
||||
|
||||
import org.hibernate.TruthValue;
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
|
@ -21,7 +21,7 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.tool.schema.spi;
|
||||
package org.hibernate.tool.schema.extract.spi;
|
||||
|
||||
import org.hibernate.metamodel.spi.relational.ObjectName;
|
||||
|
|
@ -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.tool.schema.extract.spi;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
import org.hibernate.metamodel.spi.relational.Schema;
|
||||
import org.hibernate.tool.schema.extract.internal.DatabaseInformationImpl;
|
||||
import org.hibernate.tool.schema.extract.internal.ExtractionContextImpl;
|
||||
import org.hibernate.tool.schema.extract.internal.StandardJdbcDatabaseMetaDataExtractor;
|
||||
import org.hibernate.tool.schema.extract.internal.TemporarySequenceInformationExtractor;
|
||||
|
||||
/**
|
||||
* Acts as the entry point into building {@link DatabaseInformation} instances. The correlation is 1-to-1 between
|
||||
* DatabaseInformationBuilder and DatabaseInformation, meaning a given DatabaseInformationBuilder should only be used
|
||||
* to build a single DatabaseInformation instance.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class DatabaseInformationBuilder {
|
||||
private final DatabaseInformationImpl databaseInformation;
|
||||
private final ExtractionContext extractionContext;
|
||||
|
||||
private final SchemaMetaDataExtractor metaDataExtractor;
|
||||
|
||||
public DatabaseInformationBuilder(JdbcEnvironment jdbcEnvironment, final Connection jdbcConnection) {
|
||||
this(
|
||||
jdbcEnvironment,
|
||||
new JdbcConnectionAccess() {
|
||||
@Override
|
||||
public Connection obtainConnection() throws SQLException {
|
||||
return jdbcConnection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseConnection(Connection connection) throws SQLException {
|
||||
// nothing to do, we don't "own" the connection
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsAggressiveRelease() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public DatabaseInformationBuilder(JdbcEnvironment jdbcEnvironment, JdbcConnectionAccess jdbcConnectionAccess) {
|
||||
this.databaseInformation = new DatabaseInformationImpl();
|
||||
this.extractionContext = new ExtractionContextImpl( jdbcEnvironment, jdbcConnectionAccess, databaseInformation );
|
||||
|
||||
// todo : make this pluggable...
|
||||
metaDataExtractor = new StandardJdbcDatabaseMetaDataExtractor( extractionContext );
|
||||
}
|
||||
|
||||
public DatabaseInformationBuilder prepareAll() {
|
||||
return prepare( SchemaMetaDataExtractor.ALL_CATALOGS_FILTER, SchemaMetaDataExtractor.ALL_SCHEMAS_FILTER );
|
||||
}
|
||||
|
||||
public DatabaseInformationBuilder prepareCatalogAndSchema(Schema.Name schemaName) {
|
||||
final IdentifierHelper identifierHelper = extractionContext.getJdbcEnvironment().getIdentifierHelper();
|
||||
return prepare(
|
||||
identifierHelper.toMetaDataCatalogName( schemaName.getCatalog() ),
|
||||
identifierHelper.toMetaDataSchemaName( schemaName.getSchema() )
|
||||
);
|
||||
}
|
||||
|
||||
public DatabaseInformationBuilder prepareCatalog(Identifier catalog) {
|
||||
final IdentifierHelper identifierHelper = extractionContext.getJdbcEnvironment().getIdentifierHelper();
|
||||
return prepare(
|
||||
identifierHelper.toMetaDataCatalogName( catalog ),
|
||||
SchemaMetaDataExtractor.ALL_SCHEMAS_FILTER
|
||||
);
|
||||
}
|
||||
|
||||
public DatabaseInformationBuilder prepareSchema(Identifier schema) {
|
||||
final IdentifierHelper identifierHelper = extractionContext.getJdbcEnvironment().getIdentifierHelper();
|
||||
return prepare(
|
||||
SchemaMetaDataExtractor.ALL_CATALOGS_FILTER,
|
||||
identifierHelper.toMetaDataSchemaName( schema )
|
||||
);
|
||||
}
|
||||
|
||||
private DatabaseInformationBuilder prepare(String catalog, String schema) {
|
||||
// todo : apply filtering
|
||||
|
||||
for ( TableInformation tableInformation : metaDataExtractor.getTables( catalog, schema ) ) {
|
||||
databaseInformation.registerTableInformation( tableInformation );
|
||||
}
|
||||
|
||||
final Iterable<SequenceInformation> sequences = extractSequences();
|
||||
if ( sequences != null ) {
|
||||
for ( SequenceInformation sequenceInformation : sequences ) {
|
||||
databaseInformation.registerSequenceInformation( sequenceInformation );
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private Iterable<SequenceInformation> extractSequences() {
|
||||
// todo : temporary impl!!!
|
||||
final TemporarySequenceInformationExtractor seqExtractor = new TemporarySequenceInformationExtractor();
|
||||
try {
|
||||
return seqExtractor.extractMetadata( extractionContext );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw extractionContext.getJdbcEnvironment().getSqlExceptionHelper().convert( e, "Unable to access sequence information" );
|
||||
}
|
||||
}
|
||||
|
||||
public DatabaseInformation build() {
|
||||
return databaseInformation;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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.tool.schema.extract.spi;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
|
||||
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.metamodel.spi.relational.ObjectName;
|
||||
|
||||
/**
|
||||
* Defines a context for performing extraction including providing access to information about ongoing extraction as
|
||||
* well as to delegates needed in performing extraction.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ExtractionContext {
|
||||
public JdbcEnvironment getJdbcEnvironment();
|
||||
public Connection getJdbcConnection();
|
||||
public DatabaseMetaData getJdbcDatabaseMetaData();
|
||||
|
||||
public static interface RegisteredObjectAccess {
|
||||
public TableInformation locateRegisteredTableInformation(ObjectName tableName);
|
||||
public SequenceInformation locateRegisteredSequenceInformation(ObjectName sequenceName);
|
||||
}
|
||||
|
||||
public RegisteredObjectAccess getRegisteredObjectAccess();
|
||||
}
|
|
@ -21,7 +21,7 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.tool.schema.spi;
|
||||
package org.hibernate.tool.schema.extract.spi;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -39,11 +39,11 @@ public interface ForeignKeyInformation {
|
|||
public Identifier getForeignKeyIdentifier();
|
||||
|
||||
/**
|
||||
* Get the list of column mappings that define the reference.
|
||||
* Get the column mappings that define the reference. Returned in sequential order.
|
||||
*
|
||||
* @return The mapping list
|
||||
* @return The sequential column reference mappings.
|
||||
*/
|
||||
public List<ColumnReferenceMapping> getColumnReferenceMappingList();
|
||||
public Iterable<ColumnReferenceMapping> getColumnReferenceMappings();
|
||||
|
||||
public static interface ColumnReferenceMapping {
|
||||
/**
|
|
@ -21,7 +21,7 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.tool.schema.spi;
|
||||
package org.hibernate.tool.schema.extract.spi;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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.tool.schema.extract.spi;
|
||||
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
|
||||
/**
|
||||
* Provides access to information about existing primary key for a table
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface PrimaryKeyInformation {
|
||||
/**
|
||||
* Obtain the identifier for this PK.
|
||||
*
|
||||
* @return The PK identifier.
|
||||
*/
|
||||
public Identifier getPrimaryKeyIdentifier();
|
||||
|
||||
public Iterable<ColumnInformation> getColumns();
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* 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.tool.schema.extract.spi;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
import org.hibernate.tool.schema.extract.internal.ForeignKeyInformationImpl;
|
||||
import org.hibernate.tool.schema.extract.internal.IndexInformationImpl;
|
||||
import org.hibernate.tool.schema.extract.internal.TableInformationImpl;
|
||||
|
||||
/**
|
||||
* Contract for extracting information about objects in the database schema(s). To an extent, the contract largely
|
||||
* mirrors parts of the JDBC {@link java.sql.DatabaseMetaData} contract. THe intention is to insulate callers
|
||||
* from {@link java.sql.DatabaseMetaData} since on many databases there are better ways to get information from
|
||||
* the meta schema.
|
||||
*
|
||||
* NOTE : Concepts here taken largely from the {@code MetaDataDialect} class Hibernate Tools.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface SchemaMetaDataExtractor {
|
||||
public static final String ALL_CATALOGS_FILTER = null;
|
||||
public static final String SANS_CATALOG_FILTER = "";
|
||||
|
||||
public static final String ALL_SCHEMAS_FILTER = null;
|
||||
public static final String SANS_SCHEMA_FILTER = "";
|
||||
|
||||
/**
|
||||
* Return information about all matching tables
|
||||
*
|
||||
* @param catalogFilter Filter to be applied for the catalog to which tables belong. Can be either the
|
||||
* name of the catalog to match or one of 2 special values:<ol>
|
||||
* <li>
|
||||
* {@code null} ({@link #ALL_CATALOGS_FILTER}) - Indicates that tables from all catalogs should be returned
|
||||
* </li>
|
||||
* <li>
|
||||
* {@code ""} (empty String) ({@link #SANS_CATALOG_FILTER}) - Indicates that only tables without a catalog
|
||||
* should be returned
|
||||
* </li>
|
||||
* </ol>
|
||||
* @param schemaFilter Filter to be applied for the schema to which tables belong. Can be either the
|
||||
* name of the schema to match or one of 2 special values:<ol>
|
||||
* <li>
|
||||
* {@code null} ({@link #ALL_SCHEMAS_FILTER}) - Indicates that tables from all schemas should be returned
|
||||
* </li>
|
||||
* <li>
|
||||
* {@code ""} (empty String) ({@link #SANS_SCHEMA_FILTER}) - Indicates that only tables without a schema
|
||||
* should be returned
|
||||
* </li>
|
||||
* </ol>
|
||||
*
|
||||
* @return iterator with map elements that has "TABLE_NAME", "TABLE_SCHEMA", "TABLE_CAT", "TABLE_TYPE" keys.
|
||||
*/
|
||||
public Iterable<TableInformation> getTables(String catalogFilter, String schemaFilter);
|
||||
|
||||
/**
|
||||
* Return information about columns for the given table. Typically called from the TableInformation itself
|
||||
* as part of on-demand initialization of its state.
|
||||
*
|
||||
* @param tableInformation The table for which to locate columns
|
||||
*
|
||||
* @return The extracted column information
|
||||
*/
|
||||
public Iterable<ColumnInformation> getColumns(TableInformation tableInformation);
|
||||
|
||||
/**
|
||||
* Extract information about indexes defined against the given table. Typically called from the TableInformation
|
||||
* itself as part of on-demand initialization of its state.
|
||||
*
|
||||
* @param tableInformation The table for which to locate indexes
|
||||
*
|
||||
* @return The extracted index information
|
||||
*/
|
||||
public Iterable<IndexInformation> getIndexes(TableInformation tableInformation);
|
||||
|
||||
/**
|
||||
* Extract information about foreign keys defined on the given table (targeting or point-at other tables).
|
||||
* Typically called from the TableInformation itself as part of on-demand initialization of its state.
|
||||
*
|
||||
* @param tableInformation The table for which to locate foreign-keys
|
||||
*
|
||||
* @return The extracted foreign-key information
|
||||
*/
|
||||
public Iterable<ForeignKeyInformation> getForeignKeys(TableInformation tableInformation);
|
||||
}
|
|
@ -21,7 +21,7 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.tool.schema.spi;
|
||||
package org.hibernate.tool.schema.extract.spi;
|
||||
|
||||
import org.hibernate.metamodel.spi.relational.ObjectName;
|
||||
|
|
@ -21,9 +21,8 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.tool.schema.spi;
|
||||
package org.hibernate.tool.schema.extract.spi;
|
||||
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
|
@ -36,12 +35,12 @@ public interface SequenceInformationExtractor {
|
|||
/**
|
||||
* Get the information about sequences.
|
||||
*
|
||||
* @param databaseMetaData The JDBC DatabaseMetadata
|
||||
* @param extractionContext Access to resources needed to perform the extraction
|
||||
*
|
||||
* @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;
|
||||
public Iterable<SequenceInformation> extractMetadata(ExtractionContext extractionContext) throws SQLException;
|
||||
}
|
|
@ -21,7 +21,7 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.tool.schema.spi;
|
||||
package org.hibernate.tool.schema.extract.spi;
|
||||
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
import org.hibernate.metamodel.spi.relational.ObjectName;
|
||||
|
@ -41,6 +41,27 @@ public interface TableInformation {
|
|||
*/
|
||||
public ObjectName getName();
|
||||
|
||||
/**
|
||||
* Does this information describe a physical table as opposed to a view, etc?
|
||||
*
|
||||
* @return {@code true} if this is a physical table; {@code false} otherwise.
|
||||
*/
|
||||
public boolean isPhysicalTable();
|
||||
|
||||
/**
|
||||
* Get the comments/remarks defined for the table.
|
||||
*
|
||||
* @return The table comments
|
||||
*/
|
||||
public String getComment();
|
||||
|
||||
/**
|
||||
* Get an iterable over all of the table's columns.
|
||||
*
|
||||
* @return All of the table's columns
|
||||
*/
|
||||
public Iterable<ColumnInformation> getColumns();
|
||||
|
||||
/**
|
||||
* Retrieve the named ColumnInformation
|
||||
*
|
||||
|
@ -48,7 +69,14 @@ public interface TableInformation {
|
|||
*
|
||||
* @return The matching column information. May return {@code null}
|
||||
*/
|
||||
public ColumnInformation getColumnInformation(Identifier columnIdentifier);
|
||||
public ColumnInformation getColumn(Identifier columnIdentifier);
|
||||
|
||||
/**
|
||||
* Obtain an iterable over all the table's defined foreign keys.
|
||||
*
|
||||
* @return The iterable.
|
||||
*/
|
||||
public Iterable<ForeignKeyInformation> getForeignKeys();
|
||||
|
||||
/**
|
||||
* Retrieve the named ForeignKeyInformation
|
||||
|
@ -57,17 +85,17 @@ public interface TableInformation {
|
|||
*
|
||||
* @return The matching foreign key information. May return {@code null}
|
||||
*/
|
||||
public ForeignKeyInformation getForeignKeyInformation(Identifier keyName);
|
||||
public ForeignKeyInformation getForeignKey(Identifier keyName);
|
||||
|
||||
/**
|
||||
* Obtain an iterable over all the table's defined foreign keys.
|
||||
* Obtain an iterable over all the table's defined indexes.
|
||||
*
|
||||
* @return The iterable.
|
||||
*/
|
||||
public Iterable<ForeignKeyInformation> getForeignKeyInformations();
|
||||
public Iterable<IndexInformation> getIndexes();
|
||||
|
||||
/**
|
||||
* todo : create an IndexInformation...
|
||||
* Obtain an iterable over all the table's defined indexes
|
||||
*/
|
||||
public IndexInformation getIndexInformation(Identifier indexName);
|
||||
public IndexInformation getIndex(Identifier indexName);
|
||||
}
|
|
@ -1,418 +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.tool.schema.internal;
|
||||
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.hibernate.TruthValue;
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
import org.hibernate.metamodel.spi.relational.ObjectName;
|
||||
import org.hibernate.metamodel.spi.relational.Schema;
|
||||
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.tool.schema.spi.ColumnInformation;
|
||||
import org.hibernate.tool.schema.spi.DatabaseInformation;
|
||||
import org.hibernate.tool.schema.spi.SchemaManagementException;
|
||||
import org.hibernate.tool.schema.spi.SequenceInformation;
|
||||
import org.hibernate.tool.schema.spi.TableInformation;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class DatabaseInformationImpl implements DatabaseInformation {
|
||||
private final JdbcEnvironment jdbcEnvironment;
|
||||
private final DatabaseMetaData databaseMetaData;
|
||||
|
||||
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 {
|
||||
return new BuilderImpl( jdbcEnvironment, databaseMetaData );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw jdbcEnvironment.getSqlExceptionHelper().convert( e, "Error accessing java.sql.DatabaseMetaData" );
|
||||
}
|
||||
}
|
||||
|
||||
private DatabaseInformationImpl(JdbcEnvironment jdbcEnvironment, DatabaseMetaData databaseMetaData) throws SQLException {
|
||||
this.jdbcEnvironment = jdbcEnvironment;
|
||||
this.databaseMetaData = databaseMetaData;
|
||||
this.sequences = loadSequenceMetadataMap();
|
||||
}
|
||||
|
||||
public IdentifierHelper identifierHelper() {
|
||||
return jdbcEnvironment.getIdentifierHelper();
|
||||
}
|
||||
|
||||
private static final String[] TABLE_TYPES = new String[] { "TABLE", "VIEW" };
|
||||
|
||||
private void loadTableMetadata(ResultSet resultSet) throws SQLException {
|
||||
while ( resultSet.next() ) {
|
||||
final Identifier catalogIdentifier = identifierHelper().fromMetaDataCatalogName(
|
||||
resultSet.getString(
|
||||
"TABLE_CAT"
|
||||
)
|
||||
);
|
||||
final Identifier schemaIdentifier = identifierHelper().fromMetaDataSchemaName(
|
||||
resultSet.getString(
|
||||
"TABLE_SCHEM"
|
||||
)
|
||||
);
|
||||
final Identifier tableIdentifier = identifierHelper().fromMetaDataObjectName(
|
||||
resultSet.getString(
|
||||
"TABLE_NAME"
|
||||
)
|
||||
);
|
||||
final ObjectName tableName = new ObjectName( catalogIdentifier, schemaIdentifier, tableIdentifier );
|
||||
// make sure it does not already exist...
|
||||
TableInformationImpl tableMetadata = tables.get( tableName );
|
||||
if ( tableMetadata != null ) {
|
||||
throw new IllegalStateException( "Table already found on parsing database metadata [" + tableName + "]" );
|
||||
}
|
||||
|
||||
tableMetadata = new TableInformationImpl( this, tableName );
|
||||
tables.put( toMapKey( tableName ), tableMetadata );
|
||||
}
|
||||
}
|
||||
|
||||
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 ( SequenceInformation sequenceInformation :sequenceMetadatas ) {
|
||||
sequences.put( toMapKey( sequenceInformation.getSequenceName() ), sequenceInformation );
|
||||
}
|
||||
}
|
||||
return sequences;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableInformation getTableInformation(ObjectName tableName) {
|
||||
return tables.get( toMapKey( tableName ) );
|
||||
}
|
||||
|
||||
public static ObjectName toMapKey(ObjectName qualifiedName) {
|
||||
Identifier catalog = qualifiedName.getCatalog();
|
||||
if ( catalog != null ) {
|
||||
if ( ! catalog.isQuoted() ) {
|
||||
catalog = Identifier.toIdentifier( catalog.getText().toUpperCase() );
|
||||
}
|
||||
}
|
||||
|
||||
Identifier schema = qualifiedName.getSchema();
|
||||
if ( schema != null ) {
|
||||
if ( ! schema.isQuoted() ) {
|
||||
schema = Identifier.toIdentifier( schema.getText().toUpperCase() );
|
||||
}
|
||||
}
|
||||
|
||||
Identifier name = qualifiedName.getName();
|
||||
if ( name != null ) {
|
||||
if ( ! name.isQuoted() ) {
|
||||
name = Identifier.toIdentifier( name.getText().toUpperCase() );
|
||||
}
|
||||
}
|
||||
|
||||
return new ObjectName( catalog, schema, name );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SequenceInformation getSequenceInformation(ObjectName sequenceName) {
|
||||
return sequences.get( toMapKey( sequenceName ) );
|
||||
}
|
||||
|
||||
public Map<Identifier, ColumnInformation> getColumnMetadata(TableInformation tableInformation) {
|
||||
final Map<Identifier, ColumnInformation> results = new HashMap<Identifier, ColumnInformation>();
|
||||
|
||||
try {
|
||||
ResultSet resultSet = databaseMetaData.getColumns(
|
||||
identifierHelper().toMetaDataCatalogName( tableInformation.getName().getCatalog() ),
|
||||
identifierHelper().toMetaDataSchemaName( tableInformation.getName().getSchema() ),
|
||||
identifierHelper().toMetaDataObjectName( tableInformation.getName().getName() ),
|
||||
"%"
|
||||
);
|
||||
|
||||
try {
|
||||
while ( resultSet.next() ) {
|
||||
final String columnName = resultSet.getString( "COLUMN_NAME" );
|
||||
if ( columnName == null ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final Identifier columnIdentifier = Identifier.toIdentifier( columnName );
|
||||
if ( results.containsKey( columnIdentifier ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final ColumnInformationImpl meta = new ColumnInformationImpl(
|
||||
tableInformation,
|
||||
columnIdentifier,
|
||||
resultSet.getInt( "DATA_TYPE" ),
|
||||
new StringTokenizer( resultSet.getString( "TYPE_NAME" ), "() " ).nextToken(),
|
||||
resultSet.getInt( "COLUMN_SIZE" ),
|
||||
resultSet.getInt("DECIMAL_DIGITS"),
|
||||
interpretTruthValue( resultSet.getString( "IS_NULLABLE" ) )
|
||||
);
|
||||
results.put( columnIdentifier, meta );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
resultSet.close();
|
||||
}
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw jdbcEnvironment.getSqlExceptionHelper().convert(
|
||||
e,
|
||||
"Error accessing column metadata: " + tableInformation.getName().toString()
|
||||
);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public Map<Identifier, IndexInformationImpl> getIndexInformation(TableInformationImpl tableInformation) {
|
||||
final Map<Identifier, IndexInformationImpl.Builder> builders = new HashMap<Identifier, IndexInformationImpl.Builder>();
|
||||
|
||||
try {
|
||||
ResultSet resultSet = databaseMetaData.getIndexInfo(
|
||||
identifierHelper().toMetaDataCatalogName( tableInformation.getName().getCatalog() ),
|
||||
identifierHelper().toMetaDataSchemaName( tableInformation.getName().getSchema() ),
|
||||
identifierHelper().toMetaDataObjectName( tableInformation.getName().getName() ),
|
||||
false, // don't limit to just unique
|
||||
true // do require up-to-date results
|
||||
);
|
||||
|
||||
try {
|
||||
while ( resultSet.next() ) {
|
||||
if ( resultSet.getShort("TYPE") == DatabaseMetaData.tableIndexStatistic ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final Identifier indexIdentifier = Identifier.toIdentifier( resultSet.getString( "INDEX_NAME" ) );
|
||||
IndexInformationImpl.Builder builder = builders.get( indexIdentifier );
|
||||
if ( builder == null ) {
|
||||
builder = IndexInformationImpl.builder( indexIdentifier );
|
||||
builders.put( indexIdentifier, builder );
|
||||
}
|
||||
|
||||
final Identifier columnIdentifier = Identifier.toIdentifier( resultSet.getString( "COLUMN_NAME" ) );
|
||||
final ColumnInformation columnInformation = tableInformation.getColumnInformation( columnIdentifier );
|
||||
if ( columnInformation == null ) {
|
||||
throw new SchemaManagementException(
|
||||
"Could not locate column information using identifier [" + columnIdentifier.getText() + "]"
|
||||
);
|
||||
}
|
||||
builder.addColumn( columnInformation );
|
||||
}
|
||||
}
|
||||
finally {
|
||||
resultSet.close();
|
||||
}
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw jdbcEnvironment.getSqlExceptionHelper().convert(
|
||||
e,
|
||||
"Error accessing index information: " + tableInformation.getName().toString()
|
||||
);
|
||||
}
|
||||
|
||||
final Map<Identifier, IndexInformationImpl> indexes = new HashMap<Identifier, IndexInformationImpl>();
|
||||
for ( IndexInformationImpl.Builder builder : builders.values() ) {
|
||||
IndexInformationImpl index = builder.build();
|
||||
indexes.put( index.getIndexIdentifier(), index );
|
||||
}
|
||||
return indexes;
|
||||
}
|
||||
|
||||
public Map<Identifier, ForeignKeyInformationImpl> getForeignKeyMetadata(TableInformationImpl tableMetadata) {
|
||||
final Map<Identifier, ForeignKeyInformationImpl.Builder> fkBuilders
|
||||
= new HashMap<Identifier, ForeignKeyInformationImpl.Builder>();
|
||||
|
||||
try {
|
||||
ResultSet resultSet = databaseMetaData.getImportedKeys(
|
||||
identifierHelper().toMetaDataCatalogName( tableMetadata.getName().getCatalog() ),
|
||||
identifierHelper().toMetaDataSchemaName( tableMetadata.getName().getSchema() ),
|
||||
identifierHelper().toMetaDataObjectName( tableMetadata.getName().getName() )
|
||||
);
|
||||
|
||||
// todo : need to account for getCrossReference() as well...
|
||||
|
||||
try {
|
||||
while ( resultSet.next() ) {
|
||||
// IMPL NOTE : intentionally build the builder early!
|
||||
final Identifier fkIdentifier = Identifier.toIdentifier( resultSet.getString( "FK_NAME" ) );
|
||||
ForeignKeyInformationImpl.Builder fkBuilder = fkBuilders.get( fkIdentifier );
|
||||
if ( fkBuilder == null ) {
|
||||
fkBuilder = ForeignKeyInformationImpl.builder( fkIdentifier );
|
||||
fkBuilders.put( fkIdentifier, fkBuilder );
|
||||
}
|
||||
|
||||
final ObjectName incomingPkTableName = extractKeyTableName( resultSet, "PK" );
|
||||
|
||||
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
|
||||
// not a match based solely on schema/catalog and that another row in this result set
|
||||
// should match.
|
||||
continue;
|
||||
}
|
||||
|
||||
final Identifier fkColumnIdentifier = Identifier.toIdentifier( resultSet.getString( "FKCOLUMN_NAME" ) );
|
||||
final Identifier pkColumnIdentifier = Identifier.toIdentifier( resultSet.getString( "PKCOLUMN_NAME" ) );
|
||||
|
||||
fkBuilder.addColumnMapping(
|
||||
tableMetadata.getColumnInformation( fkColumnIdentifier ),
|
||||
pkTableMetadata.getColumnInformation( pkColumnIdentifier )
|
||||
);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
resultSet.close();
|
||||
}
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw jdbcEnvironment.getSqlExceptionHelper().convert(
|
||||
e,
|
||||
"Error accessing column metadata: " + tableMetadata.getName().toString()
|
||||
);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
private ObjectName extractKeyTableName(ResultSet resultSet, String prefix) throws SQLException {
|
||||
final String incomingCatalogName = resultSet.getString( prefix + "TABLE_SCHEM" );
|
||||
final String incomingSchemaName = resultSet.getString( prefix + "TABLE_CATALOG" );
|
||||
final String incomingTableName = resultSet.getString( prefix + "TABLE_NAME" );
|
||||
|
||||
return new ObjectName(
|
||||
Identifier.toIdentifier( incomingCatalogName ), Identifier.toIdentifier( incomingSchemaName ),
|
||||
Identifier.toIdentifier( incomingTableName )
|
||||
);
|
||||
}
|
||||
|
||||
private TruthValue interpretTruthValue(String nullable) {
|
||||
if ( "yes".equalsIgnoreCase( nullable ) ) {
|
||||
return TruthValue.TRUE;
|
||||
}
|
||||
else if ( "no".equalsIgnoreCase( nullable ) ) {
|
||||
return TruthValue.FALSE;
|
||||
}
|
||||
return TruthValue.UNKNOWN;
|
||||
}
|
||||
|
||||
public static interface Builder {
|
||||
public Builder prepareAll();
|
||||
public Builder prepareCatalogAndSchema(Schema.Name schemaName);
|
||||
public Builder prepareCatalog(Identifier catalog);
|
||||
public Builder prepareSchema(Identifier schema);
|
||||
public DatabaseInformation build();
|
||||
}
|
||||
|
||||
private static class BuilderImpl implements Builder {
|
||||
private final DatabaseInformationImpl it;
|
||||
|
||||
public BuilderImpl(JdbcEnvironment jdbcEnvironment, DatabaseMetaData databaseMetaData) throws SQLException {
|
||||
it = new DatabaseInformationImpl( jdbcEnvironment, databaseMetaData );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder prepareAll() {
|
||||
prepare( null, null );
|
||||
return this;
|
||||
}
|
||||
|
||||
private void prepare(String catalog, String schema) {
|
||||
try {
|
||||
ResultSet resultSet = it.databaseMetaData.getTables(
|
||||
catalog,
|
||||
schema,
|
||||
null,
|
||||
TABLE_TYPES
|
||||
);
|
||||
|
||||
try {
|
||||
it.loadTableMetadata( resultSet );
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
resultSet.close();
|
||||
}
|
||||
catch (SQLException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SQLException sqlException) {
|
||||
throw it.jdbcEnvironment.getSqlExceptionHelper().convert( sqlException, "Error accessing table metadata" );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder prepareCatalogAndSchema(Schema.Name schemaName) {
|
||||
prepare(
|
||||
it.identifierHelper().toMetaDataCatalogName( schemaName.getCatalog() ),
|
||||
it.identifierHelper().toMetaDataSchemaName( schemaName.getSchema() )
|
||||
);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder prepareCatalog(Identifier catalog) {
|
||||
prepare(
|
||||
it.identifierHelper().toMetaDataCatalogName( catalog ),
|
||||
null
|
||||
);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder prepareSchema(Identifier schema) {
|
||||
prepare(
|
||||
null,
|
||||
it.identifierHelper().toMetaDataSchemaName( schema )
|
||||
);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DatabaseInformation build() {
|
||||
return it;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -36,12 +36,12 @@ import org.hibernate.metamodel.spi.relational.Schema;
|
|||
import org.hibernate.metamodel.spi.relational.Sequence;
|
||||
import org.hibernate.metamodel.spi.relational.Table;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.tool.schema.spi.DatabaseInformation;
|
||||
import org.hibernate.tool.schema.spi.ForeignKeyInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.DatabaseInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.ForeignKeyInformation;
|
||||
import org.hibernate.tool.schema.spi.SchemaManagementException;
|
||||
import org.hibernate.tool.schema.spi.SchemaMigrator;
|
||||
import org.hibernate.tool.schema.spi.SequenceInformation;
|
||||
import org.hibernate.tool.schema.spi.TableInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.SequenceInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.TableInformation;
|
||||
import org.hibernate.tool.schema.spi.Target;
|
||||
|
||||
|
||||
|
|
|
@ -29,12 +29,12 @@ import org.hibernate.metamodel.spi.relational.Schema;
|
|||
import org.hibernate.metamodel.spi.relational.Sequence;
|
||||
import org.hibernate.metamodel.spi.relational.Table;
|
||||
import org.hibernate.metamodel.spi.relational.Value;
|
||||
import org.hibernate.tool.schema.spi.ColumnInformation;
|
||||
import org.hibernate.tool.schema.spi.DatabaseInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.ColumnInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.DatabaseInformation;
|
||||
import org.hibernate.tool.schema.spi.SchemaManagementException;
|
||||
import org.hibernate.tool.schema.spi.SchemaValidator;
|
||||
import org.hibernate.tool.schema.spi.SequenceInformation;
|
||||
import org.hibernate.tool.schema.spi.TableInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.SequenceInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.TableInformation;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
|
@ -74,7 +74,7 @@ public class SchemaValidatorImpl implements SchemaValidator {
|
|||
for ( Value value : table.values() ) {
|
||||
if ( Column.class.isInstance( value ) ) {
|
||||
final Column column = (Column) value;
|
||||
final ColumnInformation columnInformation = tableInformation.getColumnInformation( column.getColumnName() );
|
||||
final ColumnInformation columnInformation = tableInformation.getColumn( column.getColumnName() );
|
||||
if ( columnInformation == null ) {
|
||||
throw new SchemaManagementException(
|
||||
String.format(
|
||||
|
|
|
@ -1,100 +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.tool.schema.internal;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
import org.hibernate.metamodel.spi.relational.ObjectName;
|
||||
import org.hibernate.tool.schema.spi.ColumnInformation;
|
||||
import org.hibernate.tool.schema.spi.ForeignKeyInformation;
|
||||
import org.hibernate.tool.schema.spi.IndexInformation;
|
||||
import org.hibernate.tool.schema.spi.TableInformation;
|
||||
|
||||
/**
|
||||
* Provides access to information about existing schema objects (tables, sequences etc) of existing database.
|
||||
*
|
||||
* @author Christoph Sturm
|
||||
* @author Max Rydahl Andersen
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class TableInformationImpl implements TableInformation {
|
||||
private final DatabaseInformationImpl database;
|
||||
private final ObjectName tableName;
|
||||
private final Map<Identifier, ColumnInformation> columns;
|
||||
|
||||
private Map<Identifier, ForeignKeyInformationImpl> foreignKeys;
|
||||
private Map<Identifier, IndexInformationImpl> indexes;
|
||||
|
||||
public TableInformationImpl(DatabaseInformationImpl database, ObjectName tableName) {
|
||||
this.database = database;
|
||||
this.tableName = tableName;
|
||||
this.columns = database.getColumnMetadata( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectName getName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColumnInformation getColumnInformation(Identifier columnIdentifier) {
|
||||
return columns.get( columnIdentifier );
|
||||
}
|
||||
|
||||
protected Map<Identifier, ForeignKeyInformationImpl> foreignKeys() {
|
||||
if ( foreignKeys == null ) {
|
||||
foreignKeys = database.getForeignKeyMetadata( this );
|
||||
}
|
||||
return foreignKeys;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ForeignKeyInformation getForeignKeyInformation(Identifier fkIdentifier) {
|
||||
return foreignKeys().get( fkIdentifier );
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Iterable getForeignKeyInformations() {
|
||||
return foreignKeys().values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TableInformationImpl(" + tableName.toString() + ')';
|
||||
}
|
||||
|
||||
protected Map<Identifier, IndexInformationImpl> indexes() {
|
||||
if ( indexes == null ) {
|
||||
indexes = database.getIndexInformation( this );
|
||||
}
|
||||
return indexes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IndexInformation getIndexInformation(Identifier indexName) {
|
||||
return indexes().get( indexName );
|
||||
}
|
||||
}
|
|
@ -26,6 +26,7 @@ package org.hibernate.tool.schema.spi;
|
|||
import java.util.List;
|
||||
|
||||
import org.hibernate.metamodel.spi.relational.Database;
|
||||
import org.hibernate.tool.schema.extract.spi.DatabaseInformation;
|
||||
|
||||
/**
|
||||
* Service delegate for handling schema migration.
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
package org.hibernate.tool.schema.spi;
|
||||
|
||||
import org.hibernate.metamodel.spi.relational.Database;
|
||||
import org.hibernate.tool.schema.extract.spi.DatabaseInformation;
|
||||
|
||||
/**
|
||||
* Service delegate for handling schema validations
|
||||
|
|
|
@ -28,19 +28,20 @@ import java.sql.DriverManager;
|
|||
import java.sql.SQLException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||
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.metamodel.spi.relational.ObjectName;
|
||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
import org.hibernate.tool.schema.extract.spi.DatabaseInformation;
|
||||
import org.hibernate.tool.schema.extract.spi.DatabaseInformationBuilder;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.metamodel.spi.relational.ObjectName;
|
||||
import org.hibernate.service.ServiceRegistryBuilder;
|
||||
import org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentImpl;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
import org.hibernate.tool.schema.internal.DatabaseInformationImpl;
|
||||
import org.hibernate.tool.schema.spi.DatabaseInformation;
|
||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
@ -56,7 +57,7 @@ public class ExistingDatabaseMetaDataImplTest extends BaseUnitTestCase {
|
|||
@Before
|
||||
public void prepare() throws SQLException {
|
||||
Properties props = Environment.getProperties();
|
||||
serviceRegistry = (ServiceRegistryImplementor) new ServiceRegistryBuilder().applySettings( props ).build();
|
||||
serviceRegistry = (ServiceRegistryImplementor) new StandardServiceRegistryBuilder().applySettings( props ).build();
|
||||
connection = DriverManager.getConnection(
|
||||
props.getProperty( Environment.URL ),
|
||||
props.getProperty( Environment.USER ),
|
||||
|
@ -83,14 +84,15 @@ public class ExistingDatabaseMetaDataImplTest extends BaseUnitTestCase {
|
|||
}
|
||||
}
|
||||
if ( serviceRegistry != null ) {
|
||||
ServiceRegistryBuilder.destroy( serviceRegistry );
|
||||
StandardServiceRegistryBuilder.destroy( serviceRegistry );
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTableMetadata() throws Exception {
|
||||
DatabaseInformation databaseMetaData =
|
||||
DatabaseInformationImpl.builder( jdbcEnvironment, connection.getMetaData() ).prepareAll().build();
|
||||
DatabaseInformation databaseMetaData = new DatabaseInformationBuilder( jdbcEnvironment, connection )
|
||||
.prepareAll()
|
||||
.build();
|
||||
|
||||
ObjectName name = new ObjectName( null, null, "t1" );
|
||||
assertNotNull( databaseMetaData.getTableInformation( name ) );
|
||||
|
|
Loading…
Reference in New Issue