Author: steve.ebersole(a)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(a)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 );
}