You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jcs-dev@jakarta.apache.org by as...@apache.org on 2006/03/16 18:28:52 UTC
svn commit: r386396 - in
/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/jdbc:
JDBCDiskCache.java JDBCDiskCacheAttributes.java JDBCDiskCacheFactory.java
JDBCDiskCacheManager.java
Author: asmuts
Date: Thu Mar 16 09:28:51 2006
New Revision: 386396
URL: http://svn.apache.org/viewcvs?rev=386396&view=rev
Log:
adding a general jdbc disk cache that put elements into a blob filed in a table.
Added:
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCache.java
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCacheAttributes.java
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCacheFactory.java
jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCacheManager.java
Added: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCache.java
URL: http://svn.apache.org/viewcvs/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCache.java?rev=386396&view=auto
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCache.java (added)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCache.java Thu Mar 16 09:28:51 2006
@@ -0,0 +1,1058 @@
+package org.apache.jcs.auxiliary.disk.jdbc;
+
+/*
+ * Copyright 2001-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.sql.Connection;
+import java.sql.Date;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import java.util.List;
+import java.util.Set;
+
+import org.apache.commons.dbcp.ConnectionFactory;
+import org.apache.commons.dbcp.DriverManagerConnectionFactory;
+import org.apache.commons.dbcp.PoolableConnectionFactory;
+import org.apache.commons.dbcp.PoolingDriver;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.pool.ObjectPool;
+import org.apache.commons.pool.impl.GenericObjectPool;
+import org.apache.jcs.auxiliary.disk.AbstractDiskCache;
+import org.apache.jcs.engine.CacheConstants;
+import org.apache.jcs.engine.behavior.ICacheElement;
+import org.apache.jcs.engine.behavior.IElementSerializer;
+import org.apache.jcs.engine.stats.StatElement;
+import org.apache.jcs.engine.stats.behavior.IStatElement;
+import org.apache.jcs.engine.stats.behavior.IStats;
+import org.apache.jcs.utils.serialization.StandardSerializer;
+
+/**
+ * This is the jdbc disk cache plugin.
+ * <p>
+ * It expects a table created by the following script. The table name is
+ * configurable.
+ *
+ * <pre>
+ * drop TABLE JCS_STORE;
+ *
+ * CREATE TABLE JCS_STORE
+ * (
+ * CACHE_KEY VARCHAR(250) NOT NULL,
+ * REGION VARCHAR(250) NOT NULL,
+ * ELEMENT BLOB,
+ * CREATE_TIME DATE,
+ * CREATE_TIME_SECONDS BIGINT,
+ * MAX_LIFE_SECONDS BIGINT,
+ * IS_ETERNAL CHAR(1),
+ * PRIMARY KEY (CACHE_KEY, REGION)
+ * );
+ * </pre>
+ *
+ *
+ * The cleanup thread will delete non eternal items where (now - create time) > max life seconds * 1000
+ *
+ * @author Aaron Smuts
+ *
+ */
+public class JDBCDiskCache
+ extends AbstractDiskCache
+{
+ private final static Log log = LogFactory.getLog( JDBCDiskCache.class );
+
+ private static final long serialVersionUID = -7169488308515823492L;
+
+ private IElementSerializer elementSerializer = new StandardSerializer();
+
+ private JDBCDiskCacheAttributes jdbcDiskCacheAttributes;
+
+ private static final String DEFAULT_POOL_NAME = "jcs";
+
+ private String poolName = DEFAULT_POOL_NAME;
+
+ private static final String DRIVER_NAME = "jdbc:apache:commons:dbcp:";
+
+ private int updateCount = 0;
+
+ private int getCount = 0;
+
+ // if count % interval == 0 then log
+ private static final int LOG_INTERVAL = 100;
+
+ /**
+ *
+ * @param cattr
+ */
+ public JDBCDiskCache( JDBCDiskCacheAttributes cattr )
+ {
+ super( cattr );
+
+ setJdbcDiskCacheAttributes( cattr );
+
+ if ( log.isInfoEnabled() )
+ {
+ log.info( "jdbcDiskCacheAttributes = " + getJdbcDiskCacheAttributes() );
+ }
+
+ // WE SHOULD HAVE A DIFFERENT POOL FOR EACH DB NO REGION
+ // THE SAME TABLE CAN BE USED BY MULTIPLE REGIONS
+ // this.setPoolName( jdbcDiskCacheAttributes.getCacheName() );
+
+ try
+ {
+ try
+ {
+ // org.gjt.mm.mysql.Driver
+ Class.forName( cattr.getDriverClassName() );
+ }
+ catch ( ClassNotFoundException e )
+ {
+ log.error( "Couldn't find class for driver [" + cattr.getDriverClassName() + "]", e );
+ }
+
+ setupDriver( cattr.getUrl(), cattr.getUserName(), cattr.getPassword(), cattr.getMaxActive() );
+
+ logDriverStats();
+ }
+ catch ( Exception e )
+ {
+ log.error( "Problem getting connection.", e );
+ }
+
+ // Initialization finished successfully, so set alive to true.
+ alive = true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.jcs.auxiliary.disk.AbstractDiskCache#doUpdate(org.apache.jcs.engine.behavior.ICacheElement)
+ */
+ public void doUpdate( ICacheElement ce )
+ {
+
+ incrementUpdateCount();
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "updating, ce = " + ce );
+ }
+
+ Connection con;
+ try
+ {
+ con = DriverManager.getConnection( getPoolUrl() );
+ }
+ catch ( SQLException e )
+ {
+ log.error( "Problem getting conenction.", e );
+ return;
+ }
+
+ try
+ {
+ // TEST
+ Statement sStatement = null;
+ try
+ {
+ sStatement = con.createStatement();
+ alive = true;
+ }
+ catch ( SQLException e )
+ {
+ log.error( "Problem creating statement.", e );
+ alive = false;
+ }
+ finally
+ {
+ try
+ {
+ sStatement.close();
+ }
+ catch ( SQLException e )
+ {
+ log.error( "Problem closing statement.", e );
+ }
+ }
+
+ if ( !alive )
+ {
+ if ( log.isInfoEnabled() )
+ {
+ log.info( "Disk is not alive, aborting put." );
+ }
+ return;
+ }
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "Putting [" + ce.getKey() + "] on disk." );
+ }
+
+ byte[] element;
+
+ try
+ {
+ element = serialize( ce );
+ }
+ catch ( IOException e )
+ {
+ log.error( "Could not serialize element", e );
+ return;
+ }
+
+ boolean exists = false;
+
+ // First do a query to determine if the element already exists
+ if ( this.getJdbcDiskCacheAttributes().isTestBeforeInsert() )
+ {
+ exists = doesElementExist( ce );
+ }
+
+ // If it doesn't exist, insert it, otherwise update
+ if ( !exists )
+ {
+
+ try
+ {
+ String sqlI = "insert into " + getJdbcDiskCacheAttributes().getTableName()
+ + " (CACHE_KEY, REGION, ELEMENT, MAX_LIFE_SECONDS, IS_ETERNAL, CREATE_TIME, CREATE_TIME_SECONDS) values (?, ?, ?, ?, ?, ?, ?)";
+
+ PreparedStatement psInsert = con.prepareStatement( sqlI );
+ psInsert.setString( 1, (String) ce.getKey() );
+ psInsert.setString( 2, this.getCacheName() );
+ psInsert.setBytes( 3, element );
+ psInsert.setLong( 4, ce.getElementAttributes().getMaxLifeSeconds() );
+ if ( ce.getElementAttributes().getIsEternal() )
+ {
+ psInsert.setString( 5, "T" );
+ }
+ else
+ {
+ psInsert.setString( 5, "F" );
+ }
+ Date createTime = new Date( ce.getElementAttributes().getCreateTime() );
+ psInsert.setDate( 6, createTime );
+ long now = System.currentTimeMillis() / 1000;
+ psInsert.setLong( 7, now );
+
+ psInsert.execute();
+ psInsert.close();
+ }
+ catch ( SQLException e )
+ {
+ if ( e.toString().indexOf( "Violation of unique index" ) != -1
+ || e.getMessage().indexOf( "Violation of unique index" ) != -1
+ || e.getMessage().indexOf( "Duplicate entry" ) != -1 )
+ {
+ exists = true;
+ }
+ else
+ {
+ log.error( "Could not insert element", e );
+ }
+
+ // see if it exists, if we didn't already
+ if ( !exists && !this.getJdbcDiskCacheAttributes().isTestBeforeInsert() )
+ {
+ exists = doesElementExist( ce );
+ }
+ }
+ }
+
+ // update if it exists.
+ if ( exists )
+ {
+ String sqlU = null;
+ try
+ {
+ sqlU = "update " + getJdbcDiskCacheAttributes().getTableName()
+ + " set ELEMENT = ? where CACHE_KEY = ? and REGION = ? ";
+ PreparedStatement psUpdate = con.prepareStatement( sqlU );
+ psUpdate.setBytes( 1, element );
+ psUpdate.setString( 2, (String) ce.getKey() );
+ psUpdate.setString( 3, this.getCacheName() );
+ psUpdate.execute();
+ psUpdate.close();
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "ran update " + sqlU );
+ }
+ }
+ catch ( SQLException e2 )
+ {
+ log.error( "e2 sql [" + sqlU + "] Exception: ", e2 );
+ }
+ }
+ }
+ finally
+ {
+ try
+ {
+ con.close();
+ }
+ catch ( SQLException e )
+ {
+ log.error( "Problem closing connection.", e );
+ }
+ }
+
+ if ( log.isInfoEnabled() )
+ {
+ if ( updateCount % LOG_INTERVAL == 0 )
+ {
+ // TODO make a log stats method
+ log.info( "Update Count [" + updateCount + "]" );
+ }
+ }
+ }
+
+ /**
+ * Does an element exist for this key?
+ *
+ * @param ce
+ * @return
+ */
+ protected boolean doesElementExist( ICacheElement ce )
+ {
+ boolean exists = false;
+
+ Connection con;
+ try
+ {
+ con = DriverManager.getConnection( getPoolUrl() );
+ }
+ catch ( SQLException e )
+ {
+ log.error( "Problem getting conenction.", e );
+ return exists;
+ }
+
+ Statement sStatement = null;
+ try
+ {
+ sStatement = con.createStatement();
+
+ // don't select the element, since we want this to be fast.
+ String sqlS = "select CACHE_KEY from " + getJdbcDiskCacheAttributes().getTableName() + " where REGION = '"
+ + this.getCacheName() + "' and CACHE_KEY = '" + (String) ce.getKey() + "'";
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( sqlS );
+ }
+
+ ResultSet rs = sStatement.executeQuery( sqlS );
+
+ if ( rs.next() )
+ {
+ exists = true;
+ }
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "[" + ce.getKey() + "] existing status is " + exists );
+ }
+
+ rs.close();
+ }
+ catch ( SQLException e )
+ {
+ log.error( "Problem looking for item before insert.", e );
+ }
+ finally
+ {
+ try
+ {
+ sStatement.close();
+ }
+ catch ( SQLException e1 )
+ {
+ log.error( "Problem closing statement.", e1 );
+ }
+
+ try
+ {
+ con.close();
+ }
+ catch ( SQLException e )
+ {
+ log.error( "Problem closing connection.", e );
+ }
+ }
+
+ return exists;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.jcs.auxiliary.disk.AbstractDiskCache#doGet(java.io.Serializable)
+ */
+ public ICacheElement doGet( Serializable key )
+ {
+
+ incrementGetCount();
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "Getting " + key + " from disk" );
+ }
+
+ if ( !alive )
+ {
+ return null;
+ }
+
+ ICacheElement obj = null;
+
+ byte[] data = null;
+ try
+ {
+ // region, key
+ String selectString = "select ELEMENT from " + getJdbcDiskCacheAttributes().getTableName()
+ + " where REGION = ? and CACHE_KEY = ?";
+
+ Connection con = DriverManager.getConnection( getPoolUrl() );
+ try
+ {
+ PreparedStatement psSelect = null;
+ try
+ {
+ psSelect = con.prepareStatement( selectString );
+ psSelect.setString( 1, this.getCacheName() );
+ psSelect.setString( 2, (String) key );
+ ResultSet rs = null;
+
+ rs = psSelect.executeQuery();
+ try
+ {
+ if ( rs.next() )
+ {
+ data = rs.getBytes( 1 );
+ }
+ if ( data != null )
+ {
+ try
+ {
+ // USE THE SERIALIZER
+ obj = (ICacheElement) getElementSerializer().deSerialize( data );
+
+ }
+ catch ( IOException ioe )
+ {
+ log.error( ioe );
+ }
+ catch ( Exception e )
+ {
+ log.error( "Problem getting item.", e );
+ }
+ }
+ }
+ finally
+ {
+ if ( rs != null )
+ {
+ rs.close();
+ }
+ rs.close();
+ }
+ }
+ finally
+ {
+ if ( psSelect != null )
+ {
+ psSelect.close();
+ }
+ psSelect.close();
+ }
+ }
+ finally
+ {
+ if ( con != null )
+ {
+ con.close();
+ }
+ }
+ }
+ catch ( SQLException sqle )
+ {
+ log.error( sqle );
+ }
+
+ if ( log.isInfoEnabled() )
+ {
+ if ( getCount % LOG_INTERVAL == 0 )
+ {
+ // TODO make a log stats method
+ log.info( "Get Count [" + getCount + "]" );
+ }
+ }
+
+ return obj;
+ }
+
+ /**
+ * Returns true if the removal was succesful; or false if there is nothing
+ * to remove. Current implementation always result in a disk orphan.
+ *
+ * @param key
+ * @return boolean
+ */
+ public boolean doRemove( Serializable key )
+ {
+ // remove single item.
+ String sql = "delete from " + getJdbcDiskCacheAttributes().getTableName() + " where CACHE_KEY = '" + key
+ + "' and REGION = '" + this.getCacheName() + "'";
+
+ try
+ {
+ if ( key instanceof String && key.toString().endsWith( CacheConstants.NAME_COMPONENT_DELIMITER ) )
+ {
+ // remove all keys of the same name group.
+ sql = "delete from " + getJdbcDiskCacheAttributes().getTableName() + " where REGION = '"
+ + this.getCacheName() + "' and CACHE_KEY = like '" + key + "%'";
+ }
+ Connection con = DriverManager.getConnection( getPoolUrl() );
+ Statement sStatement = null;
+ try
+ {
+ sStatement = con.createStatement();
+ alive = true;
+
+ sStatement.executeUpdate( sql );
+ }
+ catch ( SQLException e )
+ {
+ log.error( "Problem creating statement.", e );
+ alive = false;
+ }
+ finally
+ {
+ try
+ {
+ if ( sStatement != null )
+ {
+ sStatement.close();
+ }
+ con.close();
+ }
+ catch ( SQLException e1 )
+ {
+ log.error( "Problem closing statement.", e1 );
+ }
+ }
+
+ }
+ catch ( Exception e )
+ {
+ log.error( "Problem updating cache.", e );
+ reset();
+ }
+ return false;
+ }
+
+ /** This should remove all elements. For now this is not implemented. */
+ public void doRemoveAll()
+ {
+ try
+ {
+ String sql = "delete from " + getJdbcDiskCacheAttributes().getTableName() + " where REGION = '"
+ + this.getCacheName() + "'";
+ Connection con = DriverManager.getConnection( getPoolUrl() );
+ Statement sStatement = null;
+ try
+ {
+ sStatement = con.createStatement();
+ alive = true;
+
+ sStatement.executeUpdate( sql );
+ }
+ catch ( SQLException e )
+ {
+ log.error( "Problem creating statement.", e );
+ alive = false;
+ }
+ finally
+ {
+ try
+ {
+ if ( sStatement != null )
+ {
+ sStatement.close();
+ }
+ con.close();
+ }
+ catch ( SQLException e1 )
+ {
+ log.error( "Problem closing statement.", e1 );
+ }
+ }
+ }
+ catch ( Exception e )
+ {
+ log.error( "Problem removing all.", e );
+ reset();
+ }
+ }
+
+ /**
+ * Removed the expired.
+ *
+ * (now - create time) > max life seconds * 1000
+ *
+ */
+ protected void deleteExpired()
+ {
+ try
+ {
+ long now = System.currentTimeMillis() / 1000;
+ String sql = "delete from " + getJdbcDiskCacheAttributes().getTableName() + " where REGION = '"
+ + this.getCacheName() + "' and IS_ETERNAL = 'F' and (" + now + " - CREATE_TIME_SECONDS) > MAX_LIFE";
+ Connection con = DriverManager.getConnection( getPoolUrl() );
+ Statement sStatement = null;
+ try
+ {
+ sStatement = con.createStatement();
+ alive = true;
+
+ sStatement.executeUpdate( sql );
+ }
+ catch ( SQLException e )
+ {
+ log.error( "Problem creating statement.", e );
+ alive = false;
+ }
+ finally
+ {
+ try
+ {
+ if ( sStatement != null )
+ {
+ sStatement.close();
+ }
+ con.close();
+ }
+ catch ( SQLException e1 )
+ {
+ log.error( "Problem closing statement.", e1 );
+ }
+ }
+ }
+ catch ( Exception e )
+ {
+ log.error( "Problem removing all.", e );
+ reset();
+ }
+ }
+
+ /**
+ * Typically this is used to handle errors by last resort, force content
+ * update, or removeall
+ */
+ public void reset()
+ {
+ // nothing
+ }
+
+ /** Shuts down the pool */
+ public void doDispose()
+ {
+ try
+ {
+ shutdownDriver();
+ }
+ catch ( Exception e )
+ {
+ log.error( "Problem shutting down.", e );
+ }
+ }
+
+ /**
+ * Returns the current cache size.
+ *
+ * @return The size value
+ */
+ public int getSize()
+ {
+ int size = 0;
+
+ // region, key
+ String selectString = "select count(*) from " + getJdbcDiskCacheAttributes().getTableName() + " where REGION = ?";
+
+ Connection con;
+ try
+ {
+ con = DriverManager.getConnection( getPoolUrl() );
+ }
+ catch ( SQLException e1 )
+ {
+ log.error( "Problem getting conenction.", e1 );
+ return size;
+ }
+ try
+ {
+ PreparedStatement psSelect = null;
+ try
+ {
+ psSelect = con.prepareStatement( selectString );
+ psSelect.setString( 1, this.getCacheName() );
+ ResultSet rs = null;
+
+ rs = psSelect.executeQuery();
+ try
+ {
+ if ( rs.next() )
+ {
+ size = rs.getInt( 1 );
+ }
+ }
+ finally
+ {
+ if ( rs != null )
+ {
+ rs.close();
+ }
+ rs.close();
+ }
+ }
+ finally
+ {
+ if ( psSelect != null )
+ {
+ psSelect.close();
+ }
+ psSelect.close();
+ }
+ }
+ catch ( SQLException e )
+ {
+ log.error( "Problem getting size.", e );
+ }
+ finally
+ {
+ try
+ {
+ con.close();
+ }
+ catch ( SQLException e )
+ {
+ log.error( "Problem closing connection.", e );
+ }
+ }
+ return size;
+ }
+
+ /**
+ * Returns the serialized form of the given object in a byte array.
+ *
+ * @param obj
+ * @return byte[]
+ * @throws IOException
+ */
+ protected byte[] serialize( Serializable obj )
+ throws IOException
+ {
+ return getElementSerializer().serialize( obj );
+ }
+
+ /**
+ * @param groupName
+ * @return
+ *
+ */
+ public Set getGroupKeys( String groupName )
+ {
+ if ( true )
+ {
+ throw new UnsupportedOperationException( "Groups not implemented." );
+ }
+ return null;
+ }
+
+ /**
+ * @param elementSerializer
+ * The elementSerializer to set.
+ */
+ public void setElementSerializer( IElementSerializer elementSerializer )
+ {
+ this.elementSerializer = elementSerializer;
+ }
+
+ /**
+ * @return Returns the elementSerializer.
+ */
+ public IElementSerializer getElementSerializer()
+ {
+ return elementSerializer;
+ }
+
+ /**
+ *
+ * @param connectURI
+ * @param userName
+ * @param password
+ * @param maxActive max connetions
+ * @throws Exception
+ */
+ public void setupDriver( String connectURI, String userName, String password, int maxActive )
+ throws Exception
+ {
+ // First, we'll need a ObjectPool that serves as the
+ // actual pool of connections.
+ // We'll use a GenericObjectPool instance, although
+ // any ObjectPool implementation will suffice.
+ ObjectPool connectionPool = new GenericObjectPool( null, maxActive );
+
+ // Next, we'll create a ConnectionFactory that the
+ // pool will use to create Connections.
+ // We'll use the DriverManagerConnectionFactory,
+ // using the connect string passed in the command line
+ // arguments.
+ // Properties props = new Properties();
+ // props.setProperty( "user", userName );
+ // props.setProperty( "password", password );
+ ConnectionFactory connectionFactory = new DriverManagerConnectionFactory( connectURI, userName, password );
+
+ // Now we'll create the PoolableConnectionFactory, which wraps
+ // the "real" Connections created by the ConnectionFactory with
+ // the classes that implement the pooling functionality.
+ // PoolableConnectionFactory poolableConnectionFactory =
+ new PoolableConnectionFactory( connectionFactory, connectionPool, null, null, false, true );
+
+ // Finally, we create the PoolingDriver itself...
+ Class.forName( "org.apache.commons.dbcp.PoolingDriver" );
+ PoolingDriver driver = (PoolingDriver) DriverManager.getDriver( DRIVER_NAME );
+
+ // ...and register our pool with it.
+ driver.registerPool( this.getPoolName(), connectionPool );
+
+ // Now we can just use the connect string
+ // "jdbc:apache:commons:dbcp:jcs"
+ // to access our pool of Connections.
+ }
+
+ /**
+ *
+ * @throws Exception
+ */
+ public void logDriverStats()
+ throws Exception
+ {
+ PoolingDriver driver = (PoolingDriver) DriverManager.getDriver( DRIVER_NAME );
+ ObjectPool connectionPool = driver.getConnectionPool( this.getPoolName() );
+
+ if ( connectionPool != null )
+ {
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( connectionPool );
+ }
+
+ if ( log.isInfoEnabled() )
+ {
+ log.info( "NumActive: " + getNumActiveInPool() );
+ log.info( "NumIdle: " + getNumIdleInPool() );
+ }
+ }
+ else
+ {
+ log.warn( "Could not find pool." );
+ }
+ }
+
+
+ /**
+ * How many are idle in the pool.
+ *
+ * @return
+ */
+ public int getNumIdleInPool()
+ {
+ int numIdle = 0;
+ try
+ {
+ PoolingDriver driver = (PoolingDriver) DriverManager.getDriver( DRIVER_NAME );
+ ObjectPool connectionPool = driver.getConnectionPool( this.getPoolName() );
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( connectionPool );
+ }
+ numIdle = connectionPool.getNumIdle();
+ }
+ catch ( Exception e )
+ {
+ log.error( e );
+ }
+ return numIdle;
+ }
+
+ /**
+ * How many are active in the pool.
+ *
+ * @return
+ */
+ public int getNumActiveInPool()
+ {
+ int numActive = 0;
+ try
+ {
+ PoolingDriver driver = (PoolingDriver) DriverManager.getDriver( DRIVER_NAME );
+ ObjectPool connectionPool = driver.getConnectionPool( this.getPoolName() );
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( connectionPool );
+ }
+ numActive = connectionPool.getNumActive();
+ }
+ catch ( Exception e )
+ {
+ log.error( e );
+ }
+ return numActive;
+ }
+
+ /**
+ *
+ * @throws Exception
+ */
+ public void shutdownDriver()
+ throws Exception
+ {
+ PoolingDriver driver = (PoolingDriver) DriverManager.getDriver( DRIVER_NAME );
+ driver.closePool( this.getPoolName() );
+ }
+
+ /**
+ * @return Returns the poolUrl.
+ */
+ public String getPoolUrl()
+ {
+ return DRIVER_NAME + this.getPoolName();
+ }
+
+ /**
+ * @param poolName
+ * The poolName to set.
+ */
+ public void setPoolName( String poolName )
+ {
+ this.poolName = poolName;
+ }
+
+ /**
+ * @return Returns the poolName.
+ */
+ public String getPoolName()
+ {
+ return poolName;
+ }
+
+ /** safely increment */
+ private synchronized void incrementUpdateCount()
+ {
+ updateCount++;
+ }
+
+ /** safely increment */
+ private synchronized void incrementGetCount()
+ {
+ getCount++;
+ }
+
+ /**
+ * @param jdbcDiskCacheAttributes The jdbcDiskCacheAttributes to set.
+ */
+ protected void setJdbcDiskCacheAttributes( JDBCDiskCacheAttributes jdbcDiskCacheAttributes )
+ {
+ this.jdbcDiskCacheAttributes = jdbcDiskCacheAttributes;
+ }
+
+ /**
+ * @return Returns the jdbcDiskCacheAttributes.
+ */
+ protected JDBCDiskCacheAttributes getJdbcDiskCacheAttributes()
+ {
+ return jdbcDiskCacheAttributes;
+ }
+
+ /**
+ * Extends the parent stats.
+ */
+ public IStats getStatistics()
+ {
+ IStats stats = super.getStatistics();
+ stats.setTypeName( "JDBC/Abstract Disk Cache" );
+ stats.getStatElements();
+
+ ArrayList elems = new ArrayList();
+
+ IStatElement se = null;
+
+ se = new StatElement();
+ se.setName( "Update Count" );
+ se.setData( "" + updateCount );
+ elems.add( se );
+
+ se = new StatElement();
+ se.setName( "Get Count" );
+ se.setData( "" + getCount );
+ elems.add( se );
+
+ se = new StatElement();
+ se.setName( "Size" );
+ se.setData( "" + getSize() );
+ elems.add( se );
+
+ se = new StatElement();
+ se.setName( "Active DB Connections" );
+ se.setData( "" + getNumActiveInPool() );
+ elems.add( se );
+
+ se = new StatElement();
+ se.setName( "Idle DB Connections" );
+ se.setData( "" + getNumIdleInPool() );
+ elems.add( se );
+
+ se = new StatElement();
+ se.setName( "DB URL" );
+ se.setData( this.jdbcDiskCacheAttributes.getUrl() );
+ elems.add( se );
+
+ // get the stats from the event queue too
+ // get as array, convert to list, add list to our outer list
+ IStatElement[] eqSEs = stats.getStatElements();
+ List eqL = Arrays.asList( eqSEs );
+ elems.addAll( eqL );
+
+ // get an array and put them in the Stats object
+ IStatElement[] ses = (IStatElement[]) elems.toArray( new StatElement[0] );
+ stats.setStatElements( ses );
+
+ return stats;
+ }
+}
Added: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCacheAttributes.java
URL: http://svn.apache.org/viewcvs/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCacheAttributes.java?rev=386396&view=auto
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCacheAttributes.java (added)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCacheAttributes.java Thu Mar 16 09:28:51 2006
@@ -0,0 +1,188 @@
+package org.apache.jcs.auxiliary.disk.jdbc;
+
+/*
+ * Copyright 2001-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.jcs.auxiliary.disk.AbstractDiskCacheAttributes;
+
+/**
+ * The configurator will set these values based on what is in the cache.ccf
+ * file.
+ *
+ * @author Aaron Smuts
+ *
+ */
+public class JDBCDiskCacheAttributes
+ extends AbstractDiskCacheAttributes
+{
+ private static final long serialVersionUID = -6535808344813320062L;
+
+ private static final String DEFAULT_TABLE_NAME = "JCS_STORE";
+
+ private String userName;
+
+ private String password;
+
+ private String url;
+
+ private String driverClassName;
+
+ private String tableName = DEFAULT_TABLE_NAME;
+
+ private boolean testBeforeInsert = true;
+
+ private static final int DEFAULT_MAX_ACTIVE = 10;
+
+ private int maxActive = DEFAULT_MAX_ACTIVE;
+
+ /**
+ * @param userName
+ * The userName to set.
+ */
+ public void setUserName( String userName )
+ {
+ this.userName = userName;
+ }
+
+ /**
+ * @return Returns the userName.
+ */
+ public String getUserName()
+ {
+ return userName;
+ }
+
+ /**
+ * @param password
+ * The password to set.
+ */
+ public void setPassword( String password )
+ {
+ this.password = password;
+ }
+
+ /**
+ * @return Returns the password.
+ */
+ public String getPassword()
+ {
+ return password;
+ }
+
+ /**
+ * @param url
+ * The url to set.
+ */
+ public void setUrl( String url )
+ {
+ this.url = url;
+ }
+
+ /**
+ * @return Returns the url.
+ */
+ public String getUrl()
+ {
+ return url;
+ }
+
+ /**
+ * @param driverClassName
+ * The driverClassName to set.
+ */
+ public void setDriverClassName( String driverClassName )
+ {
+ this.driverClassName = driverClassName;
+ }
+
+ /**
+ * @return Returns the driverClassName.
+ */
+ public String getDriverClassName()
+ {
+ return driverClassName;
+ }
+
+ /**
+ * @param tableName
+ * The tableName to set.
+ */
+ public void setTableName( String tableName )
+ {
+ this.tableName = tableName;
+ }
+
+ /**
+ * @return Returns the tableName.
+ */
+ public String getTableName()
+ {
+ return tableName;
+ }
+
+ /**
+ * If this is true then the disk cache will check to see if the item already exists in the database.
+ * If it is false, it will try to insert. If the isnert fails it will try to update.
+ *
+ * @param testBeforeInsert
+ * The testBeforeInsert to set.
+ */
+ public void setTestBeforeInsert( boolean testBeforeInsert )
+ {
+ this.testBeforeInsert = testBeforeInsert;
+ }
+
+ /**
+ * @return Returns the testBeforeInsert.
+ */
+ public boolean isTestBeforeInsert()
+ {
+ return testBeforeInsert;
+ }
+
+ /**
+ * @param maxActive The maxActive to set.
+ */
+ public void setMaxActive( int maxActive )
+ {
+ this.maxActive = maxActive;
+ }
+
+ /**
+ * @return Returns the maxActive.
+ */
+ public int getMaxActive()
+ {
+ return maxActive;
+ }
+
+ /**
+ * For debugging.
+ */
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ buf.append( "\nJDBCCacheAttributes" );
+ buf.append( "\nUserName [" + getUserName() + "]" );
+ buf.append( "\nUrl [" + getUrl() + "]" );
+ buf.append( "\nDriverClassName [" + getDriverClassName() + "]" );
+ buf.append( "\nTableName [" + getTableName() + "]" );
+ buf.append( "\nTestBeforeInsert [" + isTestBeforeInsert() + "]" );
+ buf.append( "\nMaxActive [" + getMaxActive() + "]" );
+ return buf.toString();
+ }
+
+}
Added: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCacheFactory.java
URL: http://svn.apache.org/viewcvs/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCacheFactory.java?rev=386396&view=auto
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCacheFactory.java (added)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCacheFactory.java Thu Mar 16 09:28:51 2006
@@ -0,0 +1,61 @@
+package org.apache.jcs.auxiliary.disk.jdbc;
+
+/*
+ * Copyright 2001-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.jcs.auxiliary.AuxiliaryCache;
+import org.apache.jcs.auxiliary.AuxiliaryCacheAttributes;
+import org.apache.jcs.auxiliary.AuxiliaryCacheFactory;
+import org.apache.jcs.engine.behavior.ICompositeCacheManager;
+
+/**
+ * This factory should create mysql disk caches.
+ *
+ * @author Aaron Smuts
+ *
+ */
+public class JDBCDiskCacheFactory
+ implements AuxiliaryCacheFactory
+{
+
+ private String name = "MysqlDiskCacheFactory";
+
+ /**
+ * This factory method should create an instance of the mysqlcache.
+ */
+ public AuxiliaryCache createCache( AuxiliaryCacheAttributes rawAttr, ICompositeCacheManager arg1 )
+ {
+ JDBCDiskCacheManager mgr = JDBCDiskCacheManager.getInstance( (JDBCDiskCacheAttributes)rawAttr );
+ return mgr.getCache( (JDBCDiskCacheAttributes)rawAttr );
+ }
+
+ /**
+ * The name of the factory.
+ */
+ public void setName( String nameArg )
+ {
+ name = nameArg;
+ }
+
+ /**
+ * Returns the display name
+ */
+ public String getName()
+ {
+ return name;
+ }
+
+}
Added: jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCacheManager.java
URL: http://svn.apache.org/viewcvs/jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCacheManager.java?rev=386396&view=auto
==============================================================================
--- jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCacheManager.java (added)
+++ jakarta/jcs/trunk/src/java/org/apache/jcs/auxiliary/disk/jdbc/JDBCDiskCacheManager.java Thu Mar 16 09:28:51 2006
@@ -0,0 +1,183 @@
+package org.apache.jcs.auxiliary.disk.jdbc;
+
+/*
+ * Copyright 2001-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jcs.auxiliary.AuxiliaryCache;
+import org.apache.jcs.auxiliary.AuxiliaryCacheManager;
+
+/**
+ * This manages instances of the jdbc disk cache. It maintains one for each
+ * region. One for all regions would work, but this gives us more detailed stats
+ * by region.
+ *
+ */
+public class JDBCDiskCacheManager
+ implements AuxiliaryCacheManager
+{
+
+ private static final long serialVersionUID = -8258856770927857896L;
+
+ private static final Log log = LogFactory.getLog( JDBCDiskCacheManager.class );
+
+ private static int clients;
+
+ private static Hashtable caches = new Hashtable();
+
+ private static JDBCDiskCacheManager instance;
+
+ private static JDBCDiskCacheAttributes defaultCattr;
+
+ /**
+ * Constructor for the HSQLCacheManager object
+ *
+ * @param cattr
+ */
+ private JDBCDiskCacheManager( JDBCDiskCacheAttributes cattr )
+ {
+ defaultCattr = cattr;
+ }
+
+ /**
+ * Gets the defaultCattr attribute of the HSQLCacheManager object
+ *
+ * @return The defaultCattr value
+ */
+ public JDBCDiskCacheAttributes getDefaultCattr()
+ {
+ return defaultCattr;
+ }
+
+ /**
+ * Gets the instance attribute of the HSQLCacheManager class
+ *
+ * @param cattr
+ *
+ * @return The instance value
+ */
+ public static JDBCDiskCacheManager getInstance( JDBCDiskCacheAttributes cattr )
+ {
+ synchronized ( JDBCDiskCacheManager.class )
+ {
+ if ( instance == null )
+ {
+ instance = new JDBCDiskCacheManager( cattr );
+ }
+ }
+
+ clients++;
+ return instance;
+ }
+
+ /**
+ * Gets the cache attribute of the HSQLCacheManager object
+ *
+ * @param cacheName
+ *
+ * @return The cache value
+ */
+ public AuxiliaryCache getCache( String cacheName )
+ {
+ JDBCDiskCacheAttributes cattr = (JDBCDiskCacheAttributes) defaultCattr.copy();
+ cattr.setCacheName( cacheName );
+ return getCache( cattr );
+ }
+
+ /**
+ * Gets the cache attribute of the HSQLCacheManager object
+ *
+ * @param cattr
+ *
+ * @return The cache value
+ */
+ public AuxiliaryCache getCache( JDBCDiskCacheAttributes cattr )
+ {
+ AuxiliaryCache raf = null;
+
+ log.debug( "cacheName = " + cattr.getCacheName() );
+
+ synchronized ( caches )
+ {
+ raf = (AuxiliaryCache) caches.get( cattr.getCacheName() );
+
+ if ( raf == null )
+ {
+ raf = new JDBCDiskCache( cattr );
+ caches.put( cattr.getCacheName(), raf );
+ }
+ }
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "JDBC cache = " + raf );
+ }
+
+ return raf;
+ }
+
+ /**
+ *
+ * @param name
+ */
+ public void freeCache( String name )
+ {
+ JDBCDiskCache raf = (JDBCDiskCache) caches.get( name );
+ if ( raf != null )
+ {
+
+ raf.dispose();
+
+ }
+ }
+
+ /**
+ * Gets the cacheType attribute of the HSQLCacheManager object
+ *
+ * @return The cacheType value
+ */
+ public int getCacheType()
+ {
+ return DISK_CACHE;
+ }
+
+ /** Disposes of all regions. */
+ public void release()
+ {
+ // Wait until called by the last client
+ if ( --clients != 0 )
+ {
+ return;
+ }
+ synchronized ( caches )
+ {
+ Enumeration allCaches = caches.elements();
+
+ while ( allCaches.hasMoreElements() )
+ {
+ JDBCDiskCache raf = (JDBCDiskCache) allCaches.nextElement();
+ if ( raf != null )
+ {
+ raf.dispose();
+ }
+ }
+ }
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: jcs-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: jcs-dev-help@jakarta.apache.org