Permalink
Browse files

HHH-5638 HHH-5639 HHH-5640 : Import DialectFactory. DialectResolver, …

…ConnectionProvider, and JDBC batching services
  • Loading branch information...
gbadner committed Oct 11, 2010
1 parent 1f5c6f9 commit 0bfe7869e41076fd0846ca7592740710876f2427
Showing with 4,943 additions and 0 deletions.
  1. +188 −0 core/src/main/java/org/hibernate/engine/jdbc/batch/internal/AbstractBatchImpl.java
  2. +60 −0 core/src/main/java/org/hibernate/engine/jdbc/batch/internal/BatchBuilder.java
  3. +125 −0 core/src/main/java/org/hibernate/engine/jdbc/batch/internal/BatchingBatch.java
  4. +67 −0 core/src/main/java/org/hibernate/engine/jdbc/batch/internal/NonBatchingBatch.java
  5. +81 −0 core/src/main/java/org/hibernate/engine/jdbc/batch/spi/Batch.java
  6. +41 −0 core/src/main/java/org/hibernate/engine/jdbc/batch/spi/BatchObserver.java
  7. +85 −0 core/src/main/java/org/hibernate/engine/jdbc/proxy/AbstractProxyHandler.java
  8. +126 −0 core/src/main/java/org/hibernate/engine/jdbc/proxy/AbstractResultSetProxyHandler.java
  9. +168 −0 core/src/main/java/org/hibernate/engine/jdbc/proxy/AbstractStatementProxyHandler.java
  10. +56 −0 core/src/main/java/org/hibernate/engine/jdbc/proxy/BasicStatementProxyHandler.java
  11. +213 −0 core/src/main/java/org/hibernate/engine/jdbc/proxy/ConnectionProxyHandler.java
  12. +92 −0 core/src/main/java/org/hibernate/engine/jdbc/proxy/DatabaseMetaDataProxyHandler.java
  13. +81 −0 core/src/main/java/org/hibernate/engine/jdbc/proxy/ImplicitResultSetProxyHandler.java
  14. +48 −0 core/src/main/java/org/hibernate/engine/jdbc/proxy/ImplicitStatementProxyHandler.java
  15. +74 −0 core/src/main/java/org/hibernate/engine/jdbc/proxy/PreparedStatementProxyHandler.java
  16. +208 −0 core/src/main/java/org/hibernate/engine/jdbc/proxy/ProxyBuilder.java
  17. +70 −0 core/src/main/java/org/hibernate/engine/jdbc/proxy/ResultSetProxyHandler.java
  18. +242 −0 core/src/main/java/org/hibernate/service/jdbc/connections/internal/ConnectionProviderInitiator.java
  19. +139 −0 ...c/main/java/org/hibernate/service/jdbc/connections/internal/DatasourceConnectionProviderImpl.java
  20. +196 −0 ...ain/java/org/hibernate/service/jdbc/connections/internal/DriverManagerConnectionProviderImpl.java
  21. +60 −0 ...main/java/org/hibernate/service/jdbc/connections/internal/UserSuppliedConnectionProviderImpl.java
  22. +78 −0 core/src/main/java/org/hibernate/service/jdbc/connections/spi/ConnectionProvider.java
  23. +81 −0 core/src/main/java/org/hibernate/service/jdbc/dialect/internal/AbstractDialectResolver.java
  24. +123 −0 core/src/main/java/org/hibernate/service/jdbc/dialect/internal/DialectFactoryImpl.java
  25. +53 −0 core/src/main/java/org/hibernate/service/jdbc/dialect/internal/DialectFactoryInitiator.java
  26. +53 −0 core/src/main/java/org/hibernate/service/jdbc/dialect/internal/DialectResolverInitiator.java
  27. +98 −0 core/src/main/java/org/hibernate/service/jdbc/dialect/internal/DialectResolverSet.java
  28. +137 −0 core/src/main/java/org/hibernate/service/jdbc/dialect/internal/StandardDialectResolver.java
  29. +57 −0 core/src/main/java/org/hibernate/service/jdbc/dialect/spi/DialectFactory.java
  30. +53 −0 core/src/main/java/org/hibernate/service/jdbc/dialect/spi/DialectResolver.java
  31. +218 −0 core/src/main/java/org/hibernate/service/jdbc/internal/JdbcResourceRegistryImpl.java
  32. +339 −0 core/src/main/java/org/hibernate/service/jdbc/internal/JdbcServicesImpl.java
  33. +53 −0 core/src/main/java/org/hibernate/service/jdbc/internal/JdbcServicesInitiator.java
  34. +250 −0 core/src/main/java/org/hibernate/service/jdbc/internal/LogicalConnectionImpl.java
  35. +50 −0 core/src/main/java/org/hibernate/service/jdbc/spi/ConnectionObserver.java
  36. +133 −0 core/src/main/java/org/hibernate/service/jdbc/spi/ExtractedDatabaseMetaData.java
  37. +36 −0 core/src/main/java/org/hibernate/service/jdbc/spi/InvalidatableWrapper.java
  38. +81 −0 core/src/main/java/org/hibernate/service/jdbc/spi/JdbcResourceRegistry.java
  39. +77 −0 core/src/main/java/org/hibernate/service/jdbc/spi/JdbcServices.java
  40. +40 −0 core/src/main/java/org/hibernate/service/jdbc/spi/JdbcWrapper.java
  41. +70 −0 core/src/main/java/org/hibernate/service/jdbc/spi/LogicalConnection.java
  42. +85 −0 core/src/main/java/org/hibernate/service/jdbc/spi/LogicalConnectionImplementor.java
  43. +212 −0 core/src/main/java/org/hibernate/service/jdbc/spi/SQLExceptionHelper.java
  44. +104 −0 core/src/main/java/org/hibernate/service/jdbc/spi/SQLStatementLogger.java
  45. +42 −0 core/src/main/java/org/hibernate/service/jdbc/spi/SchemaNameResolver.java
@@ -0,0 +1,188 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc.batch.internal;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.engine.jdbc.batch.spi.Batch;
+import org.hibernate.engine.jdbc.batch.spi.BatchObserver;
+import org.hibernate.service.jdbc.spi.JdbcServices;
+import org.hibernate.service.jdbc.spi.LogicalConnectionImplementor;
+import org.hibernate.engine.jdbc.proxy.ProxyBuilder;
+
+/**
+ * Convenience base class for implementors of the Batch interface.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractBatchImpl implements Batch {
+ private static final Logger log = LoggerFactory.getLogger( AbstractBatchImpl.class );
+
+ private Object key;
+ private LogicalConnectionImplementor logicalConnection;
+ private Connection connectionProxy;
+ private LinkedHashMap<String,PreparedStatement> statements = new LinkedHashMap<String,PreparedStatement>();
+ private LinkedHashSet<BatchObserver> observers = new LinkedHashSet<BatchObserver>();
+
+ protected AbstractBatchImpl(Object key, LogicalConnectionImplementor logicalConnection) {
+ this.key = key;
+ this.logicalConnection = logicalConnection;
+ this.connectionProxy = ProxyBuilder.buildConnection( logicalConnection );
+ }
+
+ /**
+ * Perform batch execution.
+ * <p/>
+ * This is called from the explicit {@link #execute() execution}, but may also be called from elsewhere
+ * depending on the exact implementation.
+ */
+ protected abstract void doExecuteBatch();
+
+ /**
+ * Convenience access to the underlying JDBC services.
+ *
+ * @return The underlying JDBC services.
+ */
+ protected JdbcServices getJdbcServices() {
+ return logicalConnection.getJdbcServices();
+ }
+
+ /**
+ * Access to the batch's map of statements (keyed by SQL statement string).
+ *
+ * @return This batch's statements.
+ */
+ protected LinkedHashMap<String,PreparedStatement> getStatements() {
+ return statements;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final Object getKey() {
+ return key;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addObserver(BatchObserver observer) {
+ observers.add( observer );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final PreparedStatement getBatchStatement(String sql, boolean callable) {
+ PreparedStatement statement = statements.get( sql );
+ if ( statement == null ) {
+ statement = buildBatchStatement( sql, callable );
+ statements.put( sql, statement );
+ }
+ else {
+ log.debug( "reusing batch statement" );
+ getJdbcServices().getSqlStatementLogger().logStatement( sql );
+ }
+ return statement;
+ }
+
+ private PreparedStatement buildBatchStatement(String sql, boolean callable) {
+ try {
+ if ( callable ) {
+ return connectionProxy.prepareCall( sql );
+ }
+ else {
+ return connectionProxy.prepareStatement( sql );
+ }
+ }
+ catch ( SQLException sqle ) {
+ log.error( "sqlexception escaped proxy", sqle );
+ throw getJdbcServices().getSqlExceptionHelper().convert( sqle, "could not prepare batch statement", sql );
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void execute() {
+ notifyObserversExplicitExecution();
+ if ( statements.isEmpty() ) {
+ return;
+ }
+ try {
+ try {
+ doExecuteBatch();
+ }
+ finally {
+ releaseStatements();
+ }
+ }
+ finally {
+ statements.clear();
+ }
+ }
+
+ private void releaseStatements() {
+ for ( PreparedStatement statement : getStatements().values() ) {
+ try {
+ statement.close();
+ }
+ catch ( SQLException e ) {
+ log.error( "unable to release batch statement..." );
+ log.error( "sqlexception escaped proxy", e );
+ }
+ }
+ getStatements().clear();
+ }
+
+ private void notifyObserversExplicitExecution() {
+ for ( BatchObserver observer : observers ) {
+ observer.batchExplicitlyExecuted();
+ }
+ }
+
+ /**
+ * Convenience method to notify registered observers of an implicit execution of this batch.
+ */
+ protected void notifyObserversImplicitExecution() {
+ for ( BatchObserver observer : observers ) {
+ observer.batchImplicitlyExecuted();
+ }
+ }
+
+ public void release() {
+ if ( getStatements() != null && !getStatements().isEmpty() ) {
+ log.info( "On release of batch it still contained JDBC statements" );
+ }
+ releaseStatements();
+ observers.clear();
+ }
+}
@@ -0,0 +1,60 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc.batch.internal;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.engine.jdbc.batch.spi.Batch;
+import org.hibernate.service.jdbc.spi.LogicalConnectionImplementor;
+
+/**
+ * A builder for {@link Batch} instances.
+ *
+ * @author Steve Ebersole
+ */
+public class BatchBuilder {
+ private static final Logger log = LoggerFactory.getLogger( BatchBuilder.class );
+
+ private int size;
+
+ public BatchBuilder() {
+ }
+
+ public BatchBuilder(int size) {
+ this.size = size;
+ }
+
+ public void setSize(int size) {
+ this.size = size;
+ }
+
+ public Batch buildBatch(Object key, LogicalConnectionImplementor logicalConnection) {
+ log.trace( "building batch [size={}]", size );
+ return size > 1
+ ? new BatchingBatch( key, logicalConnection, size )
+ : new NonBatchingBatch( key, logicalConnection );
+ }
+}
+
@@ -0,0 +1,125 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.engine.jdbc.batch.internal;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+import org.hibernate.service.jdbc.spi.LogicalConnectionImplementor;
+import org.hibernate.jdbc.Expectation;
+
+/**
+ * A {@link org.hibernate.engine.jdbc.batch.spi.Batch} implementation which does batching based on a given size. Once the batch size is exceeded, the
+ * batch is implicitly executed.
+ *
+ * @author Steve Ebersole
+ */
+public class BatchingBatch extends AbstractBatchImpl {
+ private static final Logger log = LoggerFactory.getLogger( BatchingBatch.class );
+
+ private final int batchSize;
+ private Expectation[] expectations;
+ private int batchPosition;
+
+ public BatchingBatch(Object key, LogicalConnectionImplementor logicalConnection, int batchSize) {
+ super( key, logicalConnection );
+ this.batchSize = batchSize;
+ this.expectations = new Expectation[ batchSize ];
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addToBatch(Expectation expectation) {
+ if ( !expectation.canBeBatched() ) {
+ throw new HibernateException( "attempting to batch an operation which cannot be batched" );
+ }
+ for ( Map.Entry<String,PreparedStatement> entry : getStatements().entrySet() ) {
+ try {
+ entry.getValue().addBatch();
+ }
+ catch ( SQLException e ) {
+ log.error( "sqlexception escaped proxy", e );
+ throw getJdbcServices().getSqlExceptionHelper().convert( e, "could not perform addBatch", entry.getKey() );
+ }
+ }
+ expectations[ batchPosition++ ] = expectation;
+ if ( batchPosition == batchSize ) {
+ notifyObserversImplicitExecution();
+ doExecuteBatch();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void doExecuteBatch() {
+ if ( batchPosition == 0 ) {
+ log.debug( "no batched statements to execute" );
+ }
+ else {
+ if ( log.isDebugEnabled() ) {
+ log.debug( "Executing batch size: " + batchPosition );
+ }
+
+ try {
+ for ( Map.Entry<String,PreparedStatement> entry : getStatements().entrySet() ) {
+ try {
+ final PreparedStatement statement = entry.getValue();
+ checkRowCounts( statement.executeBatch(), statement );
+ }
+ catch ( SQLException e ) {
+ log.error( "sqlexception escaped proxy", e );
+ throw getJdbcServices().getSqlExceptionHelper()
+ .convert( e, "could not perform addBatch", entry.getKey() );
+ }
+ }
+ }
+ catch ( RuntimeException re ) {
+ log.error( "Exception executing batch [{}]", re.getMessage() );
+ throw re;
+ }
+ finally {
+ batchPosition = 0;
+ }
+
+ }
+ }
+
+ private void checkRowCounts(int[] rowCounts, PreparedStatement ps) throws SQLException, HibernateException {
+ int numberOfRowCounts = rowCounts.length;
+ if ( numberOfRowCounts != batchPosition ) {
+ log.warn( "JDBC driver did not return the expected number of row counts" );
+ }
+ for ( int i = 0; i < numberOfRowCounts; i++ ) {
+ expectations[i].verifyOutcome( rowCounts[i], ps, i );
+ }
+ }
+
+}
Oops, something went wrong.

0 comments on commit 0bfe786

Please sign in to comment.