org.apache.jackrabbit.core.util.db
Class ConnectionHelper

java.lang.Object
  extended by org.apache.jackrabbit.core.util.db.ConnectionHelper
Direct Known Subclasses:
DerbyConnectionHelper, OracleConnectionHelper

public class ConnectionHelper
extends Object

This class provides convenience methods to execute SQL statements. They can be either executed in isolation or within the context of a JDBC transaction; the so-called batch mode (use the startBatch() and endBatch(boolean) methods for this).

This class contains logic to retry execution of SQL statements. If this helper is not in batch mode and if a statement fails due to an SQLException, then it is retried. If the block argument of the constructor call was false then it is retried only once. Otherwise the statement is retried until either it succeeds or the thread is interrupted. This clearly assumes that the only cause of SQLExceptions is faulty Connections which are restored eventually.
Note: This retry logic only applies to the following methods:

This class is not thread-safe and if it is to be used by multiple threads then the clients must make sure that access to this class is properly synchronized.

Implementation note: The Connection that is retrieved from the DataSource in getConnection() may be broken. This is so because if an internal DataSource is used, then this is a commons-dbcp DataSource with a testWhileIdle validation strategy (see the ConnectionFactory class). Furthermore, if it is a DataSource obtained through JNDI then we can make no assumptions about the validation strategy. This means that our retry logic must either assume that the SQL it tries to execute can do so without errors (i.e., the statement is valid), or it must implement its own validation strategy to apply. Currently, the former is in place.


Nested Class Summary
 class ConnectionHelper.RetryManager<T>
          This class encapsulates the logic to retry a method invocation if it threw an SQLException.
 
Field Summary
protected  DataSource dataSource
           
 
Constructor Summary
  ConnectionHelper(DataSource dataSrc, boolean block)
           
protected ConnectionHelper(DataSource dataSrc, boolean checkWithUserName, boolean block)
           
 
Method Summary
protected  void closeResources(Connection con, Statement stmt, ResultSet rs)
          Closes the given resources given the batchMode state.
 void endBatch(boolean commit)
          This method always ends the batch mode.
 void exec(String sql, Object... params)
          Executes a general SQL statement and immediately closes all resources.
 ResultSet exec(String sql, Object[] params, boolean returnGeneratedKeys, int maxRows)
          Executes a general SQL statement and returns the ResultSet of the executed statement.
protected  PreparedStatement execute(PreparedStatement stmt, Object[] params)
          This method is used by all methods of this class that execute SQL statements.
protected  Connection getConnection()
          Gets a connection based on the batchMode state of this helper.
protected  boolean inBatchMode()
          Returns true if we are currently in a batch mode, false otherwise.
 String prepareDbIdentifier(String identifier)
          A utility method that makes sure that identifier does only consist of characters that are allowed in names on the target database.
protected  void replaceCharacter(StringBuffer escaped, char c)
          Called from prepareDbIdentifier(String).
 void startBatch()
          Starts the batch mode.
 boolean tableExists(String tableName)
          Checks whether the given table exists in the database.
 int update(String sql, Object[] params)
          Executes an update or delete statement and returns the update count.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

dataSource

protected final DataSource dataSource
Constructor Detail

ConnectionHelper

public ConnectionHelper(DataSource dataSrc,
                        boolean block)
Parameters:
dataSrc - the DataSource on which this instance acts
block - whether the helper should transparently block on DB connection loss (otherwise it retries once and if that fails throws exception)

ConnectionHelper

protected ConnectionHelper(DataSource dataSrc,
                           boolean checkWithUserName,
                           boolean block)
Parameters:
dataSrc - the DataSource on which this instance acts
checkWithUserName - whether the username is to be used for the tableExists(String) method
block - whether the helper should transparently block on DB connection loss (otherwise it throws exceptions)
Method Detail

prepareDbIdentifier

public final String prepareDbIdentifier(String identifier)
                                 throws SQLException
A utility method that makes sure that identifier does only consist of characters that are allowed in names on the target database. Illegal characters will be escaped as necessary. This method is not affected by the

Parameters:
identifier - the identifier to convert to a db specific identifier
Returns:
the db-normalized form of the given identifier
Throws:
SQLException - if an error occurs

replaceCharacter

protected void replaceCharacter(StringBuffer escaped,
                                char c)
Called from prepareDbIdentifier(String). Default implementation replaces the illegal characters with their hexadecimal encoding.

Parameters:
escaped - the escaped db identifier
c - the character to replace

inBatchMode

protected boolean inBatchMode()
Returns true if we are currently in a batch mode, false otherwise.

Returns:
true if the current thread is running in batch mode, false otherwise.

tableExists

public final boolean tableExists(String tableName)
                          throws SQLException
Checks whether the given table exists in the database.

Parameters:
tableName - the name of the table
Returns:
whether the given table exists
Throws:
SQLException - on error

startBatch

public final void startBatch()
                      throws SQLException
Starts the batch mode. If an SQLException is thrown, then the batch mode is not started.

Important: clients that call this method must make sure that endBatch(boolean) is called eventually.

Throws:
SQLException - on error

endBatch

public final void endBatch(boolean commit)
                    throws SQLException
This method always ends the batch mode.

Parameters:
commit - whether the changes in the batch should be committed or rolled back
Throws:
SQLException - if the commit or rollback of the underlying JDBC Connection threw an SQLException

exec

public final void exec(String sql,
                       Object... params)
                throws SQLException
Executes a general SQL statement and immediately closes all resources. Note: We use a Statement if there are no parameters to avoid a problem on the Oracle 10g JDBC driver w.r.t. :NEW and :OLD keywords that triggers ORA-17041.

Parameters:
sql - an SQL statement string
params - the parameters for the SQL statement
Throws:
SQLException - on error

update

public final int update(String sql,
                        Object[] params)
                 throws SQLException
Executes an update or delete statement and returns the update count.

Parameters:
sql - an SQL statement string
params - the parameters for the SQL statement
Returns:
the update count
Throws:
SQLException - on error

exec

public final ResultSet exec(String sql,
                            Object[] params,
                            boolean returnGeneratedKeys,
                            int maxRows)
                     throws SQLException
Executes a general SQL statement and returns the ResultSet of the executed statement. The returned ResultSet should be closed by clients.

Parameters:
sql - an SQL statement string
params - the parameters for the SQL statement
returnGeneratedKeys - whether generated keys should be returned
maxRows - the maximum number of rows in a potential ResultSet (0 means no limit)
Returns:
a ResultSet
Throws:
SQLException - on error

getConnection

protected final Connection getConnection()
                                  throws SQLException
Gets a connection based on the batchMode state of this helper. The connection should be closed by a call to closeResources(Connection, Statement, ResultSet) which also takes the batchMode state into account.

Returns:
a Connection to use, based on the batch mode state
Throws:
SQLException - on error

closeResources

protected final void closeResources(Connection con,
                                    Statement stmt,
                                    ResultSet rs)
Closes the given resources given the batchMode state.

Parameters:
con - the Connection obtained through the getConnection() method
stmt - a Statement
rs - a ResultSet

execute

protected PreparedStatement execute(PreparedStatement stmt,
                                    Object[] params)
                             throws SQLException
This method is used by all methods of this class that execute SQL statements. This default implementation sets all parameters and unwraps StreamWrapper instances. Subclasses may override this method to do something special with the parameters. E.g., the Oracle10R1ConnectionHelper overrides it in order to add special blob handling.

Parameters:
stmt - the PreparedStatement to execute
params - the parameters
Returns:
the executed statement
Throws:
SQLException - on error


Copyright © 2004-2010 The Apache Software Foundation. All Rights Reserved.