org.apache.manifoldcf.core.database
Class Database

java.lang.Object
  extended by org.apache.manifoldcf.core.database.Database
Direct Known Subclasses:
DBInterfaceDerby, DBInterfaceHSQLDB, DBInterfaceMySQL, DBInterfacePostgreSQL

public class Database
extends java.lang.Object

This class implements jskw.interfaces.IDatabase, and provides basic cached database services. The actual cache keys are determined by layers above this. It is expected that there is ONE of these objects per thread per database! If there are more, then the transaction management will get screwed up (i.e. nobody will know what happened to the connection handles...)


Nested Class Summary
protected  class Database.ExecuteQueryThread
          Thread used to execute queries.
static class Database.QueryCacheExecutor
          This object is meant to execute within a cache manager call.
 
Field Summary
static java.lang.String _rcsid
           
protected static java.lang.String _TRANSACTION_
           
protected  ICacheManager cacheManager
           
protected  java.sql.Connection connection
           
protected  IThreadContext context
           
protected  java.lang.String databaseName
           
protected  int delayedTransactionDepth
           
protected  boolean doRollback
           
protected  java.lang.String jdbcDriverClass
           
protected  java.lang.String jdbcUrl
           
protected  java.lang.String password
           
protected static java.util.Random random
           
protected  TransactionHandle th
           
protected  java.lang.String userName
           
 
Constructor Summary
Database(IThreadContext context, java.lang.String jdbcUrl, java.lang.String jdbcDriverClass, java.lang.String databaseName, java.lang.String userName, java.lang.String password)
           
 
Method Summary
 void beginTransaction(int transactionType)
          Begin a database transaction.
protected static void cleanupParameters(java.util.ArrayList data)
          Clean up parameters after query has been triggered.
protected  void commitCurrentTransaction()
          Abstract method to commit a transaction
 void endTransaction()
          End a database transaction, either performing a commit or a rollback (depending on whether signalRollback() was called within the transaction).
protected  IResultSet execute(java.sql.Connection connection, java.lang.String query, java.util.ArrayList params, boolean bResults, int maxResults, ResultSpecification spec, ILimitChecker returnLimit)
          Run a query.
 IResultSet executeQuery(java.lang.String query, java.util.ArrayList params, StringSet cacheKeys, StringSet invalidateKeys, java.lang.String queryClass, boolean needResult, int maxReturn, ResultSpecification spec, ILimitChecker returnLimits)
          Execute arbitrary database query, and optionally cache the result.
protected  IResultSet executeUncachedQuery(java.lang.String query, java.util.ArrayList params, boolean bResults, int maxResults, ResultSpecification spec, ILimitChecker returnLimit)
          This method does NOT appear in any interface; it is here to service the cache object.
protected  IResultSet executeViaThread(java.sql.Connection connection, java.lang.String query, java.util.ArrayList params, boolean bResults, int maxResults, ResultSpecification spec, ILimitChecker returnLimit)
          Do query execution via a subthread, so the primary thread can be interrupted
protected  void explainQuery(java.lang.String query, java.util.ArrayList params)
          Abstract method for explaining a query
protected  int findColumn(java.sql.ResultSet rs, java.lang.String name)
           
protected  java.sql.Blob getBLOB(java.sql.ResultSet rs, int col)
           
 int getCurrentTransactionType()
          Get the current transaction type.
protected  IResultSet getData(java.sql.ResultSet rs, boolean bResults, int maxResults, ResultSpecification spec, ILimitChecker returnLimit)
           
 java.lang.String getDatabaseName()
          Get the database name.
protected  java.lang.Object getObject(java.sql.ResultSet rs, java.sql.ResultSetMetaData rsmd, int col, int desiredForm)
           
 long getSleepAmt()
          Sleep a random amount of time after a transaction abort.
 java.lang.String getTransactionID()
          Get the current transaction id.
protected  void internalTransactionBegin()
          Perform actual transaction begin.
protected  boolean isBinary(java.sql.ResultSetMetaData rsmd, int col)
           
protected  boolean isBLOB(java.sql.ResultSetMetaData rsmd, int col)
           
protected static void loadPS(java.sql.PreparedStatement ps, java.util.ArrayList data)
           
protected  java.lang.String mapColumnName(java.lang.String rawColumnName)
          Abstract method for mapping a column name from resultset
 void noteModifications(java.lang.String tableName, int insertCount, int modifyCount, int deleteCount)
          Note a number of inserts, modifications, or deletions to a specific table.
protected  void rollbackCurrentTransaction()
          Abstract method to roll back a transaction
 void signalRollback()
          Signal that a rollback should occur on the next endTransaction().
 void sleepFor(long amt)
          Sleep, as part of recovery from deadlock.
protected  void startATransaction()
          Abstract method to start a transaction
protected  void synchronizeTransactions()
          Synchronize internal transactions.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

_rcsid

public static final java.lang.String _rcsid
See Also:
Constant Field Values

cacheManager

protected ICacheManager cacheManager

context

protected IThreadContext context

jdbcUrl

protected java.lang.String jdbcUrl

jdbcDriverClass

protected java.lang.String jdbcDriverClass

databaseName

protected java.lang.String databaseName

userName

protected java.lang.String userName

password

protected java.lang.String password

th

protected TransactionHandle th

connection

protected java.sql.Connection connection

doRollback

protected boolean doRollback

delayedTransactionDepth

protected int delayedTransactionDepth

_TRANSACTION_

protected static final java.lang.String _TRANSACTION_
See Also:
Constant Field Values

random

protected static java.util.Random random
Constructor Detail

Database

public Database(IThreadContext context,
                java.lang.String jdbcUrl,
                java.lang.String jdbcDriverClass,
                java.lang.String databaseName,
                java.lang.String userName,
                java.lang.String password)
         throws ManifoldCFException
Throws:
ManifoldCFException
Method Detail

getDatabaseName

public java.lang.String getDatabaseName()
Get the database name. This is often used as a cache key qualifier.

Returns:
the database name.

getTransactionID

public java.lang.String getTransactionID()
Get the current transaction id.

Returns:
the current transaction identifier, or null if no transaction.

startATransaction

protected void startATransaction()
                          throws ManifoldCFException
Abstract method to start a transaction

Throws:
ManifoldCFException

commitCurrentTransaction

protected void commitCurrentTransaction()
                                 throws ManifoldCFException
Abstract method to commit a transaction

Throws:
ManifoldCFException

rollbackCurrentTransaction

protected void rollbackCurrentTransaction()
                                   throws ManifoldCFException
Abstract method to roll back a transaction

Throws:
ManifoldCFException

explainQuery

protected void explainQuery(java.lang.String query,
                            java.util.ArrayList params)
                     throws ManifoldCFException
Abstract method for explaining a query

Throws:
ManifoldCFException

mapColumnName

protected java.lang.String mapColumnName(java.lang.String rawColumnName)
Abstract method for mapping a column name from resultset


executeQuery

public IResultSet executeQuery(java.lang.String query,
                               java.util.ArrayList params,
                               StringSet cacheKeys,
                               StringSet invalidateKeys,
                               java.lang.String queryClass,
                               boolean needResult,
                               int maxReturn,
                               ResultSpecification spec,
                               ILimitChecker returnLimits)
                        throws ManifoldCFException
Execute arbitrary database query, and optionally cache the result. Cached results are returned for this operation if they are valid and appropriate. Note that any cached results returned were only guaranteed to be pertinent at the time the cached result was obtained; the actual data may become invalid due to other threads writing to the database. This is NOT true, however, if a transaction is started. If a transaction was started for this database within this thread context, then the query will be executed within the transaction, and since the transaction is owned by the current thread, no others will be able to disrupt its processing.

Parameters:
query - is the actual query string.
params - if not null, are prepared statement parameters.
cacheKeys - is the set of cache keys that the query result will be cached against. If the value for this parameter is null, then the query will not be cached.
invalidateKeys - is the set of cache keys that the query will invalidate when the query occurs. If this is null, then no keys will be invalidated. Note that if this is in a transaction, the cache invalidation will only occur for queries that are part of the transaction, at least until the transaction is committed.
queryClass - describes the class of the query, for the purposes of LRU and expiration time. The queryClass groups queries together, so that they are managed with a common set of timeouts and maximum sizes. If null, then no expiration or LRU behavior will take place.
needResult - is true if the result is needed.
maxReturn - is the maximum number of rows to return. Use -1 for infinite.
spec - is the result specification object, or null for standard.
returnLimits - is a description of how to limit return results (in addition to the maxReturn value). Pass null if no limits are desired.
Returns:
the resultset
Throws:
ManifoldCFException

getCurrentTransactionType

public int getCurrentTransactionType()
Get the current transaction type. Returns "READCOMMITTED" outside of a transaction.


beginTransaction

public void beginTransaction(int transactionType)
                      throws ManifoldCFException
Begin a database transaction. This method call MUST be paired with an endTransaction() call, or database handles will be lost. If the transaction should be rolled back, then signalRollback() should be called before the transaction is ended. It is strongly recommended that the code that uses transactions be structured so that a try block starts immediately after this method call. The body of the try block will contain all direct or indirect calls to executeQuery(). After this should be a catch for every exception type, including Error, which should call the signalRollback() method, and rethrow the exception. Then, after that a finally{} block which calls endTransaction().

Parameters:
transactionType - describes the type of the transaction.
Throws:
ManifoldCFException

synchronizeTransactions

protected void synchronizeTransactions()
                                throws ManifoldCFException
Synchronize internal transactions.

Throws:
ManifoldCFException

internalTransactionBegin

protected void internalTransactionBegin()
                                 throws ManifoldCFException
Perform actual transaction begin.

Throws:
ManifoldCFException

signalRollback

public void signalRollback()
Signal that a rollback should occur on the next endTransaction().


endTransaction

public void endTransaction()
                    throws ManifoldCFException
End a database transaction, either performing a commit or a rollback (depending on whether signalRollback() was called within the transaction).

Throws:
ManifoldCFException

noteModifications

public void noteModifications(java.lang.String tableName,
                              int insertCount,
                              int modifyCount,
                              int deleteCount)
                       throws ManifoldCFException
Note a number of inserts, modifications, or deletions to a specific table. This is so we can decide when to do appropriate maintenance.

Parameters:
tableName - is the name of the table being modified.
insertCount - is the number of inserts.
modifyCount - is the number of updates.
deleteCount - is the number of deletions.
Throws:
ManifoldCFException

getSleepAmt

public long getSleepAmt()
Sleep a random amount of time after a transaction abort.


sleepFor

public void sleepFor(long amt)
              throws ManifoldCFException
Sleep, as part of recovery from deadlock.

Throws:
ManifoldCFException

executeViaThread

protected IResultSet executeViaThread(java.sql.Connection connection,
                                      java.lang.String query,
                                      java.util.ArrayList params,
                                      boolean bResults,
                                      int maxResults,
                                      ResultSpecification spec,
                                      ILimitChecker returnLimit)
                               throws ManifoldCFException
Do query execution via a subthread, so the primary thread can be interrupted

Throws:
ManifoldCFException

executeUncachedQuery

protected IResultSet executeUncachedQuery(java.lang.String query,
                                          java.util.ArrayList params,
                                          boolean bResults,
                                          int maxResults,
                                          ResultSpecification spec,
                                          ILimitChecker returnLimit)
                                   throws ManifoldCFException
This method does NOT appear in any interface; it is here to service the cache object.

Throws:
ManifoldCFException

execute

protected IResultSet execute(java.sql.Connection connection,
                             java.lang.String query,
                             java.util.ArrayList params,
                             boolean bResults,
                             int maxResults,
                             ResultSpecification spec,
                             ILimitChecker returnLimit)
                      throws ManifoldCFException
Run a query. No caching is involved at all at this level.

Parameters:
query - String the query string
bResults - boolean whether to load the resultset or not
maxResults - is the maximum number of results to load: -1 if all
params - ArrayList if params !=null, use preparedStatement
Throws:
ManifoldCFException

getData

protected IResultSet getData(java.sql.ResultSet rs,
                             boolean bResults,
                             int maxResults,
                             ResultSpecification spec,
                             ILimitChecker returnLimit)
                      throws ManifoldCFException
Throws:
ManifoldCFException

loadPS

protected static void loadPS(java.sql.PreparedStatement ps,
                             java.util.ArrayList data)
                      throws java.sql.SQLException,
                             ManifoldCFException
Throws:
java.sql.SQLException
ManifoldCFException

cleanupParameters

protected static void cleanupParameters(java.util.ArrayList data)
                                 throws ManifoldCFException
Clean up parameters after query has been triggered.

Throws:
ManifoldCFException

findColumn

protected int findColumn(java.sql.ResultSet rs,
                         java.lang.String name)
                  throws ManifoldCFException
Throws:
ManifoldCFException

getBLOB

protected java.sql.Blob getBLOB(java.sql.ResultSet rs,
                                int col)
                         throws ManifoldCFException
Throws:
ManifoldCFException

isBLOB

protected boolean isBLOB(java.sql.ResultSetMetaData rsmd,
                         int col)
                  throws ManifoldCFException
Throws:
ManifoldCFException

isBinary

protected boolean isBinary(java.sql.ResultSetMetaData rsmd,
                           int col)
                    throws ManifoldCFException
Throws:
ManifoldCFException

getObject

protected java.lang.Object getObject(java.sql.ResultSet rs,
                                     java.sql.ResultSetMetaData rsmd,
                                     int col,
                                     int desiredForm)
                              throws ManifoldCFException
Throws:
ManifoldCFException