[hibernate-commits] Hibernate SVN: r14029 - in core/trunk: core/src/main/java/org/hibernate and 18 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Thu Sep 27 12:37:27 EDT 2007


Author: steve.ebersole at jboss.com
Date: 2007-09-27 12:37:27 -0400 (Thu, 27 Sep 2007)
New Revision: 14029

Added:
   core/trunk/core/src/main/java/org/hibernate/jdbc/Work.java
   core/trunk/core/src/main/java/org/hibernate/jdbc/util/
   core/trunk/core/src/main/java/org/hibernate/jdbc/util/BasicFormatterImpl.java
   core/trunk/core/src/main/java/org/hibernate/jdbc/util/DDLFormatterImpl.java
   core/trunk/core/src/main/java/org/hibernate/jdbc/util/FormatStyle.java
   core/trunk/core/src/main/java/org/hibernate/jdbc/util/Formatter.java
   core/trunk/core/src/main/java/org/hibernate/jdbc/util/SQLStatementLogger.java
   core/trunk/core/src/test/
   core/trunk/core/src/test/java/
   core/trunk/core/src/test/java/org/
   core/trunk/core/src/test/java/org/hibernate/
   core/trunk/core/src/test/java/org/hibernate/jdbc/
   core/trunk/core/src/test/java/org/hibernate/jdbc/util/
   core/trunk/core/src/test/java/org/hibernate/jdbc/util/BasicFormatterTest.java
   core/trunk/testsuite/src/test/java/org/hibernate/jdbc/
   core/trunk/testsuite/src/test/java/org/hibernate/jdbc/Boat.java
   core/trunk/testsuite/src/test/java/org/hibernate/jdbc/GeneralWorkTest.java
   core/trunk/testsuite/src/test/java/org/hibernate/jdbc/Mappings.hbm.xml
   core/trunk/testsuite/src/test/java/org/hibernate/jdbc/Person.java
Removed:
   core/trunk/core/src/main/java/org/hibernate/pretty/DDLFormatter.java
   core/trunk/core/src/main/java/org/hibernate/pretty/Formatter.java
   core/trunk/testsuite/src/test/java/org/hibernate/test/pretty/
Modified:
   core/trunk/core/src/main/java/org/hibernate/Session.java
   core/trunk/core/src/main/java/org/hibernate/cfg/Settings.java
   core/trunk/core/src/main/java/org/hibernate/cfg/SettingsFactory.java
   core/trunk/core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java
   core/trunk/core/src/main/java/org/hibernate/id/PersistentIdentifierGenerator.java
   core/trunk/core/src/main/java/org/hibernate/id/TableGenerator.java
   core/trunk/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java
   core/trunk/core/src/main/java/org/hibernate/id/enhanced/TableStructure.java
   core/trunk/core/src/main/java/org/hibernate/impl/SessionImpl.java
   core/trunk/core/src/main/java/org/hibernate/jdbc/AbstractBatcher.java
   core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExport.java
   core/trunk/testsuite/src/test/java/org/hibernate/test/jpa/AbstractJPATest.java
Log:
HHH-2859 : work api

Modified: core/trunk/core/src/main/java/org/hibernate/Session.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/Session.java	2007-09-26 11:33:58 UTC (rev 14028)
+++ core/trunk/core/src/main/java/org/hibernate/Session.java	2007-09-27 16:37:27 UTC (rev 14029)
@@ -4,6 +4,7 @@
 import java.io.Serializable;
 import java.sql.Connection;
 
+import org.hibernate.jdbc.Work;
 import org.hibernate.stat.SessionStatistics;
 
 /**
@@ -158,7 +159,8 @@
 	 *
 	 * @return the JDBC connection in use by the <tt>Session</tt>
 	 * @throws HibernateException if the <tt>Session</tt> is disconnected
-	 * @deprecated To be replaced with a SPI for performing work against the connection; scheduled for removal in 4.x
+	 * @deprecated (scheduled for removal in 4.x).  Replacement depends on need; for doing direct JDBC stuff use
+	 * {@link #doWork}; for opening a 'temporary Session' use (TBD).
 	 */
 	public Connection connection() throws HibernateException;
 
@@ -739,6 +741,14 @@
 	 */
 	public void setReadOnly(Object entity, boolean readOnly);
 
+	/**
+	 * Controller for allowing users to perform JDBC related work using the Connection
+	 * managed by this Session.
+	 *
+	 * @param work The work to be performed.
+	 * @throws HibernateException Generally indicates wrapped {@link java.sql.SQLException}
+	 */
+	public void doWork(Work work) throws HibernateException;
 
 
 	/**

Modified: core/trunk/core/src/main/java/org/hibernate/cfg/Settings.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/Settings.java	2007-09-26 11:33:58 UTC (rev 14028)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/Settings.java	2007-09-27 16:37:27 UTC (rev 14029)
@@ -3,17 +3,18 @@
 
 import java.util.Map;
 
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.EntityMode;
 import org.hibernate.cache.QueryCacheFactory;
 import org.hibernate.cache.RegionFactory;
 import org.hibernate.connection.ConnectionProvider;
 import org.hibernate.dialect.Dialect;
+import org.hibernate.exception.SQLExceptionConverter;
 import org.hibernate.hql.QueryTranslatorFactory;
 import org.hibernate.jdbc.BatcherFactory;
+import org.hibernate.jdbc.util.SQLStatementLogger;
 import org.hibernate.transaction.TransactionFactory;
 import org.hibernate.transaction.TransactionManagerLookup;
-import org.hibernate.exception.SQLExceptionConverter;
-import org.hibernate.EntityMode;
-import org.hibernate.ConnectionReleaseMode;
 
 /**
  * Settings that affect the behaviour of Hibernate at runtime.
@@ -22,8 +23,9 @@
  */
 public final class Settings {
 
-	private boolean showSql;
-	private boolean formatSql;
+//	private boolean showSql;
+//	private boolean formatSql;
+	private SQLStatementLogger sqlStatementLogger;
 	private Integer maximumFetchDepth;
 	private Map querySubstitutions;
 	private Dialect dialect;
@@ -77,6 +79,18 @@
 
 	// public getters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+//	public boolean isShowSqlEnabled() {
+//		return showSql;
+//	}
+//
+//	public boolean isFormatSqlEnabled() {
+//		return formatSql;
+//	}
+
+	public SQLStatementLogger getSqlStatementLogger() {
+		return sqlStatementLogger;
+	}
+
 	public String getDefaultSchemaName() {
 		return defaultSchemaName;
 	}
@@ -101,14 +115,6 @@
 		return querySubstitutions;
 	}
 
-	public boolean isShowSqlEnabled() {
-		return showSql;
-	}
-
-	public boolean isFormatSqlEnabled() {
-		return formatSql;
-	}
-
 	public boolean isIdentifierRollbackEnabled() {
 		return identifierRollbackEnabled;
 	}
@@ -260,6 +266,18 @@
 
 	// package protected setters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+//	void setShowSqlEnabled(boolean b) {
+//		showSql = b;
+//	}
+//
+//	void setFormatSqlEnabled(boolean b) {
+//		formatSql = b;
+//	}
+
+	void setSqlStatementLogger(SQLStatementLogger sqlStatementLogger) {
+		this.sqlStatementLogger = sqlStatementLogger;
+	}
+
 	void setDefaultSchemaName(String string) {
 		defaultSchemaName = string;
 	}
@@ -284,14 +302,6 @@
 		querySubstitutions = map;
 	}
 
-	void setShowSqlEnabled(boolean b) {
-		showSql = b;
-	}
-
-	void setFormatSqlEnabled(boolean b) {
-		formatSql = b;
-	}
-
 	void setIdentifierRollbackEnabled(boolean b) {
 		identifierRollbackEnabled = b;
 	}

Modified: core/trunk/core/src/main/java/org/hibernate/cfg/SettingsFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/SettingsFactory.java	2007-09-26 11:33:58 UTC (rev 14028)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/SettingsFactory.java	2007-09-27 16:37:27 UTC (rev 14029)
@@ -12,6 +12,7 @@
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+
 import org.hibernate.ConnectionReleaseMode;
 import org.hibernate.EntityMode;
 import org.hibernate.HibernateException;
@@ -30,6 +31,7 @@
 import org.hibernate.jdbc.BatcherFactory;
 import org.hibernate.jdbc.BatchingBatcherFactory;
 import org.hibernate.jdbc.NonBatchingBatcherFactory;
+import org.hibernate.jdbc.util.SQLStatementLogger;
 import org.hibernate.transaction.TransactionFactory;
 import org.hibernate.transaction.TransactionFactoryFactory;
 import org.hibernate.transaction.TransactionManagerLookup;
@@ -278,11 +280,13 @@
 
 		boolean showSql = PropertiesHelper.getBoolean(Environment.SHOW_SQL, properties);
 		if (showSql) log.info("Echoing all SQL to stdout");
-		settings.setShowSqlEnabled(showSql);
+//		settings.setShowSqlEnabled(showSql);
 
 		boolean formatSql = PropertiesHelper.getBoolean(Environment.FORMAT_SQL, properties);
-		settings.setFormatSqlEnabled(formatSql);
-		
+//		settings.setFormatSqlEnabled(formatSql);
+
+		settings.setSqlStatementLogger( new SQLStatementLogger( showSql, formatSql ) );
+
 		boolean useStatistics = PropertiesHelper.getBoolean(Environment.GENERATE_STATISTICS, properties);
 		log.info( "Statistics: " + enabledDisabled(useStatistics) );
 		settings.setStatisticsEnabled(useStatistics);

Modified: core/trunk/core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java	2007-09-26 11:33:58 UTC (rev 14028)
+++ core/trunk/core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java	2007-09-27 16:37:27 UTC (rev 14029)
@@ -14,6 +14,7 @@
 import org.hibernate.HibernateException;
 import org.hibernate.LockMode;
 import org.hibernate.MappingException;
+import org.hibernate.jdbc.util.FormatStyle;
 import org.hibernate.dialect.Dialect;
 import org.hibernate.engine.SessionImplementor;
 import org.hibernate.engine.TransactionHelper;
@@ -129,7 +130,7 @@
 			// or read committed isolation level
 
 			//sql = query;
-			SQL.debug(query);
+			SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
 			PreparedStatement qps = conn.prepareStatement(query);
 			PreparedStatement ips = null;
 			try {

Modified: core/trunk/core/src/main/java/org/hibernate/id/PersistentIdentifierGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/PersistentIdentifierGenerator.java	2007-09-26 11:33:58 UTC (rev 14028)
+++ core/trunk/core/src/main/java/org/hibernate/id/PersistentIdentifierGenerator.java	2007-09-27 16:37:27 UTC (rev 14029)
@@ -1,10 +1,9 @@
 //$Id: PersistentIdentifierGenerator.java 6514 2005-04-26 06:37:54Z oneovthafew $
 package org.hibernate.id;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.hibernate.HibernateException;
 import org.hibernate.dialect.Dialect;
+import org.hibernate.jdbc.util.SQLStatementLogger;
 
 /**
  * An <tt>IdentifierGenerator</tt> that requires creation of database objects.
@@ -48,29 +47,32 @@
     
 	/**
 	 * The SQL required to create the underlying database objects.
-	 * @param dialect
-	 * @return String[]
-	 * @throws HibernateException
+	 *
+	 * @param dialect The dialect against which to generate the create command(s)
+	 * @return The create command(s)
+	 * @throws HibernateException problem creating the create command(s)
 	 */
 	public String[] sqlCreateStrings(Dialect dialect) throws HibernateException;
 
 	/**
 	 * The SQL required to remove the underlying database objects.
-	 * @param dialect
-	 * @return String
-	 * @throws HibernateException
+	 *
+	 * @param dialect The dialect against which to generate the drop command(s)
+	 * @return The drop command(s)
+	 * @throws HibernateException problem creating the drop command(s)
 	 */
 	public String[] sqlDropStrings(Dialect dialect) throws HibernateException;
 
 	/**
 	 * Return a key unique to the underlying database objects. Prevents us from
 	 * trying to create/remove them multiple times.
+	 * 
 	 * @return Object an identifying key for this generator
 	 */
 	public Object generatorKey();
-	
-	static final Logger SQL = LoggerFactory.getLogger( "org.hibernate.SQL" );
 
+	static final SQLStatementLogger SQL_STATEMENT_LOGGER = new SQLStatementLogger( false, false );
+
 }
 
 

Modified: core/trunk/core/src/main/java/org/hibernate/id/TableGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/TableGenerator.java	2007-09-26 11:33:58 UTC (rev 14028)
+++ core/trunk/core/src/main/java/org/hibernate/id/TableGenerator.java	2007-09-27 16:37:27 UTC (rev 14029)
@@ -13,6 +13,7 @@
 import org.slf4j.LoggerFactory;
 import org.hibernate.HibernateException;
 import org.hibernate.LockMode;
+import org.hibernate.jdbc.util.FormatStyle;
 import org.hibernate.dialect.Dialect;
 import org.hibernate.engine.SessionImplementor;
 import org.hibernate.engine.TransactionHelper;
@@ -128,7 +129,7 @@
 			// or read committed isolation level
 
 			sql = query;
-			SQL.debug(query);
+			SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
 			PreparedStatement qps = conn.prepareStatement(query);
 			try {
 				ResultSet rs = qps.executeQuery();
@@ -149,7 +150,7 @@
 			}
 
 			sql = update;
-			SQL.debug(update);
+			SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
 			PreparedStatement ups = conn.prepareStatement(update);
 			try {
 				ups.setInt( 1, result + 1 );

Modified: core/trunk/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java	2007-09-26 11:33:58 UTC (rev 14028)
+++ core/trunk/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java	2007-09-27 16:37:27 UTC (rev 14029)
@@ -21,6 +21,7 @@
 import org.hibernate.HibernateException;
 import org.hibernate.MappingException;
 import org.hibernate.LockMode;
+import org.hibernate.jdbc.util.FormatStyle;
 import org.hibernate.mapping.Table;
 import org.hibernate.util.PropertiesHelper;
 import org.hibernate.util.StringHelper;
@@ -223,7 +224,7 @@
 		int rows;
 		do {
 			sql = query;
-			SQL.debug( sql );
+			SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
 			PreparedStatement queryPS = conn.prepareStatement( query );
 			try {
 				queryPS.setString( 1, segmentValue );
@@ -233,7 +234,7 @@
 					try {
 						result = initialValue;
 						sql = insert;
-						SQL.debug( sql );
+						SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
 						insertPS = conn.prepareStatement( insert );
 						insertPS.setString( 1, segmentValue );
 						insertPS.setLong( 2, result );
@@ -259,7 +260,7 @@
 			}
 
 			sql = update;
-			SQL.debug( sql );
+			SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
 			PreparedStatement updatePS = conn.prepareStatement( update );
 			try {
 				long newValue = optimizer.applyIncrementSizeToSourceValues()

Modified: core/trunk/core/src/main/java/org/hibernate/id/enhanced/TableStructure.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/enhanced/TableStructure.java	2007-09-26 11:33:58 UTC (rev 14028)
+++ core/trunk/core/src/main/java/org/hibernate/id/enhanced/TableStructure.java	2007-09-27 16:37:27 UTC (rev 14029)
@@ -1,21 +1,23 @@
 package org.hibernate.id.enhanced;
 
-import java.sql.Types;
+import java.io.Serializable;
 import java.sql.Connection;
-import java.sql.SQLException;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
-import java.io.Serializable;
+import java.sql.SQLException;
+import java.sql.Types;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
 import org.hibernate.dialect.Dialect;
-import org.hibernate.LockMode;
-import org.hibernate.HibernateException;
 import org.hibernate.engine.SessionImplementor;
 import org.hibernate.engine.TransactionHelper;
 import org.hibernate.id.IdentifierGenerationException;
+import org.hibernate.jdbc.util.FormatStyle;
+import org.hibernate.jdbc.util.SQLStatementLogger;
 
 /**
  * Describes a table used to mimic sequence behavior
@@ -24,7 +26,7 @@
  */
 public class TableStructure extends TransactionHelper implements DatabaseStructure {
 	private static final Logger log = LoggerFactory.getLogger( TableStructure.class );
-	private static final Logger SQL_LOG = LoggerFactory.getLogger( "org.hibernate.SQL" );
+	private static final SQLStatementLogger SQL_STATEMENT_LOGGER = new SQLStatementLogger( false, false );
 
 	private final String tableName;
 	private final String valueColumnName;
@@ -98,7 +100,7 @@
 		int rows;
 		do {
 			sql = select;
-			SQL_LOG.debug( sql );
+			SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
 			PreparedStatement qps = conn.prepareStatement( select );
 			try {
 				ResultSet rs = qps.executeQuery();
@@ -119,7 +121,7 @@
 			}
 
 			sql = update;
-			SQL_LOG.debug( sql );
+			SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
 			PreparedStatement ups = conn.prepareStatement( update );
 			try {
 				int increment = applyIncrementSizeToSourceValues ? incrementSize : 1;

Modified: core/trunk/core/src/main/java/org/hibernate/impl/SessionImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/SessionImpl.java	2007-09-26 11:33:58 UTC (rev 14028)
+++ core/trunk/core/src/main/java/org/hibernate/impl/SessionImpl.java	2007-09-27 16:37:27 UTC (rev 14029)
@@ -6,6 +6,7 @@
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
 import java.sql.Connection;
+import java.sql.SQLException;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -15,9 +16,10 @@
 import java.util.Map;
 import java.util.Set;
 
+import org.dom4j.Element;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.dom4j.Element;
+
 import org.hibernate.CacheMode;
 import org.hibernate.ConnectionReleaseMode;
 import org.hibernate.Criteria;
@@ -41,7 +43,6 @@
 import org.hibernate.Transaction;
 import org.hibernate.TransientObjectException;
 import org.hibernate.UnresolvableObjectException;
-import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
 import org.hibernate.collection.PersistentCollection;
 import org.hibernate.engine.ActionQueue;
 import org.hibernate.engine.CollectionEntry;
@@ -55,6 +56,7 @@
 import org.hibernate.engine.query.FilterQueryPlan;
 import org.hibernate.engine.query.HQLQueryPlan;
 import org.hibernate.engine.query.NativeSQLQueryPlan;
+import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
 import org.hibernate.event.AutoFlushEvent;
 import org.hibernate.event.AutoFlushEventListener;
 import org.hibernate.event.DeleteEvent;
@@ -71,6 +73,7 @@
 import org.hibernate.event.InitializeCollectionEventListener;
 import org.hibernate.event.LoadEvent;
 import org.hibernate.event.LoadEventListener;
+import org.hibernate.event.LoadEventListener.LoadType;
 import org.hibernate.event.LockEvent;
 import org.hibernate.event.LockEventListener;
 import org.hibernate.event.MergeEvent;
@@ -83,9 +86,10 @@
 import org.hibernate.event.ReplicateEventListener;
 import org.hibernate.event.SaveOrUpdateEvent;
 import org.hibernate.event.SaveOrUpdateEventListener;
-import org.hibernate.event.LoadEventListener.LoadType;
+import org.hibernate.exception.JDBCExceptionHelper;
 import org.hibernate.jdbc.Batcher;
 import org.hibernate.jdbc.JDBCContext;
+import org.hibernate.jdbc.Work;
 import org.hibernate.loader.criteria.CriteriaLoader;
 import org.hibernate.loader.custom.CustomLoader;
 import org.hibernate.loader.custom.CustomQuery;
@@ -1841,6 +1845,16 @@
 		persistenceContext.setReadOnly(entity, readOnly);
 	}
 
+	public void doWork(Work work) throws HibernateException {
+		try {
+			work.execute( jdbcContext.getConnectionManager().getConnection() );
+			jdbcContext.getConnectionManager().afterStatement();
+		}
+		catch ( SQLException e ) {
+			throw JDBCExceptionHelper.convert( factory.getSettings().getSQLExceptionConverter(), e, "error executing work" );
+		}
+	}
+
 	public void afterScrollOperation() {
 		// nothing to do in a stateful session
 	}

Modified: core/trunk/core/src/main/java/org/hibernate/jdbc/AbstractBatcher.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/AbstractBatcher.java	2007-09-26 11:33:58 UTC (rev 14028)
+++ core/trunk/core/src/main/java/org/hibernate/jdbc/AbstractBatcher.java	2007-09-27 16:37:27 UTC (rev 14029)
@@ -11,6 +11,7 @@
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+
 import org.hibernate.AssertionFailure;
 import org.hibernate.HibernateException;
 import org.hibernate.Interceptor;
@@ -19,7 +20,7 @@
 import org.hibernate.dialect.Dialect;
 import org.hibernate.engine.SessionFactoryImplementor;
 import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.pretty.Formatter;
+import org.hibernate.jdbc.util.FormatStyle;
 import org.hibernate.util.JDBCExceptionReporter;
 
 /**
@@ -36,7 +37,6 @@
 	private int openResultSetCount;
 
 	protected static final Logger log = LoggerFactory.getLogger( AbstractBatcher.class );
-	protected static final Logger SQL_LOG = LoggerFactory.getLogger( "org.hibernate.SQL" );
 
 	private final ConnectionManager connectionManager;
 	private final SessionFactoryImplementor factory;
@@ -395,29 +395,14 @@
 	}
 
 	private void log(String sql) {
-		if ( SQL_LOG.isDebugEnabled() ) {
-			SQL_LOG.debug( format(sql) );
-		}
-		if ( factory.getSettings().isShowSqlEnabled() ) {
-			System.out.println( "Hibernate: " + format(sql) );
-		}
+		factory.getSettings().getSqlStatementLogger().logStatement( sql, FormatStyle.BASIC );
 	}
 
-	private String format(String sql) {
-		if ( factory.getSettings().isFormatSqlEnabled() ) {
-			return new Formatter(sql).format();
-		}
-		else {
-			return sql;
-		}
-	}
-
 	private PreparedStatement getPreparedStatement(
 			final Connection conn,
 	        final String sql,
 	        final boolean scrollable,
-	        final ScrollMode scrollMode)
-	throws SQLException {
+	        final ScrollMode scrollMode) throws SQLException {
 		return getPreparedStatement(
 				conn,
 		        sql,

Added: core/trunk/core/src/main/java/org/hibernate/jdbc/Work.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/Work.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/jdbc/Work.java	2007-09-27 16:37:27 UTC (rev 14029)
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ *
+ * 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, v. 2.1. This program is distributed in the
+ * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ * distribution; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Red Hat Author(s): Steve Ebersole
+ */
+package org.hibernate.jdbc;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Contract for performing a discrete piece of JDBC work.
+ *
+ * @author Steve Ebersole
+ */
+public interface Work {
+	/**
+	 * Execute the discrete work encapsulated by this work instance using the supplied connection.
+	 *
+	 * @param connection The connection on which to perform the work.
+	 * @throws SQLException Thrown during execution of the underlying JDBC interaction.
+	 * @throws HibernateException Generally indicates a wrapped SQLException.
+	 */
+	public void execute(Connection connection) throws SQLException;
+}

Copied: core/trunk/core/src/main/java/org/hibernate/jdbc/util/BasicFormatterImpl.java (from rev 12794, core/trunk/core/src/main/java/org/hibernate/pretty/Formatter.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/util/BasicFormatterImpl.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/jdbc/util/BasicFormatterImpl.java	2007-09-27 16:37:27 UTC (rev 14029)
@@ -0,0 +1,388 @@
+/*
+ * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ *
+ * 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, v. 2.1. This program is distributed in the
+ * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ * distribution; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Red Hat Author(s): Gavin King, Steve Ebersole
+ */
+package org.hibernate.jdbc.util;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.hibernate.util.StringHelper;
+
+/**
+ * Performs formatting of basic SQL statements (DML + query).
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public class BasicFormatterImpl implements Formatter {
+
+	private static final Set BEGIN_CLAUSES = new HashSet();
+	private static final Set END_CLAUSES = new HashSet();
+	private static final Set LOGICAL = new HashSet();
+	private static final Set QUANTIFIERS = new HashSet();
+	private static final Set DML = new HashSet();
+	private static final Set MISC = new HashSet();
+
+	static {
+		BEGIN_CLAUSES.add( "left" );
+		BEGIN_CLAUSES.add( "right" );
+		BEGIN_CLAUSES.add( "inner" );
+		BEGIN_CLAUSES.add( "outer" );
+		BEGIN_CLAUSES.add( "group" );
+		BEGIN_CLAUSES.add( "order" );
+
+		END_CLAUSES.add( "where" );
+		END_CLAUSES.add( "set" );
+		END_CLAUSES.add( "having" );
+		END_CLAUSES.add( "join" );
+		END_CLAUSES.add( "from" );
+		END_CLAUSES.add( "by" );
+		END_CLAUSES.add( "join" );
+		END_CLAUSES.add( "into" );
+		END_CLAUSES.add( "union" );
+
+		LOGICAL.add( "and" );
+		LOGICAL.add( "or" );
+		LOGICAL.add( "when" );
+		LOGICAL.add( "else" );
+		LOGICAL.add( "end" );
+
+		QUANTIFIERS.add( "in" );
+		QUANTIFIERS.add( "all" );
+		QUANTIFIERS.add( "exists" );
+		QUANTIFIERS.add( "some" );
+		QUANTIFIERS.add( "any" );
+
+		DML.add( "insert" );
+		DML.add( "update" );
+		DML.add( "delete" );
+
+		MISC.add( "select" );
+		MISC.add( "on" );
+	}
+
+	static final String indentString = "    ";
+	static final String initial = "\n    ";
+
+	public String format(String source) {
+		return new FormatProcess( source ).perform();
+	}
+
+	private static class FormatProcess {
+		boolean beginLine = true;
+		boolean afterBeginBeforeEnd = false;
+		boolean afterByOrSetOrFromOrSelect = false;
+		boolean afterValues = false;
+		boolean afterOn = false;
+		boolean afterBetween = false;
+		boolean afterInsert = false;
+		int inFunction = 0;
+		int parensSinceSelect = 0;
+		private LinkedList parenCounts = new LinkedList();
+		private LinkedList afterByOrFromOrSelects = new LinkedList();
+
+		int indent = 1;
+
+		StringBuffer result = new StringBuffer();
+		StringTokenizer tokens;
+		String lastToken;
+		String token;
+		String lcToken;
+
+		public FormatProcess(String sql) {
+			tokens = new StringTokenizer(
+					sql,
+					"()+*/-=<>'`\"[]," + StringHelper.WHITESPACE,
+					true
+			);
+		}
+
+		public String perform() {
+
+			result.append( initial );
+
+			while ( tokens.hasMoreTokens() ) {
+				token = tokens.nextToken();
+				lcToken = token.toLowerCase();
+
+				if ( "'".equals( token ) ) {
+					String t;
+					do {
+						t = tokens.nextToken();
+						token += t;
+					}
+					while ( !"'".equals( t ) && tokens.hasMoreTokens() ); // cannot handle single quotes
+				}
+				else if ( "\"".equals( token ) ) {
+					String t;
+					do {
+						t = tokens.nextToken();
+						token += t;
+					}
+					while ( !"\"".equals( t ) );
+				}
+
+				if ( afterByOrSetOrFromOrSelect && ",".equals( token ) ) {
+					commaAfterByOrFromOrSelect();
+				}
+				else if ( afterOn && ",".equals( token ) ) {
+					commaAfterOn();
+				}
+
+				else if ( "(".equals( token ) ) {
+					openParen();
+				}
+				else if ( ")".equals( token ) ) {
+					closeParen();
+				}
+
+				else if ( BEGIN_CLAUSES.contains( lcToken ) ) {
+					beginNewClause();
+				}
+
+				else if ( END_CLAUSES.contains( lcToken ) ) {
+					endNewClause();
+				}
+
+				else if ( "select".equals( lcToken ) ) {
+					select();
+				}
+
+				else if ( DML.contains( lcToken ) ) {
+					updateOrInsertOrDelete();
+				}
+
+				else if ( "values".equals( lcToken ) ) {
+					values();
+				}
+
+				else if ( "on".equals( lcToken ) ) {
+					on();
+				}
+
+				else if ( afterBetween && lcToken.equals( "and" ) ) {
+					misc();
+					afterBetween = false;
+				}
+
+				else if ( LOGICAL.contains( lcToken ) ) {
+					logical();
+				}
+
+				else if ( isWhitespace( token ) ) {
+					white();
+				}
+
+				else {
+					misc();
+				}
+
+				if ( !isWhitespace( token ) ) {
+					lastToken = lcToken;
+				}
+
+			}
+			return result.toString();
+		}
+
+		private void commaAfterOn() {
+			out();
+			indent--;
+			newline();
+			afterOn = false;
+			afterByOrSetOrFromOrSelect = true;
+		}
+
+		private void commaAfterByOrFromOrSelect() {
+			out();
+			newline();
+		}
+
+		private void logical() {
+			if ( "end".equals( lcToken ) ) {
+				indent--;
+			}
+			newline();
+			out();
+			beginLine = false;
+		}
+
+		private void on() {
+			indent++;
+			afterOn = true;
+			newline();
+			out();
+			beginLine = false;
+		}
+
+		private void misc() {
+			out();
+			if ( "between".equals( lcToken ) ) {
+				afterBetween = true;
+			}
+			if ( afterInsert ) {
+				newline();
+				afterInsert = false;
+			}
+			else {
+				beginLine = false;
+				if ( "case".equals( lcToken ) ) {
+					indent++;
+				}
+			}
+		}
+
+		private void white() {
+			if ( !beginLine ) {
+				result.append( " " );
+			}
+		}
+
+		private void updateOrInsertOrDelete() {
+			out();
+			indent++;
+			beginLine = false;
+			if ( "update".equals( lcToken ) ) {
+				newline();
+			}
+			if ( "insert".equals( lcToken ) ) {
+				afterInsert = true;
+			}
+		}
+
+		private void select() {
+			out();
+			indent++;
+			newline();
+			parenCounts.addLast( Integer.valueOf( parensSinceSelect ) );
+			afterByOrFromOrSelects.addLast( Boolean.valueOf( afterByOrSetOrFromOrSelect ) );
+			parensSinceSelect = 0;
+			afterByOrSetOrFromOrSelect = true;
+		}
+
+		private void out() {
+			result.append( token );
+		}
+
+		private void endNewClause() {
+			if ( !afterBeginBeforeEnd ) {
+				indent--;
+				if ( afterOn ) {
+					indent--;
+					afterOn = false;
+				}
+				newline();
+			}
+			out();
+			if ( !"union".equals( lcToken ) ) {
+				indent++;
+			}
+			newline();
+			afterBeginBeforeEnd = false;
+			afterByOrSetOrFromOrSelect = "by".equals( lcToken )
+					|| "set".equals( lcToken )
+					|| "from".equals( lcToken );
+		}
+
+		private void beginNewClause() {
+			if ( !afterBeginBeforeEnd ) {
+				if ( afterOn ) {
+					indent--;
+					afterOn = false;
+				}
+				indent--;
+				newline();
+			}
+			out();
+			beginLine = false;
+			afterBeginBeforeEnd = true;
+		}
+
+		private void values() {
+			indent--;
+			newline();
+			out();
+			indent++;
+			newline();
+			afterValues = true;
+		}
+
+		private void closeParen() {
+			parensSinceSelect--;
+			if ( parensSinceSelect < 0 ) {
+				indent--;
+				parensSinceSelect = ( ( Integer ) parenCounts.removeLast() ).intValue();
+				afterByOrSetOrFromOrSelect = ( ( Boolean ) afterByOrFromOrSelects.removeLast() ).booleanValue();
+			}
+			if ( inFunction > 0 ) {
+				inFunction--;
+				out();
+			}
+			else {
+				if ( !afterByOrSetOrFromOrSelect ) {
+					indent--;
+					newline();
+				}
+				out();
+			}
+			beginLine = false;
+		}
+
+		private void openParen() {
+			if ( isFunctionName( lastToken ) || inFunction > 0 ) {
+				inFunction++;
+			}
+			beginLine = false;
+			if ( inFunction > 0 ) {
+				out();
+			}
+			else {
+				out();
+				if ( !afterByOrSetOrFromOrSelect ) {
+					indent++;
+					newline();
+					beginLine = true;
+				}
+			}
+			parensSinceSelect++;
+		}
+
+		private static boolean isFunctionName(String tok) {
+			final char begin = tok.charAt( 0 );
+			final boolean isIdentifier = Character.isJavaIdentifierStart( begin ) || '"' == begin;
+			return isIdentifier &&
+					!LOGICAL.contains( tok ) &&
+					!END_CLAUSES.contains( tok ) &&
+					!QUANTIFIERS.contains( tok ) &&
+					!DML.contains( tok ) &&
+					!MISC.contains( tok );
+		}
+
+		private static boolean isWhitespace(String token) {
+			return StringHelper.WHITESPACE.indexOf( token ) >= 0;
+		}
+
+		private void newline() {
+			result.append( "\n" );
+			for ( int i = 0; i < indent; i++ ) {
+				result.append( indentString );
+			}
+			beginLine = true;
+		}
+	}
+
+}
\ No newline at end of file


Property changes on: core/trunk/core/src/main/java/org/hibernate/jdbc/util/BasicFormatterImpl.java
___________________________________________________________________
Name: svn:executable
   + *

Copied: core/trunk/core/src/main/java/org/hibernate/jdbc/util/DDLFormatterImpl.java (from rev 12794, core/trunk/core/src/main/java/org/hibernate/pretty/DDLFormatter.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/util/DDLFormatterImpl.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/jdbc/util/DDLFormatterImpl.java	2007-09-27 16:37:27 UTC (rev 14029)
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ *
+ * 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, v. 2.1. This program is distributed in the
+ * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ * distribution; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Red Hat Author(s): Gavin King, Steve Ebersole
+ */
+package org.hibernate.jdbc.util;
+
+import java.util.StringTokenizer;
+
+/**
+ * Performs formatting of DDL SQL statements.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public class DDLFormatterImpl implements Formatter {
+	/**
+	 * Format an SQL statement using simple rules<ul>
+	 * <li>Insert newline after each comma</li>
+	 * <li>Indent three spaces after each inserted newline</li>
+	 * </ul>
+	 * If the statement contains single/double quotes return unchanged,
+	 * it is too complex and could be broken by simple formatting.
+	 * 
+	 * @param sql The statement to be fornmatted.
+	 */
+	public String format(String sql) {
+		if ( sql.toLowerCase().startsWith( "create table" ) ) {
+			return formatCreateTable( sql );
+		}
+		else if ( sql.toLowerCase().startsWith( "alter table" ) ) {
+			return formatAlterTable( sql );
+		}
+		else if ( sql.toLowerCase().startsWith( "comment on" ) ) {
+			return formatCommentOn( sql );
+		}
+		else {
+			return "\n    " + sql;
+		}
+	}
+
+	private String formatCommentOn(String sql) {
+		StringBuffer result = new StringBuffer( 60 ).append( "\n    " );
+		StringTokenizer tokens = new StringTokenizer( sql, " '[]\"", true );
+
+		boolean quoted = false;
+		while ( tokens.hasMoreTokens() ) {
+			String token = tokens.nextToken();
+			result.append( token );
+			if ( isQuote( token ) ) {
+				quoted = !quoted;
+			}
+			else if ( !quoted ) {
+				if ( "is".equals( token ) ) {
+					result.append( "\n       " );
+				}
+			}
+		}
+
+		return result.toString();
+	}
+
+	private String formatAlterTable(String sql) {
+		StringBuffer result = new StringBuffer( 60 ).append( "\n    " );
+		StringTokenizer tokens = new StringTokenizer( sql, " (,)'[]\"", true );
+
+		boolean quoted = false;
+		while ( tokens.hasMoreTokens() ) {
+			String token = tokens.nextToken();
+			if ( isQuote( token ) ) {
+				quoted = !quoted;
+			}
+			else if ( !quoted ) {
+				if ( isBreak( token ) ) {
+					result.append( "\n        " );
+				}
+			}
+			result.append( token );
+		}
+
+		return result.toString();
+	}
+
+	private String formatCreateTable(String sql) {
+		StringBuffer result = new StringBuffer( 60 ).append( "\n    " );
+		StringTokenizer tokens = new StringTokenizer( sql, "(,)'[]\"", true );
+
+		int depth = 0;
+		boolean quoted = false;
+		while ( tokens.hasMoreTokens() ) {
+			String token = tokens.nextToken();
+			if ( isQuote( token ) ) {
+				quoted = !quoted;
+				result.append( token );
+			}
+			else if ( quoted ) {
+				result.append( token );
+			}
+			else {
+				if ( ")".equals( token ) ) {
+					depth--;
+					if ( depth == 0 ) {
+						result.append( "\n    " );
+					}
+				}
+				result.append( token );
+				if ( ",".equals( token ) && depth == 1 ) {
+					result.append( "\n       " );
+				}
+				if ( "(".equals( token ) ) {
+					depth++;
+					if ( depth == 1 ) {
+						result.append( "\n        " );
+					}
+				}
+			}
+		}
+
+		return result.toString();
+	}
+
+	private static boolean isBreak(String token) {
+		return "drop".equals( token ) ||
+				"add".equals( token ) ||
+				"references".equals( token ) ||
+				"foreign".equals( token ) ||
+				"on".equals( token );
+	}
+
+	private static boolean isQuote(String tok) {
+		return "\"".equals( tok ) ||
+				"`".equals( tok ) ||
+				"]".equals( tok ) ||
+				"[".equals( tok ) ||
+				"'".equals( tok );
+	}
+
+}
\ No newline at end of file


Property changes on: core/trunk/core/src/main/java/org/hibernate/jdbc/util/DDLFormatterImpl.java
___________________________________________________________________
Name: svn:executable
   + *

Added: core/trunk/core/src/main/java/org/hibernate/jdbc/util/FormatStyle.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/util/FormatStyle.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/jdbc/util/FormatStyle.java	2007-09-27 16:37:27 UTC (rev 14029)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ *
+ * 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, v. 2.1. This program is distributed in the
+ * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ * distribution; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Red Hat Author(s): Steve Ebersole
+ */
+package org.hibernate.jdbc.util;
+
+/**
+ * Represents the the understood types or styles of formatting. 
+ *
+ * @author Steve Ebersole
+ */
+public class FormatStyle {
+	public static final FormatStyle BASIC = new FormatStyle( "basic", new BasicFormatterImpl() );
+	public static final FormatStyle DDL = new FormatStyle( "ddl", new DDLFormatterImpl() );
+	public static final FormatStyle NONE = new FormatStyle( "none", new NoFormatImpl() );
+
+	private final String name;
+	private final Formatter formatter;
+
+	private FormatStyle(String name, Formatter formatter) {
+		this.name = name;
+		this.formatter = formatter;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public Formatter getFormatter() {
+		return formatter;
+	}
+
+	public boolean equals(Object o) {
+		if ( this == o ) {
+			return true;
+		}
+		if ( o == null || getClass() != o.getClass() ) {
+			return false;
+		}
+
+		FormatStyle that = ( FormatStyle ) o;
+
+		return name.equals( that.name );
+
+	}
+
+	public int hashCode() {
+		return name.hashCode();
+	}
+
+	private static class NoFormatImpl implements Formatter {
+		public String format(String source) {
+			return source;
+		}
+	}
+}

Added: core/trunk/core/src/main/java/org/hibernate/jdbc/util/Formatter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/util/Formatter.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/jdbc/util/Formatter.java	2007-09-27 16:37:27 UTC (rev 14029)
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ *
+ * 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, v. 2.1. This program is distributed in the
+ * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ * distribution; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Red Hat Author(s): Steve Ebersole
+ */
+package org.hibernate.jdbc.util;
+
+/**
+ * Formatter contract
+ *
+ * @author Steve Ebersole
+ */
+public interface Formatter {
+	public String format(String source);
+}

Added: core/trunk/core/src/main/java/org/hibernate/jdbc/util/SQLStatementLogger.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/util/SQLStatementLogger.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/jdbc/util/SQLStatementLogger.java	2007-09-27 16:37:27 UTC (rev 14029)
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ *
+ * 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, v. 2.1. This program is distributed in the
+ * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ * distribution; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Red Hat Author(s): Steve Ebersole
+ */
+package org.hibernate.jdbc.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Centralize logging handling for SQL statements.
+ *
+ * @author Steve Ebersole
+ */
+public class SQLStatementLogger {
+	// todo : for 4.0
+//	private static final Logger log = LoggerFactory.getLogger( SQLStatementLogger.class );
+	// this is the legacy logging 'category'...
+	private static final Logger log = LoggerFactory.getLogger( "org.hibernate.SQL" );
+
+	private boolean logToStdout;
+	private boolean formatSql;
+
+	/**
+	 * Constructs a new SQLStatementLogger instance.
+	 */
+	public SQLStatementLogger() {
+		this( false, false );
+	}
+
+	/**
+	 * Constructs a new SQLStatementLogger instance.
+	 *
+	 * @param logToStdout Should we log to STDOUT in addition to our internal logger.
+	 * @param formatSql Should we format SQL ('prettify') prior to logging.
+	 */
+	public SQLStatementLogger(boolean logToStdout, boolean formatSql) {
+		this.logToStdout = logToStdout;
+		this.formatSql = formatSql;
+	}
+
+	/**
+	 * Getter for property 'logToStdout'.
+	 * @see #setLogToStdout
+	 *
+	 * @return Value for property 'logToStdout'.
+	 */
+	public boolean isLogToStdout() {
+		return logToStdout;
+	}
+
+	/**
+	 * Setter for property 'logToStdout'.
+	 *
+	 * @param logToStdout Value to set for property 'logToStdout'.
+	 */
+	public void setLogToStdout(boolean logToStdout) {
+		this.logToStdout = logToStdout;
+	}
+
+	/**
+	 * Getter for property 'formatSql'.
+	 * @see #setFormatSql
+	 *
+	 * @return Value for property 'formatSql'.
+	 */
+	public boolean isFormatSql() {
+		return formatSql;
+	}
+
+	/**
+	 * Setter for property 'formatSql'.
+	 *
+	 * @param formatSql Value to set for property 'formatSql'.
+	 */
+	public void setFormatSql(boolean formatSql) {
+		this.formatSql = formatSql;
+	}
+
+	/**
+	 * Log a SQL statement string.
+	 *
+	 * @param statement The SQL statement.
+	 * @param style The requested formatting style.
+	 */
+	public void logStatement(String statement, FormatStyle style) {
+		if ( log.isDebugEnabled() || logToStdout ) {
+			style = determineActualStyle( style );
+			statement = style.getFormatter().format( statement );
+		}
+		log.debug( statement );
+		if ( logToStdout ) {
+			System.out.println( "Hibernate: " + statement );
+		}
+	}
+
+	private FormatStyle determineActualStyle(FormatStyle style) {
+		return formatSql ? style : FormatStyle.NONE;
+	}
+}

Deleted: core/trunk/core/src/main/java/org/hibernate/pretty/DDLFormatter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/pretty/DDLFormatter.java	2007-09-26 11:33:58 UTC (rev 14028)
+++ core/trunk/core/src/main/java/org/hibernate/pretty/DDLFormatter.java	2007-09-27 16:37:27 UTC (rev 14029)
@@ -1,126 +0,0 @@
-//$Id: DDLFormatter.java 7664 2005-07-27 23:29:37Z oneovthafew $
-package org.hibernate.pretty;
-
-import java.util.StringTokenizer;
-
-public class DDLFormatter {
-	
-	private String sql;
-	
-	public DDLFormatter(String sql) {
-		this.sql = sql;
-	}
-
-	/**
-	 * Format an SQL statement using simple rules:
-	 *  a) Insert newline after each comma;
-	 *  b) Indent three spaces after each inserted newline;
-	 * If the statement contains single/double quotes return unchanged,
-	 * it is too complex and could be broken by simple formatting.
-	 */
-	public String format() {
-		if ( sql.toLowerCase().startsWith("create table") ) {
-			return formatCreateTable();
-		}
-		else if ( sql.toLowerCase().startsWith("alter table") ) {
-			return formatAlterTable();
-		}
-		else if ( sql.toLowerCase().startsWith("comment on") ) {
-			return formatCommentOn();
-		}
-		else {
-			return "\n    " + sql;
-		}
-	}
-
-	private String formatCommentOn() {
-		StringBuffer result = new StringBuffer(60).append("\n    ");
-		StringTokenizer tokens = new StringTokenizer( sql, " '[]\"", true );
-	
-		boolean quoted = false;
-		while ( tokens.hasMoreTokens() ) {
-			String token = tokens.nextToken();
-			result.append(token);
-			if ( isQuote(token) ) {
-				quoted = !quoted;
-			}
-			else if (!quoted) {
-				if ( "is".equals(token) ) {
-					result.append("\n       ");
-				}
-			}
-		}
-		
-		return result.toString();
-	}
-
-	private String formatAlterTable() {
-		StringBuffer result = new StringBuffer(60).append("\n    ");
-		StringTokenizer tokens = new StringTokenizer( sql, " (,)'[]\"", true );
-	
-		boolean quoted = false;
-		while ( tokens.hasMoreTokens() ) {
-			String token = tokens.nextToken();
-			if ( isQuote(token) ) {
-				quoted = !quoted;
-			}
-			else if (!quoted) {
-				if ( isBreak(token) ) {
-					result.append("\n        ");
-				}
-			}
-			result.append(token);
-		}
-		
-		return result.toString();
-	}
-
-	private String formatCreateTable() {
-		StringBuffer result = new StringBuffer(60).append("\n    ");
-		StringTokenizer tokens = new StringTokenizer( sql, "(,)'[]\"", true );
-	
-		int depth = 0;
-		boolean quoted = false;
-		while ( tokens.hasMoreTokens() ) {
-			String token = tokens.nextToken();
-			if ( isQuote(token) ) {
-				quoted = !quoted;
-				result.append(token);
-			}
-			else if (quoted) {
-				result.append(token);
-			}
-			else {
-				if ( ")".equals(token) ) {
-					depth--;
-					if (depth==0) result.append("\n    ");
-				}
-				result.append(token);
-				if ( ",".equals(token) && depth==1 ) result.append("\n       ");
-				if ( "(".equals(token) ) {
-					depth++;
-					if (depth==1) result.append("\n        ");
-				}
-			}
-		}
-		
-		return result.toString();
-	}
-
-	private static boolean isBreak(String token) {
-		return "drop".equals(token) ||
-			"add".equals(token) || 
-			"references".equals(token) || 
-			"foreign".equals(token) ||
-			"on".equals(token);
-	}
-
-	private static boolean isQuote(String tok) {
-		return "\"".equals(tok) || 
-				"`".equals(tok) || 
-				"]".equals(tok) || 
-				"[".equals(tok) ||
-				"'".equals(tok);
-	}
-
-}

Deleted: core/trunk/core/src/main/java/org/hibernate/pretty/Formatter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/pretty/Formatter.java	2007-09-26 11:33:58 UTC (rev 14028)
+++ core/trunk/core/src/main/java/org/hibernate/pretty/Formatter.java	2007-09-27 16:37:27 UTC (rev 14029)
@@ -1,370 +0,0 @@
-//$Id: Formatter.java 9961 2006-05-30 13:17:45Z max.andersen at jboss.com $
-package org.hibernate.pretty;
-
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.Set;
-import java.util.StringTokenizer;
-
-import org.hibernate.util.StringHelper;
-
-public class Formatter {
-	
-	private static final Set BEGIN_CLAUSES = new HashSet();
-	private static final Set END_CLAUSES = new HashSet();
-	private static final Set LOGICAL = new HashSet();
-	private static final Set QUANTIFIERS = new HashSet();
-	private static final Set DML = new HashSet();
-	private static final Set MISC = new HashSet();
-	static {
-		
-		BEGIN_CLAUSES.add("left");
-		BEGIN_CLAUSES.add("right");
-		BEGIN_CLAUSES.add("inner");
-		BEGIN_CLAUSES.add("outer");
-		BEGIN_CLAUSES.add("group");
-		BEGIN_CLAUSES.add("order");
-
-		END_CLAUSES.add("where");
-		END_CLAUSES.add("set");
-		END_CLAUSES.add("having");
-		END_CLAUSES.add("join");
-		END_CLAUSES.add("from");
-		END_CLAUSES.add("by");
-		END_CLAUSES.add("join");
-		END_CLAUSES.add("into");
-		END_CLAUSES.add("union");
-		
-		LOGICAL.add("and");
-		LOGICAL.add("or");
-		LOGICAL.add("when");
-		LOGICAL.add("else");
-		LOGICAL.add("end");
-		
-		QUANTIFIERS.add("in");
-		QUANTIFIERS.add("all");
-		QUANTIFIERS.add("exists");
-		QUANTIFIERS.add("some");
-		QUANTIFIERS.add("any");
-		
-		DML.add("insert");
-		DML.add("update");
-		DML.add("delete");
-		
-		MISC.add("select");
-		MISC.add("on");
-		//MISC.add("values");
-
-	}
-	
-	String indentString = "    ";
-	String initial = "\n    ";
-
-	boolean beginLine = true;
-	boolean afterBeginBeforeEnd = false;
-	boolean afterByOrSetOrFromOrSelect = false;
-	boolean afterValues = false;
-	boolean afterOn = false;
-	boolean afterBetween = false;
-	boolean afterInsert = false;
-	int inFunction = 0;
-	int parensSinceSelect = 0;
-	private LinkedList parenCounts = new LinkedList();
-	private LinkedList afterByOrFromOrSelects = new LinkedList();
-
-	int indent = 1;
-
-	StringBuffer result = new StringBuffer();
-	StringTokenizer tokens;
-	String lastToken;
-	String token;
-	String lcToken;
-	
-	public Formatter(String sql) {
-		tokens = new StringTokenizer(
-				sql, 
-				"()+*/-=<>'`\"[]," + StringHelper.WHITESPACE, 
-				true
-			);
-	}
-
-	public Formatter setInitialString(String initial) {
-		this.initial = initial;
-		return this;
-	}
-	
-	public Formatter setIndentString(String indent) {
-		this.indentString = indent;
-		return this;
-	}
-	
-	public String format() {
-		
-		result.append(initial);
-		
-		while ( tokens.hasMoreTokens() ) {
-			token = tokens.nextToken();
-			lcToken = token.toLowerCase();
-			
-			if ( "'".equals(token) ) {
-				String t;
-				do {
-					t = tokens.nextToken();
-					token += t;
-				} 
-				while ( !"'".equals(t) && tokens.hasMoreTokens() ); // cannot handle single quotes
-			}		
-			else if ( "\"".equals(token) ) {
-				String t;
-				do {
-					t = tokens.nextToken();
-					token += t;
-				} 
-				while ( !"\"".equals(t) );
-			}
-			
-			if ( afterByOrSetOrFromOrSelect && ",".equals(token) ) {
-				commaAfterByOrFromOrSelect();
-			}
-			else if ( afterOn && ",".equals(token) ) {
-				commaAfterOn();
-			}
-			
-			else if ( "(".equals(token) ) {
-				openParen();
-			}
-			else if ( ")".equals(token) ) {
-				closeParen();
-			}
-
-			else if ( BEGIN_CLAUSES.contains(lcToken) ) {
-				beginNewClause();
-			}
-
-			else if ( END_CLAUSES.contains(lcToken) ) {
-				endNewClause(); 
-			}
-			
-			else if ( "select".equals(lcToken) ) {
-				select();
-			}
-			
-			else if ( DML.contains(lcToken) ) {
-				updateOrInsertOrDelete();
-			}
-			
-			else if ( "values".equals(lcToken) ) {
-				values();
-			}
-			
-			else if ( "on".equals(lcToken) ) {
-				on();
-			}
-			
-			else if ( afterBetween && lcToken.equals("and") ) {
-				misc();
-				afterBetween = false;
-			}
-			
-			else if ( LOGICAL.contains(lcToken) ) {
-				logical();
-			}
-			
-			else if ( isWhitespace(token) ) {
-				white();
-			}
-			
-			else {
-				misc();
-			}
-			
-			if ( !isWhitespace( token ) ) lastToken = lcToken;
-			
-		}
-		return result.toString();
-	}
-
-	private void commaAfterOn() {
-		out();
-		indent--;
-		newline();
-		afterOn = false;
-		afterByOrSetOrFromOrSelect = true;
-	}
-
-	private void commaAfterByOrFromOrSelect() {
-		out();
-		newline();
-	}
-
-	private void logical() {
-		if ( "end".equals(lcToken) ) indent--;
-		newline();
-		out();
-		beginLine = false;
-	}
-
-	private void on() {
-		indent++;
-		afterOn = true;
-		newline();
-		out();
-		beginLine = false;
-	}
-
-	private void misc() {
-		out();
-		if ( "between".equals(lcToken) ) {
-			afterBetween = true;
-		}
-		if (afterInsert) {
-			newline();
-			afterInsert = false;
-		}
-		else {
-			beginLine = false;
-			if ( "case".equals(lcToken) ) {
-				indent++;
-			}
-		}
-	}
-
-	private void white() {
-		if ( !beginLine ) {
-			result.append(" ");
-		}
-	}
-	
-	private void updateOrInsertOrDelete() {
-		out();
-		indent++;
-		beginLine = false;
-		if ( "update".equals(lcToken) ) newline();
-		if ( "insert".equals(lcToken) ) afterInsert = true;
-	}
-
-	private void select() {
-		out();
-		indent++;
-		newline();
-		parenCounts.addLast( new Integer(parensSinceSelect) );
-		afterByOrFromOrSelects.addLast( new Boolean(afterByOrSetOrFromOrSelect) );
-		parensSinceSelect = 0;
-		afterByOrSetOrFromOrSelect = true;
-	}
-
-	private void out() {
-		result.append(token);
-	}
-
-	private void endNewClause() {
-		if (!afterBeginBeforeEnd) {
-			indent--;
-			if (afterOn) {
-				indent--;
-				afterOn=false;
-			}
-			newline();
-		}
-		out();
-		if ( !"union".equals(lcToken) ) indent++;
-		newline();
-		afterBeginBeforeEnd = false;
-		afterByOrSetOrFromOrSelect = "by".equals(lcToken) 
-				|| "set".equals(lcToken)
-				|| "from".equals(lcToken);
-	}
-
-	private void beginNewClause() {
-		if (!afterBeginBeforeEnd) {
-			if (afterOn) {
-				indent--;
-				afterOn=false;
-			}
-			indent--;
-			newline();
-		}
-		out();
-		beginLine = false;
-		afterBeginBeforeEnd = true;
-	}
-
-	private void values() {
-		indent--;
-		newline();
-		out();
-		indent++;
-		newline();
-		afterValues = true;
-	}
-
-	private void closeParen() {
-		parensSinceSelect--;
-		if (parensSinceSelect<0) {
-			indent--;
-			parensSinceSelect = ( (Integer) parenCounts.removeLast() ).intValue();
-			afterByOrSetOrFromOrSelect = ( (Boolean) afterByOrFromOrSelects.removeLast() ).booleanValue();
-		}
-		if ( inFunction>0 ) {
-			inFunction--;
-			out();
-		}
-		else {
-			if (!afterByOrSetOrFromOrSelect) {
-				indent--;
-				newline();
-			}
-			out();
-		}
-		beginLine = false;
-	}
-
-	private void openParen() {
-		if ( isFunctionName( lastToken ) || inFunction>0 ) {
-			inFunction++;
-		}
-		beginLine = false;
-		if ( inFunction>0 ) {
-			out();
-		}
-		else {
-			out();
-			if (!afterByOrSetOrFromOrSelect) {
-				indent++;
-				newline();
-				beginLine = true;
-			}
-		}
-		parensSinceSelect++;
-	}
-
-	private static boolean isFunctionName(String tok) {
-		final char begin = tok.charAt(0);
-		final boolean isIdentifier = Character.isJavaIdentifierStart( begin ) || '"'==begin;
-		return isIdentifier && 
-				!LOGICAL.contains(tok) && 
-				!END_CLAUSES.contains(tok) &&
-				!QUANTIFIERS.contains(tok) &&
-				!DML.contains(tok) &&
-				!MISC.contains(tok);
-	}
-
-	private static boolean isWhitespace(String token) {
-		return StringHelper.WHITESPACE.indexOf(token)>=0;
-	}
-	
-	private void newline() {
-		result.append("\n");
-		for ( int i=0; i<indent; i++ ) {
-			result.append(indentString);
-		}
-		beginLine = true;
-	}
-
-	public static void main(String[] args) {
-		if ( args.length>0 ) System.out.println( 
-			new Formatter( StringHelper.join(" ", args) ).format()
-		);
-	}
-
-}

Modified: core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExport.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExport.java	2007-09-26 11:33:58 UTC (rev 14028)
+++ core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExport.java	2007-09-27 16:37:27 UTC (rev 14029)
@@ -12,14 +12,15 @@
 import java.io.Writer;
 import java.sql.Connection;
 import java.sql.SQLException;
+import java.sql.SQLWarning;
 import java.sql.Statement;
-import java.sql.SQLWarning;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Properties;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+
 import org.hibernate.HibernateException;
 import org.hibernate.JDBCException;
 import org.hibernate.cfg.Configuration;
@@ -27,17 +28,19 @@
 import org.hibernate.cfg.NamingStrategy;
 import org.hibernate.cfg.Settings;
 import org.hibernate.dialect.Dialect;
-import org.hibernate.pretty.DDLFormatter;
+import org.hibernate.jdbc.util.FormatStyle;
+import org.hibernate.jdbc.util.Formatter;
+import org.hibernate.jdbc.util.SQLStatementLogger;
 import org.hibernate.util.ConfigHelper;
+import org.hibernate.util.JDBCExceptionReporter;
 import org.hibernate.util.PropertiesHelper;
 import org.hibernate.util.ReflectHelper;
-import org.hibernate.util.JDBCExceptionReporter;
 
 /**
- * Commandline tool to export table schema to the database. This
- * class may also be called from inside an application.
+ * Commandline tool to export table schema to the database. This class may also be called from inside an application.
  *
- * @author Daniel Bradby, Gavin King
+ * @author Daniel Bradby
+ * @author Gavin King
  */
 public class SchemaExport {
 
@@ -52,37 +55,46 @@
 	private String delimiter;
 	private final List exceptions = new ArrayList();
 	private boolean haltOnError = false;
-	private boolean format = true;
+	private Formatter formatter;
+	private SQLStatementLogger sqlStatementLogger;
 
 	/**
 	 * Create a schema exporter for the given Configuration
+	 *
+	 * @param cfg The configuration from which to build a schema export.
+	 * @throws HibernateException Indicates problem preparing for schema export.
 	 */
 	public SchemaExport(Configuration cfg) throws HibernateException {
 		this( cfg, cfg.getProperties() );
 	}
 
 	/**
-	 * Create a schema exporter for the given Configuration
-	 * and given settings
+	 * Create a schema exporter for the given Configuration and given settings
+	 *
+	 * @param cfg The configuration from which to build a schema export.
+	 * @param settings The 'parsed' settings.
+	 * @throws HibernateException Indicates problem preparing for schema export.
 	 */
 	public SchemaExport(Configuration cfg, Settings settings) throws HibernateException {
 		dialect = settings.getDialect();
-		connectionHelper = new SuppliedConnectionProviderConnectionHelper(
-				settings.getConnectionProvider()
-		);
+		connectionHelper = new SuppliedConnectionProviderConnectionHelper( settings.getConnectionProvider() );
 		dropSQL = cfg.generateDropSchemaScript( dialect );
 		createSQL = cfg.generateSchemaCreationScript( dialect );
-		format = settings.isFormatSqlEnabled();
+		sqlStatementLogger = settings.getSqlStatementLogger();
+		formatter = ( sqlStatementLogger.isFormatSql() ? FormatStyle.DDL : FormatStyle.NONE ).getFormatter();
 	}
 
 	/**
 	 * Create a schema exporter for the given Configuration, with the given
 	 * database connection properties.
 	 *
+	 * @param cfg The configuration from which to build a schema export.
+	 * @param properties The properties from which to configure connectivity etc.
+	 * @throws HibernateException Indicates problem preparing for schema export.
+	 *
 	 * @deprecated properties may be specified via the Configuration object
 	 */
-	public SchemaExport(Configuration cfg, Properties properties)
-			throws HibernateException {
+	public SchemaExport(Configuration cfg, Properties properties) throws HibernateException {
 		dialect = Dialect.getDialect( properties );
 
 		Properties props = new Properties();
@@ -92,24 +104,42 @@
 		connectionHelper = new ManagedProviderConnectionHelper( props );
 		dropSQL = cfg.generateDropSchemaScript( dialect );
 		createSQL = cfg.generateSchemaCreationScript( dialect );
-		format = PropertiesHelper.getBoolean( Environment.FORMAT_SQL, props );
+
+		formatter = ( PropertiesHelper.getBoolean( Environment.FORMAT_SQL, props ) ? FormatStyle.DDL : FormatStyle.NONE ).getFormatter();
 	}
 
-	public SchemaExport(Configuration cfg, Connection connection) {
+	/**
+	 * Create a schema exporter for the given Configuration, using the supplied connection for connectivity.
+	 *
+	 * @param cfg The configuration to use.
+	 * @param connection The JDBC connection to use.
+	 * @throws HibernateException Indicates problem preparing for schema export.
+	 */
+	public SchemaExport(Configuration cfg, Connection connection) throws HibernateException {
 		this.connectionHelper = new SuppliedConnectionHelper( connection );
 		dialect = Dialect.getDialect( cfg.getProperties() );
 		dropSQL = cfg.generateDropSchemaScript( dialect );
 		createSQL = cfg.generateSchemaCreationScript( dialect );
+		formatter = ( PropertiesHelper.getBoolean( Environment.FORMAT_SQL, cfg.getProperties() ) ? FormatStyle.DDL : FormatStyle.NONE ).getFormatter();
 	}
 
 	/**
-	 * Set an output filename. The generated script will be written to this file.
+	 * For generating a export script file, this is the file which will be written.
+	 *
+	 * @param filename The name of the file to which to write the export script.
+	 * @return this
 	 */
 	public SchemaExport setOutputFile(String filename) {
 		outputFile = filename;
 		return this;
 	}
 
+	/**
+	 * An import file, containing raw SQL statements to be executed.
+	 *
+	 * @param filename The import file name.
+	 * @return this
+	 */
 	public SchemaExport setImportFile(String filename) {
 		importFile = filename;
 		return this;
@@ -117,6 +147,9 @@
 
 	/**
 	 * Set the end of statement delimiter
+	 *
+	 * @param delimiter The delimiter
+	 * @return this
 	 */
 	public SchemaExport setDelimiter(String delimiter) {
 		this.delimiter = delimiter;
@@ -124,6 +157,28 @@
 	}
 
 	/**
+	 * Should we format the sql strings?
+	 *
+	 * @param format Should we format SQL strings
+	 * @return this
+	 */
+	public SchemaExport setFormat(boolean format) {
+		this.formatter = ( format ? FormatStyle.DDL : FormatStyle.NONE ).getFormatter();
+		return this;
+	}
+
+	/**
+	 * Should we stop once an error occurs?
+	 *
+	 * @param haltOnError True if export should stop after error.
+	 * @return this
+	 */
+	public SchemaExport setHaltOnError(boolean haltOnError) {
+		this.haltOnError = haltOnError;
+		return this;
+	}
+
+	/**
 	 * Run the schema creation script.
 	 *
 	 * @param script print the DDL to the console
@@ -143,12 +198,6 @@
 		execute( script, export, true, false );
 	}
 
-	private String format(String sql) {
-		return format ?
-		       new DDLFormatter( sql ).format() :
-		       sql;
-	}
-
 	public void execute(boolean script, boolean export, boolean justDrop, boolean justCreate) {
 
 		log.info( "Running hbm2ddl schema export" );
@@ -295,7 +344,7 @@
 
 	private void execute(boolean script, boolean export, Writer fileOutput, Statement statement, final String sql)
 			throws IOException, SQLException {
-		String formatted = format( sql );
+		String formatted = formatter.format( sql );
 		if ( delimiter != null ) {
 			formatted += delimiter;
 		}
@@ -307,6 +356,7 @@
 			fileOutput.write( formatted + "\n" );
 		}
 		if ( export ) {
+
 			statement.executeUpdate( sql );
 			try {
 				SQLWarning warnings = statement.getWarnings();
@@ -423,14 +473,4 @@
 	public List getExceptions() {
 		return exceptions;
 	}
-
-	public SchemaExport setFormat(boolean format) {
-		this.format = format;
-		return this;
-	}
-
-	public SchemaExport setHaltOnError(boolean haltOnError) {
-		this.haltOnError = haltOnError;
-		return this;
-	}
 }

Added: core/trunk/core/src/test/java/org/hibernate/jdbc/util/BasicFormatterTest.java
===================================================================
--- core/trunk/core/src/test/java/org/hibernate/jdbc/util/BasicFormatterTest.java	                        (rev 0)
+++ core/trunk/core/src/test/java/org/hibernate/jdbc/util/BasicFormatterTest.java	2007-09-27 16:37:27 UTC (rev 14029)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ *
+ * 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, v. 2.1. This program is distributed in the
+ * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ * distribution; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Red Hat Author(s): Steve Ebersole
+ */
+package org.hibernate.jdbc.util;
+
+import java.util.StringTokenizer;
+
+import junit.framework.TestCase;
+
+/**
+ * BasicFormatterTest implementation
+ *
+ * @author Steve Ebersole
+ */
+public class BasicFormatterTest extends TestCase {
+	public BasicFormatterTest(String name) {
+		super( name );
+	}
+
+	public void testNoLoss() {
+		assertNoLoss( "insert into Address (city, state, zip, \"from\") values (?, ?, ?, 'insert value')" );
+		assertNoLoss( "delete from Address where id = ? and version = ?" );
+		assertNoLoss( "update Address set city = ?, state=?, zip=?, version = ? where id = ? and version = ?" );
+		assertNoLoss( "update Address set city = ?, state=?, zip=?, version = ? where id in (select aid from Person)" );
+		assertNoLoss(
+				"select p.name, a.zipCode, count(*) from Person p left outer join Employee e on e.id = p.id and p.type = 'E' and (e.effective>? or e.effective<?) join Address a on a.pid = p.id where upper(p.name) like 'G%' and p.age > 100 and (p.sex = 'M' or p.sex = 'F') and coalesce( trim(a.street), a.city, (a.zip) ) is not null order by p.name asc, a.zipCode asc"
+		);
+		assertNoLoss(
+				"select ( (m.age - p.age) * 12 ), trim(upper(p.name)) from Person p, Person m where p.mother = m.id and ( p.age = (select max(p0.age) from Person p0 where (p0.mother=m.id)) and p.name like ? )"
+		);
+		assertNoLoss(
+				"select * from Address a join Person p on a.pid = p.id, Person m join Address b on b.pid = m.id where p.mother = m.id and p.name like ?"
+		);
+		assertNoLoss(
+				"select case when p.age > 50 then 'old' when p.age > 18 then 'adult' else 'child' end from Person p where ( case when p.age > 50 then 'old' when p.age > 18 then 'adult' else 'child' end ) like ?"
+		);
+		assertNoLoss(
+				"/* Here we' go! */ select case when p.age > 50 then 'old' when p.age > 18 then 'adult' else 'child' end from Person p where ( case when p.age > 50 then 'old' when p.age > 18 then 'adult' else 'child' end ) like ?"
+		);
+	}
+
+	private void assertNoLoss(String query) {
+		String formattedQuery = FormatStyle.BASIC.getFormatter().format( query );
+		StringTokenizer formatted = new StringTokenizer( formattedQuery, " \t\n\r\f()" );
+		StringTokenizer plain = new StringTokenizer( query, " \t\n\r\f()" );
+
+		System.out.println( "Original: " + query );
+		System.out.println( "Formatted: " + formattedQuery );
+		while ( formatted.hasMoreTokens() && plain.hasMoreTokens() ) {
+			String plainToken = plain.nextToken();
+			String formattedToken = formatted.nextToken();
+			assertEquals( "formatter did not return the same token", plainToken, formattedToken );
+		}
+		assertFalse( formatted.hasMoreTokens() );
+		assertFalse( plain.hasMoreTokens() );
+	}
+}

Added: core/trunk/testsuite/src/test/java/org/hibernate/jdbc/Boat.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/jdbc/Boat.java	                        (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/jdbc/Boat.java	2007-09-27 16:37:27 UTC (rev 14029)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ *
+ * 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, v. 2.1. This program is distributed in the
+ * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ * distribution; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Red Hat Author(s): Steve Ebersole
+ */
+package org.hibernate.jdbc;
+
+/**
+ * Boat implementation
+ *
+ * @author Steve Ebersole
+ */
+public class Boat {
+	private Long id;
+	private String tag;
+	private Person driver;
+	private Person boarder;
+
+	public Boat() {
+	}
+
+	public Boat(String tag, Person driver, Person boarder) {
+		this.tag = tag;
+		this.driver = driver;
+		this.boarder = boarder;
+	}
+
+	public Long getId() {
+		return id;
+	}
+
+	public void setId(Long id) {
+		this.id = id;
+	}
+
+	public String getTag() {
+		return tag;
+	}
+
+	public void setTag(String tag) {
+		this.tag = tag;
+	}
+
+	public Person getDriver() {
+		return driver;
+	}
+
+	public void setDriver(Person driver) {
+		this.driver = driver;
+	}
+
+	public Person getBoarder() {
+		return boarder;
+	}
+
+	public void setBoarder(Person boarder) {
+		this.boarder = boarder;
+	}
+}

Added: core/trunk/testsuite/src/test/java/org/hibernate/jdbc/GeneralWorkTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/jdbc/GeneralWorkTest.java	                        (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/jdbc/GeneralWorkTest.java	2007-09-27 16:37:27 UTC (rev 14029)
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ *
+ * 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, v. 2.1. This program is distributed in the
+ * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ * distribution; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Red Hat Author(s): Steve Ebersole
+ */
+package org.hibernate.jdbc;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import junit.framework.Test;
+
+import org.hibernate.JDBCException;
+import org.hibernate.Session;
+import org.hibernate.junit.functional.FunctionalTestCase;
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+
+/**
+ * GeneralWorkTest implementation
+ *
+ * @author Steve Ebersole
+ */
+public class GeneralWorkTest extends FunctionalTestCase {
+	public GeneralWorkTest(String string) {
+		super( string );
+	}
+
+	public String getBaseForMappings() {
+		return "org/hibernate/";
+	}
+
+	public String[] getMappings() {
+		return new String[] { "jdbc/Mappings.hbm.xml" };
+	}
+
+	public static Test suite() {
+		return new FunctionalTestClassTestSuite( GeneralWorkTest.class );
+	}
+
+	public void testGeneralUsage() throws Throwable {
+		Session session = openSession();
+		session.beginTransaction();
+		session.doWork(
+				new Work() {
+					public void execute(Connection connection) throws SQLException {
+						// in this current form, users must handle try/catches themselves for proper resource release
+						Statement statement = null;
+						try {
+							statement = connection.createStatement();
+							ResultSet resultSet = null;
+							try {
+								resultSet = statement.executeQuery( "select * from T_JDBC_PERSON" );
+							}
+							finally {
+								releaseQuietly( resultSet );
+							}
+							try {
+								resultSet = statement.executeQuery( "select * from T_JDBC_BOAT" );
+							}
+							finally {
+								releaseQuietly( resultSet );
+							}
+						}
+						finally {
+							releaseQuietly( statement );
+						}
+					}
+				}
+		);
+		session.getTransaction().commit();
+		session.close();
+	}
+
+	public void testSQLExceptionThrowing() {
+		Session session = openSession();
+		session.beginTransaction();
+		try {
+			session.doWork(
+					new Work() {
+						public void execute(Connection connection) throws SQLException {
+							Statement statement = null;
+							try {
+								statement = connection.createStatement();
+								statement.executeQuery( "select * from non_existent" );
+							}
+							finally {
+								releaseQuietly( statement );
+							}
+						}
+					}
+			);
+			fail( "expecting exception" );
+		}
+		catch ( JDBCException expected ) {
+			// expected outcome
+		}
+		session.getTransaction().commit();
+		session.close();
+	}
+
+	private void releaseQuietly(Statement statement) {
+		if ( statement == null ) {
+			return;
+		}
+		try {
+			statement.close();
+		}
+		catch ( SQLException e ) {
+			// ignore
+		}
+	}
+
+	private void releaseQuietly(ResultSet resultSet) {
+		if ( resultSet == null ) {
+			return;
+		}
+		try {
+			resultSet.close();
+		}
+		catch ( SQLException e ) {
+			// ignore
+		}
+	}
+}

Added: core/trunk/testsuite/src/test/java/org/hibernate/jdbc/Mappings.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/jdbc/Mappings.hbm.xml	                        (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/jdbc/Mappings.hbm.xml	2007-09-27 16:37:27 UTC (rev 14029)
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+      "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+          "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+  ~ Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+  ~
+  ~ 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, v. 2.1. This program is distributed in the
+  ~ hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+  ~ distribution; if not, write to the Free Software Foundation, Inc.,
+  ~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+  ~
+  ~ Red Hat Author(s): Steve Ebersole
+  -->
+
+<hibernate-mapping package="org.hibernate.jdbc">
+
+    <class name="Person" table="T_JDBC_PERSON">
+        <id name="id" column="ID">
+            <generator class="increment" />
+        </id>
+        <property name="firstName" />
+        <property name="lastName" />
+    </class>
+
+    <class name="Boat" table="T_JDBC_BOAT">
+        <id name="id" column="ID">
+            <generator class="increment" />
+        </id>
+        <property name="tag" />
+        <many-to-one name="driver"/>
+        <many-to-one name="boarder"/>
+    </class>
+
+</hibernate-mapping>
\ No newline at end of file

Added: core/trunk/testsuite/src/test/java/org/hibernate/jdbc/Person.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/jdbc/Person.java	                        (rev 0)
+++ core/trunk/testsuite/src/test/java/org/hibernate/jdbc/Person.java	2007-09-27 16:37:27 UTC (rev 14029)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ *
+ * 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, v. 2.1. This program is distributed in the
+ * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ * distribution; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Red Hat Author(s): Steve Ebersole
+ */
+package org.hibernate.jdbc;
+
+/**
+ * Person implementation
+ *
+ * @author Steve Ebersole
+ */
+public class Person {
+	private Long id;
+	private String firstName;
+	private String lastName;
+
+	public Person() {
+	}
+
+	public Person(String firstName, String lastName) {
+		this.firstName = firstName;
+		this.lastName = lastName;
+	}
+
+	public Long getId() {
+		return id;
+	}
+
+	public void setId(Long id) {
+		this.id = id;
+	}
+
+	public String getFirstName() {
+		return firstName;
+	}
+
+	public void setFirstName(String firstName) {
+		this.firstName = firstName;
+	}
+
+	public String getLastName() {
+		return lastName;
+	}
+
+	public void setLastName(String lastName) {
+		this.lastName = lastName;
+	}
+}

Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/jpa/AbstractJPATest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/jpa/AbstractJPATest.java	2007-09-26 11:33:58 UTC (rev 14028)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/jpa/AbstractJPATest.java	2007-09-27 16:37:27 UTC (rev 14029)
@@ -22,7 +22,7 @@
  *
  * @author Steve Ebersole
  */
-public class AbstractJPATest extends FunctionalTestCase {
+public abstract class AbstractJPATest extends FunctionalTestCase {
 	public AbstractJPATest(String name) {
 		super( name );
 	}




More information about the hibernate-commits mailing list