diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/relational/Identifier.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/relational/Identifier.java
index 9cda8f66d6..b66ff016ef 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/relational/Identifier.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/relational/Identifier.java
@@ -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();
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/relational/Table.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/relational/Table.java
index 1ca1f7af71..cbec4852ba 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/relational/Table.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/relational/Table.java
@@ -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 TABLE (or VIEW).
@@ -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;
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/ColumnInformationImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/ColumnInformationImpl.java
similarity index 93%
rename from hibernate-core/src/main/java/org/hibernate/tool/schema/internal/ColumnInformationImpl.java
rename to hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/ColumnInformationImpl.java
index d158672f1c..e4013a73f6 100644
--- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/ColumnInformationImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/ColumnInformationImpl.java
@@ -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
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/DatabaseInformationImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/DatabaseInformationImpl.java
new file mode 100644
index 0000000000..b36c451260
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/DatabaseInformationImpl.java
@@ -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 tables = new HashMap();
+ private final Map sequences = new HashMap();
+
+ 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 );
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/ExtractionContextImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/ExtractionContextImpl.java
new file mode 100644
index 0000000000..a8f96851a9
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/ExtractionContextImpl.java
@@ -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) {
+ }
+ }
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/ForeignKeyInformationImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/ForeignKeyInformationImpl.java
similarity index 62%
rename from hibernate-core/src/main/java/org/hibernate/tool/schema/internal/ForeignKeyInformationImpl.java
rename to hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/ForeignKeyInformationImpl.java
index 3f8a02c518..a07d53a2b0 100644
--- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/ForeignKeyInformationImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/ForeignKeyInformationImpl.java
@@ -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 columnMappingList;
- private ForeignKeyInformationImpl(
+ public ForeignKeyInformationImpl(
Identifier fkIdentifier,
List columnMappingList) {
this.fkIdentifier = fkIdentifier;
@@ -51,37 +49,9 @@ public class ForeignKeyInformationImpl implements ForeignKeyInformation {
}
@Override
- public List getColumnReferenceMappingList() {
+ public Iterable getColumnReferenceMappings() {
return columnMappingList;
}
-
- public static Builder builder(Identifier fkIdentifier) {
- return new Builder( fkIdentifier );
- }
-
- public static class Builder {
- private final Identifier fkIdentifier;
- private final List columnMappingList = new ArrayList();
-
- 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;
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/IndexInformationImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/IndexInformationImpl.java
similarity index 93%
rename from hibernate-core/src/main/java/org/hibernate/tool/schema/internal/IndexInformationImpl.java
rename to hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/IndexInformationImpl.java
index 61bb31032d..b995cd0c43 100644
--- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/IndexInformationImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/IndexInformationImpl.java
@@ -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;
/**
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SequenceInformationImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/SequenceInformationImpl.java
similarity index 93%
rename from hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SequenceInformationImpl.java
rename to hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/SequenceInformationImpl.java
index bd5713af34..254c12ffb7 100644
--- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SequenceInformationImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/SequenceInformationImpl.java
@@ -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.
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/StandardJdbcDatabaseMetaDataExtractor.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/StandardJdbcDatabaseMetaDataExtractor.java
new file mode 100644
index 0000000000..683c84186f
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/StandardJdbcDatabaseMetaDataExtractor.java
@@ -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 getTables(String catalogFilter, String schemaFilter) {
+ try {
+ ResultSet resultSet = extractionContext.getJdbcDatabaseMetaData().getTables(
+ catalogFilter,
+ schemaFilter,
+ null,
+ TABLE_TYPES
+ );
+
+ final List results = new ArrayList();
+
+ 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 getColumns(TableInformation tableInformation) {
+ final List results = new ArrayList();
+
+ 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 getIndexes(TableInformation tableInformation) {
+ final Map builders = new HashMap();
+
+ 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 indexes = new ArrayList();
+ for ( IndexInformationImpl.Builder builder : builders.values() ) {
+ IndexInformationImpl index = builder.build();
+ indexes.add( index );
+ }
+ return indexes;
+ }
+
+ @Override
+ public Iterable getForeignKeys(TableInformation tableInformation) {
+ final Map fkBuilders = new HashMap();
+
+ 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 fks = new ArrayList();
+ 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 columnMappingList = new ArrayList();
+
+ 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 )
+ );
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/TableInformationImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/TableInformationImpl.java
new file mode 100644
index 0000000000..08f57285cf
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/TableInformationImpl.java
@@ -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 columns;
+ private Map foreignKeys;
+ private Map 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 getColumns() {
+ return columns().values();
+ }
+
+ protected Map columns() {
+ if ( this.columns == null ) {
+ final Map columnMap = new HashMap();
+ final Iterable 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 getForeignKeys() {
+ return foreignKeys().values();
+ }
+
+ protected Map foreignKeys() {
+ if ( foreignKeys == null ) {
+ final Map fkMap = new HashMap();
+ final Iterable 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 getIndexes() {
+ return indexes().values();
+ }
+
+ protected Map indexes() {
+ if ( indexes == null ) {
+ final Map indexMap = new HashMap();
+ final Iterable 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() + ')';
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/TemporarySequenceInformationExtractor.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/TemporarySequenceInformationExtractor.java
similarity index 66%
rename from hibernate-core/src/main/java/org/hibernate/tool/schema/internal/TemporarySequenceInformationExtractor.java
rename to hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/TemporarySequenceInformationExtractor.java
index 0d4f638df1..2a6d5b3ed0 100644
--- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/TemporarySequenceInformationExtractor.java
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/internal/TemporarySequenceInformationExtractor.java
@@ -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 extractMetadata(DatabaseMetaData databaseMetaData) throws SQLException {
- Statement statement = databaseMetaData.getConnection().createStatement();
+ public Iterable 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" )
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/package-info.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/package-info.java
new file mode 100644
index 0000000000..cb7d093f23
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/package-info.java
@@ -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.
+ */
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/spi/ColumnInformation.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/ColumnInformation.java
similarity index 98%
rename from hibernate-core/src/main/java/org/hibernate/tool/schema/spi/ColumnInformation.java
rename to hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/ColumnInformation.java
index df450dd5fd..a2cf37da0f 100644
--- a/hibernate-core/src/main/java/org/hibernate/tool/schema/spi/ColumnInformation.java
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/ColumnInformation.java
@@ -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;
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/spi/DatabaseInformation.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/DatabaseInformation.java
similarity index 97%
rename from hibernate-core/src/main/java/org/hibernate/tool/schema/spi/DatabaseInformation.java
rename to hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/DatabaseInformation.java
index 9ec824556c..0691964e55 100644
--- a/hibernate-core/src/main/java/org/hibernate/tool/schema/spi/DatabaseInformation.java
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/DatabaseInformation.java
@@ -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;
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/DatabaseInformationBuilder.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/DatabaseInformationBuilder.java
new file mode 100644
index 0000000000..4e924d39d5
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/DatabaseInformationBuilder.java
@@ -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 sequences = extractSequences();
+ if ( sequences != null ) {
+ for ( SequenceInformation sequenceInformation : sequences ) {
+ databaseInformation.registerSequenceInformation( sequenceInformation );
+ }
+ }
+
+ return this;
+ }
+
+ private Iterable 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;
+ }
+}
+
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/ExtractionContext.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/ExtractionContext.java
new file mode 100644
index 0000000000..a339d239d4
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/ExtractionContext.java
@@ -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();
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/spi/ForeignKeyInformation.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/ForeignKeyInformation.java
similarity index 87%
rename from hibernate-core/src/main/java/org/hibernate/tool/schema/spi/ForeignKeyInformation.java
rename to hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/ForeignKeyInformation.java
index 706269fb1c..7c520489c6 100644
--- a/hibernate-core/src/main/java/org/hibernate/tool/schema/spi/ForeignKeyInformation.java
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/ForeignKeyInformation.java
@@ -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 getColumnReferenceMappingList();
+ public Iterable getColumnReferenceMappings();
public static interface ColumnReferenceMapping {
/**
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/spi/IndexInformation.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/IndexInformation.java
similarity index 97%
rename from hibernate-core/src/main/java/org/hibernate/tool/schema/spi/IndexInformation.java
rename to hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/IndexInformation.java
index 19518e6a6d..6d6809bf01 100644
--- a/hibernate-core/src/main/java/org/hibernate/tool/schema/spi/IndexInformation.java
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/IndexInformation.java
@@ -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;
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/PrimaryKeyInformation.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/PrimaryKeyInformation.java
new file mode 100644
index 0000000000..4ece860e21
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/PrimaryKeyInformation.java
@@ -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 getColumns();
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/SchemaMetaDataExtractor.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/SchemaMetaDataExtractor.java
new file mode 100644
index 0000000000..dbe3b7395a
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/SchemaMetaDataExtractor.java
@@ -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:
+ * -
+ * {@code null} ({@link #ALL_CATALOGS_FILTER}) - Indicates that tables from all catalogs should be returned
+ *
+ * -
+ * {@code ""} (empty String) ({@link #SANS_CATALOG_FILTER}) - Indicates that only tables without a catalog
+ * should be returned
+ *
+ *
+ * @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:
+ * -
+ * {@code null} ({@link #ALL_SCHEMAS_FILTER}) - Indicates that tables from all schemas should be returned
+ *
+ * -
+ * {@code ""} (empty String) ({@link #SANS_SCHEMA_FILTER}) - Indicates that only tables without a schema
+ * should be returned
+ *
+ *
+ *
+ * @return iterator with map elements that has "TABLE_NAME", "TABLE_SCHEMA", "TABLE_CAT", "TABLE_TYPE" keys.
+ */
+ public Iterable 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 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 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 getForeignKeys(TableInformation tableInformation);
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/spi/SequenceInformation.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/SequenceInformation.java
similarity index 97%
rename from hibernate-core/src/main/java/org/hibernate/tool/schema/spi/SequenceInformation.java
rename to hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/SequenceInformation.java
index 258fa32368..56b329aa45 100644
--- a/hibernate-core/src/main/java/org/hibernate/tool/schema/spi/SequenceInformation.java
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/SequenceInformation.java
@@ -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;
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/spi/SequenceInformationExtractor.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/SequenceInformationExtractor.java
similarity index 86%
rename from hibernate-core/src/main/java/org/hibernate/tool/schema/spi/SequenceInformationExtractor.java
rename to hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/SequenceInformationExtractor.java
index fc33423f2a..f63edd1243 100644
--- a/hibernate-core/src/main/java/org/hibernate/tool/schema/spi/SequenceInformationExtractor.java
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/SequenceInformationExtractor.java
@@ -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 extractMetadata(DatabaseMetaData databaseMetaData) throws SQLException;
+ public Iterable extractMetadata(ExtractionContext extractionContext) throws SQLException;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/spi/TableInformation.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/TableInformation.java
similarity index 66%
rename from hibernate-core/src/main/java/org/hibernate/tool/schema/spi/TableInformation.java
rename to hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/TableInformation.java
index 4ec2c806dd..f566082181 100644
--- a/hibernate-core/src/main/java/org/hibernate/tool/schema/spi/TableInformation.java
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/extract/spi/TableInformation.java
@@ -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 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 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 getForeignKeyInformations();
+ public Iterable 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);
}
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/DatabaseInformationImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/DatabaseInformationImpl.java
deleted file mode 100644
index 3c7b00a311..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/DatabaseInformationImpl.java
+++ /dev/null
@@ -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 tables = new HashMap();
- private final Map 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 loadSequenceMetadataMap() throws SQLException {
- Map sequences = new HashMap();
- // todo : temporary impl!
- final Iterable 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 getColumnMetadata(TableInformation tableInformation) {
- final Map results = new HashMap();
-
- 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 getIndexInformation(TableInformationImpl tableInformation) {
- final Map builders = new HashMap();
-
- 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 indexes = new HashMap();
- for ( IndexInformationImpl.Builder builder : builders.values() ) {
- IndexInformationImpl index = builder.build();
- indexes.put( index.getIndexIdentifier(), index );
- }
- return indexes;
- }
-
- public Map getForeignKeyMetadata(TableInformationImpl tableMetadata) {
- final Map fkBuilders
- = new HashMap();
-
- 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 fks = new HashMap();
- 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;
- }
- }
-}
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaMigratorImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaMigratorImpl.java
index 60e8438ea0..7ec86579a1 100644
--- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaMigratorImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaMigratorImpl.java
@@ -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;
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaValidatorImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaValidatorImpl.java
index 03f50367ad..93dd2121a2 100644
--- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaValidatorImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaValidatorImpl.java
@@ -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(
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/TableInformationImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/TableInformationImpl.java
deleted file mode 100644
index b8c3eb6091..0000000000
--- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/TableInformationImpl.java
+++ /dev/null
@@ -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 columns;
-
- private Map foreignKeys;
- private Map 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 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 indexes() {
- if ( indexes == null ) {
- indexes = database.getIndexInformation( this );
- }
- return indexes;
- }
-
- @Override
- public IndexInformation getIndexInformation(Identifier indexName) {
- return indexes().get( indexName );
- }
-}
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/spi/SchemaMigrator.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/spi/SchemaMigrator.java
index 34c3988896..dc34db162d 100644
--- a/hibernate-core/src/main/java/org/hibernate/tool/schema/spi/SchemaMigrator.java
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/spi/SchemaMigrator.java
@@ -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.
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/spi/SchemaValidator.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/spi/SchemaValidator.java
index d86de8b9dc..fb45ce754a 100644
--- a/hibernate-core/src/main/java/org/hibernate/tool/schema/spi/SchemaValidator.java
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/spi/SchemaValidator.java
@@ -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
diff --git a/hibernate-core/src/test/java/org/hibernate/test/service/schema/internal/ExistingDatabaseMetaDataImplTest.java b/hibernate-core/src/test/java/org/hibernate/test/service/schema/internal/ExistingDatabaseMetaDataImplTest.java
index ed1d3db3bf..2bf92e4696 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/service/schema/internal/ExistingDatabaseMetaDataImplTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/service/schema/internal/ExistingDatabaseMetaDataImplTest.java
@@ -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 ) );