Class ConnectionHelper
- java.lang.Object
-
- org.apache.jackrabbit.core.util.db.ConnectionHelper
-
- Direct Known Subclasses:
DerbyConnectionHelper
,OracleConnectionHelper
,PostgreSQLConnectionHelper
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 thestartBatch()
andendBatch(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 theblock
argument of the constructor call wasfalse
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 ofSQLExceptions
is faultyConnections
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 theDataSource
ingetConnection(boolean)
may be broken. This is so because if an internalDataSource
is used, then this is a commons-dbcpDataSource
with atestWhileIdle
validation strategy (see theConnectionFactory
class). Furthermore, if it is aDataSource
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
Nested Classes Modifier and Type Class Description class
ConnectionHelper.RetryManager<T>
This class encapsulates the logic to retry a method invocation if it threw an SQLException.
-
Field Summary
Fields Modifier and Type Field Description protected DataSource
dataSource
-
Constructor Summary
Constructors Modifier Constructor Description ConnectionHelper(DataSource dataSrc, boolean block)
protected
ConnectionHelper(DataSource dataSrc, boolean checkWithUserName, boolean block)
protected
ConnectionHelper(DataSource dataSrc, boolean checkWithUserName, boolean block, int fetchSize)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description protected void
closeResources(Connection con, Statement stmt, ResultSet rs, boolean inBatchMode)
Closes the given resources given thebatchMode
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 theResultSet
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(boolean inBatchMode)
Gets a connection based on thebatchMode
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 thatidentifier
does only consist of characters that are allowed in names on the target database.ResultSet
query(String sql, Object... params)
Executes a SQL query and returns theResultSet
.protected void
replaceCharacter(StringBuilder escaped, char c)
Called fromprepareDbIdentifier(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.
-
-
-
Field Detail
-
dataSource
protected final DataSource dataSource
-
-
Constructor Detail
-
ConnectionHelper
public ConnectionHelper(DataSource dataSrc, boolean block)
- Parameters:
dataSrc
- theDataSource
on which this instance actsblock
- 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
- theDataSource
on which this instance actscheckWithUserName
- whether the username is to be used for thetableExists(String)
methodblock
- whether the helper should transparently block on DB connection loss (otherwise it throws exceptions)
-
ConnectionHelper
protected ConnectionHelper(DataSource dataSrc, boolean checkWithUserName, boolean block, int fetchSize)
- Parameters:
dataSrc
- theDataSource
on which this instance actscheckWithUserName
- whether the username is to be used for thetableExists(String)
methodblock
- whether the helper should transparently block on DB connection loss (otherwise it throws exceptions)fetchSize
- the fetchSize that will be used per default
-
-
Method Detail
-
prepareDbIdentifier
public final String prepareDbIdentifier(String identifier) throws SQLException
A utility method that makes sure thatidentifier
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(StringBuilder escaped, char c)
Called fromprepareDbIdentifier(String)
. Default implementation replaces the illegal characters with their hexadecimal encoding.- Parameters:
escaped
- the escaped db identifierc
- 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 or the active transaction 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 anSQLException
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 anSQLException
-
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 stringparams
- 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 stringparams
- the parameters for the SQL statement- Returns:
- the update count
- Throws:
SQLException
- on error
-
query
public final ResultSet query(String sql, Object... params) throws SQLException
- Parameters:
sql
- an SQL statement stringparams
- the parameters for the SQL statement- Returns:
- a
ResultSet
- Throws:
SQLException
-
exec
public final ResultSet exec(String sql, Object[] params, boolean returnGeneratedKeys, int maxRows) throws SQLException
Executes a general SQL statement and returns theResultSet
of the executed statement. The returnedResultSet
should be closed by clients.- Parameters:
sql
- an SQL statement stringparams
- the parameters for the SQL statementreturnGeneratedKeys
- whether generated keys should be returnedmaxRows
- the maximum number of rows in a potentialResultSet
(0 means no limit)- Returns:
- a
ResultSet
- Throws:
SQLException
- on error
-
getConnection
protected final Connection getConnection(boolean inBatchMode) throws SQLException
Gets a connection based on thebatchMode
state of this helper. The connection should be closed by a call tocloseResources(Connection, Statement, ResultSet, boolean)
which also takes thebatchMode
state into account.- Parameters:
inBatchMode
- indicates if we are in a batchMode- 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, boolean inBatchMode)
Closes the given resources given thebatchMode
state.- Parameters:
con
- theConnection
obtained through thegetConnection(boolean)
methodstmt
- aStatement
rs
- aResultSet
inBatchMode
- indicates if we are in a batchMode
-
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 unwrapsStreamWrapper
instances. Subclasses may override this method to do something special with the parameters. E.g., theOracle10R1ConnectionHelper
overrides it in order to add special blob handling.- Parameters:
stmt
- thePreparedStatement
to executeparams
- the parameters- Returns:
- the executed statement
- Throws:
SQLException
- on error
-
-