View Javadoc

1   package org.apache.jcs.auxiliary.disk.jdbc.hsql;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.sql.Connection;
23  import java.sql.DriverManager;
24  import java.sql.SQLException;
25  import java.sql.Statement;
26  import java.util.Collections;
27  import java.util.HashSet;
28  import java.util.Set;
29  
30  import org.apache.commons.logging.Log;
31  import org.apache.commons.logging.LogFactory;
32  import org.apache.jcs.auxiliary.AuxiliaryCache;
33  import org.apache.jcs.auxiliary.AuxiliaryCacheAttributes;
34  import org.apache.jcs.auxiliary.AuxiliaryCacheFactory;
35  import org.apache.jcs.auxiliary.disk.jdbc.JDBCDiskCacheAttributes;
36  import org.apache.jcs.auxiliary.disk.jdbc.JDBCDiskCacheManager;
37  import org.apache.jcs.engine.behavior.ICompositeCacheManager;
38  
39  /***
40   * This factory should create mysql disk caches.
41   * <p>
42   * @author Aaron Smuts
43   */
44  public class HSQLDiskCacheFactory
45      implements AuxiliaryCacheFactory
46  {
47      private final static Log log = LogFactory.getLog( HSQLDiskCacheFactory.class );
48  
49      private String name = "HSQLDiskCacheFactory";
50  
51      private Set databases = Collections.synchronizedSet( new HashSet() );
52  
53      /***
54       * This factory method should create an instance of the mysqlcache.
55       */
56      public AuxiliaryCache createCache( AuxiliaryCacheAttributes rawAttr, ICompositeCacheManager arg1 )
57      {
58          JDBCDiskCacheManager mgr = JDBCDiskCacheManager.getInstance( (JDBCDiskCacheAttributes) rawAttr );
59          try
60          {
61              setupDatabase( (JDBCDiskCacheAttributes) rawAttr );
62          }
63          catch ( Exception e )
64          {
65              // TODO we may not want to try and get the cache at this point.
66              log.error( "Problem setting up database.", e );
67          }
68          return mgr.getCache( (JDBCDiskCacheAttributes) rawAttr );
69      }
70  
71      /***
72       * The name of the factory.
73       */
74      public void setName( String nameArg )
75      {
76          name = nameArg;
77      }
78  
79      /***
80       * Returns the display name
81       */
82      public String getName()
83      {
84          return name;
85      }
86  
87      /***
88       * Creates the database if it doesn't exist, registers the driver class,
89       * etc.
90       * <p>
91       * @param attributes
92       * @throws Exception
93       */
94      protected void setupDatabase( JDBCDiskCacheAttributes attributes )
95          throws Exception
96      {
97          if ( attributes == null )
98          {
99              throw new Exception( "The attributes are null." );
100         }
101 
102         // url should start with "jdbc:hsqldb:"
103         String database = attributes.getUrl() + attributes.getDatabase();
104 
105         if ( databases.contains( database ) )
106         {
107             if ( log.isInfoEnabled() )
108             {
109                 log.info( "We already setup database [" + database + "]" );
110             }
111             return;
112         }
113 
114         // TODO get this from the attributes.
115         System.setProperty( "hsqldb.cache_scale", "8" );
116 
117         // "org.hsqldb.jdbcDriver"
118         String driver = attributes.getDriverClassName();
119         // "sa"
120         String user = attributes.getUserName();
121         // ""
122         String password = attributes.getPassword();
123 
124         new org.hsqldb.jdbcDriver();
125         try
126         {
127             Class.forName( driver ).newInstance();
128 
129             Connection cConn = DriverManager.getConnection( database, user, password );
130 
131             setupTABLE( cConn, attributes.getTableName() );
132 
133             if ( log.isInfoEnabled() )
134             {
135                 log.info( "Finished setting up database [" + database + "]" );
136             }
137 
138             databases.add( database );
139         }
140         catch ( Exception e )
141         {
142             log.error( "Fatal problem setting up the database.", e );
143         }
144     }
145 
146     /***
147      * SETUP TABLE FOR CACHE
148      * <p>
149      * @param cConn
150      * @param tableName
151      */
152     private void setupTABLE( Connection cConn, String tableName )
153     {
154         boolean newT = true;
155 
156         // TODO make the cached nature of the table configurable
157         StringBuffer createSql = new StringBuffer();
158         createSql.append( "CREATE CACHED TABLE " + tableName );
159         createSql.append( "( " );
160         createSql.append( "CACHE_KEY             VARCHAR(250)          NOT NULL, " );
161         createSql.append( "REGION                VARCHAR(250)          NOT NULL, " );
162         createSql.append( "ELEMENT               BINARY, " );
163         createSql.append( "CREATE_TIME           DATE, " );
164         createSql.append( "CREATE_TIME_SECONDS   BIGINT, " );
165         createSql.append( "MAX_LIFE_SECONDS      BIGINT, " );
166         createSql.append( "SYSTEM_EXPIRE_TIME_SECONDS      BIGINT, " );
167         createSql.append( "IS_ETERNAL            CHAR(1), " );
168         createSql.append( "PRIMARY KEY (CACHE_KEY, REGION) " );
169         createSql.append( ");" );
170 
171         Statement sStatement = null;
172         try
173         {
174             sStatement = cConn.createStatement();
175         }
176         catch ( SQLException e )
177         {
178             log.error( "problem creating a statement.", e );
179         }
180 
181         try
182         {
183             sStatement.executeQuery( createSql.toString() );
184             sStatement.close();
185         }
186         catch ( SQLException e )
187         {
188             if ( e.toString().indexOf( "already exists" ) != -1 )
189             {
190                 newT = false;
191             }
192             else
193             {
194                 log.error( "Problem creating table.", e );
195             }
196         }
197 
198         // TODO create an index on SYSTEM_EXPIRE_TIME_SECONDS
199         String setupData[] = { "create index iKEY on " + tableName + " (CACHE_KEY, REGION)" };
200 
201         if ( newT )
202         {
203             for ( int i = 1; i < setupData.length; i++ )
204             {
205                 try
206                 {
207                     sStatement.executeQuery( setupData[i] );
208                 }
209                 catch ( SQLException e )
210                 {
211                     log.error( "Exception caught when creating index." + e );
212                 }
213             }
214         }
215     }
216 }