@@ -0,0 +1,101 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.engine.jdbc.env.internal;

import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.metamodel.spi.relational.ObjectName;
import org.hibernate.service.schema.internal.ExistingSequenceMetadataImpl;
import org.hibernate.service.schema.spi.ExistingSequenceMetadata;
import org.hibernate.service.schema.spi.ExistingSequenceMetadataExtractor;

/**
* Temporary implementation that works for H2.
*
* @author Steve Ebersole
*/
public class TemporaryExistingSequenceMetadataExtractor implements ExistingSequenceMetadataExtractor {
private final JdbcEnvironmentImpl jdbcEnvironment;

public TemporaryExistingSequenceMetadataExtractor(JdbcEnvironmentImpl jdbcEnvironment) {
this.jdbcEnvironment = jdbcEnvironment;
}

@Override
public Iterable<ExistingSequenceMetadata> extractMetadata(DatabaseMetaData databaseMetaData) throws SQLException {
Statement statement = databaseMetaData.getConnection().createStatement();
try {
ResultSet resultSet = statement.executeQuery(
"select SEQUENCE_CATALOG, SEQUENCE_SCHEMA, SEQUENCE_NAME " +
"from information_schema.sequences"
);
try {
final List<ExistingSequenceMetadata> sequenceMetadataList = new ArrayList<ExistingSequenceMetadata>();
while ( resultSet.next() ) {
sequenceMetadataList.add(
new ExistingSequenceMetadataImpl(
new ObjectName(
jdbcEnvironment.getIdentifierHelper().fromMetaDataCatalogName(
resultSet.getString(
"SEQUENCE_CATALOG"
)
),
jdbcEnvironment.getIdentifierHelper().fromMetaDataSchemaName(
resultSet.getString(
"SEQUENCE_SCHEMA"
)
),
jdbcEnvironment.getIdentifierHelper().fromMetaDataCatalogName(
resultSet.getString(
"SEQUENCE_NAME"
)
)
)
)
);
}
return sequenceMetadataList;
}
finally {
try {
resultSet.close();
}
catch (SQLException ignore) {
}
}
}
finally {
try {
statement.close();
}
catch (SQLException ignore) {
}
}
}
}
@@ -0,0 +1,69 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.engine.jdbc.env.internal;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.hibernate.engine.jdbc.env.spi.SchemaNameResolver;

/**
* Temporary implementation that works for H2.
*
* @author Steve Ebersole
*/
public class TemporarySchemaNameResolver implements SchemaNameResolver {
public static final TemporarySchemaNameResolver INSTANCE = new TemporarySchemaNameResolver();

@Override
public String resolveSchemaName(Connection connection) throws SQLException {
// the H2 variant...
Statement statement = connection.createStatement();
try {
ResultSet resultSet = statement.executeQuery( "call schema()" );
try {
if ( ! resultSet.next() ) {
return null;
}
return resultSet.getString( 1 );
}
finally {
try {
resultSet.close();
}
catch (SQLException ignore) {
}
}
}
finally {
try {
statement.close();
}
catch (SQLException ignore) {
}
}
}
}
@@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.service.schema.spi;
package org.hibernate.engine.jdbc.env.spi;

import org.hibernate.metamodel.spi.relational.Identifier;

@@ -26,8 +26,8 @@
import java.util.Set;

import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.spi.SchemaNameResolver;
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
import org.hibernate.metamodel.spi.relational.Identifier;
import org.hibernate.service.schema.spi.ExistingSequenceMetadataExtractor;

/**
@@ -39,9 +39,13 @@
public interface JdbcEnvironment {
public Dialect getDialect();

public Identifier getCurrentCatalog();

public Identifier getCurrentSchema();

public SchemaCatalogSupport getSchemaCatalogSupport();

public SchemaNameResolver getSchemaNameResolver();
public IdentifierHelper getIdentifierHelper();

public Set<String> getReservedWords();

@@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.engine.jdbc.spi;
package org.hibernate.engine.jdbc.env.spi;

import java.sql.Connection;
import java.sql.SQLException;

This file was deleted.

@@ -46,7 +46,7 @@
import org.hibernate.engine.jdbc.spi.JdbcConnectionAccess;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.jdbc.spi.ResultSetWrapper;
import org.hibernate.engine.jdbc.spi.SchemaNameResolver;
import org.hibernate.engine.jdbc.env.spi.SchemaNameResolver;
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
import org.hibernate.engine.jdbc.spi.SqlStatementLogger;
import org.hibernate.exception.internal.SQLExceptionTypeDelegate;
@@ -30,31 +30,24 @@
import java.util.Map;
import java.util.StringTokenizer;

import org.jboss.logging.Logger;

import org.hibernate.TruthValue;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.spi.relational.Identifier;
import org.hibernate.metamodel.spi.relational.ObjectName;
import org.hibernate.metamodel.spi.relational.Schema;
import org.hibernate.service.schema.spi.ExistingColumnMetadata;
import org.hibernate.service.schema.spi.ExistingDatabaseMetaData;
import org.hibernate.service.schema.spi.ExistingSequenceMetadata;
import org.hibernate.service.schema.spi.ExistingTableMetadata;
import org.hibernate.service.schema.spi.IdentifierHelper;

/**
* @author Steve Ebersole
*/
public class ExistingDatabaseMetaDataImpl implements ExistingDatabaseMetaData {
private static final Logger log = Logger.getLogger( ExistingDatabaseMetaDataImpl.class );

private final JdbcEnvironment jdbcEnvironment;
private final DatabaseMetaData databaseMetaData;

private final IdentifierHelperImpl identifierHelper;

private final Map<ObjectName,ExistingTableMetadataImpl> tables = new HashMap<ObjectName, ExistingTableMetadataImpl>();
private final Map<ObjectName,ExistingSequenceMetadata> sequences;

@@ -70,34 +63,28 @@ public static Builder builder(JdbcEnvironment jdbcEnvironment, DatabaseMetaData
private ExistingDatabaseMetaDataImpl(JdbcEnvironment jdbcEnvironment, DatabaseMetaData databaseMetaData) throws SQLException {
this.jdbcEnvironment = jdbcEnvironment;
this.databaseMetaData = databaseMetaData;
this.identifierHelper = new IdentifierHelperImpl(
databaseMetaData.getConnection().getCatalog(),
jdbcEnvironment.getSchemaNameResolver().resolveSchemaName( databaseMetaData.getConnection() ),
databaseMetaData.storesMixedCaseQuotedIdentifiers(),
databaseMetaData.storesLowerCaseQuotedIdentifiers(),
databaseMetaData.storesUpperCaseQuotedIdentifiers(),
databaseMetaData.storesUpperCaseIdentifiers(),
databaseMetaData.storesLowerCaseIdentifiers()
);
this.sequences = loadSequenceMetadataMap();
}

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(
final Identifier catalogIdentifier = identifierHelper().fromMetaDataCatalogName(
resultSet.getString(
"TABLE_CAT"
)
);
final Identifier schemaIdentifier = identifierHelper.fromMetaDataSchemaName(
final Identifier schemaIdentifier = identifierHelper().fromMetaDataSchemaName(
resultSet.getString(
"TABLE_SCHEM"
)
);
final Identifier tableIdentifier = identifierHelper.fromMetaDataObjectName(
final Identifier tableIdentifier = identifierHelper().fromMetaDataObjectName(
resultSet.getString(
"TABLE_NAME"
)
@@ -110,43 +97,65 @@ private void loadTableMetadata(ResultSet resultSet) throws SQLException {
}

tableMetadata = new ExistingTableMetadataImpl( this, tableName );
tables.put( tableName, tableMetadata );
tables.put( toMapKey( tableName ), tableMetadata );
}
}

private Map<ObjectName,ExistingSequenceMetadata> loadSequenceMetadataMap() throws SQLException {
Map<ObjectName,ExistingSequenceMetadata> sequences = new HashMap<ObjectName, ExistingSequenceMetadata>();
final Iterable<ExistingSequenceMetadata> sequenceMetadatas =
jdbcEnvironment.getExistingSequenceMetadataExtractor().extractMetadata(
databaseMetaData,
identifierHelper
);
jdbcEnvironment.getExistingSequenceMetadataExtractor().extractMetadata( databaseMetaData );
if ( sequenceMetadatas != null ) {
for ( ExistingSequenceMetadata sequenceMetadata :sequenceMetadatas ) {
sequences.put( sequenceMetadata.getSequenceName(), sequenceMetadata );
sequences.put( toMapKey( sequenceMetadata.getSequenceName() ), sequenceMetadata );
}
}
return sequences;
}

@Override
public ExistingTableMetadata getTableMetadata(ObjectName tableName) {
return tables.get( 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 ExistingSequenceMetadata getSequenceMetadata(ObjectName sequenceName) {
return sequences.get( sequenceName );
return sequences.get( toMapKey( sequenceName ) );
}

public Map<Identifier, ExistingColumnMetadata> getColumnMetadata(ExistingTableMetadata tableMetadata) {
final Map<Identifier, ExistingColumnMetadata> results = new HashMap<Identifier, ExistingColumnMetadata>();

try {
ResultSet resultSet = databaseMetaData.getColumns(
identifierHelper.toMetaDataCatalogName( tableMetadata.getName().getCatalog() ),
identifierHelper.toMetaDataSchemaName( tableMetadata.getName().getSchema() ),
identifierHelper.toMetaDataObjectName( tableMetadata.getName().getName() ),
identifierHelper().toMetaDataCatalogName( tableMetadata.getName().getCatalog() ),
identifierHelper().toMetaDataSchemaName( tableMetadata.getName().getSchema() ),
identifierHelper().toMetaDataObjectName( tableMetadata.getName().getName() ),
"%"
);

@@ -194,9 +203,9 @@ public Map<Identifier, ExistingForeignKeyMetadataImpl> getForeignKeyMetadata(Exi

try {
ResultSet resultSet = databaseMetaData.getImportedKeys(
identifierHelper.toMetaDataCatalogName( tableMetadata.getName().getCatalog() ),
identifierHelper.toMetaDataSchemaName( tableMetadata.getName().getSchema() ),
identifierHelper.toMetaDataObjectName( tableMetadata.getName().getName() )
identifierHelper().toMetaDataCatalogName( tableMetadata.getName().getCatalog() ),
identifierHelper().toMetaDataSchemaName( tableMetadata.getName().getSchema() ),
identifierHelper().toMetaDataObjectName( tableMetadata.getName().getName() )
);

// todo : need to account for getCrossReference() as well...
@@ -271,172 +280,6 @@ else if ( "no".equalsIgnoreCase( nullable ) ) {
return TruthValue.UNKNOWN;
}

public class IdentifierHelperImpl implements IdentifierHelper {
private final String currentCatalog;
private final String currentSchema;
private final boolean storesMixedCaseQuotedIdentifiers;
private final boolean storesLowerCaseQuotedIdentifiers;
private final boolean storesUpperCaseQuotedIdentifiers;
private final boolean storesUpperCaseIdentifiers;
private final boolean storesLowerCaseIdentifiers;

public IdentifierHelperImpl(
String currentCatalog,
String currentSchema,
boolean storesMixedCaseQuotedIdentifiers,
boolean storesLowerCaseQuotedIdentifiers,
boolean storesUpperCaseQuotedIdentifiers,
boolean storesUpperCaseIdentifiers,
boolean storesLowerCaseIdentifiers) {
this.currentCatalog = currentCatalog;
this.currentSchema = currentSchema;
this.storesMixedCaseQuotedIdentifiers = storesMixedCaseQuotedIdentifiers;
this.storesLowerCaseQuotedIdentifiers = storesLowerCaseQuotedIdentifiers;
this.storesUpperCaseQuotedIdentifiers = storesUpperCaseQuotedIdentifiers;
this.storesUpperCaseIdentifiers = storesUpperCaseIdentifiers;
this.storesLowerCaseIdentifiers = storesLowerCaseIdentifiers;

if ( storesMixedCaseQuotedIdentifiers && storesLowerCaseQuotedIdentifiers && storesUpperCaseQuotedIdentifiers ) {
log.warn( "JDBC Driver reports it stores quoted identifiers in mixed, upper and lower case" );
}
else if ( storesMixedCaseQuotedIdentifiers && storesUpperCaseQuotedIdentifiers ) {
log.warn( "JDBC Driver reports it stores quoted identifiers in both mixed and upper case" );
}
else if ( storesMixedCaseQuotedIdentifiers && storesLowerCaseQuotedIdentifiers ) {
log.warn( "JDBC Driver reports it stores quoted identifiers in both mixed and lower case" );
}

if ( storesUpperCaseIdentifiers && storesLowerCaseIdentifiers ) {
log.warn( "JDBC Driver reports it stores non-quoted identifiers in both upper and lower case" );
}

if ( storesUpperCaseIdentifiers && storesUpperCaseQuotedIdentifiers ) {
log.warn( "JDBC Driver reports it stores both quoted and non-quoted identifiers in upper case" );
}

if ( storesLowerCaseIdentifiers && storesLowerCaseQuotedIdentifiers ) {
log.warn( "JDBC Driver reports it stores both quoted and non-quoted identifiers in lower case" );
}
}

// In the DatabaseMetaData method params for catalog and schema name have the following meaning:
// 1) <""> means to match things "without a catalog/schema"
// 2) <null> means to not limit results based on this field
//
// todo : not sure how "without a catalog/schema" is interpreted. Current?

@Override
public String toMetaDataCatalogName(Identifier identifier) {
if ( identifier == null ) {
// todo : not sure if this is interpreted as <""> or <currentCatalog>
return currentCatalog;
}

return toText( identifier );
}

private String toText(Identifier identifier) {
if ( identifier == null ) {
throw new IllegalArgumentException( "Identifier cannot be null; bad usage" );
}

if ( identifier.isQuoted() && storesMixedCaseQuotedIdentifiers ) {
return identifier.getText();
}
else if ( ( identifier.isQuoted() && storesUpperCaseQuotedIdentifiers )
|| ( !identifier.isQuoted() && storesUpperCaseIdentifiers ) ) {
return StringHelper.toUpperCase( identifier.getText() );
}
else if ( ( identifier.isQuoted() && storesLowerCaseQuotedIdentifiers )
|| ( !identifier.isQuoted() && storesLowerCaseIdentifiers ) ) {
return StringHelper.toLowerCase( identifier.getText() );
}
return identifier.getText();
}

@Override
public String toMetaDataSchemaName(Identifier identifier) {
if ( identifier == null ) {
// todo : not sure if this is interpreted as <""> or <currentSchema>
return currentSchema;
}

return toText( identifier );
}

@Override
public String toMetaDataObjectName(Identifier identifier) {
if ( identifier == null ) {
// if this method was called, the value is needed
throw new IllegalArgumentException( );
}
return toText( identifier );
}

@Override
public Identifier fromMetaDataCatalogName(String catalogName) {
if ( catalogName == null ) {
return null;
}

if ( catalogName.equals( currentCatalog ) ) {
return null;
}

return toIdentifier( catalogName );
// note really sure the best way to know (can you?) whether the identifier is quoted

}

private Identifier toIdentifier(String incomingName) {
// lovely decipher of whether the incoming value represents a quoted identifier...
final boolean isUpperCase = incomingName.toUpperCase().equals( incomingName );
final boolean isLowerCase = incomingName.toLowerCase().equals( incomingName );
final boolean isMixedCase = ! isLowerCase && ! isUpperCase;

if ( jdbcEnvironment.getReservedWords().contains( incomingName ) ) {
// unequivocally it needs to be quoted...
return Identifier.toIdentifier( incomingName, true );
}

if ( storesMixedCaseQuotedIdentifiers && isMixedCase ) {
return Identifier.toIdentifier( incomingName, true );
}

if ( storesLowerCaseQuotedIdentifiers && isLowerCase ) {
return Identifier.toIdentifier( incomingName, true );
}

if ( storesUpperCaseQuotedIdentifiers && isUpperCase ) {
return Identifier.toIdentifier( incomingName, true );
}

return Identifier.toIdentifier( incomingName );
}

@Override
public Identifier fromMetaDataSchemaName(String schemaName) {
if ( schemaName == null ) {
return null;
}

if ( schemaName.equals( currentSchema ) ) {
return null;
}

return toIdentifier( schemaName );
}

@Override
public Identifier fromMetaDataObjectName(String objectName) {
if ( objectName == null ) {
return null;
}

return toIdentifier( objectName );
}
}

public static interface Builder {
public Builder prepareAll();
public Builder prepareCatalogAndSchema(Schema.Name schemaName);
@@ -487,16 +330,16 @@ private void prepare(String catalog, String schema) {
@Override
public Builder prepareCatalogAndSchema(Schema.Name schemaName) {
prepare(
it.identifierHelper.toMetaDataCatalogName( schemaName.getCatalog() ),
it.identifierHelper.toMetaDataSchemaName( schemaName.getSchema() )
it.identifierHelper().toMetaDataCatalogName( schemaName.getCatalog() ),
it.identifierHelper().toMetaDataSchemaName( schemaName.getSchema() )
);
return this;
}

@Override
public Builder prepareCatalog(Identifier catalog) {
prepare(
it.identifierHelper.toMetaDataCatalogName( catalog ),
it.identifierHelper().toMetaDataCatalogName( catalog ),
null
);
return this;
@@ -506,7 +349,7 @@ public Builder prepareCatalog(Identifier catalog) {
public Builder prepareSchema(Identifier schema) {
prepare(
null,
it.identifierHelper.toMetaDataSchemaName( schema )
it.identifierHelper().toMetaDataSchemaName( schema )
);
return this;
}
@@ -31,7 +31,5 @@
* @author Steve Ebersole
*/
public interface ExistingSequenceMetadataExtractor {
public Iterable<ExistingSequenceMetadata> extractMetadata(
DatabaseMetaData databaseMetaData,
IdentifierHelper identifierHelper) throws SQLException;
public Iterable<ExistingSequenceMetadata> extractMetadata(DatabaseMetaData databaseMetaData) throws SQLException;
}
@@ -30,8 +30,9 @@

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.engine.jdbc.env.spi.StandardJdbcEnvironmentBuilder;
import org.hibernate.metamodel.spi.relational.ObjectName;
import org.hibernate.service.schema.internal.ExistingDatabaseMetaDataImpl;
import org.hibernate.service.schema.spi.ExistingDatabaseMetaData;

@@ -41,6 +42,8 @@

import org.hibernate.testing.junit4.BaseUnitTestCase;

import static org.junit.Assert.assertNotNull;

/**
* @author Steve Ebersole
*/
@@ -56,18 +59,15 @@ public void prepare() throws SQLException {
props.getProperty( Environment.USER ),
props.getProperty( Environment.PASS )
);
connection.createStatement().execute( "CREATE SCHEMA \"another_schema\"" );
connection.createStatement().execute( "CREATE SCHEMA another_schema" );

connection.createStatement().execute( "CREATE TABLE t1 (name varchar)" );
connection.createStatement().execute( "CREATE TABLE db1.\"another_schema\".t2 (name varchar)" );
connection.createStatement().execute( "CREATE TABLE another_schema.t2 (name varchar)" );

connection.createStatement().execute( "CREATE SEQUENCE seq1" );
connection.createStatement().execute( "CREATE SEQUENCE db1.\"another_schema\".seq1" );
connection.createStatement().execute( "CREATE SEQUENCE db1.another_schema.seq2" );

jdbcEnvironment = StandardJdbcEnvironmentBuilder.INSTANCE.buildJdbcEnvironment(
connection.getMetaData(),
Dialect.getDialect( props )
);
jdbcEnvironment = new JdbcEnvironmentImpl( connection.getMetaData(), Dialect.getDialect( props ), props );
}

@After
@@ -81,10 +81,26 @@ public void release() {
}
}

// @Test
@Test
public void testGetTableMetadata() throws Exception {
ExistingDatabaseMetaData databaseMetaData =
ExistingDatabaseMetaDataImpl.builder( jdbcEnvironment, connection.getMetaData() ).prepareAll().build();
databaseMetaData.toString();

ObjectName name = new ObjectName( null, null, "t1" );
assertNotNull( databaseMetaData.getTableMetadata( name ) );

name = new ObjectName( null, "another_schema", "t2" );
assertNotNull( databaseMetaData.getTableMetadata( name ) );

name = new ObjectName( null, null, "seq1" );
assertNotNull( databaseMetaData.getSequenceMetadata( name ) );

name = new ObjectName( null, "another_schema", "seq2" );
assertNotNull( databaseMetaData.getSequenceMetadata( name ) );

// knowing if identifiers coming back from the database are quoted is all dicked up...
// see org.hibernate.engine.jdbc.env.internal.NormalizingIdentifierHelperImpl
//
// surely JDBC has a better way to determine this right?
}
}