HHH-14618 Allow passing multiple script source files separated by comma

This commit is contained in:
Christian Beikov 2021-05-20 14:27:01 +02:00 committed by Andrea Boriero
parent bf19f98c2d
commit a57c0e34ff
11 changed files with 153 additions and 31 deletions

View File

@ -12,6 +12,7 @@ import java.io.Writer;
import java.net.URL;
import java.sql.SQLException;
import java.util.Map;
import java.util.regex.Pattern;
import org.hibernate.boot.model.relational.Namespace;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
@ -24,6 +25,7 @@ import org.hibernate.resource.transaction.spi.DdlTransactionIsolator;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.tool.schema.extract.spi.DatabaseInformation;
import org.hibernate.tool.schema.extract.internal.DatabaseInformationImpl;
import org.hibernate.tool.schema.internal.exec.ScriptSourceInputAggregate;
import org.hibernate.tool.schema.internal.exec.ScriptSourceInputFromFile;
import org.hibernate.tool.schema.internal.exec.ScriptSourceInputFromReader;
import org.hibernate.tool.schema.internal.exec.ScriptSourceInputFromUrl;
@ -33,8 +35,6 @@ import org.hibernate.tool.schema.internal.exec.ScriptTargetOutputToWriter;
import org.hibernate.tool.schema.spi.ScriptSourceInput;
import org.hibernate.tool.schema.spi.ScriptTargetOutput;
import org.jboss.logging.Logger;
/**
* Helper methods.
*
@ -43,6 +43,7 @@ import org.jboss.logging.Logger;
public class Helper {
private static final CoreMessageLogger log = CoreLogging.messageLogger( Helper.class );
private static final Pattern COMMA_PATTERN = Pattern.compile( "\\s*,\\s*" );
public static ScriptSourceInput interpretScriptSourceSetting(
Object scriptSourceSetting,
@ -55,24 +56,40 @@ public class Helper {
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, charsetName );
final String[] paths = COMMA_PATTERN.split( scriptSourceSettingString );
if ( paths.length == 1 ) {
return interpretScriptSourceSetting( scriptSourceSettingString, classLoaderService, charsetName );
}
final ScriptSourceInput[] inputs = new ScriptSourceInput[paths.length];
for ( int i = 0; i < paths.length; i++ ) {
inputs[i] = interpretScriptSourceSetting( paths[i], classLoaderService, charsetName ) ;
}
// assume it is a File path
final File file = new File( scriptSourceSettingString );
return new ScriptSourceInputFromFile( file, charsetName );
return new ScriptSourceInputAggregate( inputs );
}
}
private static ScriptSourceInput interpretScriptSourceSetting(
String scriptSourceSettingString,
ClassLoaderService classLoaderService,
String charsetName) {
// 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, charsetName );
}
// assume it is a File path
final File file = new File( scriptSourceSettingString );
return new ScriptSourceInputFromFile( file, charsetName );
}
public static ScriptTargetOutput interpretScriptTargetSetting(
Object scriptTargetSetting,
ClassLoaderService classLoaderService,

View File

@ -0,0 +1,87 @@
/*
* 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.exec;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.hibernate.tool.hbm2ddl.ImportSqlCommandExtractor;
import org.hibernate.tool.schema.spi.ScriptSourceInput;
/**
* A script source input that aggregates over multiple other {@link ScriptSourceInput}.
*
* @author Christian Beikov
*/
public class ScriptSourceInputAggregate implements ScriptSourceInput {
private final ScriptSourceInput[] inputs;
/**
* Constructs a ScriptSourceInputAggregate
*
* @param inputs The script source inputs
*/
public ScriptSourceInputAggregate(ScriptSourceInput[] inputs) {
this.inputs = inputs;
}
@Override
public void prepare() {
for ( ScriptSourceInput input : inputs ) {
input.prepare();
}
}
@Override
public void release() {
Throwable t = null;
for ( ScriptSourceInput input : inputs ) {
try {
input.release();
}
catch (Throwable t2) {
if ( t == null ) {
t = t2;
}
else {
t.addSuppressed( t2 );
}
}
}
if ( t != null ) {
doThrow( t );
}
}
@SuppressWarnings("unchecked")
private static <T extends Throwable> void doThrow(Throwable e) throws T {
throw (T) e;
}
@Override
public List<String> read(ImportSqlCommandExtractor commandExtractor) {
final List<String>[] lists = new List[inputs.length];
int size = 0;
for ( int i = 0; i < inputs.length; i++ ) {
lists[i] = inputs[i].read( commandExtractor );
size += lists[i].size();
}
final List<String> list = new ArrayList<>( size );
for ( List<String> strings : lists ) {
list.addAll( strings );
}
return list;
}
@Override
public String toString() {
return "ScriptSourceInputAggregate(" + Arrays.toString( inputs ) + ")";
}
}

View File

@ -30,10 +30,6 @@ public class JpaFileSchemaGeneratorTest extends JpaSchemaGeneratorTest {
return toFilePath(super.getDropSqlScript());
}
protected String toFilePath(String relativePath) {
return Thread.currentThread().getContextClassLoader().getResource( relativePath ).getFile();
}
@Override
protected String getResourceUrlString(String resource) {
return resource;

View File

@ -8,6 +8,7 @@ package org.hibernate.jpa.test.schemagen;
import java.net.URL;
import java.util.Map;
import java.util.function.Function;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
@ -20,6 +21,7 @@ import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.TestForIssue;
import org.hibernate.test.legacy.S;
import org.junit.Assert;
import org.junit.Test;
@ -29,9 +31,9 @@ import org.junit.Test;
@RequiresDialect( H2Dialect.class )
public class JpaSchemaGeneratorTest extends BaseEntityManagerFunctionalTestCase {
private final String LOAD_SQL = getScriptFolderPath() + "load-script-source.sql";
private final String CREATE_SQL = getScriptFolderPath() + "create-script-source.sql";
private final String DROP_SQL = getScriptFolderPath() + "drop-script-source.sql";
private final String LOAD_SQL = getScriptFolderPath() + "load-script-source.sql , " + getScriptFolderPath() + "load-script-source2.sql";
private final String CREATE_SQL = getScriptFolderPath() + "create-script-source.sql , " + getScriptFolderPath() + "create-script-source2.sql";
private final String DROP_SQL = getScriptFolderPath() + "drop-script-source.sql , " + getScriptFolderPath() + "drop-script-source2.sql";
private static int schemagenNumber = 0;
@ -65,12 +67,29 @@ public class JpaSchemaGeneratorTest extends BaseEntityManagerFunctionalTestCase
doTest( settings );
}
protected String getResourceUrlString(String resource) {
final URL url = getClass().getClassLoader().getResource( resource );
if ( url == null ) {
throw new RuntimeException( "Unable to locate requested resource [" + resource + "]" );
protected String getResourceUrlString(String string) {
return getResourceUrlString( getClass().getClassLoader(), string, URL::toString );
}
protected String getResourceUrlString(ClassLoader classLoader, String string, Function<URL, String> transformer) {
final String[] strings = string.split( "\\s*,\\s*" );
final StringBuilder sb = new StringBuilder( string.length() );
for ( int i = 0; i < strings.length; i++ ) {
if ( i != 0 ) {
sb.append( ',' );
}
final String resource = strings[i];
final URL url = classLoader.getResource( resource );
if ( url == null ) {
throw new RuntimeException( "Unable to locate requested resource [" + resource + "]" );
}
sb.append( transformer.apply( url ) );
}
return url.toString();
return sb.toString();
}
protected String toFilePath(String relativePath) {
return getResourceUrlString( Thread.currentThread().getContextClassLoader(), relativePath, URL::getFile );
}
@SuppressWarnings("unchecked")
@ -143,6 +162,7 @@ public class JpaSchemaGeneratorTest extends BaseEntityManagerFunctionalTestCase
EntityManager em = emf.createEntityManager();
try {
Assert.assertNotNull( em.find( Item.class, encodedName() ) );
Assert.assertNotNull( em.find( Item.class, "multi-file-test" ) );
}
finally {
em.close();

View File

@ -45,10 +45,6 @@ public class JpaFileSchemaGeneratorWithHbm2DdlCharsetNameTest extends JpaSchemaG
return toFilePath(super.getDropSqlScript());
}
protected String toFilePath(String relativePath) {
return Thread.currentThread().getContextClassLoader().getResource( relativePath ).getFile();
}
@Override
protected String getResourceUrlString(String resource) {
return resource;

View File

@ -0,0 +1 @@
INSERT INTO Item(name) VALUES('multi-file-test');

View File

@ -0,0 +1 @@
INSERT INTO Item(name) VALUES('multi-file-test');

View File

@ -0,0 +1 @@
INSERT INTO Item(name) VALUES('multi-file-test');

View File

@ -0,0 +1 @@
INSERT INTO Item(name) VALUES('multi-file-test');

View File

@ -0,0 +1 @@
INSERT INTO Item(name) VALUES('multi-file-test');

View File

@ -0,0 +1 @@
INSERT INTO Item(name) VALUES('multi-file-test');