001package org.apache.commons.jcs3.auxiliary.disk.jdbc.mysql;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.sql.SQLException;
023import java.util.Map;
024
025import org.apache.commons.jcs3.auxiliary.disk.jdbc.JDBCDiskCache;
026import org.apache.commons.jcs3.auxiliary.disk.jdbc.TableState;
027import org.apache.commons.jcs3.auxiliary.disk.jdbc.dsfactory.DataSourceFactory;
028import org.apache.commons.jcs3.engine.behavior.ICacheElement;
029import org.apache.commons.jcs3.log.Log;
030import org.apache.commons.jcs3.log.LogManager;
031
032/**
033 * The MySQLDiskCache extends the core JDBCDiskCache.
034 * <p>
035 * Although the generic JDBC Disk Cache can be used for MySQL, the MySQL JDBC Disk Cache has
036 * additional features, such as table optimization that are particular to MySQL.
037 * </p>
038 */
039public class MySQLDiskCache<K, V>
040        extends JDBCDiskCache<K, V>
041{
042    /** local logger */
043    private static final Log log = LogManager.getLog( MySQLDiskCache.class );
044
045    /** config attributes */
046    private final MySQLDiskCacheAttributes mySQLDiskCacheAttributes;
047
048    /**
049     * Delegates to the super and makes use of the MySQL specific parameters used for scheduled
050     * optimization.
051     * <p>
052     * @param attributes the configuration object for this cache
053     * @param dsFactory the DataSourceFactory for this cache
054     * @param tableState an object to track table operations
055     * @throws SQLException if the pool access could not be set up
056     */
057    public MySQLDiskCache( final MySQLDiskCacheAttributes attributes, final DataSourceFactory dsFactory,
058                final TableState tableState) throws SQLException
059    {
060        super( attributes, dsFactory, tableState);
061
062        mySQLDiskCacheAttributes = attributes;
063
064        log.debug( "MySQLDiskCacheAttributes = {0}", attributes );
065    }
066
067    /**
068     * This delegates to the generic JDBC disk cache. If we are currently optimizing, then this
069     * method will balk and return null.
070     * <p>
071     * @param key Key to locate value for.
072     * @return An object matching key, or null.
073     */
074    @Override
075    protected ICacheElement<K, V> processGet( final K key )
076    {
077        if (this.getTableState().getState() == TableState.OPTIMIZATION_RUNNING &&
078            this.mySQLDiskCacheAttributes.isBalkDuringOptimization())
079        {
080            return null;
081        }
082        return super.processGet( key );
083    }
084
085    /**
086     * This delegates to the generic JDBC disk cache. If we are currently optimizing, then this
087     * method will balk and return null.
088     * <p>
089     * @param pattern used for like query.
090     * @return An object matching key, or null.
091     */
092    @Override
093    protected Map<K, ICacheElement<K, V>> processGetMatching( final String pattern )
094    {
095        if (this.getTableState().getState() == TableState.OPTIMIZATION_RUNNING &&
096            this.mySQLDiskCacheAttributes.isBalkDuringOptimization())
097        {
098            return null;
099        }
100        return super.processGetMatching( pattern );
101    }
102
103    /**
104     * @param pattern
105     * @return String to use in the like query.
106     */
107    @Override
108    public String constructLikeParameterFromPattern( final String pattern )
109    {
110        String likePattern = pattern.replace( ".+", "%" );
111        likePattern = likePattern.replace( ".", "_" );
112
113        log.debug( "pattern = [{0}]", likePattern );
114
115        return likePattern;
116    }
117
118    /**
119     * This delegates to the generic JDBC disk cache. If we are currently optimizing, then this
120     * method will balk and do nothing.
121     * <p>
122     * @param element
123     */
124    @Override
125    protected void processUpdate( final ICacheElement<K, V> element )
126    {
127        if (this.getTableState().getState() == TableState.OPTIMIZATION_RUNNING &&
128            this.mySQLDiskCacheAttributes.isBalkDuringOptimization())
129        {
130            return;
131        }
132        super.processUpdate( element );
133    }
134
135    /**
136     * Removed the expired. (now - create time) &gt; max life seconds * 1000
137     * <p>
138     * If we are currently optimizing, then this method will balk and do nothing.
139     * <p>
140     * TODO consider blocking and trying again.
141     * <p>
142     * @return the number deleted
143     */
144    @Override
145    protected int deleteExpired()
146    {
147        if (this.getTableState().getState() == TableState.OPTIMIZATION_RUNNING &&
148            this.mySQLDiskCacheAttributes.isBalkDuringOptimization())
149        {
150            return -1;
151        }
152        return super.deleteExpired();
153    }
154}