HHH-10458 - Better encapsulate SchemaManagementTool (OGM) - unify JPA schema generation and hbm2ddl capabilities;

HHH-10487 - Add @Incubating annotation
This commit is contained in:
Steve Ebersole 2016-02-09 11:43:15 -06:00
parent 17de173cb5
commit 0a2a709f9e
14 changed files with 80 additions and 118 deletions

View File

@ -11,14 +11,19 @@ import java.io.Reader;
import org.hibernate.service.Service; import org.hibernate.service.Service;
/** /**
* Contract for extracting statements from <i>import.sql</i> script. * Contract for extracting statements from source/import/init scripts.
* *
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*
* @see org.hibernate.cfg.AvailableSettings#HBM2DDL_IMPORT_FILES
* @see org.hibernate.cfg.AvailableSettings#HBM2DDL_LOAD_SCRIPT_SOURCE
* @see org.hibernate.cfg.AvailableSettings#HBM2DDL_CREATE_SCRIPT_SOURCE
* @see org.hibernate.cfg.AvailableSettings#HBM2DDL_DROP_SCRIPT_SOURCE
*/ */
public interface ImportSqlCommandExtractor extends Service { public interface ImportSqlCommandExtractor extends Service {
/** /**
* @param reader Character stream reader of SQL script. * @param reader Character stream reader of SQL script.
* @return List of single SQL statements. Each command may or may not contain semicolon at the end. * @return List of single SQL statements. Each command may or may not contain semicolon at the end.
*/ */
public String[] extractCommands(Reader reader); String[] extractCommands(Reader reader);
} }

View File

@ -6,7 +6,6 @@
*/ */
package org.hibernate.tool.schema; package org.hibernate.tool.schema;
import org.hibernate.internal.log.DeprecationLogger;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
/** /**
@ -77,17 +76,15 @@ public enum Action {
this.externalHbm2ddlName = externalHbm2ddlName; this.externalHbm2ddlName = externalHbm2ddlName;
} }
public boolean isValidJpaAction() {
return externalJpaName != null;
}
@Override @Override
public String toString() { public String toString() {
return getClass().getSimpleName() + "(externalJpaName=" + externalJpaName + ", externalHbm2ddlName=" + externalHbm2ddlName + ")"; return getClass().getSimpleName() + "(externalJpaName=" + externalJpaName + ", externalHbm2ddlName=" + externalHbm2ddlName + ")";
} }
/** /**
* Used when processing JPA configuration to interpret the user config values. * Used when processing JPA configuration to interpret the user config values. Generally
* this will be a value specified by {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_DATABASE_ACTION}
* or {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_SCRIPTS_ACTION}
* *
* @param value The encountered config value * @param value The encountered config value
* *
@ -136,7 +133,7 @@ public enum Action {
} }
/** /**
* Used when processing JPA configuration to interpret the user config values. * Used to interpret the value of {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_AUTO}
* *
* @param value The encountered config value * @param value The encountered config value
* *

View File

@ -52,7 +52,7 @@ public enum SourceType {
private final String externalName; private final String externalName;
private SourceType(String externalName) { SourceType(String externalName) {
this.externalName = externalName; this.externalName = externalName;
} }

View File

@ -7,6 +7,11 @@
package org.hibernate.tool.schema; package org.hibernate.tool.schema;
/** /**
* Describes the allowable targets (SPI wise) for schema management actions.
* <p/>
* Under the covers corresponds to provider-specific implementations of
* {@link org.hibernate.tool.schema.internal.exec.GenerationTarget}
*
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public enum TargetType { public enum TargetType {
@ -19,7 +24,7 @@ public enum TargetType {
*/ */
SCRIPT, SCRIPT,
/** /**
* Write to System.out * Write to {@link System#out}
*/ */
STDOUT; STDOUT;
} }

View File

@ -1,76 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.tool.schema.internal;
import java.util.Map;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.tool.schema.Action;
/**
* For JPA-style schema-gen handling database and script target handing are
* configured individually. This tuple allows grouping the action for both
* targets.
*
* @author Steve Ebersole
*/
public class ActionGrouping {
private final Action databaseAction;
private final Action scriptAction;
public ActionGrouping(Action databaseAction, Action scriptAction) {
this.databaseAction = databaseAction;
this.scriptAction = scriptAction;
}
public Action getDatabaseAction() {
return databaseAction;
}
public Action getScriptAction() {
return scriptAction;
}
public boolean needsJdbcAccess() {
if ( databaseAction != Action.NONE ) {
// to execute the commands
return true;
}
switch ( scriptAction ) {
case VALIDATE:
case UPDATE: {
// to get the existing metadata
return true;
}
}
return false;
}
public static ActionGrouping interpret(Map configurationValues) {
// interpret the JPA settings first
Action databaseAction = Action.interpretJpaSetting(
configurationValues.get( AvailableSettings.HBM2DDL_DATABASE_ACTION )
);
Action scriptAction = Action.interpretJpaSetting(
configurationValues.get( AvailableSettings.HBM2DDL_SCRIPTS_ACTION )
);
// if no JPA settings were specified, look at the legacy HBM2DDL_AUTO setting...
if ( databaseAction == Action.NONE && scriptAction == Action.NONE ) {
final Action hbm2ddlAutoAction = Action.interpretHbm2ddlSetting(
configurationValues.get( AvailableSettings.HBM2DDL_AUTO )
);
if ( hbm2ddlAutoAction != Action.NONE ) {
databaseAction = hbm2ddlAutoAction;
}
}
return new ActionGrouping( databaseAction, scriptAction );
}
}

View File

@ -19,7 +19,6 @@ import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.internal.util.config.ConfigurationHelper; import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistry;
import org.hibernate.tool.schema.Action;
import org.hibernate.tool.schema.extract.spi.DatabaseInformation; import org.hibernate.tool.schema.extract.spi.DatabaseInformation;
import org.hibernate.tool.schema.internal.exec.ImprovedDatabaseInformationImpl; import org.hibernate.tool.schema.internal.exec.ImprovedDatabaseInformationImpl;
import org.hibernate.tool.schema.internal.exec.JdbcConnectionContext; import org.hibernate.tool.schema.internal.exec.JdbcConnectionContext;
@ -35,33 +34,13 @@ import org.hibernate.tool.schema.spi.ScriptTargetOutput;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
/** /**
* Helper methods.
*
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class Helper { public class Helper {
private static final Logger log = Logger.getLogger( Helper.class ); private static final Logger log = Logger.getLogger( Helper.class );
public static boolean includesCreate(ActionGrouping actions) {
return includesCreate( actions.getDatabaseAction() )
|| includesCreate( actions.getScriptAction() );
}
public static boolean includesCreate(Action action) {
return action == Action.CREATE_ONLY
|| action == Action.CREATE
|| action == Action.CREATE_DROP;
}
private static boolean includesDrop(ActionGrouping actions) {
return includesDrop( actions.getDatabaseAction() )
|| includesDrop( actions.getScriptAction() );
}
public static boolean includesDrop(Action action) {
return action == Action.DROP
|| action == Action.CREATE
|| action == Action.CREATE_DROP;
}
public static ScriptSourceInput interpretScriptSourceSetting(Object scriptSourceSetting, ClassLoaderService classLoaderService) { public static ScriptSourceInput interpretScriptSourceSetting(Object scriptSourceSetting, ClassLoaderService classLoaderService) {
if ( Reader.class.isInstance( scriptSourceSetting ) ) { if ( Reader.class.isInstance( scriptSourceSetting ) ) {
return new ScriptSourceInputFromReader( (Reader) scriptSourceSetting ); return new ScriptSourceInputFromReader( (Reader) scriptSourceSetting );
@ -155,5 +134,4 @@ public class Helper {
throw jdbcEnvironment.getSqlExceptionHelper().convert( e, "Unable to build DatabaseInformation" ); throw jdbcEnvironment.getSqlExceptionHelper().convert( e, "Unable to build DatabaseInformation" );
} }
} }
} }

View File

@ -15,6 +15,8 @@ import org.hibernate.tool.hbm2ddl.ImportSqlCommandExtractor;
import org.hibernate.tool.schema.spi.ScriptSourceInput; import org.hibernate.tool.schema.spi.ScriptSourceInput;
/** /**
* Convenience base class for ScriptSourceInput implementations
*
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public abstract class AbstractScriptSourceInput implements ScriptSourceInput { public abstract class AbstractScriptSourceInput implements ScriptSourceInput {
@ -22,6 +24,7 @@ public abstract class AbstractScriptSourceInput implements ScriptSourceInput {
@Override @Override
public void prepare() { public void prepare() {
// by default there is nothing to do
} }
@Override @Override
@ -37,5 +40,6 @@ public abstract class AbstractScriptSourceInput implements ScriptSourceInput {
@Override @Override
public void release() { public void release() {
// by default there is nothing to do
} }
} }

View File

@ -9,6 +9,8 @@ package org.hibernate.tool.schema.spi;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
/** /**
* Indicates a problem accepting/executing a schema management command.
*
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class CommandAcceptanceException extends HibernateException { public class CommandAcceptanceException extends HibernateException {

View File

@ -13,6 +13,8 @@ import org.hibernate.boot.model.relational.Exportable;
/** /**
* Defines a contract for exporting of database objects (tables, sequences, etc) for use in SQL {@code CREATE} and * Defines a contract for exporting of database objects (tables, sequences, etc) for use in SQL {@code CREATE} and
* {@code DROP} scripts. * {@code DROP} scripts.
* <p/>
* This is an ORM-centric contract
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */

View File

@ -13,5 +13,5 @@ package org.hibernate.tool.schema.spi;
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public interface JpaTargetAndSourceDescriptor extends TargetDescriptor, SourceDescriptor { public interface JpaTargetAndSourceDescriptor extends SourceDescriptor, TargetDescriptor {
} }

View File

@ -12,8 +12,7 @@ import org.hibernate.HibernateException;
* Indicates a problem in performing schema management. * Indicates a problem in performing schema management.
* <p/> * <p/>
* Specifically this represents a a problem of an infrastructural-nature. For * Specifically this represents a a problem of an infrastructural-nature. For
* representing problems applying a specific command see * problems applying a specific command see {@link CommandAcceptanceException}
* {@link CommandAcceptanceException}
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */

View File

@ -15,16 +15,18 @@ import org.hibernate.service.ServiceRegistry;
import org.hibernate.tool.schema.Action; import org.hibernate.tool.schema.Action;
import org.hibernate.tool.schema.SourceType; import org.hibernate.tool.schema.SourceType;
import org.hibernate.tool.schema.TargetType; import org.hibernate.tool.schema.TargetType;
import org.hibernate.tool.schema.internal.ActionGrouping;
import org.hibernate.tool.schema.internal.ExceptionHandlerLoggedImpl; import org.hibernate.tool.schema.internal.ExceptionHandlerLoggedImpl;
import org.hibernate.tool.schema.internal.Helper; import org.hibernate.tool.schema.internal.Helper;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import static org.hibernate.cfg.AvailableSettings.HBM2DDL_AUTO;
import static org.hibernate.cfg.AvailableSettings.HBM2DDL_CREATE_SCRIPT_SOURCE; import static org.hibernate.cfg.AvailableSettings.HBM2DDL_CREATE_SCRIPT_SOURCE;
import static org.hibernate.cfg.AvailableSettings.HBM2DDL_CREATE_SOURCE; import static org.hibernate.cfg.AvailableSettings.HBM2DDL_CREATE_SOURCE;
import static org.hibernate.cfg.AvailableSettings.HBM2DDL_DATABASE_ACTION;
import static org.hibernate.cfg.AvailableSettings.HBM2DDL_DROP_SCRIPT_SOURCE; import static org.hibernate.cfg.AvailableSettings.HBM2DDL_DROP_SCRIPT_SOURCE;
import static org.hibernate.cfg.AvailableSettings.HBM2DDL_DROP_SOURCE; import static org.hibernate.cfg.AvailableSettings.HBM2DDL_DROP_SOURCE;
import static org.hibernate.cfg.AvailableSettings.HBM2DDL_SCRIPTS_ACTION;
import static org.hibernate.cfg.AvailableSettings.HBM2DDL_SCRIPTS_CREATE_TARGET; import static org.hibernate.cfg.AvailableSettings.HBM2DDL_SCRIPTS_CREATE_TARGET;
import static org.hibernate.cfg.AvailableSettings.HBM2DDL_SCRIPTS_DROP_TARGET; import static org.hibernate.cfg.AvailableSettings.HBM2DDL_SCRIPTS_DROP_TARGET;
@ -440,4 +442,43 @@ public class SchemaManagementToolCoordinator {
return configurationValues.get( HBM2DDL_SCRIPTS_CREATE_TARGET ); return configurationValues.get( HBM2DDL_SCRIPTS_CREATE_TARGET );
} }
} }
/**
* For JPA-style schema-gen, database and script target handing are configured
* individually - this tuple allows interpreting the the action for both targets
* simultaneously
*/
public static class ActionGrouping {
private final Action databaseAction;
private final Action scriptAction;
public ActionGrouping(Action databaseAction, Action scriptAction) {
this.databaseAction = databaseAction;
this.scriptAction = scriptAction;
}
public Action getDatabaseAction() {
return databaseAction;
}
public Action getScriptAction() {
return scriptAction;
}
public static ActionGrouping interpret(Map configurationValues) {
// interpret the JPA settings first
Action databaseAction = Action.interpretJpaSetting( configurationValues.get( HBM2DDL_DATABASE_ACTION ) );
Action scriptAction = Action.interpretJpaSetting( configurationValues.get( HBM2DDL_SCRIPTS_ACTION ) );
// if no JPA settings were specified, look at the legacy HBM2DDL_AUTO setting...
if ( databaseAction == Action.NONE && scriptAction == Action.NONE ) {
final Action hbm2ddlAutoAction = Action.interpretHbm2ddlSetting( configurationValues.get( HBM2DDL_AUTO ) );
if ( hbm2ddlAutoAction != Action.NONE ) {
databaseAction = hbm2ddlAutoAction;
}
}
return new ActionGrouping( databaseAction, scriptAction );
}
}
} }

View File

@ -31,7 +31,11 @@ public interface SourceDescriptor {
/** /**
* If {@link #getSourceType()} indicates scripts are involved, returns * If {@link #getSourceType()} indicates scripts are involved, returns
* a representation of the script file to read. Otherwise, returns {@code null} * a representation of the script file to read. Otherwise, returns {@code null}.
* <p/>
* While it is ultimately up to the actual tooling provider, it is generally an error
* for {@link #getSourceType()} to indicate that scripts are involved and for this
* method to return {@code null}.
* *
* @return The script file to read. * @return The script file to read.
*/ */

View File

@ -33,8 +33,9 @@ public interface TargetDescriptor {
* If {@link #getTargetTypes()} includes scripts, return a representation * If {@link #getTargetTypes()} includes scripts, return a representation
* of the script file to write to. Otherwise, returns {@code null}. * of the script file to write to. Otherwise, returns {@code null}.
* <p/> * <p/>
* If {@link #getTargetTypes()} includes scripts, and this method returns * While it is ultimately up to the actual tooling provider, it is generally an error
* {@code null} an exception will be thrown interpreting this descriptor * for {@link #getTargetTypes()} to indicate that scripts are a target and for this
* method to return {@code null}.
* *
* @return The script output target * @return The script output target
*/ */