HHH-8270 - Support for accessing JPA schema export script files specified by URL
This commit is contained in:
parent
51834421c5
commit
3bc26b6448
|
@ -23,8 +23,6 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.jpa.internal.schemagen;
|
package org.hibernate.jpa.internal.schemagen;
|
||||||
|
|
||||||
import java.io.Reader;
|
|
||||||
|
|
||||||
import org.hibernate.tool.hbm2ddl.ImportSqlCommandExtractor;
|
import org.hibernate.tool.hbm2ddl.ImportSqlCommandExtractor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,28 +31,22 @@ import org.hibernate.tool.hbm2ddl.ImportSqlCommandExtractor;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class GenerationSourceFromScript implements GenerationSource {
|
public class GenerationSourceFromScript implements GenerationSource {
|
||||||
private final SqlScriptInput reader;
|
private final ScriptSourceInput inputSource;
|
||||||
private final ImportSqlCommandExtractor scriptCommandExtractor;
|
private final ImportSqlCommandExtractor scriptCommandExtractor;
|
||||||
|
|
||||||
public GenerationSourceFromScript(Object scriptSourceSetting, ImportSqlCommandExtractor scriptCommandExtractor) {
|
public GenerationSourceFromScript(ScriptSourceInput inputSource, ImportSqlCommandExtractor scriptCommandExtractor) {
|
||||||
|
this.inputSource = inputSource;
|
||||||
this.scriptCommandExtractor = scriptCommandExtractor;
|
this.scriptCommandExtractor = scriptCommandExtractor;
|
||||||
|
|
||||||
if ( Reader.class.isInstance( scriptSourceSetting ) ) {
|
|
||||||
reader = new SqlScriptReaderInput( (Reader) scriptSourceSetting );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
reader = new SqlScriptFileInput( scriptSourceSetting.toString() );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<String> getCommands() {
|
public Iterable<String> getCommands() {
|
||||||
return reader.read( scriptCommandExtractor );
|
return inputSource.read( scriptCommandExtractor );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void release() {
|
public void release() {
|
||||||
reader.release();
|
inputSource.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,15 +23,6 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.jpa.internal.schemagen;
|
package org.hibernate.jpa.internal.schemagen;
|
||||||
|
|
||||||
import javax.persistence.PersistenceException;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.Writer;
|
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
|
|
||||||
import org.hibernate.jpa.AvailableSettings;
|
|
||||||
import org.hibernate.jpa.SchemaGenAction;
|
import org.hibernate.jpa.SchemaGenAction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,59 +31,17 @@ import org.hibernate.jpa.SchemaGenAction;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
class GenerationTargetToScript implements GenerationTarget {
|
class GenerationTargetToScript implements GenerationTarget {
|
||||||
private static final Logger log = Logger.getLogger( GenerationTargetToScript.class );
|
private final ScriptTargetOutput createScriptTarget;
|
||||||
|
private final ScriptTargetOutput dropScriptTarget;
|
||||||
private final ScriptTargetTarget createScriptTarget;
|
|
||||||
private final ScriptTargetTarget dropScriptTarget;
|
|
||||||
private final SchemaGenAction scriptsAction;
|
private final SchemaGenAction scriptsAction;
|
||||||
|
|
||||||
public GenerationTargetToScript(
|
public GenerationTargetToScript(
|
||||||
Object createScriptTargetSetting,
|
ScriptTargetOutput createScriptTarget,
|
||||||
Object dropScriptTargetSetting,
|
ScriptTargetOutput dropScriptTarget,
|
||||||
SchemaGenAction scriptsAction) {
|
SchemaGenAction scriptsAction) {
|
||||||
|
this.createScriptTarget = createScriptTarget;
|
||||||
|
this.dropScriptTarget = dropScriptTarget;
|
||||||
this.scriptsAction = scriptsAction;
|
this.scriptsAction = scriptsAction;
|
||||||
|
|
||||||
if ( scriptsAction.includesCreate() ) {
|
|
||||||
if ( Writer.class.isInstance( createScriptTargetSetting ) ) {
|
|
||||||
createScriptTarget = new WriterScriptTarget( (Writer) createScriptTargetSetting );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
createScriptTarget = new FileScriptTarget( createScriptTargetSetting.toString() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ( createScriptTargetSetting != null ) {
|
|
||||||
// the wording in the spec hints that this maybe should be an error, but does not explicitly
|
|
||||||
// call out an exception to use.
|
|
||||||
log.debugf(
|
|
||||||
"Value was specified for '%s' [%s], but create scripting was not requested",
|
|
||||||
AvailableSettings.SCHEMA_GEN_SCRIPTS_CREATE_TARGET,
|
|
||||||
createScriptTargetSetting
|
|
||||||
);
|
|
||||||
}
|
|
||||||
createScriptTarget = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( scriptsAction.includesDrop() ) {
|
|
||||||
if ( Writer.class.isInstance( dropScriptTargetSetting ) ) {
|
|
||||||
dropScriptTarget = new WriterScriptTarget( (Writer) dropScriptTargetSetting );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dropScriptTarget = new FileScriptTarget( dropScriptTargetSetting.toString() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ( dropScriptTargetSetting != null ) {
|
|
||||||
// the wording in the spec hints that this maybe should be an error, but does not explicitly
|
|
||||||
// call out an exception to use.
|
|
||||||
log.debugf(
|
|
||||||
"Value was specified for '%s' [%s], but drop scripting was not requested",
|
|
||||||
AvailableSettings.SCHEMA_GEN_SCRIPTS_DROP_TARGET,
|
|
||||||
dropScriptTargetSetting
|
|
||||||
);
|
|
||||||
}
|
|
||||||
dropScriptTarget = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -123,73 +72,4 @@ class GenerationTargetToScript implements GenerationTarget {
|
||||||
dropScriptTarget.release();
|
dropScriptTarget.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal contract for handling Writer/File differences
|
|
||||||
*/
|
|
||||||
private static interface ScriptTargetTarget {
|
|
||||||
public void accept(String command);
|
|
||||||
public void release();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class WriterScriptTarget implements ScriptTargetTarget {
|
|
||||||
private final Writer writer;
|
|
||||||
|
|
||||||
public WriterScriptTarget(Writer writer) {
|
|
||||||
this.writer = writer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void accept(String command) {
|
|
||||||
try {
|
|
||||||
writer.write( command );
|
|
||||||
writer.flush();
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
throw new PersistenceException( "Could not write to target script file", e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void release() {
|
|
||||||
// nothing to do for a supplied writer
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Writer writer() {
|
|
||||||
return writer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class FileScriptTarget extends WriterScriptTarget implements ScriptTargetTarget {
|
|
||||||
public FileScriptTarget(String fileUrl) {
|
|
||||||
super( toFileWriter( fileUrl ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void release() {
|
|
||||||
try {
|
|
||||||
writer().close();
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
throw new PersistenceException( "Unable to close file writer : " + e.toString() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
|
||||||
private static Writer toFileWriter(String fileUrl) {
|
|
||||||
final File file = new File( fileUrl );
|
|
||||||
try {
|
|
||||||
// best effort, since this is very well not allowed in EE environments
|
|
||||||
file.createNewFile();
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
log.debug( "Exception calling File#createNewFile : " + e.toString() );
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return new FileWriter( file );
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
throw new PersistenceException( "Unable to open specified script target file for writing : " + fileUrl, e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,11 @@
|
||||||
package org.hibernate.jpa.internal.schemagen;
|
package org.hibernate.jpa.internal.schemagen;
|
||||||
|
|
||||||
import javax.persistence.PersistenceException;
|
import javax.persistence.PersistenceException;
|
||||||
|
import java.io.File;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.DatabaseMetaData;
|
import java.sql.DatabaseMetaData;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
@ -38,6 +42,7 @@ import java.util.List;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.boot.registry.selector.spi.StrategySelector;
|
import org.hibernate.boot.registry.selector.spi.StrategySelector;
|
||||||
import org.hibernate.cfg.Configuration;
|
import org.hibernate.cfg.Configuration;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
|
@ -64,8 +69,38 @@ import org.hibernate.tool.hbm2ddl.ImportSqlCommandExtractor;
|
||||||
public class JpaSchemaGenerator {
|
public class JpaSchemaGenerator {
|
||||||
private static final Logger log = Logger.getLogger( JpaSchemaGenerator.class );
|
private static final Logger log = Logger.getLogger( JpaSchemaGenerator.class );
|
||||||
|
|
||||||
public static void performGeneration(Configuration hibernateConfiguration, ServiceRegistry serviceRegistry) {
|
private JpaSchemaGenerator() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void performGeneration(Configuration hibernateConfiguration, ServiceRegistry serviceRegistry) {
|
||||||
|
new Generation( serviceRegistry ).execute( hibernateConfiguration );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the process of performing a schema generation
|
||||||
|
*/
|
||||||
|
public static class Generation {
|
||||||
|
private final ServiceRegistry serviceRegistry;
|
||||||
|
private final ImportSqlCommandExtractor scriptCommandExtractor;
|
||||||
|
private final ClassLoaderService classLoaderService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a generation process
|
||||||
|
*
|
||||||
|
* @param serviceRegistry The Hibernate service registry to use
|
||||||
|
*/
|
||||||
|
public Generation(ServiceRegistry serviceRegistry) {
|
||||||
|
this.serviceRegistry = serviceRegistry;
|
||||||
|
this.scriptCommandExtractor = serviceRegistry.getService( ImportSqlCommandExtractor.class );
|
||||||
|
this.classLoaderService = serviceRegistry.getService( ClassLoaderService.class );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform the generation, as indicated by the settings
|
||||||
|
*
|
||||||
|
* @param hibernateConfiguration
|
||||||
|
*/
|
||||||
|
public void execute(Configuration hibernateConfiguration) {
|
||||||
// First, determine the actions (if any) to be performed ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// First, determine the actions (if any) to be performed ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
final SchemaGenAction databaseAction = SchemaGenAction.interpret(
|
final SchemaGenAction databaseAction = SchemaGenAction.interpret(
|
||||||
|
@ -95,11 +130,11 @@ public class JpaSchemaGenerator {
|
||||||
// determine sources ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// determine sources ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
final List<GenerationSource> createSourceList = databaseAction.includesCreate() || scriptsAction.includesCreate()
|
final List<GenerationSource> createSourceList = databaseAction.includesCreate() || scriptsAction.includesCreate()
|
||||||
? buildCreateSourceList( hibernateConfiguration, serviceRegistry, dialect )
|
? buildCreateSourceList( hibernateConfiguration, dialect )
|
||||||
: Collections.<GenerationSource>emptyList();
|
: Collections.<GenerationSource>emptyList();
|
||||||
|
|
||||||
final List<GenerationSource> dropSourceList = databaseAction.includesDrop() || scriptsAction.includesDrop()
|
final List<GenerationSource> dropSourceList = databaseAction.includesDrop() || scriptsAction.includesDrop()
|
||||||
? buildDropSourceList( hibernateConfiguration, serviceRegistry, dialect )
|
? buildDropSourceList( hibernateConfiguration, dialect )
|
||||||
: Collections.<GenerationSource>emptyList();
|
: Collections.<GenerationSource>emptyList();
|
||||||
|
|
||||||
|
|
||||||
|
@ -113,7 +148,19 @@ public class JpaSchemaGenerator {
|
||||||
final Object dropScriptTargetSetting = hibernateConfiguration.getProperties().get(
|
final Object dropScriptTargetSetting = hibernateConfiguration.getProperties().get(
|
||||||
AvailableSettings.SCHEMA_GEN_SCRIPTS_DROP_TARGET
|
AvailableSettings.SCHEMA_GEN_SCRIPTS_DROP_TARGET
|
||||||
);
|
);
|
||||||
final GenerationTarget scriptsTarget = new GenerationTargetToScript( createScriptTargetSetting, dropScriptTargetSetting, scriptsAction );
|
final GenerationTarget scriptsTarget = new GenerationTargetToScript(
|
||||||
|
interpretScriptTargetSetting(
|
||||||
|
createScriptTargetSetting,
|
||||||
|
scriptsAction.includesCreate(),
|
||||||
|
AvailableSettings.SCHEMA_GEN_SCRIPTS_CREATE_TARGET
|
||||||
|
),
|
||||||
|
interpretScriptTargetSetting(
|
||||||
|
dropScriptTargetSetting,
|
||||||
|
scriptsAction.includesDrop(),
|
||||||
|
AvailableSettings.SCHEMA_GEN_SCRIPTS_DROP_TARGET
|
||||||
|
),
|
||||||
|
scriptsAction
|
||||||
|
);
|
||||||
|
|
||||||
final List<GenerationTarget> targets = Arrays.asList( databaseTarget, scriptsTarget );
|
final List<GenerationTarget> targets = Arrays.asList( databaseTarget, scriptsTarget );
|
||||||
|
|
||||||
|
@ -146,12 +193,62 @@ public class JpaSchemaGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<GenerationSource> buildCreateSourceList(
|
private ScriptTargetOutput interpretScriptTargetSetting(
|
||||||
Configuration hibernateConfiguration,
|
Object scriptTargetSetting,
|
||||||
ServiceRegistry serviceRegistry,
|
boolean actionIndicatedScripting,
|
||||||
Dialect dialect) {
|
String settingName) {
|
||||||
|
if ( actionIndicatedScripting ) {
|
||||||
|
if ( scriptTargetSetting == null ) {
|
||||||
|
throw new PersistenceException( "Scripting was requested, but no target was specified" );
|
||||||
|
}
|
||||||
|
if ( Writer.class.isInstance( scriptTargetSetting ) ) {
|
||||||
|
return new ScriptTargetOutputToWriter( (Writer) scriptTargetSetting );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
final String scriptTargetSettingString = scriptTargetSetting.toString();
|
||||||
|
try {
|
||||||
|
final URL url = new URL( scriptTargetSettingString );
|
||||||
|
return new ScriptTargetOutputToUrl( url );
|
||||||
|
}
|
||||||
|
catch (MalformedURLException ignore) {
|
||||||
|
}
|
||||||
|
return new ScriptTargetOutputToFile( new File( scriptTargetSettingString ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ( scriptTargetSetting != null ) {
|
||||||
|
// the wording in the spec hints that this maybe should be an error, but does not explicitly
|
||||||
|
// call out an exception to use.
|
||||||
|
log.debugf(
|
||||||
|
"Value was specified for '%s' [%s], but scripting action was not requested",
|
||||||
|
settingName,
|
||||||
|
scriptTargetSetting
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return NoOpScriptTargetOutput.INSTANCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class NoOpScriptTargetOutput implements ScriptTargetOutput {
|
||||||
|
/**
|
||||||
|
* Singleton access
|
||||||
|
*/
|
||||||
|
public static final NoOpScriptTargetOutput INSTANCE = new NoOpScriptTargetOutput();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(String command) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void release() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<GenerationSource> buildCreateSourceList(Configuration hibernateConfiguration, Dialect dialect) {
|
||||||
final List<GenerationSource> generationSourceList = new ArrayList<GenerationSource>();
|
final List<GenerationSource> generationSourceList = new ArrayList<GenerationSource>();
|
||||||
|
|
||||||
|
// If we are asked to perform CREATE SCHEMA commands do them first ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
final boolean createSchemas = ConfigurationHelper.getBoolean(
|
final boolean createSchemas = ConfigurationHelper.getBoolean(
|
||||||
AvailableSettings.SCHEMA_GEN_CREATE_SCHEMAS,
|
AvailableSettings.SCHEMA_GEN_CREATE_SCHEMAS,
|
||||||
hibernateConfiguration.getProperties(),
|
hibernateConfiguration.getProperties(),
|
||||||
|
@ -161,6 +258,9 @@ public class JpaSchemaGenerator {
|
||||||
generationSourceList.add( new CreateSchemaCommandSource( hibernateConfiguration, dialect ) );
|
generationSourceList.add( new CreateSchemaCommandSource( hibernateConfiguration, dialect ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Next figure out the intended sources of generation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
SchemaGenSource sourceType = SchemaGenSource.interpret(
|
SchemaGenSource sourceType = SchemaGenSource.interpret(
|
||||||
hibernateConfiguration.getProperty( AvailableSettings.SCHEMA_GEN_CREATE_SOURCE )
|
hibernateConfiguration.getProperty( AvailableSettings.SCHEMA_GEN_CREATE_SOURCE )
|
||||||
);
|
);
|
||||||
|
@ -178,37 +278,72 @@ public class JpaSchemaGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final ImportSqlCommandExtractor scriptCommandExtractor = serviceRegistry.getService( ImportSqlCommandExtractor.class );
|
final boolean includesScripts = sourceType != SchemaGenSource.METADATA;
|
||||||
|
if ( includesScripts && createScriptSourceSetting == null ) {
|
||||||
|
throw new PersistenceException(
|
||||||
|
"Schema generation configuration indicated to include CREATE scripts, but no script was specified"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
final ScriptSourceInput scriptSourceInput = includesScripts
|
||||||
|
? interpretScriptSourceSetting( createScriptSourceSetting )
|
||||||
|
: null;
|
||||||
|
|
||||||
if ( sourceType == SchemaGenSource.METADATA ) {
|
if ( sourceType == SchemaGenSource.METADATA ) {
|
||||||
generationSourceList.add( new GenerationSourceFromMetadata( hibernateConfiguration, dialect, true ) );
|
generationSourceList.add( new GenerationSourceFromMetadata( hibernateConfiguration, dialect, true ) );
|
||||||
}
|
}
|
||||||
else if ( sourceType == SchemaGenSource.SCRIPT ) {
|
else if ( sourceType == SchemaGenSource.SCRIPT ) {
|
||||||
generationSourceList.add( new GenerationSourceFromScript( createScriptSourceSetting, scriptCommandExtractor ) );
|
generationSourceList.add( new GenerationSourceFromScript( scriptSourceInput, scriptCommandExtractor ) );
|
||||||
}
|
}
|
||||||
else if ( sourceType == SchemaGenSource.METADATA_THEN_SCRIPT ) {
|
else if ( sourceType == SchemaGenSource.METADATA_THEN_SCRIPT ) {
|
||||||
generationSourceList.add( new GenerationSourceFromMetadata( hibernateConfiguration, dialect, true ) );
|
generationSourceList.add( new GenerationSourceFromMetadata( hibernateConfiguration, dialect, true ) );
|
||||||
generationSourceList.add( new GenerationSourceFromScript( createScriptSourceSetting, scriptCommandExtractor ) );
|
generationSourceList.add( new GenerationSourceFromScript( scriptSourceInput, scriptCommandExtractor ) );
|
||||||
}
|
}
|
||||||
else if ( sourceType == SchemaGenSource.SCRIPT_THEN_METADATA ) {
|
else if ( sourceType == SchemaGenSource.SCRIPT_THEN_METADATA ) {
|
||||||
generationSourceList.add( new GenerationSourceFromScript( createScriptSourceSetting, scriptCommandExtractor ) );
|
generationSourceList.add( new GenerationSourceFromScript( scriptSourceInput, scriptCommandExtractor ) );
|
||||||
generationSourceList.add( new GenerationSourceFromMetadata( hibernateConfiguration, dialect, true ) );
|
generationSourceList.add( new GenerationSourceFromMetadata( hibernateConfiguration, dialect, true ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// finally, see if there is an import script specified ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
final Object importScriptSetting = hibernateConfiguration.getProperties().get(
|
final Object importScriptSetting = hibernateConfiguration.getProperties().get(
|
||||||
AvailableSettings.SCHEMA_GEN_LOAD_SCRIPT_SOURCE
|
AvailableSettings.SCHEMA_GEN_LOAD_SCRIPT_SOURCE
|
||||||
);
|
);
|
||||||
if ( importScriptSetting != null ) {
|
if ( importScriptSetting != null ) {
|
||||||
generationSourceList.add( new ImportScriptSource( importScriptSetting, scriptCommandExtractor ) );
|
final ScriptSourceInput importScriptInput = interpretScriptSourceSetting( importScriptSetting );
|
||||||
|
generationSourceList.add( new ImportScriptSource( importScriptInput, scriptCommandExtractor ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return generationSourceList;
|
return generationSourceList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<GenerationSource> buildDropSourceList(
|
private ScriptSourceInput interpretScriptSourceSetting(Object scriptSourceSetting) {
|
||||||
Configuration hibernateConfiguration,
|
if ( Reader.class.isInstance( scriptSourceSetting ) ) {
|
||||||
ServiceRegistry serviceRegistry,
|
return new ScriptSourceInputFromReader( (Reader) scriptSourceSetting );
|
||||||
Dialect dialect) {
|
}
|
||||||
|
else {
|
||||||
|
final String scriptSourceSettingString = scriptSourceSetting.toString();
|
||||||
|
log.debugf( "Attempting to resolve script source setting : %s", scriptSourceSettingString );
|
||||||
|
|
||||||
|
// setting could be either:
|
||||||
|
// 1) string URL representation (i.e., "file://...")
|
||||||
|
// 2) relative file path (resource lookup)
|
||||||
|
// 3) absolute file path
|
||||||
|
|
||||||
|
log.trace( "Trying as URL..." );
|
||||||
|
// ClassLoaderService.locateResource() first tries the given resource name as url form...
|
||||||
|
final URL url = classLoaderService.locateResource( scriptSourceSettingString );
|
||||||
|
if ( url != null ) {
|
||||||
|
return new ScriptSourceInputFromUrl( url );
|
||||||
|
}
|
||||||
|
|
||||||
|
// assume it is a File path
|
||||||
|
final File file = new File( scriptSourceSettingString );
|
||||||
|
return new ScriptSourceInputFromFile( file );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<GenerationSource> buildDropSourceList(Configuration hibernateConfiguration, Dialect dialect) {
|
||||||
final List<GenerationSource> generationSourceList = new ArrayList<GenerationSource>();
|
final List<GenerationSource> generationSourceList = new ArrayList<GenerationSource>();
|
||||||
|
|
||||||
SchemaGenSource sourceType = SchemaGenSource.interpret(
|
SchemaGenSource sourceType = SchemaGenSource.interpret(
|
||||||
|
@ -228,25 +363,35 @@ public class JpaSchemaGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final ImportSqlCommandExtractor scriptCommandExtractor = serviceRegistry.getService( ImportSqlCommandExtractor.class );
|
|
||||||
|
final boolean includesScripts = sourceType != SchemaGenSource.METADATA;
|
||||||
|
if ( includesScripts && dropScriptSourceSetting == null ) {
|
||||||
|
throw new PersistenceException(
|
||||||
|
"Schema generation configuration indicated to include CREATE scripts, but no script was specified"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
final ScriptSourceInput scriptSourceInput = includesScripts
|
||||||
|
? interpretScriptSourceSetting( dropScriptSourceSetting )
|
||||||
|
: null;
|
||||||
|
|
||||||
if ( sourceType == SchemaGenSource.METADATA ) {
|
if ( sourceType == SchemaGenSource.METADATA ) {
|
||||||
generationSourceList.add( new GenerationSourceFromMetadata( hibernateConfiguration, dialect, false ) );
|
generationSourceList.add( new GenerationSourceFromMetadata( hibernateConfiguration, dialect, false ) );
|
||||||
}
|
}
|
||||||
else if ( sourceType == SchemaGenSource.SCRIPT ) {
|
else if ( sourceType == SchemaGenSource.SCRIPT ) {
|
||||||
generationSourceList.add( new GenerationSourceFromScript( dropScriptSourceSetting, scriptCommandExtractor ) );
|
generationSourceList.add( new GenerationSourceFromScript( scriptSourceInput, scriptCommandExtractor ) );
|
||||||
}
|
}
|
||||||
else if ( sourceType == SchemaGenSource.METADATA_THEN_SCRIPT ) {
|
else if ( sourceType == SchemaGenSource.METADATA_THEN_SCRIPT ) {
|
||||||
generationSourceList.add( new GenerationSourceFromMetadata( hibernateConfiguration, dialect, false ) );
|
generationSourceList.add( new GenerationSourceFromMetadata( hibernateConfiguration, dialect, false ) );
|
||||||
generationSourceList.add( new GenerationSourceFromScript( dropScriptSourceSetting, scriptCommandExtractor ) );
|
generationSourceList.add( new GenerationSourceFromScript( scriptSourceInput, scriptCommandExtractor ) );
|
||||||
}
|
}
|
||||||
else if ( sourceType == SchemaGenSource.SCRIPT_THEN_METADATA ) {
|
else if ( sourceType == SchemaGenSource.SCRIPT_THEN_METADATA ) {
|
||||||
generationSourceList.add( new GenerationSourceFromScript( dropScriptSourceSetting, scriptCommandExtractor ) );
|
generationSourceList.add( new GenerationSourceFromScript( scriptSourceInput, scriptCommandExtractor ) );
|
||||||
generationSourceList.add( new GenerationSourceFromMetadata( hibernateConfiguration, dialect, false ) );
|
generationSourceList.add( new GenerationSourceFromMetadata( hibernateConfiguration, dialect, false ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return generationSourceList;
|
return generationSourceList;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static JdbcConnectionContext determineAppropriateJdbcConnectionContext(
|
private static JdbcConnectionContext determineAppropriateJdbcConnectionContext(
|
||||||
Configuration hibernateConfiguration,
|
Configuration hibernateConfiguration,
|
||||||
|
@ -383,7 +528,7 @@ public class JpaSchemaGenerator {
|
||||||
private static Dialect determineDialectBasedOnJdbcMetadata(
|
private static Dialect determineDialectBasedOnJdbcMetadata(
|
||||||
JdbcConnectionContext jdbcConnectionContext,
|
JdbcConnectionContext jdbcConnectionContext,
|
||||||
ServiceRegistry serviceRegistry) {
|
ServiceRegistry serviceRegistry) {
|
||||||
DialectResolver dialectResolver = serviceRegistry.getService( DialectResolver.class );
|
final DialectResolver dialectResolver = serviceRegistry.getService( DialectResolver.class );
|
||||||
try {
|
try {
|
||||||
final DatabaseMetaData databaseMetaData = jdbcConnectionContext.getJdbcConnection().getMetaData();
|
final DatabaseMetaData databaseMetaData = jdbcConnectionContext.getJdbcConnection().getMetaData();
|
||||||
final Dialect dialect = dialectResolver.resolveDialect( databaseMetaData );
|
final Dialect dialect = dialectResolver.resolveDialect( databaseMetaData );
|
||||||
|
@ -508,18 +653,12 @@ public class JpaSchemaGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ImportScriptSource implements GenerationSource {
|
private static class ImportScriptSource implements GenerationSource {
|
||||||
private final SqlScriptInput sourceReader;
|
private final ScriptSourceInput sourceReader;
|
||||||
private final ImportSqlCommandExtractor scriptCommandExtractor;
|
private final ImportSqlCommandExtractor scriptCommandExtractor;
|
||||||
|
|
||||||
public ImportScriptSource(Object scriptSourceSetting, ImportSqlCommandExtractor scriptCommandExtractor) {
|
public ImportScriptSource(ScriptSourceInput sourceReader, ImportSqlCommandExtractor scriptCommandExtractor) {
|
||||||
|
this.sourceReader = sourceReader;
|
||||||
this.scriptCommandExtractor = scriptCommandExtractor;
|
this.scriptCommandExtractor = scriptCommandExtractor;
|
||||||
|
|
||||||
if ( Reader.class.isInstance( scriptSourceSetting ) ) {
|
|
||||||
sourceReader = new SqlScriptReaderInput( (Reader) scriptSourceSetting );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sourceReader = new SqlScriptFileInput( scriptSourceSetting.toString() );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, 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.jpa.internal.schemagen;
|
||||||
|
|
||||||
|
import org.hibernate.tool.hbm2ddl.ImportSqlCommandExtractor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contract for hiding the differences between a passed Reader, File or URL in terms of how we read input
|
||||||
|
* scripts.
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public interface ScriptSourceInput {
|
||||||
|
/**
|
||||||
|
* Read the abstracted script, using the given extractor to split up the input into individual commands.
|
||||||
|
*
|
||||||
|
* @param commandExtractor The extractor for individual commands within the input.
|
||||||
|
*
|
||||||
|
* @return The scripted commands
|
||||||
|
*/
|
||||||
|
public Iterable<String> read(ImportSqlCommandExtractor commandExtractor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Release this input.
|
||||||
|
*/
|
||||||
|
public void release();
|
||||||
|
}
|
|
@ -32,16 +32,21 @@ import java.io.Reader;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SqlScriptInput implementation for File references. A reader is opened here and then explicitly closed on
|
* ScriptSourceInput implementation for File references. A reader is opened here and then explicitly closed on
|
||||||
* {@link #release}.
|
* {@link #release}.
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
class SqlScriptFileInput extends SqlScriptReaderInput implements SqlScriptInput {
|
public class ScriptSourceInputFromFile extends ScriptSourceInputFromReader implements ScriptSourceInput {
|
||||||
private static final Logger log = Logger.getLogger( SqlScriptFileInput.class );
|
private static final Logger log = Logger.getLogger( ScriptSourceInputFromFile.class );
|
||||||
|
|
||||||
public SqlScriptFileInput(String fileUrl) {
|
/**
|
||||||
super( toFileReader( fileUrl ) );
|
* Constructs a ScriptSourceInputFromFile
|
||||||
|
*
|
||||||
|
* @param file The file to read from
|
||||||
|
*/
|
||||||
|
public ScriptSourceInputFromFile(File file) {
|
||||||
|
super( toFileReader( file ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -55,10 +60,9 @@ class SqlScriptFileInput extends SqlScriptReaderInput implements SqlScriptInput
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||||
private static Reader toFileReader(String fileUrl) {
|
private static Reader toFileReader(File file) {
|
||||||
final File file = new File( fileUrl );
|
|
||||||
if ( ! file.exists() ) {
|
if ( ! file.exists() ) {
|
||||||
log.warnf( "Specified schema generation script file [%s] did not exist for reading", fileUrl );
|
log.warnf( "Specified schema generation script file [%s] did not exist for reading", file );
|
||||||
return new Reader() {
|
return new Reader() {
|
||||||
@Override
|
@Override
|
||||||
public int read(char[] cbuf, int off, int len) throws IOException {
|
public int read(char[] cbuf, int off, int len) throws IOException {
|
||||||
|
@ -76,7 +80,7 @@ class SqlScriptFileInput extends SqlScriptReaderInput implements SqlScriptInput
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
throw new PersistenceException(
|
throw new PersistenceException(
|
||||||
"Unable to open specified script target file [" + fileUrl + "] for reading",
|
"Unable to open specified script target file [" + file + "] for reading",
|
||||||
e
|
e
|
||||||
);
|
);
|
||||||
}
|
}
|
|
@ -30,14 +30,19 @@ import java.util.Collections;
|
||||||
import org.hibernate.tool.hbm2ddl.ImportSqlCommandExtractor;
|
import org.hibernate.tool.hbm2ddl.ImportSqlCommandExtractor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SqlScriptInput implementation for explicitly given Readers. The readers are not released by this class.
|
* ScriptSourceInput implementation for explicitly given Readers. The readers are not released by this class.
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
class SqlScriptReaderInput implements SqlScriptInput {
|
public class ScriptSourceInputFromReader implements ScriptSourceInput {
|
||||||
private final Reader reader;
|
private final Reader reader;
|
||||||
|
|
||||||
public SqlScriptReaderInput(Reader reader) {
|
/**
|
||||||
|
* Constructs a ScriptSourceInputFromReader
|
||||||
|
*
|
||||||
|
* @param reader The reader to read from
|
||||||
|
*/
|
||||||
|
public ScriptSourceInputFromReader(Reader reader) {
|
||||||
this.reader = reader;
|
this.reader = reader;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, 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.jpa.internal.schemagen;
|
||||||
|
|
||||||
|
import javax.persistence.PersistenceException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ScriptSourceInput implementation for URL references. A reader is opened here and then explicitly closed on
|
||||||
|
* {@link #release}.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class ScriptSourceInputFromUrl extends ScriptSourceInputFromReader implements ScriptSourceInput {
|
||||||
|
private static final Logger log = Logger.getLogger( ScriptSourceInputFromFile.class );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a ScriptSourceInputFromUrl instance
|
||||||
|
*
|
||||||
|
* @param url The url to read from
|
||||||
|
*/
|
||||||
|
public ScriptSourceInputFromUrl(URL url) {
|
||||||
|
super( toReader( url ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void release() {
|
||||||
|
try {
|
||||||
|
reader().close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
log.warn( "Unable to close file reader for generation script source" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Reader toReader(URL url) {
|
||||||
|
try {
|
||||||
|
return new InputStreamReader( url.openStream() );
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
throw new PersistenceException(
|
||||||
|
"Unable to open specified script source url [" + url + "] for reading"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,14 +23,22 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.jpa.internal.schemagen;
|
package org.hibernate.jpa.internal.schemagen;
|
||||||
|
|
||||||
import org.hibernate.tool.hbm2ddl.ImportSqlCommandExtractor;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contract for handling Reader/File differences
|
* Contract for hiding the differences between a passed Writer, File or URL in terms of how we write output
|
||||||
|
* scripts.
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface SqlScriptInput {
|
public interface ScriptTargetOutput {
|
||||||
public Iterable<String> read(ImportSqlCommandExtractor commandExtractor);
|
/**
|
||||||
|
* Accept the given command and write it to the abstracted script
|
||||||
|
*
|
||||||
|
* @param command The command
|
||||||
|
*/
|
||||||
|
public void accept(String command);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Release this output
|
||||||
|
*/
|
||||||
public void release();
|
public void release();
|
||||||
}
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, 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.jpa.internal.schemagen;
|
||||||
|
|
||||||
|
import javax.persistence.PersistenceException;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Writer;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import org.hibernate.jpa.internal.HEMLogging;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ScriptTargetOutput implementation for writing to supplied File references
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class ScriptTargetOutputToFile extends ScriptTargetOutputToWriter implements ScriptTargetOutput {
|
||||||
|
private static final Logger log = HEMLogging.logger( ScriptTargetOutputToFile.class );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a ScriptTargetOutputToFile
|
||||||
|
*
|
||||||
|
* @param file The file to write to
|
||||||
|
*/
|
||||||
|
public ScriptTargetOutputToFile(File file) {
|
||||||
|
super( toFileWriter( file ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void release() {
|
||||||
|
try {
|
||||||
|
writer().close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
throw new PersistenceException( "Unable to close file writer : " + e.toString() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||||
|
static Writer toFileWriter(File file) {
|
||||||
|
try {
|
||||||
|
// best effort, since this is very well not allowed in EE environments
|
||||||
|
file.createNewFile();
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
log.debug( "Exception calling File#createNewFile : " + e.toString() );
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return new FileWriter( file );
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
throw new PersistenceException( "Unable to open specified script target file for writing : " + file, e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, 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.jpa.internal.schemagen;
|
||||||
|
|
||||||
|
import javax.persistence.PersistenceException;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import org.hibernate.jpa.internal.HEMLogging;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ScriptTargetOutput implementation for writing to supplied URL references
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class ScriptTargetOutputToUrl extends ScriptTargetOutputToWriter implements ScriptTargetOutput {
|
||||||
|
private static final Logger log = HEMLogging.logger( ScriptTargetOutputToUrl.class );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a ScriptTargetOutputToUrl
|
||||||
|
*
|
||||||
|
* @param url The url to write to
|
||||||
|
*/
|
||||||
|
public ScriptTargetOutputToUrl(URL url) {
|
||||||
|
super( toWriter( url ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void release() {
|
||||||
|
try {
|
||||||
|
writer().close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
throw new PersistenceException( "Unable to close file writer : " + e.toString() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static Writer toWriter(URL url) {
|
||||||
|
log.debug( "Attempting to resolve writer for URL : " + url );
|
||||||
|
// technically only "strings corresponding to file URLs" are supported, which I take to mean URLs whose
|
||||||
|
// protocol is "file"
|
||||||
|
try {
|
||||||
|
return ScriptTargetOutputToFile.toFileWriter( new File( url.toURI() ) );
|
||||||
|
}
|
||||||
|
catch (URISyntaxException e) {
|
||||||
|
throw new PersistenceException(
|
||||||
|
String.format(
|
||||||
|
"Could not convert specified URL[%s] to a File reference",
|
||||||
|
url
|
||||||
|
),
|
||||||
|
e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, 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.jpa.internal.schemagen;
|
||||||
|
|
||||||
|
import javax.persistence.PersistenceException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Writer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ScriptTargetOutput implementation for supplied Writer references
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class ScriptTargetOutputToWriter implements ScriptTargetOutput {
|
||||||
|
private final Writer writer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a ScriptTargetOutputToWriter
|
||||||
|
*
|
||||||
|
* @param writer The writer to write to
|
||||||
|
*/
|
||||||
|
public ScriptTargetOutputToWriter(Writer writer) {
|
||||||
|
this.writer = writer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(String command) {
|
||||||
|
try {
|
||||||
|
writer.write( command );
|
||||||
|
writer.flush();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
throw new PersistenceException( "Could not write to target script file", e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void release() {
|
||||||
|
// nothing to do for a supplied writer
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Writer writer() {
|
||||||
|
return writer;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
/**
|
||||||
|
* Support for JPA 2.1 defined database schema generation. The main class in this package is
|
||||||
|
* {@link org.hibernate.jpa.internal.schemagen.JpaSchemaGenerator}.
|
||||||
|
* <p/>
|
||||||
|
* @see org.hibernate.jpa.SchemaGenAction
|
||||||
|
*/
|
||||||
|
package org.hibernate.jpa.internal.schemagen;
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, 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.jpa.test.schemagen;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test entity
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@Entity(name = "Item")
|
||||||
|
public class Item implements Serializable {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private String descr;
|
||||||
|
|
||||||
|
public Item() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item(String name, String desc) {
|
||||||
|
this.name = name;
|
||||||
|
this.descr = desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Column(length = 200)
|
||||||
|
public String getDescr() {
|
||||||
|
return descr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescr(String desc) {
|
||||||
|
this.descr = desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@Column(length = 30)
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,159 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, 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.jpa.test.schemagen;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
|
||||||
|
import org.hibernate.jpa.AvailableSettings;
|
||||||
|
import org.hibernate.jpa.boot.spi.Bootstrap;
|
||||||
|
import org.hibernate.jpa.boot.spi.EntityManagerFactoryBuilder;
|
||||||
|
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor;
|
||||||
|
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic tests for JPA 2.1 schema export
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class JpaSchemaGeneratorTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
|
private static final String LOAD_SQL = "org/hibernate/jpa/test/schemagen/load-script-source.sql";
|
||||||
|
private static final String CREATE_SQL = "org/hibernate/jpa/test/schemagen/create-script-source.sql";
|
||||||
|
private static final String DROP_SQL = "org/hibernate/jpa/test/schemagen/drop-script-source.sql";
|
||||||
|
|
||||||
|
private static int schemagenNumber = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class[] getAnnotatedClasses() {
|
||||||
|
return new Class[] { Item.class };
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-8271")
|
||||||
|
public void testSqlLoadScriptSourceClasspath() throws Exception {
|
||||||
|
Map settings = buildSettings();
|
||||||
|
settings.put( AvailableSettings.SCHEMA_GEN_DATABASE_ACTION, "drop-and-create" );
|
||||||
|
settings.put( AvailableSettings.SCHEMA_GEN_LOAD_SCRIPT_SOURCE, LOAD_SQL );
|
||||||
|
doTest( settings );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-8271")
|
||||||
|
public void testSqlLoadScriptSourceUrl() throws Exception {
|
||||||
|
Map settings = buildSettings();
|
||||||
|
settings.put( AvailableSettings.SCHEMA_GEN_DATABASE_ACTION, "drop-and-create" );
|
||||||
|
settings.put( AvailableSettings.SCHEMA_GEN_LOAD_SCRIPT_SOURCE, getResourceUrlString( LOAD_SQL ) );
|
||||||
|
doTest( settings );
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getResourceUrlString(String resource) {
|
||||||
|
final URL url = getClass().getClassLoader().getResource( resource );
|
||||||
|
if ( url == null ) {
|
||||||
|
throw new RuntimeException( "Unable to locate requested resource [" + resource + "]" );
|
||||||
|
}
|
||||||
|
return url.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-8271")
|
||||||
|
public void testSqlCreateScriptSourceClasspath() throws Exception {
|
||||||
|
Map settings = buildSettings();
|
||||||
|
settings.put( AvailableSettings.SCHEMA_GEN_DATABASE_ACTION, "drop-and-create" );
|
||||||
|
settings.put( AvailableSettings.SCHEMA_GEN_CREATE_SOURCE, "metadata-then-script" );
|
||||||
|
settings.put( AvailableSettings.SCHEMA_GEN_CREATE_SCRIPT_SOURCE, CREATE_SQL );
|
||||||
|
doTest( settings );
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-8271")
|
||||||
|
public void testSqlCreateScriptSourceUrl() throws Exception {
|
||||||
|
Map settings = buildSettings();
|
||||||
|
settings.put( AvailableSettings.SCHEMA_GEN_DATABASE_ACTION, "drop-and-create" );
|
||||||
|
settings.put( AvailableSettings.SCHEMA_GEN_CREATE_SOURCE, "metadata-then-script" );
|
||||||
|
settings.put( AvailableSettings.SCHEMA_GEN_CREATE_SCRIPT_SOURCE, getResourceUrlString( CREATE_SQL ) );
|
||||||
|
doTest( settings );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-8271")
|
||||||
|
public void testSqlDropScriptSourceClasspath() throws Exception {
|
||||||
|
Map settings = buildSettings();
|
||||||
|
settings.put( AvailableSettings.SCHEMA_GEN_DROP_SOURCE, "metadata-then-script" );
|
||||||
|
settings.put( AvailableSettings.SCHEMA_GEN_DATABASE_ACTION, "drop" );
|
||||||
|
settings.put( AvailableSettings.SCHEMA_GEN_DROP_SCRIPT_SOURCE, DROP_SQL );
|
||||||
|
doTest( settings );
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-8271")
|
||||||
|
public void testSqlDropScriptSourceUrl() throws Exception {
|
||||||
|
Map settings = buildSettings();
|
||||||
|
settings.put( AvailableSettings.SCHEMA_GEN_DROP_SOURCE, "metadata-then-script" );
|
||||||
|
settings.put( AvailableSettings.SCHEMA_GEN_DATABASE_ACTION, "drop" );
|
||||||
|
settings.put( AvailableSettings.SCHEMA_GEN_DROP_SCRIPT_SOURCE, getResourceUrlString( DROP_SQL ) );
|
||||||
|
doTest( settings );
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void doTest(Map settings) {
|
||||||
|
// We want a fresh db after emf close
|
||||||
|
// Unfortunately we have to use this dirty hack because the db seems not to be closed otherwise
|
||||||
|
settings.put( "hibernate.connection.url", "jdbc:h2:mem:db-schemagen" + schemagenNumber++
|
||||||
|
+ ";MVCC=TRUE;LOCK_TIMEOUT=10000" );
|
||||||
|
EntityManagerFactoryBuilder emfb = Bootstrap.getEntityManagerFactoryBuilder( buildPersistenceUnitDescriptor(),
|
||||||
|
settings );
|
||||||
|
|
||||||
|
EntityManagerFactory emf = emfb.build();
|
||||||
|
|
||||||
|
Assert.assertNotNull( emf.createEntityManager().find( Item.class, "schemagen-test" ) );
|
||||||
|
|
||||||
|
emf.close();
|
||||||
|
emfb.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
private PersistenceUnitDescriptor buildPersistenceUnitDescriptor() {
|
||||||
|
return new TestingPersistenceUnitDescriptorImpl( getClass().getSimpleName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disable hibernate schema export */
|
||||||
|
@Override
|
||||||
|
protected boolean createSchema() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
INSERT INTO Item(name) VALUES('schemagen-test');
|
|
@ -0,0 +1,2 @@
|
||||||
|
create table Item ( name varchar(30) not null, descr varchar(200), primary key (name));
|
||||||
|
INSERT INTO Item(name) VALUES('schemagen-test');
|
|
@ -0,0 +1 @@
|
||||||
|
INSERT INTO Item(name) VALUES('schemagen-test');
|
Loading…
Reference in New Issue