HHH-7957 - Integrate Public Review Draft of the JPA 2.1 spec : schema generation
This commit is contained in:
parent
6599f710bb
commit
9ab924041d
|
@ -876,7 +876,7 @@ public class Configuration implements Serializable {
|
|||
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
private Iterator<IdentifierGenerator> iterateGenerators(Dialect dialect) throws MappingException {
|
||||
public Iterator<IdentifierGenerator> iterateGenerators(Dialect dialect) throws MappingException {
|
||||
|
||||
TreeMap generators = new TreeMap();
|
||||
String defaultCatalog = properties.getProperty( Environment.DEFAULT_CATALOG );
|
||||
|
|
|
@ -32,8 +32,6 @@ import org.hibernate.service.Service;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface DatabaseInfoDialectResolver extends Service {
|
||||
public static final int NO_VERSION = -9999;
|
||||
|
||||
/**
|
||||
* Determine the {@link Dialect} to use based on the given information. Implementations are
|
||||
* expected to return the {@link Dialect} instance to use, or {@code null} if the they did not locate a match.
|
||||
|
@ -45,6 +43,8 @@ public interface DatabaseInfoDialectResolver extends Service {
|
|||
public Dialect resolve(DatabaseInfo databaseInfo);
|
||||
|
||||
public static interface DatabaseInfo {
|
||||
public static final int NO_VERSION = -9999;
|
||||
|
||||
/**
|
||||
* Obtain access to the database name, as returned from {@link java.sql.DatabaseMetaData#getDatabaseProductName()}
|
||||
* for the target database
|
||||
|
|
|
@ -96,6 +96,9 @@ public interface PersistentIdentifierGenerator extends IdentifierGenerator {
|
|||
*/
|
||||
public Object generatorKey();
|
||||
|
||||
public String getSchema();
|
||||
|
||||
public String getCatalog();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
package org.hibernate.jpa;
|
||||
|
||||
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
|
||||
/**
|
||||
* Defines the available HEM settings, both JPA-defined as well as Hibernate-specific
|
||||
* <p/>
|
||||
|
@ -192,6 +194,171 @@ public interface AvailableSettings {
|
|||
*/
|
||||
public static final String CDI_BEAN_MANAGER = "javax.persistence.bean.manager";
|
||||
|
||||
/**
|
||||
* Specifies the action to be taken by the persistence provider. The set of possible values are:<ul>
|
||||
* <li>none</li>
|
||||
* <li>create</li>
|
||||
* <li>drop</li>
|
||||
* <li>drop-and-create</li>
|
||||
* </ul>
|
||||
*
|
||||
* If no value is specified, the default is "none".
|
||||
*
|
||||
* @see SchemaGenAction
|
||||
*/
|
||||
public static final String SCHEMA_GEN_ACTION = "javax.persistence.schema-generation-action";
|
||||
|
||||
/**
|
||||
* Specifies whether the schema is to be created in the database, whether scripts are to be generated, or both.
|
||||
* The values for this property are:<ul>
|
||||
* <li>database</li>
|
||||
* <li>scripts</li>
|
||||
* <li>database-and-scripts</li>
|
||||
* </ul>
|
||||
* If no value is specified, a default is assumed as follows:<ul>
|
||||
* <li>
|
||||
* if script targets are specified (per {@value #SCHEMA_GEN_CREATE_SCRIPT_TARGET} and
|
||||
* {@value #SCHEMA_GEN_DROP_SCRIPT_TARGET}), then the default is assumed to be "scripts"
|
||||
* </li>
|
||||
* <li>
|
||||
* Otherwise, "database" is assumed
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* @see SchemaGenTarget
|
||||
*/
|
||||
public static final String SCHEMA_GEN_TARGET = "javax.persistence.schema-generation-target";
|
||||
|
||||
/**
|
||||
* If schema creations scripts are to be generated, the target/location for these scripts must be specified. This
|
||||
* target may take the form of either a {@link java.io.Writer} or a string designating a
|
||||
* {@link java.net.URL}.
|
||||
* <p/>
|
||||
* Create and drop scripts are written separately (though the same Writer/URL could be passed).
|
||||
* {@value #SCHEMA_GEN_CREATE_SCRIPT_TARGET} specifies the target for the create script.
|
||||
*
|
||||
* @see #SCHEMA_GEN_DROP_SCRIPT_TARGET
|
||||
*/
|
||||
@SuppressWarnings("JavaDoc")
|
||||
public static final String SCHEMA_GEN_CREATE_SCRIPT_TARGET = "javax.persistence.ddl-create-script-target";
|
||||
|
||||
/**
|
||||
* If schema creations scripts are to be generated, the target/location for these scripts must be specified. This
|
||||
* target may take the form of either a {@link java.io.Writer} or a string designating a
|
||||
* {@link java.net.URL}.
|
||||
* <p/>
|
||||
* Create and drop scripts are written separately (though the same Writer/URL could be passed).
|
||||
* {@value #SCHEMA_GEN_DROP_SCRIPT_TARGET} specifies the target for the create script.
|
||||
*
|
||||
* @see #SCHEMA_GEN_CREATE_SCRIPT_TARGET
|
||||
*/
|
||||
@SuppressWarnings("JavaDoc")
|
||||
public static final String SCHEMA_GEN_DROP_SCRIPT_TARGET = "javax.persistence.ddl-drop-script-target";
|
||||
|
||||
/**
|
||||
* Specifies whether schema generation is to occur on the basis of the object/relational mapping metadata, DDL
|
||||
* scripts, or a combination of the two. The valid values for this property are: <ul>
|
||||
* <li>metadata</li>
|
||||
* <li>scripts</li>
|
||||
* <li>metadata-then-scripts</li>
|
||||
* <li>scripts-then-metadata</li>
|
||||
* </ul>
|
||||
* If no value is specified, a default is assumed as follows:<ul>
|
||||
* <li>
|
||||
* if source scripts are specified (per {@value #SCHEMA_GEN_CREATE_SCRIPT_SOURCE} and
|
||||
* {@value #SCHEMA_GEN_DROP_SCRIPT_SOURCE}),then "scripts" is assumed
|
||||
* </li>
|
||||
* <li>
|
||||
* otherwise, "metadata" is assumed
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* @see SchemaGenSource
|
||||
*/
|
||||
public static final String SCHEMA_GEN_SOURCE = "javax.persistence.schema-generation-source";
|
||||
|
||||
/**
|
||||
* Specifies the CREATE script file as either a {@link java.io.Reader} configured for reading of the DDL script
|
||||
* file or a string designating a file {@link java.net.URL} for the DDL script.
|
||||
*
|
||||
* @see #SCHEMA_GEN_DROP_SCRIPT_SOURCE
|
||||
*/
|
||||
public static final String SCHEMA_GEN_CREATE_SCRIPT_SOURCE = "javax.persistence.ddl-create-script-source";
|
||||
|
||||
/**
|
||||
* Specifies the DROP script file as either a {@link java.io.Reader} configured for reading of the DDL script
|
||||
* file or a string designating a file {@link java.net.URL} for the DDL script.
|
||||
*
|
||||
* @see #SCHEMA_GEN_CREATE_SCRIPT_SOURCE
|
||||
*/
|
||||
public static final String SCHEMA_GEN_DROP_SCRIPT_SOURCE = "javax.persistence.ddl-drop-script-source";
|
||||
|
||||
/**
|
||||
* Specifies whether the persistence provider is to create the database schema(s) in addition to creating
|
||||
* database objects (tables, sequences, constraints, etc). The value of this boolean property should be set
|
||||
* to {@code true} if the persistence provider is to create schemas in the database or to generate DDL that
|
||||
* contains “CREATE SCHEMA” commands. If this property is not supplied (or is explicitly {@code false}), the
|
||||
* provider should not attempt to create database schemas.
|
||||
*/
|
||||
public static final String SCHEMA_GEN_CREATE_SCHEMAS = "javax.persistence.create-database-schemas";
|
||||
|
||||
/**
|
||||
* Allows passing the specific {@link java.sql.Connection} instance to be used for performing schema generation
|
||||
* where the target is "database".
|
||||
* <p/>
|
||||
* May also be used to determine the values for {@value #SCHEMA_GEN_DB_NAME},
|
||||
* {@value #SCHEMA_GEN_DB_MAJOR_VERSION} and {@value #SCHEMA_GEN_DB_MINOR_VERSION}.
|
||||
*/
|
||||
public static final String SCHEMA_GEN_CONNECTION = "javax.persistence.schema-generation-connection";
|
||||
|
||||
/**
|
||||
* Specifies the name of the database provider in cases where a Connection to the underlying database is
|
||||
* not available (aka, mainly in generating scripts). In such cases, a value for
|
||||
* {@value #SCHEMA_GEN_DB_NAME} *must* be specified.
|
||||
* <p/>
|
||||
* The value of this setting is expected to match the value returned by
|
||||
* {@link java.sql.DatabaseMetaData#getDatabaseProductName()} for the target database.
|
||||
* <p/>
|
||||
* Additionally specifying {@value #SCHEMA_GEN_DB_MAJOR_VERSION} and/or {@value #SCHEMA_GEN_DB_MINOR_VERSION}
|
||||
* may be required to understand exactly how to generate the required schema commands.
|
||||
*
|
||||
* @see #SCHEMA_GEN_DB_MAJOR_VERSION
|
||||
* @see #SCHEMA_GEN_DB_MINOR_VERSION
|
||||
*/
|
||||
@SuppressWarnings("JavaDoc")
|
||||
public static final String SCHEMA_GEN_DB_NAME = "javax.persistence.database-product-name";
|
||||
|
||||
/**
|
||||
* Specifies the major version of the underlying database, as would be returned by
|
||||
* {@link java.sql.DatabaseMetaData#getDatabaseMajorVersion} for the target database. This value is used to
|
||||
* help more precisely determine how to perform schema generation tasks for the underlying database in cases
|
||||
* where {@value #SCHEMA_GEN_DB_NAME} does not provide enough distinction.
|
||||
|
||||
* @see #SCHEMA_GEN_DB_NAME
|
||||
* @see #SCHEMA_GEN_DB_MINOR_VERSION
|
||||
*/
|
||||
public static final String SCHEMA_GEN_DB_MAJOR_VERSION = "javax.persistence.database-major-version";
|
||||
|
||||
/**
|
||||
* Specifies the minor version of the underlying database, as would be returned by
|
||||
* {@link java.sql.DatabaseMetaData#getDatabaseMinorVersion} for the target database. This value is used to
|
||||
* help more precisely determine how to perform schema generation tasks for the underlying database in cases
|
||||
* where te combination of {@value #SCHEMA_GEN_DB_NAME} and {@value #SCHEMA_GEN_DB_MAJOR_VERSION} does not provide
|
||||
* enough distinction.
|
||||
*
|
||||
* @see #SCHEMA_GEN_DB_NAME
|
||||
* @see #SCHEMA_GEN_DB_MAJOR_VERSION
|
||||
*/
|
||||
public static final String SCHEMA_GEN_DB_MINOR_VERSION = "javax.persistence.database-minor-version";
|
||||
|
||||
/**
|
||||
* Specifies a {@link java.io.Reader} configured for reading of the SQL load script or a string designating the
|
||||
* file {@link java.net.URL} for the SQL load script.
|
||||
* <p/>
|
||||
* A "SQL load script" is a script that performs some database initialization (INSERT, etc).
|
||||
*/
|
||||
public static final String SCHEMA_GEN_LOAD_SCRIPT_SOURCE = "javax.persistence.sql-load-script-source";
|
||||
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Hibernate specific settings
|
||||
|
|
|
@ -36,6 +36,7 @@ import java.util.Map;
|
|||
import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor;
|
||||
import org.hibernate.jpa.boot.internal.PersistenceXmlParser;
|
||||
import org.hibernate.jpa.boot.spi.Bootstrap;
|
||||
import org.hibernate.jpa.boot.spi.EntityManagerFactoryBuilder;
|
||||
import org.hibernate.jpa.boot.spi.ProviderChecker;
|
||||
import org.hibernate.jpa.internal.util.PersistenceUtilHelper;
|
||||
|
||||
|
@ -56,6 +57,11 @@ public class HibernatePersistenceProvider implements PersistenceProvider {
|
|||
*/
|
||||
@Override
|
||||
public EntityManagerFactory createEntityManagerFactory(String persistenceUnitName, Map properties) {
|
||||
final EntityManagerFactoryBuilder builder = getEntityManagerFactoryBuilderOrNull( persistenceUnitName, properties );
|
||||
return builder == null ? null : builder.build();
|
||||
}
|
||||
|
||||
private EntityManagerFactoryBuilder getEntityManagerFactoryBuilderOrNull(String persistenceUnitName, Map properties) {
|
||||
final Map integration = wrap( properties );
|
||||
final List<ParsedPersistenceXmlDescriptor> units = PersistenceXmlParser.locatePersistenceUnits( integration );
|
||||
|
||||
|
@ -75,7 +81,7 @@ public class HibernatePersistenceProvider implements PersistenceProvider {
|
|||
continue;
|
||||
}
|
||||
|
||||
return Bootstrap.getEntityManagerFactoryBuilder( persistenceUnit, integration ).build();
|
||||
return Bootstrap.getEntityManagerFactoryBuilder( persistenceUnit, integration );
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -98,13 +104,18 @@ public class HibernatePersistenceProvider implements PersistenceProvider {
|
|||
|
||||
@Override
|
||||
public void generateSchema(PersistenceUnitInfo info, Map map) {
|
||||
// todo : implement
|
||||
EntityManagerFactoryBuilder builder = Bootstrap.getEntityManagerFactoryBuilder( info, map );
|
||||
builder.generateSchema();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generateSchema(String persistenceUnitName, Map map) {
|
||||
// todo : implement
|
||||
return false;
|
||||
final EntityManagerFactoryBuilder builder = getEntityManagerFactoryBuilderOrNull( persistenceUnitName, map );
|
||||
if ( builder == null ) {
|
||||
return false;
|
||||
}
|
||||
builder.generateSchema();
|
||||
return true;
|
||||
}
|
||||
|
||||
private final ProviderUtil providerUtil = new ProviderUtil() {
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
|
||||
/**
|
||||
* Describes the allowable values of the {@value AvailableSettings#SCHEMA_GEN_ACTION} setting.
|
||||
*
|
||||
* @see AvailableSettings#SCHEMA_GEN_ACTION
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public enum SchemaGenAction {
|
||||
/**
|
||||
* "none" - no actions will be performed (aka, generation is disabled).
|
||||
*/
|
||||
NONE( "none" ),
|
||||
/**
|
||||
* "create" - database creation will be generated
|
||||
*/
|
||||
CREATE( "create" ),
|
||||
/**
|
||||
* "drop" - database dropping will be generated
|
||||
*/
|
||||
DROP( "drop" ),
|
||||
/**
|
||||
* "drop-and-create" - both database creation and database dropping will be generated.
|
||||
*/
|
||||
BOTH( "drop-and-create" );
|
||||
|
||||
private final String externalName;
|
||||
|
||||
private SchemaGenAction(String externalName) {
|
||||
this.externalName = externalName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used when processing JPA configuration to interpret the {@value AvailableSettings#SCHEMA_GEN_ACTION} setting.
|
||||
*
|
||||
* @param value The encountered value of {@value AvailableSettings#SCHEMA_GEN_ACTION}
|
||||
*
|
||||
* @return The matching enum value. An empty value will return {@link #NONE}.
|
||||
*
|
||||
* @throws IllegalArgumentException If the incoming value is unrecognized
|
||||
*/
|
||||
public static SchemaGenAction interpret(String value) {
|
||||
if ( StringHelper.isEmpty( value ) ) {
|
||||
// default is NONE
|
||||
return NONE;
|
||||
}
|
||||
|
||||
if ( CREATE.externalName.equals( value ) ) {
|
||||
return CREATE;
|
||||
}
|
||||
else if ( DROP.externalName.equals( value ) ) {
|
||||
return DROP;
|
||||
}
|
||||
else if ( BOTH.externalName.equals( value ) ) {
|
||||
return BOTH;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(
|
||||
String.format( "Unrecognized '%s' value : %s", AvailableSettings.SCHEMA_GEN_ACTION, value )
|
||||
);
|
||||
}
|
||||
|
||||
public boolean includesCreate() {
|
||||
return this == CREATE || this == BOTH;
|
||||
}
|
||||
|
||||
public boolean includesDrop() {
|
||||
return this == DROP || this == BOTH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + "(" + externalName + ")";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
|
||||
/**
|
||||
* Describes the allowable values of the {@value AvailableSettings#SCHEMA_GEN_SOURCE} setting.
|
||||
*
|
||||
* @see AvailableSettings#SCHEMA_GEN_SOURCE
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public enum SchemaGenSource {
|
||||
/**
|
||||
* "metadata" - The O/RM metadata is used as the exclusive source for generation
|
||||
*/
|
||||
METADATA( "metadata" ),
|
||||
/**
|
||||
* "scripts" - External DDL script(s) are used as the exclusive source for generation. The scripts for schema
|
||||
* creation and dropping come from different sources. The creation DDL script is identified by the
|
||||
* {@value AvailableSettings#SCHEMA_GEN_CREATE_SCRIPT_SOURCE} setting; the drop DDL script is identified by the
|
||||
* {@value AvailableSettings#SCHEMA_GEN_DROP_SCRIPT_SOURCE} setting.
|
||||
*
|
||||
* @see AvailableSettings#SCHEMA_GEN_CREATE_SCRIPT_SOURCE
|
||||
* @see AvailableSettings#SCHEMA_GEN_DROP_SCRIPT_SOURCE
|
||||
*/
|
||||
SCRIPTS( "scripts" ),
|
||||
/**
|
||||
* "metadata-then-scripts" - Both the O/RM metadata and external DDL scripts are used as sources for generation,
|
||||
* with the O/RM metadata being applied first.
|
||||
*
|
||||
* @see #METADATA
|
||||
* @see #SCRIPTS
|
||||
*/
|
||||
METADATA_THEN_SCRIPTS( "metadata-then-scripts" ),
|
||||
/**
|
||||
* "scripts-then-metadata" - Both the O/RM metadata and external DDL scripts are used as sources for generation,
|
||||
* with the commands from the external DDL script(s) being applied first
|
||||
*
|
||||
* @see #SCRIPTS
|
||||
* @see #METADATA
|
||||
*/
|
||||
SCRIPTS_THEN_METADATA( "scripts-then-metadata" );
|
||||
|
||||
private final String externalName;
|
||||
|
||||
private SchemaGenSource(String externalName) {
|
||||
this.externalName = externalName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used when processing JPA configuration to interpret the {@value AvailableSettings#SCHEMA_GEN_SOURCE} setting.
|
||||
*
|
||||
* @param value The encountered value of {@value AvailableSettings#SCHEMA_GEN_SOURCE}
|
||||
*
|
||||
* @return The matching enum value. An empty value will return {@code null}.
|
||||
*
|
||||
* @throws IllegalArgumentException If the incoming value is unrecognized
|
||||
*/
|
||||
public static SchemaGenSource interpret(String value) {
|
||||
if ( StringHelper.isEmpty( value ) ) {
|
||||
// empty is in fact valid as means to interpret default value based on other settings
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( METADATA.externalName.equals( value ) ) {
|
||||
return METADATA;
|
||||
}
|
||||
else if ( SCRIPTS.externalName.equals( value ) ) {
|
||||
return SCRIPTS;
|
||||
}
|
||||
else if ( METADATA_THEN_SCRIPTS.externalName.equals( value ) ) {
|
||||
return METADATA_THEN_SCRIPTS;
|
||||
}
|
||||
else if ( SCRIPTS_THEN_METADATA.externalName.equals( value ) ) {
|
||||
return SCRIPTS_THEN_METADATA;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException( "Unrecognized schema generation source value : " + value );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
|
||||
/**
|
||||
* Describes the allowable values of the {@value AvailableSettings#SCHEMA_GEN_TARGET} setting.
|
||||
*
|
||||
* @see AvailableSettings#SCHEMA_GEN_TARGET
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public enum SchemaGenTarget {
|
||||
/**
|
||||
* "database" - Generation commands will be executed directly against the database (via JDBC Statements).
|
||||
*/
|
||||
DATABASE( "database" ),
|
||||
/**
|
||||
* "scripts" - Generation commands will be written to script (text) "targets" as indicated by the
|
||||
* {@value AvailableSettings#SCHEMA_GEN_CREATE_SCRIPT_TARGET} and
|
||||
* {@value AvailableSettings#SCHEMA_GEN_DROP_SCRIPT_TARGET} settings.
|
||||
*/
|
||||
SCRIPTS( "scripts" ),
|
||||
/**
|
||||
* "database-and-scripts" - Generation commands will be sent to both.
|
||||
*
|
||||
* @see #DATABASE
|
||||
* @see #SCRIPTS
|
||||
*/
|
||||
BOTH( "database-and-scripts" );
|
||||
|
||||
private final String externalName;
|
||||
|
||||
private SchemaGenTarget(String externalName) {
|
||||
this.externalName = externalName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used when processing JPA configuration to interpret the {@value AvailableSettings#SCHEMA_GEN_TARGET} setting.
|
||||
*
|
||||
* @param value The encountered value of {@value AvailableSettings#SCHEMA_GEN_TARGET}
|
||||
*
|
||||
* @return The matching enum value. An empty value will return {@code null}.
|
||||
*
|
||||
* @throws IllegalArgumentException If the incoming value is unrecognized
|
||||
*/
|
||||
public static SchemaGenTarget interpret(String value) {
|
||||
if ( StringHelper.isEmpty( value ) ) {
|
||||
// empty is in fact valid as means to interpret default value based on other settings
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( DATABASE.externalName.equals( value ) ) {
|
||||
return DATABASE;
|
||||
}
|
||||
else if ( SCRIPTS.externalName.equals( value ) ) {
|
||||
return SCRIPTS;
|
||||
}
|
||||
else if ( BOTH.externalName.equals( value ) ) {
|
||||
return BOTH;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException( "Unknown schema generation target value : " + value );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + "(" + externalName + ")";
|
||||
}
|
||||
}
|
|
@ -81,6 +81,7 @@ import org.hibernate.jpa.boot.spi.EntityManagerFactoryBuilder;
|
|||
import org.hibernate.jpa.boot.spi.IntegratorProvider;
|
||||
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor;
|
||||
import org.hibernate.jpa.event.spi.JpaIntegrator;
|
||||
import org.hibernate.jpa.internal.schemagen.JpaSchemaGenerator;
|
||||
import org.hibernate.jpa.internal.EntityManagerFactoryImpl;
|
||||
import org.hibernate.jpa.internal.EntityManagerMessageLogger;
|
||||
import org.hibernate.jpa.internal.util.LogHelper;
|
||||
|
@ -731,6 +732,32 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateSchema() {
|
||||
processProperties();
|
||||
|
||||
final ServiceRegistry serviceRegistry = buildServiceRegistry();
|
||||
final ClassLoaderService classLoaderService = serviceRegistry.getService( ClassLoaderService.class );
|
||||
|
||||
// IMPL NOTE : TCCL handling here is temporary.
|
||||
// It is needed because this code still uses Hibernate Configuration and Hibernate commons-annotations
|
||||
// in turn which relies on TCCL being set.
|
||||
|
||||
( (ClassLoaderServiceImpl) classLoaderService ).withTccl(
|
||||
new ClassLoaderServiceImpl.Work() {
|
||||
@Override
|
||||
public Object perform() {
|
||||
final Configuration hibernateConfiguration = buildHibernateConfiguration( serviceRegistry );
|
||||
JpaSchemaGenerator.performGeneration( hibernateConfiguration, serviceRegistry );
|
||||
return null;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// release this builder
|
||||
cancel();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public EntityManagerFactory build() {
|
||||
processProperties();
|
||||
|
|
|
@ -73,4 +73,9 @@ public interface EntityManagerFactoryBuilder {
|
|||
* something having gone wrong during the bootstrap process
|
||||
*/
|
||||
public void cancel();
|
||||
|
||||
/**
|
||||
* Perform an explicit schema generation (rather than an "auto" one) based on the
|
||||
*/
|
||||
public void generateSchema();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* 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.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* GenerationTarget implementation for handling generation directly to the database
|
||||
*
|
||||
* @see org.hibernate.jpa.SchemaGenTarget#DATABASE
|
||||
* @see org.hibernate.jpa.SchemaGenTarget#BOTH
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
class DatabaseTarget implements GenerationTarget {
|
||||
private static final Logger log = Logger.getLogger( DatabaseTarget.class );
|
||||
|
||||
private final JdbcConnectionContext jdbcConnectionContext;
|
||||
|
||||
private Statement jdbcStatement;
|
||||
|
||||
DatabaseTarget(JdbcConnectionContext jdbcConnectionContext) {
|
||||
this.jdbcConnectionContext = jdbcConnectionContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptCreateCommands(Iterable<String> commands) {
|
||||
for ( String command : commands ) {
|
||||
try {
|
||||
jdbcStatement().execute( command );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw new PersistenceException(
|
||||
"Unable to execute JPA schema generation create command [" + command + "]"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Statement jdbcStatement() {
|
||||
if ( jdbcStatement == null ) {
|
||||
try {
|
||||
jdbcStatement = jdbcConnectionContext.getJdbcConnection().createStatement();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw new PersistenceException( "Unable to generate JDBC Statement object for schema generation" );
|
||||
}
|
||||
}
|
||||
return jdbcStatement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptDropCommands(Iterable<String> commands) {
|
||||
for ( String command : commands ) {
|
||||
try {
|
||||
jdbcStatement().execute( command );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw new PersistenceException(
|
||||
"Unable to execute JPA schema generation drop command [" + command + "]"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
if ( jdbcStatement != null ) {
|
||||
try {
|
||||
jdbcStatement.close();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
log.debug( "Unable to close JDBC statement after JPA schema generation : " + e.toString() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* 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.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* SqlScriptReader implementation for File references. A reader is opened here and then explicitly closed on
|
||||
* {@link #reader}.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
class FileScriptSource extends ReaderScriptSource implements SqlScriptReader {
|
||||
private static final Logger log = Logger.getLogger( FileScriptSource.class );
|
||||
|
||||
public FileScriptSource(String fileUrl) {
|
||||
super( toFileReader( fileUrl ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
try {
|
||||
reader().close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
log.warn( "Unable to close file reader for generation script source" );
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
private static Reader toFileReader(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 FileReader( file );
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new PersistenceException( "Unable to open specified script target file for writing : " + fileUrl );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Contract describing a generation source for create commands
|
||||
*
|
||||
* @see org.hibernate.jpa.SchemaGenSource
|
||||
* @see org.hibernate.jpa.AvailableSettings#SCHEMA_GEN_SOURCE
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
interface GenerationSource {
|
||||
/**
|
||||
* Retrieve the create generation commands from this source.
|
||||
*
|
||||
* @return The generation commands
|
||||
*/
|
||||
public Iterable<String> getCreateCommands();
|
||||
|
||||
/**
|
||||
* Retrieve the drop generation commands from this source
|
||||
*
|
||||
* @return The generation commands
|
||||
*/
|
||||
public Iterable<String> getDropCommands();
|
||||
|
||||
/**
|
||||
* Release this source. Give it a change to release its resources, if any.
|
||||
*/
|
||||
public void release();
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Describes a schema generation target
|
||||
*
|
||||
* @see org.hibernate.jpa.SchemaGenTarget
|
||||
* @see org.hibernate.jpa.AvailableSettings#SCHEMA_GEN_TARGET
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
interface GenerationTarget {
|
||||
/**
|
||||
* Accept a group of create generation commands
|
||||
*
|
||||
* @param commands The commands
|
||||
*/
|
||||
public void acceptCreateCommands(Iterable<String> commands);
|
||||
|
||||
/**
|
||||
* Accept a group of drop generation commands.
|
||||
*
|
||||
* @param commands The commands
|
||||
*/
|
||||
public void acceptDropCommands(Iterable<String> commands);
|
||||
|
||||
/**
|
||||
* Release this target, giving it a change to release its resources.
|
||||
*/
|
||||
public void release();
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* 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.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.engine.jdbc.spi.JdbcConnectionAccess;
|
||||
|
||||
/**
|
||||
* Defines access to a JDBC Connection for use in Schema generation
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
class JdbcConnectionContext {
|
||||
private final JdbcConnectionAccess jdbcConnectionAccess;
|
||||
private Connection jdbcConnection;
|
||||
|
||||
JdbcConnectionContext(JdbcConnectionAccess jdbcConnectionAccess) {
|
||||
this.jdbcConnectionAccess = jdbcConnectionAccess;
|
||||
}
|
||||
|
||||
public Connection getJdbcConnection() {
|
||||
if ( jdbcConnection == null ) {
|
||||
try {
|
||||
this.jdbcConnection = jdbcConnectionAccess.obtainConnection();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw new PersistenceException( "Unable to obtain JDBC Connection", e );
|
||||
}
|
||||
}
|
||||
return jdbcConnection;
|
||||
}
|
||||
|
||||
public void release() {
|
||||
if ( jdbcConnection != null ) {
|
||||
try {
|
||||
jdbcConnectionAccess.releaseConnection( jdbcConnection );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw new PersistenceException( "Unable to release JDBC Connection", e );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,428 @@
|
|||
/*
|
||||
* 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.Reader;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.hibernate.engine.jdbc.dialect.spi.DatabaseInfoDialectResolver;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.id.PersistentIdentifierGenerator;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||
import org.hibernate.jpa.AvailableSettings;
|
||||
import org.hibernate.jpa.SchemaGenAction;
|
||||
import org.hibernate.jpa.SchemaGenSource;
|
||||
import org.hibernate.jpa.SchemaGenTarget;
|
||||
import org.hibernate.mapping.Table;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.tool.hbm2ddl.ImportSqlCommandExtractor;
|
||||
|
||||
/**
|
||||
* Class responsible for the JPA-defined schema generation behavior.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class JpaSchemaGenerator {
|
||||
private static final Logger log = Logger.getLogger( JpaSchemaGenerator.class );
|
||||
|
||||
public static void performGeneration(Configuration hibernateConfiguration, ServiceRegistry serviceRegistry) {
|
||||
|
||||
// First, determine the actions (if any) to be performed ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
final SchemaGenAction action = SchemaGenAction.interpret(
|
||||
hibernateConfiguration.getProperty( AvailableSettings.SCHEMA_GEN_ACTION )
|
||||
);
|
||||
if ( action == SchemaGenAction.NONE ) {
|
||||
// no generation requested
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Figure out the JDBC Connection context, if any ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
final JdbcConnectionContext jdbcConnectionContext = determineAppropriateJdbcConnectionContext(
|
||||
hibernateConfiguration,
|
||||
serviceRegistry
|
||||
);
|
||||
|
||||
final Dialect dialect = determineDialect( jdbcConnectionContext, hibernateConfiguration, serviceRegistry );
|
||||
|
||||
final ImportSqlCommandExtractor scriptCommandExtractor = serviceRegistry.getService( ImportSqlCommandExtractor.class );
|
||||
|
||||
|
||||
// Next, determine the targets ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
final List<GenerationTarget> generationTargetList = new ArrayList<GenerationTarget>();
|
||||
|
||||
SchemaGenTarget target = SchemaGenTarget.interpret(
|
||||
hibernateConfiguration.getProperty( AvailableSettings.SCHEMA_GEN_TARGET )
|
||||
);
|
||||
|
||||
// the default is dependent upon whether script targets were also specified...
|
||||
final Object createScriptTargetSetting = hibernateConfiguration.getProperties().get(
|
||||
AvailableSettings.SCHEMA_GEN_CREATE_SCRIPT_TARGET
|
||||
);
|
||||
final Object dropScriptTargetSetting = hibernateConfiguration.getProperties().get(
|
||||
AvailableSettings.SCHEMA_GEN_CREATE_SCRIPT_TARGET
|
||||
);
|
||||
|
||||
if ( target == null ) {
|
||||
if ( createScriptTargetSetting != null && dropScriptTargetSetting != null ) {
|
||||
target = SchemaGenTarget.SCRIPTS;
|
||||
}
|
||||
else {
|
||||
target = SchemaGenTarget.DATABASE;
|
||||
}
|
||||
}
|
||||
|
||||
if ( target == SchemaGenTarget.DATABASE || target == SchemaGenTarget.BOTH ) {
|
||||
generationTargetList.add( new DatabaseTarget( jdbcConnectionContext ) );
|
||||
}
|
||||
if ( target == SchemaGenTarget.SCRIPTS || target == SchemaGenTarget.BOTH ) {
|
||||
// both create and drop scripts are expected per JPA spec
|
||||
if ( createScriptTargetSetting == null ) {
|
||||
throw new IllegalArgumentException( "For schema generation creation script target missing" );
|
||||
}
|
||||
if ( dropScriptTargetSetting == null ) {
|
||||
throw new IllegalArgumentException( "For schema generation drop script target missing" );
|
||||
}
|
||||
generationTargetList.add( new ScriptsTarget( createScriptTargetSetting, dropScriptTargetSetting ) );
|
||||
}
|
||||
|
||||
|
||||
// determine sources ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
final List<GenerationSource> generationSourceList = new ArrayList<GenerationSource>();
|
||||
|
||||
SchemaGenSource source = SchemaGenSource.interpret(
|
||||
hibernateConfiguration.getProperty( AvailableSettings.SCHEMA_GEN_SOURCE )
|
||||
);
|
||||
|
||||
// the default for sources is dependent upon whether script sources were specified...
|
||||
final Object createScriptSourceSetting = hibernateConfiguration.getProperties().get(
|
||||
AvailableSettings.SCHEMA_GEN_CREATE_SCRIPT_SOURCE
|
||||
);
|
||||
final Object dropScriptSourceSetting = hibernateConfiguration.getProperties().get(
|
||||
AvailableSettings.SCHEMA_GEN_DROP_SCRIPT_SOURCE
|
||||
);
|
||||
|
||||
if ( source == null ) {
|
||||
if ( createScriptSourceSetting != null && dropScriptSourceSetting != null ) {
|
||||
source = SchemaGenSource.SCRIPTS;
|
||||
}
|
||||
else {
|
||||
source = SchemaGenSource.METADATA;
|
||||
}
|
||||
}
|
||||
|
||||
final boolean createSchemas = ConfigurationHelper.getBoolean(
|
||||
AvailableSettings.SCHEMA_GEN_CREATE_SCHEMAS,
|
||||
hibernateConfiguration.getProperties(),
|
||||
false
|
||||
);
|
||||
if ( createSchemas ) {
|
||||
// todo : does it make sense to generate schema(s) defined in metadata if only script sources are to be used?
|
||||
generationSourceList.add( new CreateSchemaCommandSource( hibernateConfiguration, dialect ) );
|
||||
}
|
||||
|
||||
if ( source == SchemaGenSource.METADATA ) {
|
||||
generationSourceList.add( new MetadataSource( hibernateConfiguration, dialect ) );
|
||||
}
|
||||
else if ( source == SchemaGenSource.SCRIPTS ) {
|
||||
generationSourceList.add( new ScriptSource( createScriptSourceSetting, dropScriptSourceSetting, scriptCommandExtractor ) );
|
||||
}
|
||||
else if ( source == SchemaGenSource.METADATA_THEN_SCRIPTS ) {
|
||||
generationSourceList.add( new MetadataSource( hibernateConfiguration, dialect ) );
|
||||
generationSourceList.add( new ScriptSource( createScriptSourceSetting, dropScriptSourceSetting, scriptCommandExtractor ) );
|
||||
}
|
||||
else if ( source == SchemaGenSource.SCRIPTS_THEN_METADATA ) {
|
||||
generationSourceList.add( new ScriptSource( createScriptSourceSetting, dropScriptSourceSetting, scriptCommandExtractor ) );
|
||||
generationSourceList.add( new MetadataSource( hibernateConfiguration, dialect ) );
|
||||
}
|
||||
|
||||
final Object importScriptSetting = hibernateConfiguration.getProperties().get(
|
||||
AvailableSettings.SCHEMA_GEN_LOAD_SCRIPT_SOURCE
|
||||
);
|
||||
if ( importScriptSetting != null ) {
|
||||
generationSourceList.add( new ImportScriptSource( importScriptSetting, scriptCommandExtractor ) );
|
||||
}
|
||||
|
||||
|
||||
// do the generation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
try {
|
||||
doGeneration( action, generationSourceList, generationTargetList );
|
||||
}
|
||||
finally {
|
||||
releaseResources( generationSourceList, generationTargetList, jdbcConnectionContext );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static JdbcConnectionContext determineAppropriateJdbcConnectionContext(
|
||||
Configuration hibernateConfiguration,
|
||||
ServiceRegistry serviceRegistry) {
|
||||
// see if a specific connection has been provided:
|
||||
final Connection providedConnection = (Connection) hibernateConfiguration.getProperties().get(
|
||||
AvailableSettings.SCHEMA_GEN_CONNECTION
|
||||
);
|
||||
|
||||
if ( providedConnection != null ) {
|
||||
return new JdbcConnectionContext(
|
||||
new JdbcConnectionAccess() {
|
||||
@Override
|
||||
public Connection obtainConnection() throws SQLException {
|
||||
return providedConnection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseConnection(Connection connection) throws SQLException {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsAggressiveRelease() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
final ConnectionProvider connectionProvider = serviceRegistry.getService( ConnectionProvider.class );
|
||||
if ( connectionProvider != null ) {
|
||||
return new JdbcConnectionContext(
|
||||
new JdbcConnectionAccess() {
|
||||
@Override
|
||||
public Connection obtainConnection() throws SQLException {
|
||||
return connectionProvider.getConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseConnection(Connection connection) throws SQLException {
|
||||
connectionProvider.closeConnection( connection );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsAggressiveRelease() {
|
||||
return connectionProvider.supportsAggressiveRelease();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// otherwise, return a no-op impl
|
||||
return new JdbcConnectionContext( null ) {
|
||||
@Override
|
||||
public Connection getJdbcConnection() {
|
||||
throw new PersistenceException( "No connection information supplied" );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static Dialect determineDialect(
|
||||
JdbcConnectionContext jdbcConnectionContext,
|
||||
Configuration hibernateConfiguration,
|
||||
ServiceRegistry serviceRegistry) {
|
||||
final String explicitDbName = hibernateConfiguration.getProperty( AvailableSettings.SCHEMA_GEN_DB_NAME );
|
||||
final String explicitDbMajor = hibernateConfiguration.getProperty( AvailableSettings.SCHEMA_GEN_DB_MAJOR_VERSION );
|
||||
final String explicitDbMinor = hibernateConfiguration.getProperty( AvailableSettings.SCHEMA_GEN_DB_MINOR_VERSION );
|
||||
|
||||
if ( StringHelper.isNotEmpty( explicitDbName ) ) {
|
||||
serviceRegistry.getService( DatabaseInfoDialectResolver.class ).resolve(
|
||||
new DatabaseInfoDialectResolver.DatabaseInfo() {
|
||||
@Override
|
||||
public String getDatabaseName() {
|
||||
return explicitDbName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDatabaseMajorVersion() {
|
||||
return StringHelper.isEmpty( explicitDbMajor )
|
||||
? NO_VERSION
|
||||
: Integer.parseInt( explicitDbMajor );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDatabaseMinorVersion() {
|
||||
return StringHelper.isEmpty( explicitDbMinor )
|
||||
? NO_VERSION
|
||||
: Integer.parseInt( explicitDbMinor );
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return serviceRegistry.getService( JdbcServices.class ).getDialect();
|
||||
}
|
||||
|
||||
private static void doGeneration(
|
||||
SchemaGenAction action,
|
||||
List<GenerationSource> generationSourceList,
|
||||
List<GenerationTarget> generationTargetList) {
|
||||
|
||||
for ( GenerationSource source : generationSourceList ) {
|
||||
if ( action.includesCreate() ) {
|
||||
final Iterable<String> createCommands = source.getCreateCommands();
|
||||
for ( GenerationTarget target : generationTargetList ) {
|
||||
target.acceptCreateCommands( createCommands );
|
||||
}
|
||||
}
|
||||
|
||||
if ( action.includesDrop() ) {
|
||||
final Iterable<String> dropCommands = source.getDropCommands();
|
||||
for ( GenerationTarget target : generationTargetList ) {
|
||||
target.acceptDropCommands( dropCommands );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void releaseResources(
|
||||
List<GenerationSource> generationSourceList,
|
||||
List<GenerationTarget> generationTargetList,
|
||||
JdbcConnectionContext jdbcConnectionContext) {
|
||||
for ( GenerationTarget target : generationTargetList ) {
|
||||
try {
|
||||
target.release();
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.debug( "Problem releasing generation target : " + e.toString() );
|
||||
}
|
||||
}
|
||||
|
||||
for ( GenerationSource source : generationSourceList ) {
|
||||
try {
|
||||
source.release();
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.debug( "Problem releasing generation source : " + e.toString() );
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
jdbcConnectionContext.release();
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.debug( "Unable to release JDBC connection after generation" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class CreateSchemaCommandSource implements GenerationSource {
|
||||
private final List<String> commands;
|
||||
|
||||
private CreateSchemaCommandSource(Configuration hibernateConfiguration, Dialect dialect) {
|
||||
final HashSet<String> schemas = new HashSet<String>();
|
||||
// final HashSet<String> catalogs = new HashSet<String>();
|
||||
|
||||
final Iterator<Table> tables = hibernateConfiguration.getTableMappings();
|
||||
while ( tables.hasNext() ) {
|
||||
final Table table = tables.next();
|
||||
// catalogs.add( table.getCatalog() );
|
||||
schemas.add( table.getSchema() );
|
||||
}
|
||||
|
||||
final Iterator<IdentifierGenerator> generators = hibernateConfiguration.iterateGenerators( dialect );
|
||||
while ( generators.hasNext() ) {
|
||||
final IdentifierGenerator generator = generators.next();
|
||||
if ( PersistentIdentifierGenerator.class.isInstance( generator ) ) {
|
||||
// catalogs.add( ( (PersistentIdentifierGenerator) generator ).getCatalog() );
|
||||
schemas.add( ( (PersistentIdentifierGenerator) generator ).getCatalog() );
|
||||
}
|
||||
}
|
||||
|
||||
// if ( schemas.isEmpty() && catalogs.isEmpty() ) {
|
||||
if ( schemas.isEmpty() ) {
|
||||
commands = Collections.emptyList();
|
||||
return;
|
||||
}
|
||||
|
||||
commands = new ArrayList<String>();
|
||||
|
||||
for ( String schema : schemas ) {
|
||||
commands.add( dialect.getCreateSchemaCommand( schema ) );
|
||||
}
|
||||
|
||||
// generate "create catalog" commands
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> getCreateCommands() {
|
||||
return commands;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> getDropCommands() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
// nothing to do
|
||||
}
|
||||
}
|
||||
|
||||
private static class ImportScriptSource implements GenerationSource {
|
||||
private final SqlScriptReader sourceReader;
|
||||
private final ImportSqlCommandExtractor scriptCommandExtractor;
|
||||
|
||||
public ImportScriptSource(Object scriptSourceSetting, ImportSqlCommandExtractor scriptCommandExtractor) {
|
||||
this.scriptCommandExtractor = scriptCommandExtractor;
|
||||
|
||||
if ( Reader.class.isInstance( scriptSourceSetting ) ) {
|
||||
sourceReader = new ReaderScriptSource( (Reader) scriptSourceSetting );
|
||||
}
|
||||
else {
|
||||
sourceReader = new FileScriptSource( scriptSourceSetting.toString() );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> getCreateCommands() {
|
||||
return sourceReader.read( scriptCommandExtractor );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> getDropCommands() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
sourceReader.release();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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 java.util.Arrays;
|
||||
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class MetadataSource implements GenerationSource {
|
||||
private final Configuration hibernateConfiguration;
|
||||
private final Dialect dialect;
|
||||
|
||||
public MetadataSource(Configuration hibernateConfiguration, Dialect dialect) {
|
||||
this.hibernateConfiguration = hibernateConfiguration;
|
||||
this.dialect = dialect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> getCreateCommands() {
|
||||
return Arrays.asList( hibernateConfiguration.generateSchemaCreationScript( dialect ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> getDropCommands() {
|
||||
return Arrays.asList( hibernateConfiguration.generateDropSchemaScript( dialect ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
// nothing to do
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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 java.io.Reader;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.hibernate.tool.hbm2ddl.ImportSqlCommandExtractor;
|
||||
|
||||
/**
|
||||
* SqlScriptReader implementation for explicitly given Readers. The readers are not released by this class.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
class ReaderScriptSource implements SqlScriptReader {
|
||||
private final Reader reader;
|
||||
|
||||
public ReaderScriptSource(Reader reader) {
|
||||
this.reader = reader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> read(ImportSqlCommandExtractor commandExtractor) {
|
||||
final String[] commands = commandExtractor.extractCommands( reader );
|
||||
if ( commands == null ) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
else {
|
||||
return Arrays.asList( commands );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
protected Reader reader() {
|
||||
return reader;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* 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.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.tool.hbm2ddl.ImportSqlCommandExtractor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ScriptSource implements GenerationSource {
|
||||
private static final Logger log = Logger.getLogger( ScriptSource.class );
|
||||
|
||||
private final SqlScriptReader createSource;
|
||||
private final SqlScriptReader dropSource;
|
||||
private final ImportSqlCommandExtractor scriptCommandExtractor;
|
||||
|
||||
public ScriptSource(
|
||||
Object createScriptSourceSetting,
|
||||
Object dropScriptSourceSetting,
|
||||
ImportSqlCommandExtractor scriptCommandExtractor) {
|
||||
this.scriptCommandExtractor = scriptCommandExtractor;
|
||||
|
||||
if ( Reader.class.isInstance( createScriptSourceSetting ) ) {
|
||||
createSource = new ReaderScriptSource( (Reader) createScriptSourceSetting );
|
||||
}
|
||||
else {
|
||||
createSource = new FileScriptSource( createScriptSourceSetting.toString() );
|
||||
}
|
||||
|
||||
if ( Writer.class.isInstance( dropScriptSourceSetting ) ) {
|
||||
dropSource = new ReaderScriptSource( (Reader) dropScriptSourceSetting );
|
||||
}
|
||||
else {
|
||||
dropSource = new FileScriptSource( dropScriptSourceSetting.toString() );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> getCreateCommands() {
|
||||
return createSource.read( scriptCommandExtractor );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> getDropCommands() {
|
||||
return dropSource.read( scriptCommandExtractor );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
createSource.release();
|
||||
dropSource.release();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* GenerationTarget implementation for handling generation to scripts
|
||||
*
|
||||
* @see org.hibernate.jpa.SchemaGenTarget#SCRIPTS
|
||||
* @see org.hibernate.jpa.SchemaGenTarget#BOTH
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
class ScriptsTarget implements GenerationTarget {
|
||||
private static final Logger log = Logger.getLogger( ScriptsTarget.class );
|
||||
|
||||
private final ScriptTargetTarget createScriptTarget;
|
||||
private final ScriptTargetTarget dropScriptTarget;
|
||||
|
||||
public ScriptsTarget(Object createScriptTargetSetting, Object dropScriptTargetSetting) {
|
||||
if ( Writer.class.isInstance( createScriptTargetSetting ) ) {
|
||||
createScriptTarget = new WriterScriptTarget( (Writer) createScriptTargetSetting );
|
||||
}
|
||||
else {
|
||||
createScriptTarget = new FileScriptTarget( createScriptTargetSetting.toString() );
|
||||
}
|
||||
|
||||
if ( Writer.class.isInstance( dropScriptTargetSetting ) ) {
|
||||
dropScriptTarget = new WriterScriptTarget( (Writer) dropScriptTargetSetting );
|
||||
}
|
||||
else {
|
||||
dropScriptTarget = new FileScriptTarget( dropScriptTargetSetting.toString() );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptCreateCommands(Iterable<String> commands) {
|
||||
for ( String command : commands ) {
|
||||
createScriptTarget.accept( command );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptDropCommands(Iterable<String> commands) {
|
||||
for ( String command : commands ) {
|
||||
dropScriptTarget.accept( command );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
createScriptTarget.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 );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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 handling Reader/File differences
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface SqlScriptReader {
|
||||
public Iterable<String> read(ImportSqlCommandExtractor commandExtractor);
|
||||
public void release();
|
||||
}
|
Loading…
Reference in New Issue