package org.hibernate.metamodel.relational;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.hibernate.MappingException;
import org.hibernate.dialect.Dialect;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.metamodel.Metadata;
public class Database {
private final Schema.Name implicitSchemaName;
private final Map<Schema.Name,Schema> schemaMap = new HashMap<Schema.Name, Schema>();
private final List<AuxiliaryDatabaseObject> auxiliaryDatabaseObjects = new ArrayList<AuxiliaryDatabaseObject>();
public Database(Metadata.Options options) {
String schemaName = options.getDefaultSchemaName();
String catalogName = options.getDefaultCatalogName();
if ( options.isGloballyQuotedIdentifiers() ) {
schemaName = StringHelper.quote( schemaName );
catalogName = StringHelper.quote( catalogName );
}
implicitSchemaName = new Schema.Name( schemaName, catalogName );
makeSchema( implicitSchemaName );
}
public Schema getDefaultSchema() {
return schemaMap.get( implicitSchemaName );
}
public Schema locateSchema(Schema.Name name) {
if ( name.getSchema() == null && name.getCatalog() == null ) {
return getDefaultSchema();
}
Schema schema = schemaMap.get( name );
if ( schema == null ) {
schema = makeSchema( name );
}
return schema;
}
private Schema makeSchema(Schema.Name name) {
Schema schema;
schema = new Schema( name );
schemaMap.put( name, schema );
return schema;
}
public Schema getSchema(Identifier schema, Identifier catalog) {
return locateSchema( new Schema.Name( schema, catalog ) );
}
public Schema getSchema(String schema, String catalog) {
return locateSchema( new Schema.Name( Identifier.toIdentifier( schema ), Identifier.toIdentifier( catalog ) ) );
}
public void addAuxiliaryDatabaseObject(AuxiliaryDatabaseObject auxiliaryDatabaseObject) {
if ( auxiliaryDatabaseObject == null ) {
throw new IllegalArgumentException( "Auxiliary database object is null." );
}
auxiliaryDatabaseObjects.add( auxiliaryDatabaseObject );
}
public Iterable<AuxiliaryDatabaseObject> getAuxiliaryDatabaseObjects() {
return auxiliaryDatabaseObjects;
}
public String[] generateSchemaCreationScript(Dialect dialect) {
Set<String> exportIdentifiers = new HashSet<String>( 50 );
List<String> script = new ArrayList<String>( 50 );
for ( Schema schema : schemaMap.values() ) {
for ( Table table : schema.getTables() ) {
addSqlCreateStrings( dialect, exportIdentifiers, script, table );
}
}
for ( Schema schema : schemaMap.values() ) {
for ( Table table : schema.getTables() ) {
for ( UniqueKey uniqueKey : table.getUniqueKeys() ) {
addSqlCreateStrings( dialect, exportIdentifiers, script, uniqueKey );
}
for ( Index index : table.getIndexes() ) {
addSqlCreateStrings( dialect, exportIdentifiers, script, index );
}
if ( dialect.hasAlterTable() ) {
for ( ForeignKey foreignKey : table.getForeignKeys() ) {
if ( Table.class.isInstance( foreignKey.getTargetTable() ) ) {
addSqlCreateStrings( dialect, exportIdentifiers, script, foreignKey );
}
}
}
}
}
for ( AuxiliaryDatabaseObject auxiliaryDatabaseObject : auxiliaryDatabaseObjects ) {
if ( auxiliaryDatabaseObject.appliesToDialect( dialect ) ) {
addSqlCreateStrings( dialect, exportIdentifiers, script, auxiliaryDatabaseObject );
}
}
return ArrayHelper.toStringArray( script );
}
public String[] generateDropSchemaScript(Dialect dialect) {
Set<String> exportIdentifiers = new HashSet<String>( 50 );
List<String> script = new ArrayList<String>( 50 );
for ( int i = auxiliaryDatabaseObjects.size() - 1 ; i >= 0 ; i-- ) {
AuxiliaryDatabaseObject object = auxiliaryDatabaseObjects.get( i );
if ( object.appliesToDialect( dialect ) ) {
addSqlDropStrings( dialect, exportIdentifiers, script, object );
}
}
if ( dialect.dropConstraints() ) {
for ( Schema schema : schemaMap.values() ) {
for ( Table table : schema.getTables() ) {
for ( ForeignKey foreignKey : table.getForeignKeys() ) {
if ( foreignKey.getTargetTable() instanceof Table ) {
addSqlDropStrings( dialect, exportIdentifiers, script, foreignKey );
}
}
}
}
}
for ( Schema schema : schemaMap.values() ) {
for ( Table table : schema.getTables() ) {
addSqlDropStrings( dialect, exportIdentifiers, script, table );
}
}
return ArrayHelper.toStringArray( script );
}
private static void addSqlDropStrings(
Dialect dialect,
Set<String> exportIdentifiers,
List<String> script,
Exportable exportable) {
addSqlStrings(
exportIdentifiers, script, exportable.getExportIdentifier(), exportable.sqlDropStrings( dialect )
);
}
private static void addSqlCreateStrings(
Dialect dialect,
Set<String> exportIdentifiers,
List<String> script,
Exportable exportable) {
addSqlStrings(
exportIdentifiers, script, exportable.getExportIdentifier(), exportable.sqlCreateStrings( dialect )
);
}
private static void addSqlStrings(
Set<String> exportIdentifiers,
List<String> script,
String exportIdentifier,
String[] sqlStrings) {
if ( sqlStrings == null ) {
return;
}
if ( exportIdentifiers.contains( exportIdentifier ) ) {
throw new MappingException(
"SQL strings added more than once for: " + exportIdentifier
);
}
exportIdentifiers.add( exportIdentifier );
script.addAll( Arrays.asList( sqlStrings ) );
}
}