HHH-7472 - Introduce a "schema management" service : ordering of statements including ordering of auxiliary objects

This commit is contained in:
Steve Ebersole 2012-08-14 13:48:20 -05:00
parent 07973f29a2
commit d24f3e76f1
6 changed files with 89 additions and 25 deletions

View File

@ -1844,6 +1844,28 @@ public final String quote(String name) {
// DDL support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Get the SQL command used to create the named schema
*
* @param schemaName The name of the schema to be created.
*
* @return The creation command
*/
public String getCreateSchemaCommand(String schemaName) {
return "create schema " + schemaName;
}
/**
* Get the SQL command used to drop the named schema
*
* @param schemaName The name of the schema to be dropped.
*
* @return The drop command
*/
public String getDropSchemaCommand(String schemaName) {
return "drop schema " + schemaName;
}
/**
* Does this dialect support the <tt>ALTER TABLE</tt> syntax?
*

View File

@ -46,9 +46,15 @@ public abstract class AbstractAuxiliaryDatabaseObject implements AuxiliaryDataba
private static final AtomicInteger counter = new AtomicInteger( 0 );
private final String exportIdentifier;
private final Set<String> dialectScopes;
private boolean beforeTablesOnCreation;
protected AbstractAuxiliaryDatabaseObject(Set<String> dialectScopes) {
this( dialectScopes, false );
}
protected AbstractAuxiliaryDatabaseObject(Set<String> dialectScopes, boolean beforeTablesOnCreation) {
this.dialectScopes = dialectScopes == null ? new HashSet<String>() : dialectScopes;
this.beforeTablesOnCreation = beforeTablesOnCreation;
this.exportIdentifier =
new StringBuilder( EXPORT_IDENTIFIER_PREFIX )
.append( '.' )
@ -73,4 +79,9 @@ public boolean appliesToDialect(Dialect dialect) {
public String getExportIdentifier() {
return exportIdentifier;
}
@Override
public boolean beforeTablesOnCreation() {
return beforeTablesOnCreation;
}
}

View File

@ -41,5 +41,18 @@ public interface AuxiliaryDatabaseObject extends Exportable, Serializable {
* @param dialect The dialect to check against.
* @return True if this database object does apply to the given dialect.
*/
boolean appliesToDialect(Dialect dialect);
public boolean appliesToDialect(Dialect dialect);
/**
* Defines a simple precedence. Should creation of this auxiliary object happen before creation of
* tables? If {@code true}, the auxiliary object creation will happen after any explicit schema creations
* but before table/sequence creations; if {@code false}, the auxiliary object creation will happen after
* explicit schema creations and after table/sequence creations.
*
* This precedence is automatically inverted for dropping.
*
* @return {@code true} indicates this object should be created before tables; {@code false} indicates
* it should be created after.
*/
public boolean beforeTablesOnCreation();
}

View File

@ -35,6 +35,7 @@
public class BasicAuxiliaryDatabaseObjectImpl extends AbstractAuxiliaryDatabaseObject {
private static final String CATALOG_NAME_PLACEHOLDER = "${catalog}";
private static final String SCHEMA_NAME_PLACEHOLDER = "${schema}";
private final Schema defaultSchema;
private final String createString;
private final String dropString;

View File

@ -66,22 +66,30 @@ public void doCreation(Database database, boolean createSchemas, Target... targe
final Set<String> exportIdentifiers = new HashSet<String>( 50 );
// first, create each schema
for ( Schema schema : database.getSchemas() ) {
if ( createSchemas ) {
// todo : add dialect method for getting a CREATE SCHEMA command and use it here
applySqlStrings( targets, dialect.getCreateSchemaCommand( schema.getName().getSchema().getText( dialect ) ) );
}
}
// next, create all "before table" auxiliary objects
for ( AuxiliaryDatabaseObject auxiliaryDatabaseObject : database.getAuxiliaryDatabaseObjects() ) {
if ( auxiliaryDatabaseObject.appliesToDialect( dialect ) && auxiliaryDatabaseObject.beforeTablesOnCreation() ) {
applySqlStrings( auxiliaryDatabaseObject, targets, dialect, exportIdentifiers );
}
}
// then, create all schema objects: tables, sequences, constraints, etc
for ( Schema schema : database.getSchemas() ) {
for ( Table table : schema.getTables() ) {
applySqlStrings( table, targets, dialect, exportIdentifiers );
}
for ( Sequence sequence : schema.getSequences() ) {
applySqlStrings( sequence, targets, dialect, exportIdentifiers );
}
// todo : allow stuff like user datatypes.
// maybe reusing AuxiliaryDatabaseObject as the general vehicle, but adding a notion of where
// it needs to be in terms of creation?
for ( Table table : schema.getTables() ) {
if ( ! dialect.supportsUniqueConstraintInCreateAlterTable() ) {
for ( UniqueKey uniqueKey : table.getUniqueKeys() ) {
@ -102,16 +110,18 @@ public void doCreation(Database database, boolean createSchemas, Target... targe
}
}
}
}
for ( AuxiliaryDatabaseObject auxiliaryDatabaseObject : database.getAuxiliaryDatabaseObjects() ) {
if ( auxiliaryDatabaseObject.appliesToDialect( dialect ) ) {
applySqlStrings( auxiliaryDatabaseObject, targets, dialect, exportIdentifiers );
}
// next, create all "after table" auxiliary objects
for ( AuxiliaryDatabaseObject auxiliaryDatabaseObject : database.getAuxiliaryDatabaseObjects() ) {
if ( auxiliaryDatabaseObject.appliesToDialect( dialect ) && !auxiliaryDatabaseObject.beforeTablesOnCreation() ) {
applySqlStrings( auxiliaryDatabaseObject, targets, dialect, exportIdentifiers );
}
}
for ( InitCommand initCommand : database.getInitCommands() ) {
applySqlStrings( initCommand.getInitCommands(), targets );
}
// and finally add all init commands
for ( InitCommand initCommand : database.getInitCommands() ) {
applySqlStrings( targets, initCommand.getInitCommands() );
}
for ( Target target : targets ) {
@ -130,10 +140,10 @@ private static void applySqlStrings(
}
exportIdentifiers.add( exportIdentifier );
applySqlStrings( exportable.sqlCreateStrings( dialect ), targets );
applySqlStrings( targets, exportable.sqlCreateStrings( dialect ) );
}
private static void applySqlStrings(String[] sqlStrings, Target[] targets) {
private static void applySqlStrings(Target[] targets, String... sqlStrings) {
if ( sqlStrings == null ) {
return;
}

View File

@ -64,15 +64,15 @@ public void doDrop(Database database, boolean dropSchemas, Target... targets) th
final Set<String> exportIdentifiers = new HashSet<String>( 50 );
for ( Schema schema : database.getSchemas() ) {
// NOTE : init commands are irrelevant for dropping...
// NOTE : init commands are irrelevant for dropping...
for ( AuxiliaryDatabaseObject auxiliaryDatabaseObject : database.getAuxiliaryDatabaseObjects() ) {
if ( auxiliaryDatabaseObject.appliesToDialect( dialect ) ) {
applySqlStrings( auxiliaryDatabaseObject, targets, dialect, exportIdentifiers );
}
for ( AuxiliaryDatabaseObject auxiliaryDatabaseObject : database.getAuxiliaryDatabaseObjects() ) {
if ( auxiliaryDatabaseObject.appliesToDialect( dialect ) && ! auxiliaryDatabaseObject.beforeTablesOnCreation() ) {
applySqlStrings( auxiliaryDatabaseObject, targets, dialect, exportIdentifiers );
}
}
for ( Schema schema : database.getSchemas() ) {
for ( Table table : schema.getTables() ) {
if ( dialect.dropConstraints() ) {
// we need to drop constraints prior to dropping table
@ -99,11 +99,18 @@ public void doDrop(Database database, boolean dropSchemas, Target... targets) th
for ( Sequence sequence : schema.getSequences() ) {
applySqlStrings( sequence, targets, dialect, exportIdentifiers );
}
}
if ( dropSchemas ) {
// todo : add dialect method for getting a DROP SCHEMA command and use it here
for ( AuxiliaryDatabaseObject auxiliaryDatabaseObject : database.getAuxiliaryDatabaseObjects() ) {
if ( auxiliaryDatabaseObject.appliesToDialect( dialect ) && ! auxiliaryDatabaseObject.beforeTablesOnCreation() ) {
applySqlStrings( auxiliaryDatabaseObject, targets, dialect, exportIdentifiers );
}
}
for ( Schema schema : database.getSchemas() ) {
if ( dropSchemas ) {
applySqlStrings( targets, dialect.getDropSchemaCommand( schema.getName().getSchema().getText( dialect ) ) );
}
}
for ( Target target : targets ) {
@ -122,10 +129,10 @@ private static void applySqlStrings(
}
exportIdentifiers.add( exportIdentifier );
applySqlStrings( exportable.sqlDropStrings( dialect ), targets );
applySqlStrings( targets, exportable.sqlDropStrings( dialect ) );
}
private static void applySqlStrings(String[] sqlStrings, Target[] targets) {
private static void applySqlStrings(Target[] targets, String... sqlStrings) {
if ( sqlStrings == null ) {
return;
}